Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ tags
collected_static/
testing/
env/
*.db
.vscode

.mypy_cache/

Expand Down
2 changes: 1 addition & 1 deletion main/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def filter(self, record):
try:
cache.set(self.prefix, 1, 300)
use_cache = (cache.get(self.prefix) == 1)
except:
except Exception:
use_cache = False

if use_cache:
Expand Down
128 changes: 71 additions & 57 deletions main/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from devel.models import DeveloperKey
from packages.alpm import AlpmAPI

from django.db.models.signals import pre_save


class PackageManager(models.Manager):
def flagged(self):
Expand All @@ -29,8 +31,9 @@ def restricted(self, user=None):

class Donor(models.Model):
name = models.CharField(max_length=255, unique=True)
visible = models.BooleanField(default=True,
help_text="Should we show this donor on the public page?")
visible = models.BooleanField(
default=True,
help_text="Should we show this donor on the public page?")
created = models.DateTimeField()

def __str__(self):
Expand All @@ -44,10 +47,11 @@ class Meta:

class Arch(models.Model):
name = models.CharField(max_length=255, unique=True)
agnostic = models.BooleanField(default=False,
help_text="Is this architecture non-platform specific?")
required_signoffs = models.PositiveIntegerField(default=2,
help_text="Number of signoffs required for packages of this architecture")
agnostic = models.BooleanField(
default=False, help_text="Is this architecture non-platform specific?")
required_signoffs = models.PositiveIntegerField(
default=2, help_text="Number of signoffs required \
for packages of this architecture")

def __str__(self):
return self.name
Expand All @@ -63,18 +67,24 @@ class Meta:

class Repo(models.Model):
name = models.CharField(max_length=255, unique=True)
testing = models.BooleanField(default=False,
help_text="Is this repo meant for package testing?")
public_testing = models.BooleanField(default=False,
help_text="Is this repo meant for package testing (without signoffs)?")
staging = models.BooleanField(default=False,
help_text="Is this repo meant for package staging?")
bugs_project = models.SmallIntegerField(default=1,
help_text="Flyspray project ID for this repository.")
bugs_category = models.SmallIntegerField(default=2,
help_text="Flyspray category ID for this repository.")
svn_root = models.CharField(max_length=64,
help_text="SVN root (e.g. path) for this repository.")
testing = models.BooleanField(
default=False, help_text="Is this repo meant for package testing?")

public_testing = models.BooleanField(
default=False,
help_text="Is this repo meant for package testing (without signoffs)?")

staging = models.BooleanField(
default=False, help_text="Is this repo meant for package staging?")

bugs_project = models.SmallIntegerField(
default=1, help_text="Flyspray project ID for this repository.")

bugs_category = models.SmallIntegerField(
default=2, help_text="Flyspray category ID for this repository.")

svn_root = models.CharField(
max_length=64, help_text="SVN root (e.g. path) for this repository.")

def __str__(self):
return self.name
Expand All @@ -88,10 +98,10 @@ class Meta:


class Package(models.Model):
repo = models.ForeignKey(Repo, related_name="packages",
on_delete=models.PROTECT)
arch = models.ForeignKey(Arch, related_name="packages",
on_delete=models.PROTECT)
repo = models.ForeignKey(
Repo, related_name="packages", on_delete=models.PROTECT)
arch = models.ForeignKey(
Arch, related_name="packages", on_delete=models.PROTECT)
pkgname = models.CharField(max_length=255)
pkgbase = models.CharField(max_length=255, db_index=True)
pkgver = models.CharField(max_length=255)
Expand All @@ -107,8 +117,8 @@ class Package(models.Model):
files_last_update = models.DateTimeField(null=True, blank=True)
created = models.DateTimeField()
packager_str = models.CharField('packager string', max_length=255)
packager = models.ForeignKey(User, null=True, blank=True,
on_delete=models.SET_NULL)
packager = models.ForeignKey(
User, null=True, blank=True, on_delete=models.SET_NULL)
signature_bytes = models.BinaryField('PGP signature', null=True)
flag_date = models.DateTimeField(null=True, blank=True)

Expand All @@ -126,17 +136,17 @@ def __str__(self):
@property
def full_version(self):
if self.epoch > 0:
return '%d:%s-%s' % (self.epoch, self.pkgver, self.pkgrel)
return '%s-%s' % (self.pkgver, self.pkgrel)
return '{0}:{1}-{2}'.format(self.epoch, self.pkgver, self.pkgrel)
return '{0}-{1}'.format(self.pkgver, self.pkgrel)

def get_absolute_url(self):
return '/packages/%s/%s/%s/' % (self.repo.name.lower(),
self.arch.name, self.pkgname)
return '/packages/{0}/{1}/{2}/'.format(
self.repo.name.lower(), self.arch.name, self.pkgname)

def get_full_url(self, proto='https'):
'''get a URL suitable for things like email including the domain'''
domain = Site.objects.get_current().domain
return '%s://%s%s' % (proto, domain, self.get_absolute_url())
return '{}://{}{}'.format(proto, domain, self.get_absolute_url())

