summaryrefslogtreecommitdiff
path: root/main/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'main/models.py')
-rw-r--r--main/models.py79
1 files changed, 55 insertions, 24 deletions
diff --git a/main/models.py b/main/models.py
index a5d6c42e..70372823 100644
--- a/main/models.py
+++ b/main/models.py
@@ -6,6 +6,7 @@ from django.forms import ValidationError
from main.utils import cache_function, make_choice
from packages.models import PackageRelation
+from packages.models import Signoff as PackageSignoff
from datetime import datetime
from itertools import groupby
@@ -22,6 +23,25 @@ class PositiveBigIntegerField(models.BigIntegerField):
defaults.update(kwargs)
return super(PositiveBigIntegerField, self).formfield(**defaults)
+class PGPKeyField(models.CharField):
+ _south_introspects = True
+
+ def to_python(self, value):
+ if value == '':
+ return None
+ value = super(PGPKeyField, self).to_python(value)
+ # remove all spaces
+ value = value.replace(' ', '')
+ # prune prefixes, either 0x or 2048R/ type
+ if value.startswith('0x'):
+ value = value[2:]
+ value = value.split('/')[-1]
+ return value
+
+ def formfield(self, **kwargs):
+ # override so we don't set max_length form field attribute
+ return models.Field.formfield(self, **kwargs)
+
def validate_pgp_key_length(value):
if len(value) not in (8, 16, 40):
raise ValidationError(
@@ -45,7 +65,7 @@ class UserProfile(models.Model):
max_length=50,
help_text="Required field")
other_contact = models.CharField(max_length=100, null=True, blank=True)
- pgp_key = models.CharField(max_length=40, null=True, blank=True,
+ pgp_key = PGPKeyField(max_length=40, null=True, blank=True,
verbose_name="PGP key", validators=[RegexValidator(r'^[0-9A-F]+$',
"Ensure this value consists of only hex characters.", 'hex_char'),
validate_pgp_key_length],
@@ -73,6 +93,10 @@ class TodolistManager(models.Manager):
return self.filter(todolistpkg__complete=False).distinct()
class PackageManager(models.Manager):
+ def flagged(self):
+ """Used by dev dashboard."""
+ return self.filter(flag_date__isnull=False)
+
def normal(self):
return self.select_related('arch', 'repo')
@@ -183,16 +207,13 @@ class Package(models.Model):
@property
def signoffs(self):
- if 'signoffs_cache' in dir(self):
- return self.signoffs_cache
- self.signoffs_cache = list(Signoff.objects.filter(
- pkg=self,
- pkgver=self.pkgver,
- pkgrel=self.pkgrel))
- return self.signoffs_cache
+ return PackageSignoff.objects.select_related('user').filter(
+ pkgbase=self.pkgbase, pkgver=self.pkgver, pkgrel=self.pkgrel,
+ epoch=self.epoch, arch=self.arch, repo=self.repo)
def approved_for_signoff(self):
- return len(self.signoffs) >= 2
+ count = self.signoffs.filter(revoked__isnull=True).count()
+ return count >= PackageSignoff.REQUIRED
@cache_function(300)
def applicable_arches(self):
@@ -222,6 +243,7 @@ class Package(models.Model):
groupby(requiredby, lambda x: x.pkg.id)]
# find another package by this name in the opposite testing setup
+ # TODO: figure out staging exclusions too
if not Package.objects.filter(pkgname=self.pkgname,
arch=self.arch).exclude(id=self.id).exclude(
repo__testing=self.repo.testing).exists():
@@ -237,7 +259,8 @@ class Package(models.Model):
dep = dep_pkgs[0]
if len(dep_pkgs) > 1:
dep_pkgs = [d for d in dep_pkgs
- if d.pkg.repo.testing == self.repo.testing]
+ if d.pkg.repo.testing == self.repo.testing and
+ d.pkg.repo.staging == self.repo.staging]
if len(dep_pkgs) > 0:
dep = dep_pkgs[0]
trimmed.append(dep)
@@ -269,7 +292,8 @@ class Package(models.Model):
# grab the first though in case we fail
pkg = pkgs[0]
# prevents yet more DB queries, these lists should be short
- pkgs = [p for p in pkgs if p.repo.testing == self.repo.testing]
+ pkgs = [p for p in pkgs if p.repo.testing == self.repo.testing
+ and p.repo.staging == self.repo.staging]
if len(pkgs) > 0:
pkg = pkgs[0]
deps.append({'dep': dep, 'pkg': pkg})
@@ -283,13 +307,14 @@ class Package(models.Model):
"""
try:
# start by looking for something in this repo
- return Package.objects.get(arch=self.arch,
+ return Package.objects.normal().get(arch=self.arch,
repo=self.repo, pkgname=self.pkgbase)
except Package.DoesNotExist:
# this package might be split across repos? just find one
# that matches the correct [testing] repo flag
- pkglist = Package.objects.filter(arch=self.arch,
- repo__testing=self.repo.testing, pkgname=self.pkgbase)
+ pkglist = Package.objects.normal().filter(arch=self.arch,
+ repo__testing=self.repo.testing,
+ repo__staging=self.repo.staging, pkgname=self.pkgbase)
if len(pkglist) > 0:
return pkglist[0]
return None
@@ -299,11 +324,12 @@ class Package(models.Model):
Return all packages that were built with this one (e.g. share a pkgbase
value). The package this method is called on will never be in the list,
and we will never return a package that does not have the same
- repo.testing flag. For any non-split packages, the return value will be
- an empty list.
+ repo.testing and repo.staging flags. For any non-split packages, the
+ return value will be an empty list.
"""
- return Package.objects.filter(arch__in=self.applicable_arches(),
- repo__testing=self.repo.testing, pkgbase=self.pkgbase).exclude(id=self.id)
+ return Package.objects.normal().filter(arch__in=self.applicable_arches(),
+ repo__testing=self.repo.testing, repo__staging=self.repo.staging,
+ pkgbase=self.pkgbase).exclude(id=self.id)
def is_same_version(self, other):
'is this package similar, name and version-wise, to another'
@@ -323,6 +349,17 @@ class Package(models.Model):
except Package.DoesNotExist:
return None
+ def in_staging(self):
+ '''attempt to locate this package in a staging repo; if we are in
+ a staging repo we will always return None.'''
+ if self.repo.staging:
+ return None
+ try:
+ return Package.objects.normal().get(repo__staging=True,
+ pkgname=self.pkgname, arch=self.arch)
+ except Package.DoesNotExist:
+ return None
+
def elsewhere(self):
'''attempt to locate this package anywhere else, regardless of
architecture or repository. Excludes this package from the list.'''
@@ -330,12 +367,6 @@ class Package(models.Model):
pkgname=self.pkgname).exclude(id=self.id).order_by(
'arch__name', 'repo__name')
-class Signoff(models.Model):
- pkg = models.ForeignKey(Package)
- pkgver = models.CharField(max_length=255)
- pkgrel = models.CharField(max_length=255)
- packager = models.ForeignKey(User)
-
class PackageFile(models.Model):
pkg = models.ForeignKey(Package)
is_directory = models.BooleanField(default=False)