From 94c5bda1c13960f8626b3c8e8ec47d9e3005f792 Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Mon, 5 Dec 2011 23:10:44 -0600
Subject: Add a stub admin command to help fix permissions/content types

I needed this today to get the application working from scratch on
another host.  Probably not all there yet, but we'll see how far it gets
us.

Signed-off-by: Dan McGee <dan@archlinux.org>
---
 .../commands/update_types_permissions.py           | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 devel/management/commands/update_types_permissions.py

diff --git a/devel/management/commands/update_types_permissions.py b/devel/management/commands/update_types_permissions.py
new file mode 100644
index 00000000..bbe8dc47
--- /dev/null
+++ b/devel/management/commands/update_types_permissions.py
@@ -0,0 +1,25 @@
+from django.core.management.base import BaseCommand
+from django.db.models import get_models, get_app
+from django.contrib.auth.management import create_permissions
+from django.contrib.contenttypes.management import update_contenttypes
+
+
+class Command(BaseCommand):
+    args = '<app app ...>'
+    help = 'reloads permissions for specified apps, or all apps if no args are specified'
+
+    def handle(self, *args, **options):
+        if not args:
+            apps = []
+            for model in get_models():
+                apps.append(get_app(model._meta.app_label))
+        else:
+            apps = []
+            for arg in args:
+                apps.append(get_app(arg))
+
+        for app in apps:
+            update_contenttypes(app, None, options.get('verbosity', 2), interactive=True)
+            create_permissions(app, get_models(), options.get('verbosity', 0))
+
+# vim: set ts=4 sw=4 et:
-- 
cgit v1.2.3-2-g168b


From 7b6ec8662a306c5754dbe4fe2484de61284942ac Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Wed, 7 Dec 2011 13:04:34 -0600
Subject: Enhance devel model admin

Signed-off-by: Dan McGee <dan@archlinux.org>
---
 devel/admin.py  | 11 ++++++++++-
 devel/models.py | 10 +++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/devel/admin.py b/devel/admin.py
index 84082fb8..717ba1b2 100644
--- a/devel/admin.py
+++ b/devel/admin.py
@@ -1,12 +1,21 @@
 from django.contrib import admin
 
-from .models import MasterKey
+from .models import MasterKey, PGPSignature
 
 
 class MasterKeyAdmin(admin.ModelAdmin):
     list_display = ('pgp_key', 'owner', 'created', 'revoker', 'revoked')
     search_fields = ('pgp_key', 'owner', 'revoker')
+    date_hierarchy = 'created'
+
+class PGPSignatureAdmin(admin.ModelAdmin):
+    list_display = ('signer', 'signee', 'created', 'expires', 'valid')
+    list_filter = ('valid',)
+    search_fields = ('signer', 'signee')
+    date_hierarchy = 'created'
+
 
 admin.site.register(MasterKey, MasterKeyAdmin)
+admin.site.register(PGPSignature, PGPSignatureAdmin)
 
 # vim: set ts=4 sw=4 et:
diff --git a/devel/models.py b/devel/models.py
index 6c97375c..e46fbba1 100644
--- a/devel/models.py
+++ b/devel/models.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 from django.db import models
 from django.contrib.auth.models import User
 
@@ -17,6 +18,10 @@ class MasterKey(models.Model):
     class Meta:
         ordering = ('created',)
 
