summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-04-25 18:09:39 -0500
committerDan McGee <dan@archlinux.org>2011-04-25 18:09:39 -0500
commit381e0a787205af530ae11bac1b1a17e567eecc84 (patch)
tree7d1904c757972b3ffd7f2aa101b2d88be3df7987
parente6717510a0a7976fca1ccd3e5aaf1a16123a1ad4 (diff)
Developer reports
This commit adds four initial developer reports that are hopefully useful to developers and packages in checking up on the state of things. They include: * big : the 100 biggest packages in the repos * old : packages built > 2 years ago * uncompressed-man : self-explanatory * uncompressed-info : self-explanatory There should obviously be some sort of index page to access all of these, so that will be coming soon. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--devel/urls.py9
-rw-r--r--devel/views.py54
-rw-r--r--main/templatetags/attributes.py21
-rw-r--r--templates/devel/packages.html56
4 files changed, 131 insertions, 9 deletions
diff --git a/devel/urls.py b/devel/urls.py
index 41be2b31..9bf50f45 100644
--- a/devel/urls.py
+++ b/devel/urls.py
@@ -1,12 +1,13 @@
from django.conf.urls.defaults import patterns
urlpatterns = patterns('devel.views',
- (r'^$', 'index'),
+ (r'^admin_log/$','admin_log'),
+ (r'^admin_log/(?P<username>.*)/$','admin_log'),
(r'^clock/$', 'clock'),
- (r'^profile/$', 'change_profile'),
+ (r'^$', 'index'),
(r'^newuser/$', 'new_user_form'),
- (r'^admin_log/(?P<username>.*)/$','admin_log'),
- (r'^admin_log/$','admin_log'),
+ (r'^profile/$', 'change_profile'),
+ (r'^reports/(?P<report>.*)/$', 'report'),
)
# vim: set ts=4 sw=4 et:
diff --git a/devel/views.py b/devel/views.py
index b61e605f..01d54e6f 100644
--- a/devel/views.py
+++ b/devel/views.py
@@ -6,19 +6,22 @@ from django.contrib.auth.models import User, Group
from django.contrib.sites.models import Site
from django.core.mail import send_mail
from django.db import transaction
+from django.db.models import Q
+from django.http import Http404
from django.shortcuts import get_object_or_404
from django.template import loader, Context
from django.views.decorators.cache import never_cache
from django.views.generic.simple import direct_to_template
-from main.models import Package, TodolistPkg
+from main.models import Package, PackageFile, TodolistPkg
from main.models import Arch, Repo
from main.models import UserProfile
from packages.models import PackageRelation
from todolists.utils import get_annotated_todolists
from .utils import get_annotated_maintainers
-import datetime
+from datetime import datetime, timedelta
+import operator
import pytz
import random
from string import ascii_letters, digits
@@ -26,7 +29,7 @@ from string import ascii_letters, digits
@login_required
@never_cache
def index(request):
- '''the Developer dashboard'''
+ '''the developer dashboard'''
inner_q = PackageRelation.objects.filter(user=request.user).values('pkgbase')
flagged = Package.objects.select_related('arch', 'repo').filter(
flag_date__isnull=False, pkgbase__in=inner_q).order_by('pkgname')
@@ -70,8 +73,8 @@ def clock(request):
'username').select_related('userprofile')
# now annotate each dev object with their current time
- now = datetime.datetime.now()
- utc_now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
+ now = datetime.now()
+ utc_now = datetime.utcnow().replace(tzinfo=pytz.utc)
for dev in devs:
# Work around https://bugs.launchpad.net/pytz/+bug/718673
timezone = str(dev.userprofile.time_zone)
@@ -123,6 +126,47 @@ def change_profile(request):
return direct_to_template(request, 'devel/profile.html',
{'form': form, 'profile_form': profile_form})
+@login_required
+def report(request, report):
+ title = "Developer Report"
+ packages = Package.objects.select_related('arch', 'repo')
+ names = attrs = None
+ if report == "old":
+ title = "Packages last built more than two years ago"
+ cutoff = datetime.now() - timedelta(days=730)
+ packages = packages.filter(build_date__lt=cutoff).order_by('build_date')
+ elif report == "big":
+ title = "100 largest compressed packages"
+ packages = packages.order_by('-compressed_size')[:100]
+ names = [ 'Compressed Size', 'Installed Size' ]
+ attrs = [ 'compressed_size', 'installed_size' ]
+ elif report == "uncompressed-man":
+ title = "Packages with uncompressed manpages"
+ # magic going on here! Checking for all '.1'...'.9' extensions
+ invalid_endings = [Q(filename__endswith='.%d' % n) for n in range(1,10)]
+ invalid_endings.append(Q(filename__endswith='.n'))
+ bad_files = PackageFile.objects.filter(Q(directory__contains='man') & (
+ reduce(operator.or_, invalid_endings))
+ ).values_list('pkg_id', flat=True).distinct()
+ packages = packages.filter(id__in=set(bad_files))
+ elif report == "uncompressed-info":
+ title = "Packages with uncompressed infopages"
+ bad_files = PackageFile.objects.filter(directory__contains='/info',
+ filename__endswith='.info').values_list(
+ 'pkg_id', flat=True).distinct()
+ packages = packages.filter(id__in=set(bad_files))
+ else:
+ raise Http404
+
+ context = {
+ 'title': title,
+ 'packages': packages,
+ 'column_names': names,
+ 'column_attrs': attrs,
+ }
+ return direct_to_template(request, 'devel/packages.html', context)
+
+
class NewUserForm(forms.ModelForm):
username = forms.CharField(max_length=30)
private_email = forms.EmailField()
diff --git a/main/templatetags/attributes.py b/main/templatetags/attributes.py
new file mode 100644
index 00000000..bd4ccf3d
--- /dev/null
+++ b/main/templatetags/attributes.py
@@ -0,0 +1,21 @@
+import re
+from django import template
+from django.conf import settings
+
+numeric_test = re.compile("^\d+$")
+register = template.Library()
+
+def attribute(value, arg):
+ """Gets an attribute of an object dynamically from a string name"""
+ if hasattr(value, str(arg)):
+ return getattr(value, arg)
+ elif hasattr(value, 'has_key') and value.has_key(arg):
+ return value[arg]
+ elif numeric_test.match(str(arg)) and len(value) > int(arg):
+ return value[int(arg)]
+ else:
+ return settings.TEMPLATE_STRING_IF_INVALID
+
+register.filter('attribute', attribute)
+
+# vim: set ts=4 sw=4 et:
diff --git a/templates/devel/packages.html b/templates/devel/packages.html
new file mode 100644
index 00000000..3b511c98
--- /dev/null
+++ b/templates/devel/packages.html
@@ -0,0 +1,56 @@
+{% extends "base.html" %}
+{% load attributes %}
+
+{% block title %}Arch Linux - {{ title }}{% endblock %}
+
+{% block content %}
+<div class="box">
+ <h2>{{ title }}</h2>
+ <table class="results">
+ <thead>
+ <tr>
+ <th>Arch</th>
+ <th>Repo</th>
+ <th>Name</th>
+ <th>Version</th>
+ <th>Description</th>
+ <th>Last Updated</th>
+ <th>Build Date</th>
+ <th>Flag Date</th>
+ {% for name in column_names %}
+ <th>{{ name }}</th>
+ {% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for pkg in packages %}
+ <tr class="{% cycle pkgr2,pkgr1 %}">
+ <td>{{ pkg.arch.name }}</td>
+ <td>{{ pkg.repo.name|capfirst }}</td>
+ <td><a href="{{ pkg.get_absolute_url }}"
+ title="Package details for {{ pkg.pkgname }}">{{ pkg.pkgname }}</a></td>
+ {% if pkg.flag_date %}
+ <td><span class="flagged">{{ pkg.full_version }}</span></td>
+ {% else %}
+ <td>{{ pkg.full_version }}</td>
+ {% endif %}
+ <td class="wrap">{{ pkg.pkgdesc }}</td>
+ <td>{{ pkg.last_update|date }}</td>
+ <td>{{ pkg.build_date|date }}</td>
+ <td>{{ pkg.flag_date|date }}</td>
+ {% for attr in column_attrs %}
+ <td>{{ pkg|attribute:attr }}</td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+{% load cdn %}{% jquery %}
+<script type="text/javascript" src="/media/jquery.tablesorter.min.js"></script>
+<script type="text/javascript">
+$(document).ready(function() {
+ $(".results").tablesorter({widgets: ['zebra']});
+});
+</script>
+{% endblock %}