@property
def signature(self):
Expand Down Expand Up @@ -201,8 +211,8 @@ def get_requiredby(self):
SELECT %s UNION ALL
SELECT z.name FROM packages_provision z WHERE z.pkg_id = %s
)'''
requiredby = Depend.objects.select_related('pkg',
'pkg__arch', 'pkg__repo').extra(
requiredby = Depend.objects.select_related(
'pkg', 'pkg__arch', 'pkg__repo').extra(
select={'sorttype': sorttype},
where=[name_clause], params=[self.pkgname, self.id]).order_by(
'sorttype', 'pkg__pkgname',
Expand All @@ -225,21 +235,21 @@ def get_requiredby(self):
elif self.pkgname == dep.name:
# depends on this package, so check it directly
if alpm.compare_versions(self.full_version,
dep.comparison, dep.version):
dep.comparison, dep.version):
new_rqd.append(dep)
else:
# it must be a provision of ours at this point
for provide in (p for p in provides if p.name == dep.name):
if alpm.compare_versions(provide.version,
dep.comparison, dep.version):
dep.comparison, dep.version):
new_rqd.append(dep)
break
requiredby = new_rqd

# sort out duplicate packages; this happens if something has a double
# versioned depend such as a kernel module
requiredby = [list(vals)[0] for _, vals in
groupby(requiredby, lambda x: x.pkg.id)]
requiredby = [list(vals)[0] for _, vals in groupby(
requiredby, lambda x: x.pkg.id)]
if not requiredby:
return requiredby

Expand All @@ -260,7 +270,7 @@ def grouper(depend):
# find another package by this name in a different testing or staging
# repo; if we can't, we can short-circuit some checks
repo_q = (Q(repo__testing=(not self.repo.testing)) |
Q(repo__staging=(not self.repo.staging)))
Q(repo__staging=(not self.repo.staging)))
if not Package.objects.filter(
repo_q, pkgname=self.pkgname, arch=self.arch
).exclude(id=self.id).exists():
Expand All @@ -275,9 +285,9 @@ def grouper(depend):
dep_pkgs = list(dep_pkgs)
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 and
d.pkg.repo.staging == self.repo.staging]
dep_pkgs = [d for d in dep_pkgs 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)
Expand Down Expand Up @@ -333,7 +343,8 @@ def reverse_conflicts(self):
continue
if not conflict.comparison or not conflict.version \
or alpm.compare_versions(self.full_version,
conflict.comparison, conflict.version):
conflict.comparison,
conflict.version):
new_pkgs.append(package)
return new_pkgs

Expand All @@ -346,13 +357,15 @@ def base_package(self):
try:
# start by looking for something in this repo
return Package.objects.normal().get(arch=self.arch,
repo=self.repo, pkgname=self.pkgbase)
repo=self.repo,
pkgname=self.pkgbase)
except Package.DoesNotExist:
# this package might be split across repos? find one
# that matches the correct [testing] repo flag
pkglist = Package.objects.normal().filter(arch=self.arch,
repo__testing=self.repo.testing,
repo__staging=self.repo.staging, 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
Expand All @@ -379,28 +392,30 @@ def flag_request(self):
# Note that we don't match on pkgrel here; this is because a pkgrel
# bump does not unflag a package so we can still show the same flag
# request from a different pkgrel.
request = FlagRequest.objects.filter(pkgbase=self.pkgbase,
repo=self.repo, pkgver=self.pkgver,
epoch=self.epoch, is_spam=False).latest()
request = FlagRequest.objects.filter(
pkgbase=self.pkgbase,
repo=self.repo, pkgver=self.pkgver,
epoch=self.epoch, is_spam=False).latest()
return request
except FlagRequest.DoesNotExist:
return None

def is_same_version(self, other):
'is this package similar, name and version-wise, to another'
return self.pkgname == other.pkgname \
and self.pkgver == other.pkgver \
and self.pkgrel == other.pkgrel \
and self.epoch == other.epoch
and self.pkgver == other.pkgver \
and self.pkgrel == other.pkgrel \
and self.epoch == other.epoch

def in_testing(self):
'''attempt to locate this package in a testing repo; if we are in
a testing repo we will always return None.'''
if self.repo.testing:
return None
try:
return Package.objects.normal().get(repo__testing=True,
pkgname=self.pkgname, arch=self.arch)
return Package.objects.normal().get(
repo__testing=True,
pkgname=self.pkgname, arch=self.arch)
except Package.DoesNotExist:
return None

Expand All @@ -410,8 +425,9 @@ def in_staging(self):
if self.repo.staging:
return None
try:
return Package.objects.normal().get(repo__staging=True,
pkgname=self.pkgname, arch=self.arch)
return Package.objects.normal().get(
repo__staging=True,
pkgname=self.pkgname, arch=self.arch)
except Package.DoesNotExist:
return None

Expand Down Expand Up @@ -444,11 +460,9 @@ class Meta:
db_table = 'package_files'


from django.db.models.signals import pre_save

# note: reporead sets the 'created' field on Package objects, so no signal
# listener is set up here to do so
pre_save.connect(set_created_field, sender=Donor,
dispatch_uid="main.models")
dispatch_uid="main.models")

# vim: set ts=4 sw=4 et:
6 changes: 3 additions & 3 deletions mirrors/fields.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from IPy import IP
from ipaddress import ip_address

from django import forms
from django.core import validators
Expand All @@ -11,7 +11,7 @@ def to_python(self, value):
if value in validators.EMPTY_VALUES:
return None
try:
value = IP(value)
value = ip_address(value)
except ValueError as e:
raise ValidationError(str(e))
return value
Expand All @@ -30,7 +30,7 @@ def get_internal_type(self):
def to_python(self, value):
if not value:
return None
return IP(value)
return ip_address(value)

def get_prep_value(self, value):
value = self.to_python(value)
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
-e git+git://github.com/fredj/cssmin.git@master#egg=cssmin
Django==2.2.10
IPy==1.00
Markdown==3.1.1
bencode.py==2.0.0
django-countries==5.5
Expand Down