+    def __unicode__(self):
+        return u'%s, created %s' % (
+                self.owner.get_full_name(), self.created)
+
 
 class PGPSignature(models.Model):
     signer = PGPKeyField(max_length=40, verbose_name="PGP key fingerprint",
@@ -24,10 +29,13 @@ class PGPSignature(models.Model):
     signee = PGPKeyField(max_length=40, verbose_name="PGP key fingerprint",
         help_text="consists of 40 hex digits; use `gpg --fingerprint`")
     created = models.DateField()
-    expires = models.DateField(null=True)
+    expires = models.DateField(null=True, blank=True)
     valid = models.BooleanField(default=True)
 
     class Meta:
         verbose_name = 'PGP signature'
 
+    def __unicode__(self):
+        return u'%s → %s' % (self.signer, self.signee)
+
 # vim: set ts=4 sw=4 et:
-- 
cgit v1.2.3-2-g168b


From b1c42e16ac0c49a574cfa154162353ac555ac342 Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Wed, 7 Dec 2011 13:05:46 -0600
Subject: Convert master key datetimes to dates

The extra precision is not necessary and just makes entry of the data
harder anyway.
---
 devel/migrations/0004_masterkey_dates.py | 74 ++++++++++++++++++++++++++++++++
 devel/models.py                          |  4 +-
 2 files changed, 76 insertions(+), 2 deletions(-)
 create mode 100644 devel/migrations/0004_masterkey_dates.py

diff --git a/devel/migrations/0004_masterkey_dates.py b/devel/migrations/0004_masterkey_dates.py
new file mode 100644
index 00000000..dc7750dc
--- /dev/null
+++ b/devel/migrations/0004_masterkey_dates.py
@@ -0,0 +1,74 @@
+# encoding: utf-8
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        db.alter_column('devel_masterkey', 'revoked', self.gf('django.db.models.fields.DateField')(null=True))
+        db.alter_column('devel_masterkey', 'created', self.gf('django.db.models.fields.DateField')())
+
+    def backwards(self, orm):
+        db.alter_column('devel_masterkey', 'revoked', self.gf('django.db.models.fields.DateTimeField')(null=True))
+        db.alter_column('devel_masterkey', 'created', self.gf('django.db.models.fields.DateTimeField')())
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'devel.masterkey': {
+            'Meta': {'ordering': "('created',)", 'object_name': 'MasterKey'},
+            'created': ('django.db.models.fields.DateField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_owner'", 'to': "orm['auth.User']"}),
+            'pgp_key': ('main.fields.PGPKeyField', [], {'max_length': '40'}),
+            'revoked': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'revoker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_revoker'", 'to': "orm['auth.User']"})
+        },
+        'devel.pgpsignature': {
+            'Meta': {'object_name': 'PGPSignature'},
+            'created': ('django.db.models.fields.DateField', [], {}),
+            'expires': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'signee': ('main.fields.PGPKeyField', [], {'max_length': '40'}),
+            'signer': ('main.fields.PGPKeyField', [], {'max_length': '40'}),
+            'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+        }
+    }
+
+    complete_apps = ['devel']
diff --git a/devel/models.py b/devel/models.py
index e46fbba1..03a5b15e 100644
--- a/devel/models.py
+++ b/devel/models.py
@@ -12,8 +12,8 @@ class MasterKey(models.Model):
         help_text="The developer holding the revocation certificate")
     pgp_key = PGPKeyField(max_length=40, verbose_name="PGP key fingerprint",
         help_text="consists of 40 hex digits; use `gpg --fingerprint`")
-    created = models.DateTimeField()
-    revoked = models.DateTimeField(null=True, blank=True)
+    created = models.DateField()
+    revoked = models.DateField(null=True, blank=True)
 
     class Meta:
         ordering = ('created',)
-- 
cgit v1.2.3-2-g168b


From c2e84a787a4e0b66648f6b8a076a4d25e2289b4d Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Wed, 7 Dec 2011 13:11:52 -0600
Subject: Various small admin touchups

* Don't capitalize things in verbose_name, Django does this
  automatically and uses title case
* Add overrides for IP, URL, ISO, etc.

Signed-off-by: Dan McGee <dan@archlinux.org>
---
 main/admin.py     |  3 ++-
 mirrors/models.py | 13 ++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/main/admin.py b/main/admin.py
index e5da9fb9..783d07e4 100644
--- a/main/admin.py
+++ b/main/admin.py
@@ -24,7 +24,8 @@ class PackageAdmin(admin.ModelAdmin):
     list_display = ('pkgname', 'full_version', 'repo', 'arch', 'packager',
             'last_update', 'build_date')
     list_filter = ('repo', 'arch')
-    search_fields = ('pkgname',)
+    search_fields = ('pkgname', 'pkgbase', 'pkgdesc')
+    date_hierarchy = 'build_date'
 
 class TodolistAdmin(admin.ModelAdmin):
     list_display = ('name', 'date_added', 'creator', 'description')
diff --git a/mirrors/models.py b/mirrors/models.py
index a8217844..111654fd 100644
--- a/mirrors/models.py
+++ b/mirrors/models.py
@@ -28,7 +28,7 @@ class Mirror(models.Model):
     admin_email = models.EmailField(max_length=255, blank=True)
     public = models.BooleanField(default=True)
     active = models.BooleanField(default=True)
-    isos = models.BooleanField(default=True)
+    isos = models.BooleanField("ISOs", default=True)
     rsync_user = models.CharField(max_length=50, blank=True, default='')
     rsync_password = models.CharField(max_length=50, blank=True, default='')
     notes = models.TextField(blank=True)
@@ -59,11 +59,10 @@ class MirrorProtocol(models.Model):
         return self.protocol
 
     class Meta:
-        verbose_name = 'Mirror Protocol'
         ordering = ('protocol',)
 
 class MirrorUrl(models.Model):
-    url = models.CharField(max_length=255, unique=True)
+    url = models.CharField("URL", max_length=255, unique=True)
     protocol = models.ForeignKey(MirrorProtocol, related_name="urls",
             editable=False, on_delete=models.PROTECT)
     mirror = models.ForeignKey(Mirror, related_name="urls")
@@ -108,17 +107,17 @@ class MirrorUrl(models.Model):
         return self.url
 
     class Meta:
-        verbose_name = 'Mirror URL'
+        verbose_name = 'mirror URL'
 
 class MirrorRsync(models.Model):
-    ip = models.CharField(max_length=24)
+    ip = models.CharField("IP", max_length=24)
     mirror = models.ForeignKey(Mirror, related_name="rsync_ips")
 
     def __unicode__(self):
         return "%s" % (self.ip)
 
     class Meta:
-        verbose_name = 'Mirror Rsync IP'
+        verbose_name = 'mirror rsync IP'
 
 class MirrorLog(models.Model):
     url = models.ForeignKey(MirrorUrl, related_name="logs")
@@ -132,6 +131,6 @@ class MirrorLog(models.Model):
         return "Check of %s at %s" % (self.url.url, self.check_time)
 
     class Meta:
-        verbose_name = 'Mirror Check Log'
+        verbose_name = 'mirror check log'
 
 # vim: set ts=4 sw=4 et:
-- 
cgit v1.2.3-2-g168b


From 604c748f8f8dee5e51e2ea5937d1be0b60fb0e7b Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Wed, 7 Dec 2011 14:15:15 -0600
Subject: Admin index template updates

We can't do everything in the upcoming 1.4 release, but we can take care
of a few small bugfixes and changes from the SVN trunk template.

Signed-off-by: Dan McGee <dan@archlinux.org>
---
 templates/admin/index.html | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/templates/admin/index.html b/templates/admin/index.html
index 93cf258d..1755d86f 100644
--- a/templates/admin/index.html
+++ b/templates/admin/index.html
@@ -32,8 +32,8 @@
 {% if app_list %}
     {% for app in app_list %}
         <div class="module">
-        <table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
-        <caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
+        <table summary="{% blocktrans with name=app.name %}Models available in the {{ name }} application.{% endblocktrans %}">
+        <caption><a href="{{ app.app_url }}" class="section">{% blocktrans with name=app.name %}{{ name }}{% endblocktrans %}</a></caption>
         {% for model in app.models %}
             <tr>
             {% if model.perms.change %}
@@ -43,7 +43,7 @@
             {% endif %}
 
             {% if model.perms.add %}
-                <td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
+                <td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
             {% else %}
                 <td>&nbsp;</td>
             {% endif %}
@@ -77,7 +77,7 @@
             <ul class="actionlist">
             {% for entry in admin_log %}
             <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
-                {% if entry.is_deletion %}
+                {% if entry.is_deletion or not entry.get_admin_url %}
                     {{ entry.object_repr }}
                 {% else %}
                     <a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
-- 
cgit v1.2.3-2-g168b