From 9730be60a8ef4a04358b0a026ce6b706de21d4e8 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 13 Mar 2011 11:29:05 -0500 Subject: Add package epoch support This comes with pacman 3.5, replacing the old "force" PKGBUILD option. We parse it and store it for now, but don't display it anywhere just yet. Also update a few queries relying on version differences in any of the multiple parts. Signed-off-by: Dan McGee --- main/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index a7cc2335..d0ccb12a 100644 --- a/main/models.py +++ b/main/models.py @@ -107,6 +107,7 @@ class Package(models.Model): 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) pkgdesc = models.CharField(max_length=255, null=True) url = models.CharField(max_length=255, null=True) filename = models.CharField(max_length=255) @@ -286,7 +287,8 @@ class Package(models.Model): '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.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 -- cgit v1.2.3-2-g168b From 5abe0727bfa9a4fab24afcccb66da7d8832bf6b9 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 13 Mar 2011 11:41:36 -0500 Subject: Show epoch in package version if != 0 Add a full_version property method to our package object that does the version formatting, and switch all templates displaying package versions over to this new method. Signed-off-by: Dan McGee --- main/models.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index d0ccb12a..727dc010 100644 --- a/main/models.py +++ b/main/models.py @@ -131,6 +131,12 @@ class Package(models.Model): def __unicode__(self): return self.pkgname + @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 get_absolute_url(self): return '/packages/%s/%s/%s/' % (self.repo.name.lower(), self.arch.name, self.pkgname) -- cgit v1.2.3-2-g168b From 3d6392391b3a0b37bea06f36f1998344ae170df2 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 15 Mar 2011 09:00:20 -0500 Subject: Check in actual models update for DateTime migration Signed-off-by: Dan McGee --- main/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index 727dc010..24befddd 100644 --- a/main/models.py +++ b/main/models.py @@ -349,7 +349,7 @@ class Todolist(models.Model): creator = models.ForeignKey(User) name = models.CharField(max_length=255) description = models.TextField() - date_added = models.DateField(auto_now_add=True) + date_added = models.DateTimeField(auto_now_add=True) objects = TodolistManager() def __unicode__(self): return self.name -- cgit v1.2.3-2-g168b From 06550061b6c01a5def1b5b418fe9cdcfb4bd0a99 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 22 Mar 2011 20:46:28 -0500 Subject: Add index to todo list date added Signed-off-by: Dan McGee --- main/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index 24befddd..c37ea915 100644 --- a/main/models.py +++ b/main/models.py @@ -349,8 +349,9 @@ class Todolist(models.Model): creator = models.ForeignKey(User) name = models.CharField(max_length=255) description = models.TextField() - date_added = models.DateTimeField(auto_now_add=True) + date_added = models.DateTimeField(auto_now_add=True, db_index=True) objects = TodolistManager() + def __unicode__(self): return self.name -- cgit v1.2.3-2-g168b From 3f6aaf6ebea24de850afd670a04810c6b25f9bc7 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 16 Mar 2011 12:03:40 -0500 Subject: Add 'staging' field to Repo model First steps towards implementing FS#23298. Signed-off-by: Dan McGee --- main/models.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index c37ea915..a6eec9ca 100644 --- a/main/models.py +++ b/main/models.py @@ -84,6 +84,8 @@ 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?") + 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.") svn_root = models.CharField(max_length=64, -- cgit v1.2.3-2-g168b From 2ccedba2b55994fb2ef4dc17c23592bd06aed1b5 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 22 Mar 2011 21:46:37 -0500 Subject: Fix potential logic bug in requiredby filtering Signed-off-by: Dan McGee --- main/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index a6eec9ca..4370fa24 100644 --- a/main/models.py +++ b/main/models.py @@ -193,7 +193,7 @@ class Package(models.Model): # find another package by this name in the opposite testing setup if not Package.objects.filter(pkgname=self.pkgname, - arch=self.arch).exclude(id=self.id, + arch=self.arch).exclude(id=self.id).exclude( repo__testing=self.repo.testing).exists(): # there isn't one? short circuit, all required by entries are fine return requiredby -- cgit v1.2.3-2-g168b From 01db07bad844e17e084f650b6732647f77a91c5c Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 7 Apr 2011 15:39:53 -0500 Subject: Use UTC datetime objects everywhere Rather than the twisted mix of local times and UTC times we currently have. Signed-off-by: Dan McGee --- main/models.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index 4370fa24..8d34731f 100644 --- a/main/models.py +++ b/main/models.py @@ -5,6 +5,7 @@ from django.contrib.sites.models import Site from main.utils import cache_function, make_choice from packages.models import PackageRelation +from datetime import datetime from itertools import groupby import pytz @@ -351,7 +352,7 @@ class Todolist(models.Model): creator = models.ForeignKey(User) name = models.CharField(max_length=255) description = models.TextField() - date_added = models.DateTimeField(auto_now_add=True, db_index=True) + date_added = models.DateTimeField(db_index=True) objects = TodolistManager() def __unicode__(self): @@ -383,10 +384,18 @@ class TodolistPkg(models.Model): db_table = 'todolist_pkgs' unique_together = (('list','pkg'),) +def set_todolist_fields(sender, **kwargs): + todolist = kwargs['instance'] + if not todolist.date_added: + todolist.date_added = datetime.utcnow() + # connect signals needed to keep cache in line with reality from main.utils import refresh_package_latest -from django.db.models.signals import post_save +from django.db.models.signals import pre_save, post_save + post_save.connect(refresh_package_latest, sender=Package, dispatch_uid="main.models") +pre_save.connect(set_todolist_fields, sender=Todolist, + dispatch_uid="main.models") # vim: set ts=4 sw=4 et: -- cgit v1.2.3-2-g168b From 77842a6c76095277b024505708bf528d455b9c89 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 7 Apr 2011 16:52:52 -0500 Subject: Consolidate caching black magic Get the stuff used to retrieve and refresh the latest date values all in the same place, and make it a bit more beautiful by refactoring it all into a common set of methods. Signed-off-by: Dan McGee --- main/models.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index 8d34731f..38120134 100644 --- a/main/models.py +++ b/main/models.py @@ -128,8 +128,7 @@ class Package(models.Model): class Meta: db_table = 'packages' ordering = ('pkgname',) - #get_latest_by = 'last_update' - #ordering = ('-last_update',) + get_latest_by = 'last_update' def __unicode__(self): return self.pkgname @@ -390,10 +389,10 @@ def set_todolist_fields(sender, **kwargs): todolist.date_added = datetime.utcnow() # connect signals needed to keep cache in line with reality -from main.utils import refresh_package_latest +from main.utils import refresh_latest from django.db.models.signals import pre_save, post_save -post_save.connect(refresh_package_latest, sender=Package, +post_save.connect(refresh_latest, sender=Package, dispatch_uid="main.models") pre_save.connect(set_todolist_fields, sender=Todolist, dispatch_uid="main.models") -- cgit v1.2.3-2-g168b From 6fe08cd68901e698f4a0741e177354a45c753b46 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 29 Mar 2011 17:39:59 -0500 Subject: Utilize Django 1.3 'on_delete' feature on several foreign keys The most important one here is PROTECT to keep people from making bone-headed plays and deleting an Arch or Repo and every package along with it. We can use this in a few other places, as well as some carefully placed SET_NULL indicators. Note that nothing here pushes deletion responsibilities down to the database, although that will probably happen in a future commit. Signed-off-by: Dan McGee --- main/models.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index 38120134..772d85bb 100644 --- a/main/models.py +++ b/main/models.py @@ -104,8 +104,10 @@ class Repo(models.Model): verbose_name_plural = 'repos' class Package(models.Model): - repo = models.ForeignKey(Repo, related_name="packages") - arch = models.ForeignKey(Arch, related_name="packages") + 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, db_index=True) pkgbase = models.CharField(max_length=255, db_index=True) pkgver = models.CharField(max_length=255) @@ -121,7 +123,8 @@ class Package(models.Model): last_update = models.DateTimeField(null=True, blank=True) files_last_update = models.DateTimeField(null=True, blank=True) packager_str = models.CharField(max_length=255) - packager = models.ForeignKey(User, null=True) + packager = models.ForeignKey(User, null=True, + on_delete=models.SET_NULL) flag_date = models.DateTimeField(null=True) objects = PackageManager() @@ -348,7 +351,7 @@ class PackageDepend(models.Model): db_table = 'package_depends' class Todolist(models.Model): - creator = models.ForeignKey(User) + creator = models.ForeignKey(User, on_delete=models.PROTECT) name = models.CharField(max_length=255) description = models.TextField() date_added = models.DateTimeField(db_index=True) -- cgit v1.2.3-2-g168b From d8022fd5720a8367a03bbff58668ed701a0bebcf Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 18 Apr 2011 23:00:30 -0500 Subject: Add a "Report a Bug" link We need Flyspray category data to make this more useful, and we can prefill the Subject and Category fields (along with putting it on the right project). Implements FS#23751. Signed-off-by: Dan McGee --- main/models.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index 772d85bb..d84a6af3 100644 --- a/main/models.py +++ b/main/models.py @@ -8,6 +8,7 @@ from packages.models import PackageRelation from datetime import datetime from itertools import groupby import pytz +from urllib import urlencode class UserProfile(models.Model): notify = models.BooleanField( @@ -89,6 +90,8 @@ class Repo(models.Model): 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=0, + 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.") @@ -294,6 +297,14 @@ class Package(models.Model): return "https://bugs.archlinux.org/?project=%d&string=%s" % \ (self.repo.bugs_project, self.pkgname) + def get_bug_report_link(self): + data = { + 'project': self.repo.bugs_project, + 'product_category': self.repo.bugs_category, + 'item_summary': '[%s]' % self.pkgname, + } + return "https://bugs.archlinux.org/newtask?%s" % urlencode(data) + def is_same_version(self, other): 'is this package similar, name and version-wise, to another' return self.pkgname == other.pkgname \ -- cgit v1.2.3-2-g168b From f1f01ecf0216441dd66f3bc6afc14fe104de291f Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 18 Apr 2011 23:26:10 -0500 Subject: Reimplement links code as template tags These were starting to get a bit too much inside the model itself, and they don't really belong there as they are view layer concerns anyway. Signed-off-by: Dan McGee --- main/models.py | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index d84a6af3..e8f189e7 100644 --- a/main/models.py +++ b/main/models.py @@ -8,7 +8,6 @@ from packages.models import PackageRelation from datetime import datetime from itertools import groupby import pytz -from urllib import urlencode class UserProfile(models.Model): notify = models.BooleanField( @@ -282,29 +281,6 @@ class Package(models.Model): return Package.objects.filter(arch__in=self.applicable_arches(), repo__testing=self.repo.testing, pkgbase=self.pkgbase).exclude(id=self.id) - def get_svn_link(self, svnpath): - linkbase = "http://projects.archlinux.org/svntogit/%s.git/tree/%s/%s/" - return linkbase % (self.repo.svn_root, self.pkgbase, svnpath) - - def get_arch_svn_link(self): - repo = self.repo.name.lower() - return self.get_svn_link("repos/%s-%s" % (repo, self.arch.name)) - - def get_trunk_svn_link(self): - return self.get_svn_link("trunk") - - def get_bugs_link(self): - return "https://bugs.archlinux.org/?project=%d&string=%s" % \ - (self.repo.bugs_project, self.pkgname) - - def get_bug_report_link(self): - data = { - 'project': self.repo.bugs_project, - 'product_category': self.repo.bugs_category, - 'item_summary': '[%s]' % self.pkgname, - } - return "https://bugs.archlinux.org/newtask?%s" % urlencode(data) - def is_same_version(self, other): 'is this package similar, name and version-wise, to another' return self.pkgname == other.pkgname \ -- cgit v1.2.3-2-g168b From 72bf6a02f3ee80cba40bb8556e161fd89ad7d886 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 9 May 2011 16:49:20 -0500 Subject: Ensure required by works for arch-agnostic packages We weren't showing required by entries for arch-specific packages that depended on arch-agnostic ones. Make the check a bit less specific for arch-agnostic packages similar to what we do for dependencies. Fixes FS#24184. Signed-off-by: Dan McGee --- main/models.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'main/models.py') diff --git a/main/models.py b/main/models.py index e8f189e7..59dc154b 100644 --- a/main/models.py +++ b/main/models.py @@ -188,9 +188,12 @@ class Package(models.Model): """ requiredby = PackageDepend.objects.select_related('pkg', 'pkg__arch', 'pkg__repo').filter( - pkg__arch__in=self.applicable_arches(), depname=self.pkgname).order_by( - 'pkg__pkgname', 'pkg__id') + 'pkg__pkgname', 'pkg__arch__name', 'pkg__repo__name') + if not self.arch.agnostic: + # make sure we match architectures if possible + requiredby = requiredby.filter( + pkg__arch__in=self.applicable_arches()) # sort out duplicate packages; this happens if something has a double # versioned dep such as a kernel module requiredby = [list(vals)[0] for k, vals in -- cgit v1.2.3-2-g168b