From f0a858aab6691438eeec9094c2d46d95b5ddb306 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 7 Feb 2012 00:46:21 -0600 Subject: Make rematch command do a bit more Now that we have a few objects that can potentially link back to developers, allow flag requests to also be rematched. Signed-off-by: Dan McGee --- devel/management/commands/rematch_developers.py | 97 +++++++++++++++++++++++++ devel/management/commands/rematch_packager.py | 64 ---------------- devel/utils.py | 21 ++++++ 3 files changed, 118 insertions(+), 64 deletions(-) create mode 100644 devel/management/commands/rematch_developers.py delete mode 100644 devel/management/commands/rematch_packager.py diff --git a/devel/management/commands/rematch_developers.py b/devel/management/commands/rematch_developers.py new file mode 100644 index 00000000..8383cc8d --- /dev/null +++ b/devel/management/commands/rematch_developers.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +""" +rematch_developers command + +Match all packages with a packager_str but NULL packager_id to a packager if we +can find one. + +Also, match all flag requests with a NULL user_id that have a user_email +matching up to a developer if we can find one. + +Usage: ./manage.py rematch_developers +""" + +from django.core.management.base import NoArgsCommand +from django.db import transaction + +import sys +import logging + +from devel.utils import UserFinder +from main.models import Package +from packages.models import FlagRequest + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s -> %(levelname)s: %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + stream=sys.stderr) +logger = logging.getLogger() + +class Command(NoArgsCommand): + help = "Match and map objects in database to developer emails" + + def handle_noargs(self, **options): + v = int(options.get('verbosity', None)) + if v == 0: + logger.level = logging.ERROR + elif v == 1: + logger.level = logging.INFO + elif v == 2: + logger.level = logging.DEBUG + + finder = UserFinder() + match_packager(finder) + match_flagrequest(finder) + +@transaction.commit_on_success +def match_packager(finder): + logger.info("getting all unmatched packages") + package_count = matched_count = 0 + unknown = set() + + for package in Package.objects.filter(packager__isnull=True): + if package.packager_str in unknown: + continue + logger.debug("package %s, packager string %s", + package.pkgname, package.packager_str) + package_count += 1 + user = finder.find(package.packager_str) + if user: + package.packager = user + logger.debug(" found user %s" % user.username) + package.save() + matched_count += 1 + else: + unknown.add(package.packager_str) + + logger.info("%d packager strings checked, %d newly matched", + package_count, matched_count) + logger.debug("unknown packagers:\n%s", + "\n".join(unknown)) + + +@transaction.commit_on_success +def match_flagrequest(finder): + logger.info("getting all non-user flag requests") + req_count = matched_count = 0 + unknown = set() + + for request in FlagRequest.objects.filter(user__isnull=True): + if request.user_email in unknown: + continue + logger.debug("email %s", request.user_email) + req_count += 1 + user = finder.find_by_email(request.user_email) + if user: + request.user = user + logger.debug(" found user %s" % user.username) + request.save() + matched_count += 1 + else: + unknown.add(request.user_email) + + logger.info("%d request emails checked, %d newly matched", + req_count, matched_count) + +# vim: set ts=4 sw=4 et: diff --git a/devel/management/commands/rematch_packager.py b/devel/management/commands/rematch_packager.py deleted file mode 100644 index 461d83ab..00000000 --- a/devel/management/commands/rematch_packager.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -""" -rematch_packager command - -Match all packages with a packager_str but NULL packager_id to a packager if we -can find one. - -Usage: ./manage.py rematch_packager -""" - -from django.core.management.base import NoArgsCommand - -import sys -import logging - -from devel.utils import UserFinder -from main.models import Package - -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s -> %(levelname)s: %(message)s', - datefmt='%Y-%m-%d %H:%M:%S', - stream=sys.stderr) -logger = logging.getLogger() - -class Command(NoArgsCommand): - help = "Match all packages with a packager_str but NULL packager_id to a packager if we can find one." - - def handle_noargs(self, **options): - v = int(options.get('verbosity', None)) - if v == 0: - logger.level = logging.ERROR - elif v == 1: - logger.level = logging.INFO - elif v == 2: - logger.level = logging.DEBUG - - return match_packager() - -def match_packager(): - finder = UserFinder() - logger.info("getting all unmatched packages") - package_count = matched_count = 0 - unknown = set() - - for package in Package.objects.filter(packager__isnull=True): - logger.debug("package %s, packager string %s", - package.pkgname, package.packager_str) - package_count += 1 - user = finder.find(package.packager_str) - if user: - package.packager = user - logger.debug(" found user %s" % user.username) - package.save() - matched_count += 1 - else: - unknown.add(package.packager_str) - - logger.info("%d packages checked, %d newly matched", - package_count, matched_count) - logger.debug("unknown packagers:\n%s", - "\n".join(unknown)) - -# vim: set ts=4 sw=4 et: diff --git a/devel/utils.py b/devel/utils.py index 62b12cd5..ec035d13 100644 --- a/devel/utils.py +++ b/devel/utils.py @@ -48,6 +48,7 @@ class UserFinder(object): def __init__(self): self.cache = {} self.username_cache = {} + self.email_cache = {} @staticmethod def user_email(name, email): @@ -110,6 +111,7 @@ def find(self, userstring): pass self.cache[userstring] = user + self.email_cache[email] = user return user def find_by_username(self, username): @@ -126,8 +128,27 @@ def find_by_username(self, username): self.username_cache[username] = user return user + def find_by_email(self, email): + if not email: + return None + if email in self.email_cache: + return self.email_cache[email] + + user = None + try: + user = self.user_email(None, email) + except User.DoesNotExist: + try: + user = self.profile_email(None, email) + except User.DoesNotExist: + pass + + self.email_cache[email] = user + return user + def clear_cache(self): self.cache = {} self.username_cache = {} + self.email_cache = {} # vim: set ts=4 sw=4 et: -- cgit v1.2.3-54-g00ecf From 087aca5cceb2dc8ac4625eb61f95b57b704bd30f Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 2 Feb 2012 18:27:46 -0600 Subject: FlagRequest model behavior tweaks * Add a default field to be used for latest() calls. * Remove signal-based set of created date; instead, set it explicitly so all of our packages and flag request have the exact same date and time attached. Signed-off-by: Dan McGee --- packages/models.py | 5 ++++- packages/views/flag.py | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/models.py b/packages/models.py index f63d6db0..820e61ba 100644 --- a/packages/models.py +++ b/packages/models.py @@ -184,6 +184,9 @@ class FlagRequest(models.Model): is_legitimate = models.BooleanField(default=True, help_text="Is this actually an out-of-date flag request?") + class Meta: + get_latest_by = 'created' + def who(self): if self.user: return self.user.get_full_name() @@ -258,7 +261,7 @@ class Meta: # hook up some signals -for sender in (PackageRelation, SignoffSpecification, Signoff, FlagRequest): +for sender in (PackageRelation, SignoffSpecification, Signoff): pre_save.connect(set_created_field, sender=sender, dispatch_uid="packages.models") diff --git a/packages/views/flag.py b/packages/views/flag.py index 4ee37f6f..8879695c 100644 --- a/packages/views/flag.py +++ b/packages/views/flag.py @@ -61,9 +61,11 @@ def flag(request, name, repo, arch): @transaction.commit_on_success def perform_updates(): - pkgs.update(flag_date=datetime.utcnow()) + now = datetime.utcnow() + pkgs.update(flag_date=now) # store our flag request - flag_request = FlagRequest(user_email=email, message=message, + flag_request = FlagRequest(created=now, + user_email=email, message=message, ip_address=ip_addr, pkgbase=pkg.pkgbase, version=version, repo=pkg.repo, num_packages=len(flagged_pkgs)) -- cgit v1.2.3-54-g00ecf From b2cfd30094b07546bbbdd2c83499cfd3d03f2161 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 2 Feb 2012 18:29:35 -0600 Subject: Show the latest flag request on package details if out of date This only shows up for logged in users, but might be helpful for developers browsing around the site, especially if they did not receive the email themselves, or in the case of orphan packages. Signed-off-by: Dan McGee --- main/models.py | 11 +++++++++++ sitestatic/archweb.css | 5 +++++ templates/packages/details.html | 5 +++++ 3 files changed, 21 insertions(+) diff --git a/main/models.py b/main/models.py index d72f2c05..15a92662 100644 --- a/main/models.py +++ b/main/models.py @@ -312,6 +312,17 @@ def split_packages(self): repo__testing=self.repo.testing, repo__staging=self.repo.staging, pkgbase=self.pkgbase).exclude(id=self.id) + def flag_request(self): + if not self.flag_date: + return None + from packages.models import FlagRequest + try: + request = FlagRequest.objects.filter(pkgbase=self.pkgbase, + repo=self.repo).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 \ diff --git a/sitestatic/archweb.css b/sitestatic/archweb.css index 46fd7844..d653d98c 100644 --- a/sitestatic/archweb.css +++ b/sitestatic/archweb.css @@ -728,6 +728,11 @@ div#pkglist-about { padding: 0.25em 0 0.25em 1.5em; } + #pkgdetails #pkginfo .userdata { + font-size: 0.85em; + padding: 0.5em; + } + /* pkgdetails: flag package */ form#flag-pkg-form label { width: 10em; diff --git a/templates/packages/details.html b/templates/packages/details.html index f68aefa3..fd7bea4d 100644 --- a/templates/packages/details.html +++ b/templates/packages/details.html @@ -161,6 +161,11 @@

