From 92e13e0670661a542db646c668780cb4620c0b13 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 20 Jun 2011 01:09:20 -0500 Subject: Differentiate between no filelist and empty filelist We had these two cases munged together before; some packages have seen filelist updates but simply don't have any files ('firefox-i18n' for example). Signed-off-by: Dan McGee --- templates/packages/files-list.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'templates/packages') diff --git a/templates/packages/files-list.html b/templates/packages/files-list.html index bb89b663..95a85d24 100644 --- a/templates/packages/files-list.html +++ b/templates/packages/files-list.html @@ -2,12 +2,16 @@

Note: This file list was generated from a previous version of the package; it may be out of date.

{% endif %} -{% if files.count %} +{% if pkg.files_last_update %} +{% if files|length %} {% else %} +

Package has no files.

+{% endif %} +{% else %}

No file list available.

{% endif %} -- cgit v1.2.3-54-g00ecf From 33b9bf44aac4b70fa4cc6e9d1e82fb556b836801 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 29 Jun 2011 09:17:00 -0500 Subject: Use normal date format on signoffs page Fixes FS#24949. Signed-off-by: Dan McGee --- templates/packages/signoffs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates/packages') diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html index b7184039..93be4979 100644 --- a/templates/packages/signoffs.html +++ b/templates/packages/signoffs.html @@ -27,7 +27,7 @@

Package Signoffs

{{ pkg.pkgname }} {{ pkg.full_version }} - {{ pkg.last_update }} + {{ pkg.last_update|date }} {{ target }} {{ pkg.approved_for_signoff|yesno:"Yes,No" }} -- cgit v1.2.3-54-g00ecf From fa65115afccc612dd902b6324069a0b312f6a0f6 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 3 Jul 2011 18:56:29 -0500 Subject: Add rel="nofollow" to download package links Signed-off-by: Dan McGee --- templates/packages/details.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates/packages') diff --git a/templates/packages/details.html b/templates/packages/details.html index 1926abc2..68016501 100644 --- a/templates/packages/details.html +++ b/templates/packages/details.html @@ -38,7 +38,7 @@

Package Actions

