diff options
Diffstat (limited to 'packages/models.py')
-rw-r--r-- | packages/models.py | 104 |
1 files changed, 96 insertions, 8 deletions
diff --git a/packages/models.py b/packages/models.py index d2fe1878..0d02ab31 100644 --- a/packages/models.py +++ b/packages/models.py @@ -1,3 +1,5 @@ +from collections import namedtuple + from django.db import models from django.db.models.signals import pre_save, post_save from django.contrib.auth.models import User @@ -38,6 +40,90 @@ class PackageRelation(models.Model): class Meta: unique_together = (('pkgbase', 'user', 'type'),) + +class SignoffSpecificationManager(models.Manager): + def get_from_package(self, pkg): + '''Utility method to pull all relevant name-version fields from a + package and get a matching signoff specification.''' + return self.get( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo) + + def get_or_default_from_package(self, pkg): + '''utility method to pull all relevant name-version fields from a + package and get a matching signoff specification, or return the default + base case.''' + try: + return self.get( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo) + except SignoffSpecification.DoesNotExist: + return DEFAULT_SIGNOFF_SPEC + +class SignoffSpecification(models.Model): + ''' + A specification for the signoff policy for this particular revision of a + package. The default is requiring two signoffs for a given package. These + are created only if necessary; e.g., if one wanted to override the + required=2 attribute, otherwise a sane default object is used. + ''' + pkgbase = models.CharField(max_length=255, db_index=True) + pkgver = models.CharField(max_length=255) + pkgrel = models.CharField(max_length=255) + epoch = models.PositiveIntegerField(default=0) + arch = models.ForeignKey('main.Arch') + repo = models.ForeignKey('main.Repo') + user = models.ForeignKey(User, null=True) + created = models.DateTimeField(editable=False) + required = models.PositiveIntegerField(default=2, + help_text="How many signoffs are required for this package?") + enabled = models.BooleanField(default=True, + help_text="Is this package eligible for signoffs?") + known_bad = models.BooleanField(default=False, + help_text="Is package is known to be broken in some way?") + comments = models.TextField(null=True, blank=True) + + objects = SignoffSpecificationManager() + + @property + def full_version(self): + if self.epoch > 0: + return u'%d:%s-%s' % (self.epoch, self.pkgver, self.pkgrel) + return u'%s-%s' % (self.pkgver, self.pkgrel) + + def __unicode__(self): + return u'%s-%s' % (self.pkgbase, self.full_version) + + +# fake default signoff spec when we don't have a persisted one in the database +FakeSignoffSpecification = namedtuple('FakeSignoffSpecification', + ('required', 'enabled', 'known_bad', 'comments')) +DEFAULT_SIGNOFF_SPEC = FakeSignoffSpecification(2, True, False, u'') + + +class SignoffManager(models.Manager): + def get_from_package(self, pkg, user, revoked=False): + '''Utility method to pull all relevant name-version fields from a + package and get a matching signoff.''' + not_revoked = not revoked + return self.get( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo, + revoked__isnull=not_revoked, user=user) + + def get_or_create_from_package(self, pkg, user): + '''Utility method to pull all relevant name-version fields from a + package and get or create a matching signoff.''' + return self.get_or_create( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo, + revoked=None, user=user) + + def for_package(self, pkg): + return self.select_related('user').filter( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo) + class Signoff(models.Model): ''' A signoff for a package (by pkgbase) at a given point in time. These are @@ -55,14 +141,14 @@ class Signoff(models.Model): revoked = models.DateTimeField(null=True) comments = models.TextField(null=True, blank=True) - REQUIRED = 2 + objects = SignoffManager() @property def packages(self): # TODO: delayed import to avoid circular reference from main.models import Package return Package.objects.normal().filter(pkgbase=self.pkgbase, - pkgver=self.pkgver, pkgrel=self.pkgrel, epoch=pkg.epoch, + pkgver=self.pkgver, pkgrel=self.pkgrel, epoch=self.epoch, arch=self.arch, repo=self.repo) @property @@ -72,8 +158,11 @@ class Signoff(models.Model): return u'%s-%s' % (self.pkgver, self.pkgrel) def __unicode__(self): - return u'%s-%s: %s' % ( - self.pkgbase, self.full_version, self.user) + revoked = u'' + if self.revoked: + revoked = u' (revoked)' + return u'%s-%s: %s%s' % ( + self.pkgbase, self.full_version, self.user, revoked) class PackageGroup(models.Model): ''' @@ -150,9 +239,8 @@ def remove_inactive_maintainers(sender, instance, created, **kwargs): post_save.connect(remove_inactive_maintainers, sender=User, dispatch_uid="packages.models") -pre_save.connect(set_created_field, sender=PackageRelation, - dispatch_uid="packages.models") -pre_save.connect(set_created_field, sender=Signoff, - dispatch_uid="packages.models") +for sender in (PackageRelation, SignoffSpecification, Signoff): + pre_save.connect(set_created_field, sender=sender, + dispatch_uid="packages.models") # vim: set ts=4 sw=4 et: |