Versions Elsewhere

Last Updated: {{ pkg.last_update|date }} + {% if user.is_authenticated %}{% with pkg.flag_request as flag_request %}{% if flag_request %} + Last Flag Request: + From {{ flag_request.who }} on {{ flag_request.created|date }}:
+
{{ flag_request.message|linebreaksbr|default:"{no message}" }}
+ {% endif %}{% endwith %}{% endif %}
-- cgit v1.2.3-54-g00ecf From 6dfc85affc01785f77e8696aad2ac5c74df18659 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 8 Feb 2012 12:40:26 -0600 Subject: Update requirements.txt Signed-off-by: Dan McGee --- requirements.txt | 2 +- requirements_prod.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index fd58616e..a9643581 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ Django==1.3.1 -Markdown==2.0.3 +Markdown==2.1.1 South==0.7.3 pytz>=2011n diff --git a/requirements_prod.txt b/requirements_prod.txt index 47d37ce2..bb8c6954 100644 --- a/requirements_prod.txt +++ b/requirements_prod.txt @@ -1,7 +1,7 @@ Django==1.3.1 -Markdown==2.0.3 +Markdown==2.1.1 MySQL-python==1.2.3 South==0.7.3 pyinotify==0.9.2 -python-memcached==1.47 +python-memcached==1.48 pytz>=2011n -- cgit v1.2.3-54-g00ecf From 2ac90512fd17012208d34c4b86ac56d39e3cecd2 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 11 Feb 2012 18:46:02 -0600 Subject: reporead: only reset flag date if upstream version changes This preserves the flag date if only a simple pkgrel bump occurred, which makes sense more often than not for rebuilds. Signed-off-by: Dan McGee --- devel/management/commands/reporead.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index d149a276..3ed95a9d 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -191,6 +191,13 @@ def create_multivalued(dbpkg, repopkg, db_attr, repo_attr): finder = UserFinder() def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): + # we reset the flag date only if the upstream version components change; + # e.g. epoch or pkgver, but not pkgrel + if dbpkg.epoch is None or dbpkg.epoch != repopkg.epoch: + dbpkg.flag_date = None + elif dbpkg.pkgver is None or dbpkg.pkgver != repopkg.ver: + dbpkg.flag_date = None + if repopkg.base: dbpkg.pkgbase = repopkg.base else: @@ -210,7 +217,6 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): dbpkg.pgp_signature = repopkg.pgpsig if timestamp: - dbpkg.flag_date = None dbpkg.last_update = timestamp dbpkg.save() -- cgit v1.2.3-54-g00ecf From c3ebf7deae0bb04f1637e9a52e7f9f38d454fec7 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 11 Feb 2012 18:53:23 -0600 Subject: Show current version in todolist details view This also reorders the columns to be in the same order as package search for consistency. Addresses FS#28369. Signed-off-by: Dan McGee --- templates/todolists/view.html | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/templates/todolists/view.html b/templates/todolists/view.html index d45905e3..8c9361cc 100644 --- a/templates/todolists/view.html +++ b/templates/todolists/view.html @@ -31,9 +31,10 @@

Todo List: {{ list.name }}

- - + + + @@ -41,9 +42,14 @@

Todo List: {{ list.name }}

{% for pkg in list.packages %} - + + {% if pkg.pkg.flag_date %} + + {% else %} + + {% endif %}
Name ArchRepoRepositoryNameCurrent Version Maintainers Status
{% pkg_details_link pkg.pkg %} {{ pkg.pkg.arch.name }} {{ pkg.pkg.repo.name|capfirst }}{% pkg_details_link pkg.pkg %}{{ pkg.pkg.full_version }}{{ pkg.pkg.full_version }}{{ pkg.pkg.maintainers|join:', ' }} {% if perms.main.change_todolistpkg %} @@ -71,7 +77,7 @@

Todo List: {{ list.name }}

$('a.status-link').click(todolist_flag); $(".results").tablesorter({ widgets: ['zebra'], - sortList: [[0,0], [1,0]], + sortList: [[2,0], [0,0]], headers: { 4: { sorter: 'todostatus' } } }); }); -- cgit v1.2.3-54-g00ecf