diff options
Diffstat (limited to 'releng/models.py')
-rw-r--r-- | releng/models.py | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/releng/models.py b/releng/models.py new file mode 100644 index 00000000..a4af81ab --- /dev/null +++ b/releng/models.py @@ -0,0 +1,193 @@ +from base64 import b64decode +from bencode import bdecode, bencode +from datetime import datetime +import hashlib +from pytz import utc + +from django.conf import settings +from django.core.urlresolvers import reverse +from django.db import models +from django.db.models.signals import pre_save +from django.utils.safestring import mark_safe + +from main.fields import PositiveBigIntegerField +from main.utils import set_created_field, parse_markdown + + +class IsoOption(models.Model): + name = models.CharField(max_length=200) + + def __unicode__(self): + return self.name + + class Meta: + abstract = True + + +class RollbackOption(IsoOption): + class Meta: + abstract = True + + +class Iso(models.Model): + name = models.CharField(max_length=255) + created = models.DateTimeField(editable=False) + removed = models.DateTimeField(null=True, blank=True, default=None) + active = models.BooleanField(default=True) + + def get_absolute_url(self): + return reverse('releng-results-iso', args=[self.pk]) + + def __unicode__(self): + return self.name + + class Meta: + verbose_name = 'ISO' + + +class Architecture(IsoOption): + pass + + +class IsoType(IsoOption): + class Meta: + verbose_name = 'ISO type' + + +class BootType(IsoOption): + pass + + +class HardwareType(IsoOption): + pass + + +class InstallType(IsoOption): + pass + + +class Source(IsoOption): + pass + + +class ClockChoice(IsoOption): + pass + + +class Filesystem(RollbackOption): + pass + + +class Module(RollbackOption): + pass + + +class Bootloader(IsoOption): + pass + + +class Test(models.Model): + user_name = models.CharField(max_length=500) + user_email = models.EmailField('email address') + ip_address = models.GenericIPAddressField('IP address', unpack_ipv4=True) + created = models.DateTimeField(editable=False) + + iso = models.ForeignKey(Iso) + architecture = models.ForeignKey(Architecture) + iso_type = models.ForeignKey(IsoType) + boot_type = models.ForeignKey(BootType) + hardware_type = models.ForeignKey(HardwareType) + install_type = models.ForeignKey(InstallType) + source = models.ForeignKey(Source) + clock_choice = models.ForeignKey(ClockChoice) + filesystem = models.ForeignKey(Filesystem) + modules = models.ManyToManyField(Module, null=True, blank=True) + bootloader = models.ForeignKey(Bootloader) + rollback_filesystem = models.ForeignKey(Filesystem, + related_name="rollback_test_set", null=True, blank=True) + rollback_modules = models.ManyToManyField(Module, + related_name="rollback_test_set", null=True, blank=True) + + success = models.BooleanField(default=True) + comments = models.TextField(null=True, blank=True) + + +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) + md5_sum = models.CharField('MD5 digest', max_length=32, blank=True) + sha1_sum = models.CharField('SHA1 digest', max_length=40, blank=True) + created = models.DateTimeField(editable=False) + last_modified = models.DateTimeField(editable=False) + available = models.BooleanField(default=True) + info = models.TextField('Public information', blank=True) + torrent_data = models.TextField(blank=True, + help_text="base64-encoded torrent file") + + class Meta: + get_latest_by = 'release_date' + ordering = ('-release_date', '-version') + + def __unicode__(self): + return self.version + + def get_absolute_url(self): + return reverse('releng-release-detail', args=[self.version]) + + def dir_path(self): + return "iso/%s/" % self.version + + def iso_url(self): + return "iso/%s/%s-%s-dual.iso" % (self.version, settings.BRANDING_SLUG, self.version) + + def magnet_uri(self): + query = [ + ('dn', "%s-%s-dual.iso" % (settings.BRANDING_SLUG, self.version)), + ] + if settings.TORRENT_TRACKERS: + query.extend(('tr', uri) for uri in settings.TORRENT_TRACKERS) + 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): + return mark_safe(parse_markdown(self.info)) + + def torrent(self): + try: + data = b64decode(self.torrent_data.encode('utf-8')) + except TypeError: + return None + if not data: + return None + data = bdecode(data) + # transform the data into a template-friendly dict + info = data.get('info', {}) + metadata = { + 'comment': data.get('comment', None), + 'created_by': data.get('created by', None), + 'creation_date': None, + 'announce': data.get('announce', None), + 'file_name': info.get('name', None), + 'file_length': info.get('length', None), + 'piece_count': len(info.get('pieces', '')) / 20, + 'piece_length': info.get('piece length', None), + 'url_list': data.get('url-list', []), + 'info_hash': None, + } + if 'creation date' in data: + created= datetime.utcfromtimestamp(data['creation date']) + metadata['creation_date'] = created.replace(tzinfo=utc) + if info: + metadata['info_hash'] = hashlib.sha1(bencode(info)).hexdigest() + + return metadata + + +for model in (Iso, Test, Release): + pre_save.connect(set_created_field, sender=model, + dispatch_uid="releng.models") + +# vim: set ts=4 sw=4 et: |