onclick="return !window.open('/packages/flaghelp/','FlagHelp', 'height=350,width=450,location=no,scrollbars=yes,menubars=no,toolbars=no,resizable=no');">(?) {% endif %} -
  • Download From Mirror
  • +
  • Download From Mirror
  • {% if perms.main.change_package %} -- cgit v1.2.3-54-g00ecf From 1bcb2b7ed0bdb11ea3b22cdbc93192b4259303d5 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 3 Jul 2011 18:56:05 -0500 Subject: Add a default datetime format Signed-off-by: Dan McGee --- settings.py | 1 + templates/packages/details.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'templates/packages') diff --git a/settings.py b/settings.py index e0d1b1a2..5cca6047 100644 --- a/settings.py +++ b/settings.py @@ -32,6 +32,7 @@ # Default date format in templates for 'date' filter DATE_FORMAT = 'Y-m-d' +DATETIME_FORMAT = 'Y-m-d H:i' # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a # trailing slash. diff --git a/templates/packages/details.html b/templates/packages/details.html index 68016501..7972b9ab 100644 --- a/templates/packages/details.html +++ b/templates/packages/details.html @@ -144,7 +144,7 @@

    Versions Elsewhere

    {% with pkg.packager as pkgr %}{% if pkgr %}{% userpkgs pkgr %}{% else %}{{ pkg.packager_str }}{% endif %}{% endwith %} Build Date: - {{ pkg.build_date }} UTC + {{ pkg.build_date|date:"DATETIME_FORMAT" }} UTC Last Updated: {{ pkg.last_update|date }} -- cgit v1.2.3-54-g00ecf From 52363933c0b04848a26c8ed65e7f975ccfc5b846 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 6 Jul 2011 11:00:58 -0500 Subject: Initial signoff template changes Signed-off-by: Dan McGee --- templates/packages/signoffs.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'templates/packages') diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html index 93be4979..ab00b645 100644 --- a/templates/packages/signoffs.html +++ b/templates/packages/signoffs.html @@ -3,11 +3,12 @@ {% block navbarclass %}anb-packages{% endblock %} {% block content %} -{% if packages %}

    Package Signoffs

    +

    {{ packages|length }} package{{ packages|pluralize }} found.

    + @@ -43,7 +44,7 @@

    Package Signoffs

    - {% endfor %} + {% endfor %}
    @@ -57,5 +58,4 @@

    Package Signoffs

    headers: { 6: { sorter: false } } }); }); -{% endif %} {% endblock %} -- cgit v1.2.3-54-g00ecf From 0f9a1da2cb9dd2a20a5e12bb346ec460b4335f9f Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 6 Jul 2011 11:08:22 -0500 Subject: Move package signoff URL to more logical location Signed-off-by: Dan McGee --- packages/models.py | 3 +-- packages/urls.py | 3 +-- packages/views.py | 6 ++---- templates/packages/signoffs.html | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) (limited to 'templates/packages') diff --git a/packages/models.py b/packages/models.py index 0983c642..faf5f398 100644 --- a/packages/models.py +++ b/packages/models.py @@ -25,8 +25,7 @@ class PackageRelation(models.Model): def get_associated_packages(self): # TODO: delayed import to avoid circular reference from main.models import Package - return Package.objects.filter(pkgbase=self.pkgbase).select_related( - 'arch', 'repo') + return Package.objects.normal().filter(pkgbase=self.pkgbase) def repositories(self): packages = self.get_associated_packages() diff --git a/packages/urls.py b/packages/urls.py index d408e6cf..d7d01170 100644 --- a/packages/urls.py +++ b/packages/urls.py @@ -9,14 +9,13 @@ (r'^flag/done/$', 'flag_confirmed', {}, 'package-flag-confirmed'), (r'^unflag/$', 'unflag'), (r'^unflag/all/$', 'unflag_all'), + (r'^signoff/$', 'signoff_package'), (r'^download/$', 'download'), ) urlpatterns = patterns('packages.views', (r'^flaghelp/$', 'flaghelp'), (r'^signoffs/$', 'signoffs', {}, 'package-signoffs'), - (r'^signoff_package/(?P[A-z0-9]+)/(?P[A-z0-9\-+.]+)/$', - 'signoff_package'), (r'^update/$', 'update'), (r'^$', 'search', {}, 'packages-search'), diff --git a/packages/views.py b/packages/views.py index 01d01e20..d12583f0 100644 --- a/packages/views.py +++ b/packages/views.py @@ -372,11 +372,9 @@ def signoffs(request): @permission_required('main.change_package') @never_cache -def signoff_package(request, arch, pkgname): +def signoff_package(request, name, repo, arch): pkg = get_object_or_404(Package, - arch__name=arch, - pkgname=pkgname, - repo__testing=True) + pkgname=name, repo__name__iexact=repo, arch__name=arch) signoff, created = Signoff.objects.get_or_create( pkg=pkg, diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html index ab00b645..b1153d7c 100644 --- a/templates/packages/signoffs.html +++ b/templates/packages/signoffs.html @@ -34,7 +34,7 @@

    Package Signoffs

    {{ pkg.approved_for_signoff|yesno:"Yes,No" }}
      -
    • Signoff
    • {% for signoff in pkg.signoffs %} -- cgit v1.2.3-54-g00ecf From f95abca269aec1409ec1e57de4c6cb5ba1da6369 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 6 Jul 2011 12:05:19 -0500 Subject: Refactor code to use new signoff model This moves signoff creation and display to the new packages.Signoff model. Signed-off-by: Dan McGee --- main/models.py | 14 ++--- packages/models.py | 2 + packages/views.py | 120 ++++++++++++++++++++++++++++++--------- templates/packages/signoffs.html | 25 ++++---- 4 files changed, 115 insertions(+), 46 deletions(-) (limited to 'templates/packages') diff --git a/main/models.py b/main/models.py index 2f549081..473144da 100644 --- a/main/models.py +++ b/main/models.py @@ -6,6 +6,7 @@ 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 @@ -206,16 +207,13 @@ def maintainers(self): @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): diff --git a/packages/models.py b/packages/models.py index 55725e8e..7ae2d57a 100644 --- a/packages/models.py +++ b/packages/models.py @@ -55,6 +55,8 @@ class Signoff(models.Model): revoked = models.DateTimeField(null=True) comments = models.TextField(null=True, blank=True) + REQUIRED = 2 + @property def packages(self): # TODO: delayed import to avoid circular reference diff --git a/packages/views.py b/packages/views.py index d12583f0..3d9032e6 100644 --- a/packages/views.py +++ b/packages/views.py @@ -8,7 +8,7 @@ from django.core.serializers.json import DjangoJSONEncoder from django.db.models import Q from django.http import HttpResponse, Http404 -from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import get_object_or_404, get_list_or_404, redirect from django.template import loader, Context from django.utils import simplejson from django.views.decorators.cache import never_cache @@ -18,15 +18,16 @@ from django.views.generic.simple import direct_to_template from datetime import datetime +from operator import attrgetter import string from urllib import urlencode -from main.models import Package, PackageFile -from main.models import Arch, Repo, Signoff -from main.utils import make_choice +from main.models import Package, PackageFile, Arch, Repo +from main.utils import make_choice, groupby_preserve_order, PackageStandin from mirrors.models import MirrorUrl -from .models import PackageRelation, PackageGroup -from .utils import get_group_info, get_differences_info, get_wrong_permissions +from .models import PackageRelation, PackageGroup, Signoff +from .utils import (get_group_info, get_differences_info, + get_wrong_permissions, get_current_signoffs) class PackageJSONEncoder(DjangoJSONEncoder): pkg_attributes = [ 'pkgname', 'pkgbase', 'repo', 'arch', 'pkgver', @@ -349,38 +350,101 @@ def unflag_all(request, name, repo, arch): pkgs.update(flag_date=None) return redirect(pkg) +class PackageSignoffGroup(object): + '''Encompasses all packages in testing with the same pkgbase.''' + def __init__(self, packages, target_repo=None, signoffs=None): + if len(packages) == 0: + raise Exception + self.packages = packages + self.target_repo = target_repo + self.signoffs = signoffs + + first = packages[0] + self.pkgbase = first.pkgbase + self.arch = first.arch + self.repo = first.repo + self.version = '' + + version = first.full_version + if all(version == pkg.full_version for pkg in packages): + self.version = version + + @property + def package(self): + '''Try and return a relevant single package object representing this + group. Start by seeing if there is only one package, then look for the + matching package by name, finally falling back to a standin package + object.''' + if len(self.packages) == 1: + return self.packages[0] + + same_pkgs = [p for p in self.packages if p.pkgname == p.pkgbase] + if same_pkgs: + return same_pkgs[0] + + return PackageStandin(self.packages[0]) + + def find_signoffs(self, all_signoffs): + '''Look through a list of Signoff objects for ones matching this + particular group and store them on the object.''' + if self.signoffs is None: + self.signoffs = [] + for s in all_signoffs: + if s.pkgbase != self.pkgbase: + continue + if self.version and not s.full_version == self.version: + continue + if s.arch_id == self.arch.id and s.repo_id == self.repo.id: + self.signoffs.append(s) + + def approved(self): + if self.signoffs: + good_signoffs = [s for s in self.signoffs if not s.revoked] + return len(good_signoffs) >= Signoff.REQUIRED + return False + @permission_required('main.change_package') @never_cache def signoffs(request): - packages = Package.objects.select_related('arch', 'repo', 'signoffs').filter(repo__testing=True).order_by("pkgname") - package_list = [] - - q_pkgname = Package.objects.filter(repo__testing=True).values('pkgname').distinct().query - package_repos = Package.objects.values('pkgname', 'repo__name').exclude(repo__testing=True).filter(pkgname__in=q_pkgname) - pkgtorepo = dict() - for pr in package_repos: - pkgtorepo[pr['pkgname']] = pr['repo__name'] - - for package in packages: - if package.pkgname in pkgtorepo: - repo = pkgtorepo[package.pkgname] - else: - repo = "Unknown" - package_list.append((package, repo)) + test_pkgs = Package.objects.normal().filter(repo__testing=True) + packages = test_pkgs.order_by('pkgname') + + # Collect all pkgbase values in testing repos + q_pkgbase = test_pkgs.values('pkgbase') + package_repos = Package.objects.order_by().values_list( + 'pkgbase', 'repo__name').filter( + repo__testing=False, repo__staging=False, + pkgbase__in=q_pkgbase).distinct() + pkgtorepo = dict(package_repos) + + # Collect all existing signoffs for these packages + signoffs = get_current_signoffs() + + same_pkgbase_key = lambda x: (x.repo.name, x.arch.name, x.pkgbase) + grouped = groupby_preserve_order(packages, same_pkgbase_key) + signoff_groups = [] + for group in grouped: + signoff_group = PackageSignoffGroup(group) + signoff_group.target_repo = pkgtorepo.get(signoff_group.pkgbase, + "Unknown") + signoff_group.find_signoffs(signoffs) + signoff_groups.append(signoff_group) + + signoff_groups.sort(key=attrgetter('pkgbase')) + return direct_to_template(request, 'packages/signoffs.html', - {'packages': package_list}) + {'signoff_groups': signoff_groups}) @permission_required('main.change_package') @never_cache def signoff_package(request, name, repo, arch): - pkg = get_object_or_404(Package, - pkgname=name, repo__name__iexact=repo, arch__name=arch) + packages = get_list_or_404(Package, pkgbase=name, + arch__name=arch, repo__name__iexact=repo, repo__testing=True) + pkg = packages[0] signoff, created = Signoff.objects.get_or_create( - pkg=pkg, - pkgver=pkg.pkgver, - pkgrel=pkg.pkgrel, - packager=request.user) + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo, user=request.user) if request.is_ajax(): data = { diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html index b1153d7c..6014396c 100644 --- a/templates/packages/signoffs.html +++ b/templates/packages/signoffs.html @@ -7,13 +7,15 @@

      Package Signoffs

      -

      {{ packages|length }} package{{ packages|pluralize }} found.

      +

      {{ signoff_groups|length }} signoff group{{ signoff_groups|pluralize }} found. + A "signoff group" consists of packages grouped by pkgbase, architecture, and repository.

      - + + @@ -22,28 +24,31 @@

      Package Signoffs

      - {% for pkg,target in packages %} + {% for group in signoff_groups %} + {% with group.package as pkg %} + - - + + + {% endwith %} {% endfor %}
      ArchPackagePackage Base# of Packages Version Last Updated Target Repo
      {{ pkg.arch.name }} {{ pkg.pkgname }}{{ group.packages|length }} {{ pkg.full_version }} {{ pkg.last_update|date }}{{ target }} - {{ pkg.approved_for_signoff|yesno:"Yes,No" }}{{ group.target_repo }} + {{ group.approved|yesno:"Yes,No" }}
      • Signoff + title="Signoff {{ pkg.pkgname }} for {{ pkg.arch }}">Signoff
      • - {% for signoff in pkg.signoffs %} -
      • - {{signoff.packager}}
      • + {% for signoff in group.signoffs %} +
      • + {{ signoff.user }}{% if signoff.revoked %} (revoked){% endif %}
      • {% endfor %}
      -- cgit v1.2.3-54-g00ecf From 59badd066238c946cbe64d7002a260b9de606938 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 15 Jul 2011 10:10:11 -0500 Subject: Add pacakge count to group/split package details page Signed-off-by: Dan McGee --- templates/packages/packages_list.html | 1 + 1 file changed, 1 insertion(+) (limited to 'templates/packages') diff --git a/templates/packages/packages_list.html b/templates/packages/packages_list.html index c897aac5..ccc091d8 100644 --- a/templates/packages/packages_list.html +++ b/templates/packages/packages_list.html @@ -5,6 +5,7 @@ {% block content %}

      {{ list_title }} - {{ name }} ({{ arch.name }})

      +

      {{ packages|length }} package{{ packages|pluralize }} found.

      -- cgit v1.2.3-54-g00ecf From ae12aa58fd6c6965b3eadcf3843ea68602069c60 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 25 Jul 2011 12:27:46 -0500 Subject: Small template updates * Show full version in developer dashboard out of date pane * Link packages on flag confirmation screen Signed-off-by: Dan McGee --- templates/devel/index.html | 2 +- templates/packages/flag_confirmed.html | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'templates/packages') diff --git a/templates/devel/index.html b/templates/devel/index.html index 1689319b..ad101145 100644 --- a/templates/devel/index.html +++ b/templates/devel/index.html @@ -27,7 +27,7 @@

      My Flagged Packages

      - + diff --git a/templates/packages/flag_confirmed.html b/templates/packages/flag_confirmed.html index 02c24f72..9ef316cb 100644 --- a/templates/packages/flag_confirmed.html +++ b/templates/packages/flag_confirmed.html @@ -4,12 +4,13 @@ {% block content %}
      -

      Package Flagged - {{ package.pkgname }}

      +

      Package Flagged - {{ package.pkgname }}

      Thank you, the maintainers have been notified the following packages are out-of-date:

        {% for pkg in packages %} -
      • {{ pkg.pkgname }} {{ pkg.full_version }} [{{ pkg.repo.name|lower }}] ({{ pkg.arch.name }})
      • +
      • {{ pkg.pkgname }} {{ pkg.full_version }} [{{ pkg.repo.name|lower }}] ({{ pkg.arch.name }})
      • {% endfor %}
      -- cgit v1.2.3-54-g00ecf
      {{ pkg.pkgname }} {{ pkg.repo.name }}{{ pkg.pkgver }}{{ pkg.full_version }} {{ pkg.arch.name }} {{ pkg.flag_date|date }} {{ pkg.last_update|date }}