diff options
author | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-05-25 19:34:21 -0400 |
---|---|---|
committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-05-25 19:34:21 -0400 |
commit | 1a1fd4a3d6aa7f6b2338f7751f5f97a30a059a04 (patch) | |
tree | f608874663d24f19ecf175ec556f2a330d47a726 /releng | |
parent | 747a562ddca10e29dd003e8b3c59f8f384d1bc8d (diff) | |
parent | cd7222047b41ac3efa389a22fdd22148d03c1d61 (diff) |
Merge tag 'release_2014-03-22' into archweb-generic
Fix long filenames; local storage for filter prefs
Conflicts:
templates/public/download.html
Diffstat (limited to 'releng')
-rw-r--r-- | releng/migrations/0008_auto__del_field_release_torrent_infohash__del_field_release_file_size.py | 118 | ||||
-rw-r--r-- | releng/models.py | 10 | ||||
-rw-r--r-- | releng/urls.py | 2 | ||||
-rw-r--r-- | releng/views.py | 45 |
4 files changed, 170 insertions, 5 deletions
diff --git a/releng/migrations/0008_auto__del_field_release_torrent_infohash__del_field_release_file_size.py b/releng/migrations/0008_auto__del_field_release_torrent_infohash__del_field_release_file_size.py new file mode 100644 index 00000000..4a80fd8e --- /dev/null +++ b/releng/migrations/0008_auto__del_field_release_torrent_infohash__del_field_release_file_size.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.delete_column(u'releng_release', 'torrent_infohash') + db.delete_column(u'releng_release', 'file_size') + + def backwards(self, orm): + db.add_column(u'releng_release', 'torrent_infohash', + self.gf('django.db.models.fields.CharField')(default='', max_length=40, blank=True), + keep_default=False) + db.add_column(u'releng_release', 'file_size', + self.gf('main.fields.PositiveBigIntegerField')(null=True, blank=True), + keep_default=False) + + models = { + u'releng.architecture': { + 'Meta': {'object_name': 'Architecture'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.bootloader': { + 'Meta': {'object_name': 'Bootloader'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.boottype': { + 'Meta': {'object_name': 'BootType'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.clockchoice': { + 'Meta': {'object_name': 'ClockChoice'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.filesystem': { + 'Meta': {'object_name': 'Filesystem'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.hardwaretype': { + 'Meta': {'object_name': 'HardwareType'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.installtype': { + 'Meta': {'object_name': 'InstallType'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.iso': { + 'Meta': {'object_name': 'Iso'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'removed': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}) + }, + u'releng.isotype': { + 'Meta': {'object_name': 'IsoType'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.module': { + 'Meta': {'object_name': 'Module'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.release': { + 'Meta': {'ordering': "('-release_date', '-version')", 'object_name': 'Release'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'info': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'kernel_version': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'md5_sum': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'release_date': ('django.db.models.fields.DateField', [], {'db_index': 'True'}), + 'sha1_sum': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}), + 'torrent_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'version': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'}) + }, + u'releng.source': { + 'Meta': {'object_name': 'Source'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + u'releng.test': { + 'Meta': {'object_name': 'Test'}, + 'architecture': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.Architecture']"}), + 'boot_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.BootType']"}), + 'bootloader': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.Bootloader']"}), + 'clock_choice': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.ClockChoice']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'filesystem': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.Filesystem']"}), + 'hardware_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.HardwareType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'install_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.InstallType']"}), + 'ip_address': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), + 'iso': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.Iso']"}), + 'iso_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.IsoType']"}), + 'modules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['releng.Module']", 'null': 'True', 'blank': 'True'}), + 'rollback_filesystem': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rollback_test_set'", 'null': 'True', 'to': u"orm['releng.Filesystem']"}), + 'rollback_modules': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'rollback_test_set'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['releng.Module']"}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['releng.Source']"}), + 'success': ('django.db.models.fields.BooleanField', [], {}), + 'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'user_name': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + } + } + + complete_apps = ['releng'] diff --git a/releng/models.py b/releng/models.py index 47803a36..a3af54f9 100644 --- a/releng/models.py +++ b/releng/models.py @@ -119,14 +119,13 @@ class Release(models.Model): release_date = models.DateField(db_index=True) version = models.CharField(max_length=50, unique=True) kernel_version = models.CharField(max_length=50, blank=True) - torrent_infohash = models.CharField(max_length=40, blank=True) md5_sum = models.CharField('MD5 digest', max_length=32, blank=True) sha1_sum = models.CharField('SHA1 digest', max_length=40, blank=True) - file_size = PositiveBigIntegerField(null=True, blank=True) created = models.DateTimeField(editable=False) available = models.BooleanField(default=True) info = models.TextField('Public information', blank=True) - torrent_data = models.TextField(blank=True) + torrent_data = models.TextField(blank=True, + help_text="base64-encoded torrent file") class Meta: get_latest_by = 'release_date' @@ -150,8 +149,9 @@ class Release(models.Model): ] if settings.TORRENT_TRACKERS: query.extend(('tr', uri) for uri in settings.TORRENT_TRACKERS) - if self.torrent_infohash: - query.insert(0, ('xt', "urn:btih:%s" % self.torrent_infohash)) + metadata = self.torrent() + if metadata and 'info_hash' in metadata: + query.insert(0, ('xt', "urn:btih:%s" % metadata['info_hash'])) return "magnet:?%s" % '&'.join(['%s=%s' % (k, v) for k, v in query]) def info_html(self): diff --git a/releng/urls.py b/releng/urls.py index 76c36345..ca76eb25 100644 --- a/releng/urls.py +++ b/releng/urls.py @@ -14,6 +14,8 @@ feedback_patterns = patterns('releng.views', releases_patterns = patterns('releng.views', (r'^$', ReleaseListView.as_view(), {}, 'releng-release-list'), + (r'^json/$', + 'releases_json', {}, 'releng-release-list-json'), (r'^(?P<version>[-.\w]+)/$', ReleaseDetailView.as_view(), {}, 'releng-release-detail'), (r'^(?P<version>[-.\w]+)/torrent/$', diff --git a/releng/views.py b/releng/views.py index bc7ddb34..af25b966 100644 --- a/releng/views.py +++ b/releng/views.py @@ -1,7 +1,10 @@ from base64 import b64decode +import json from django import forms from django.conf import settings +from django.core.serializers.json import DjangoJSONEncoder +from django.core.urlresolvers import reverse from django.db.models import Count, Max from django.http import Http404, HttpResponse from django.shortcuts import get_object_or_404, redirect, render @@ -238,4 +241,46 @@ def release_torrent(request, version): response['Content-Disposition'] = 'attachment; filename=%s' % filename return response + +class ReleaseJSONEncoder(DjangoJSONEncoder): + release_attributes = ('release_date', 'version', 'kernel_version', + 'created', 'md5_sum', 'sha1_sum') + + def default(self, obj): + if hasattr(obj, '__iter__'): + # mainly for queryset serialization + return list(obj) + if isinstance(obj, Release): + data = {attr: getattr(obj, attr) or None + for attr in self.release_attributes} + data['available'] = obj.available + data['iso_url'] = '/' + obj.iso_url() + data['magnet_uri'] = obj.magnet_uri() + data['torrent_url'] = reverse('releng-release-torrent', args=[obj.version]) + data['info'] = obj.info_html() + torrent_data = obj.torrent() + if torrent_data: + torrent_data.pop('url_list', None) + data['torrent'] = torrent_data + return data + return super(ReleaseJSONEncoder, self).default(obj) + + +def releases_json(request): + releases = Release.objects.all() + try: + latest_version = Release.objects.filter(available=True).values_list( + 'version', flat=True).latest() + except Release.DoesNotExist: + latest_version = None + + data = { + 'version': 1, + 'releases': releases, + 'latest_version': latest_version, + } + to_json = json.dumps(data, ensure_ascii=False, cls=ReleaseJSONEncoder) + response = HttpResponse(to_json, content_type='application/json') + return response + # vim: set ts=4 sw=4 et: |