123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- 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, 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", 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-x86_64.iso" % (self.version, settings.BRANDING_SLUG, self.version)
- def magnet_uri(self):
- query = [
- ('dn', "%s-%s-x86_64.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:
|