[damned-lies] Add a weight attribute to releases and display accordingly



commit 7ad0fa11d8cc7a5f9ced5870981d01ddab2ca3a1
Author: Claude Paroz <claude 2xlibre net>
Date:   Sat Nov 14 15:12:25 2009 +0100

    Add a weight attribute to releases and display accordingly
    
    This commit contains a schema modification. To update your database,
    run:
    python manage.py migrate stats

 stats/admin.py                              |    3 +-
 stats/migrations/0002_add_release_weight.py |  177 +++++++++++++++++++++++++++
 stats/models.py                             |    2 +
 stats/views.py                              |   11 +-
 templates/release_list.html                 |   15 ++-
 5 files changed, 202 insertions(+), 6 deletions(-)
---
diff --git a/stats/admin.py b/stats/admin.py
index 0a134d1..634d1c1 100644
--- a/stats/admin.py
+++ b/stats/admin.py
@@ -71,7 +71,8 @@ class CategoryAdmin(admin.ModelAdmin):
     search_fields = ('name', 'branch__module__name')
 
 class ReleaseAdmin(admin.ModelAdmin):
-    list_display = ('name', 'status', 'string_frozen')
+    list_display = ('name', 'status', 'weight', 'string_frozen')
+    list_editable = ('weight',)
     inlines = [ CategoryInline ]
 
 class InformationInline(admin.TabularInline):
diff --git a/stats/migrations/0002_add_release_weight.py b/stats/migrations/0002_add_release_weight.py
new file mode 100644
index 0000000..1a6cfa9
--- /dev/null
+++ b/stats/migrations/0002_add_release_weight.py
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*-
+
+from south.db import db
+from django.db import models
+from stats.models import *
+
+class Migration:
+    
+    def forwards(self, orm):
+        
+        # Adding field 'Release.weight'
+        db.add_column('release', 'weight', orm['stats.release:weight'])
+        
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting field 'Release.weight'
+        db.delete_column('release', 'weight')
+        
+    
+    
+    models = {
+        'auth.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']", 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'unique_together': "(('content_type', 'codename'),)"},
+            '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': {
+            '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']", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            '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']", 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'unique_together': "(('app_label', 'model'),)", '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'})
+        },
+        'languages.language': {
+            'Meta': {'db_table': "'language'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'locale': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '15'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'}),
+            'plurals': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'team': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['teams.Team']", 'null': 'True', 'blank': 'True'})
+        },
+        'people.person': {
+            'Meta': {'db_table': "'person'"},
+            'activation_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+            'bugzilla_account': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+            'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'irc_nick': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '20', 'null': 'True', 'blank': 'True'}),
+            'svn_account': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '20', 'null': 'True', 'blank': 'True'}),
+            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}),
+            'webpage_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
+        },
+        'stats.branch': {
+            'Meta': {'unique_together': "(('name', 'module'),)", 'db_table': "'branch'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'module': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Module']"}),
+            'name': ('BranchCharField', [], {'max_length': '50'}),
+            'vcs_subpath': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
+        },
+        'stats.category': {
+            'Meta': {'unique_together': "(('release', 'branch'),)", 'db_table': "'category'"},
+            'branch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Branch']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '30'}),
+            'release': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Release']"})
+        },
+        'stats.domain': {
+            'Meta': {'db_table': "'domain'"},
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'directory': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'dtype': ('django.db.models.fields.CharField', [], {'default': "'ui'", 'max_length': '5'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'linguas_location': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'module': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Module']"}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'pot_method': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'stats.information': {
+            'Meta': {'db_table': "'information'"},
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'statistics': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Statistics']"}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        'stats.informationarchived': {
+            'Meta': {'db_table': "'information_archived'"},
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'statistics': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.StatisticsArchived']"}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        'stats.module': {
+            'Meta': {'db_table': "'module'"},
+            'bugs_base': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'bugs_component': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'bugs_product': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'homepage': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['people.Person']", 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'vcs_root': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'vcs_type': ('django.db.models.fields.CharField', [], {'max_length': '5'}),
+            'vcs_web': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+        },
+        'stats.release': {
+            'Meta': {'db_table': "'release'"},
+            'branches': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['stats.Branch']"}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.SlugField', [], {'max_length': '20', 'db_index': 'True'}),
+            'status': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+            'string_frozen': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'weight': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'stats.statistics': {
+            'Meta': {'unique_together': "(('branch', 'domain', 'language'),)", 'db_table': "'statistics'"},
+            'branch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Branch']"}),
+            'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Domain']"}),
+            'fuzzy': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['languages.Language']", 'null': 'True'}),
+            'num_figures': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'translated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'untranslated': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'stats.statisticsarchived': {
+            'Meta': {'db_table': "'statistics_archived'"},
+            'branch': ('django.db.models.fields.TextField', [], {}),
+            'date': ('django.db.models.fields.DateTimeField', [], {}),
+            'domain': ('django.db.models.fields.TextField', [], {}),
+            'fuzzy': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'module': ('django.db.models.fields.TextField', [], {}),
+            'translated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '3'}),
+            'untranslated': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'teams.team': {
+            'Meta': {'db_table': "'team'"},
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'mailing_list': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+            'mailing_list_subscribe': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['people.Person']"}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+            'webpage_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
+        }
+    }
+    
+    complete_apps = ['stats']
diff --git a/stats/models.py b/stats/models.py
index 535822a..3db1f10 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -731,6 +731,8 @@ class Release(models.Model):
     description = models.CharField(max_length=50)
     string_frozen = models.BooleanField(default=False)
     status = models.CharField(max_length=12, choices=RELEASE_STATUS_CHOICES)
+    # weight is used to sort releases, higher on top, below 0 in archives
+    weight   = models.IntegerField(default=0)
     branches = models.ManyToManyField(Branch, through='Category', related_name='releases')
 
     class Meta:
diff --git a/stats/views.py b/stats/views.py
index 5b3ee66..44d118b 100644
--- a/stats/views.py
+++ b/stats/views.py
@@ -217,14 +217,17 @@ def dynamic_po(request, filename):
     return HttpResponse(dyn_content, 'text/plain')
 
 def releases(request, format='html'):
-    all_releases = Release.objects.order_by('status', '-name')
+    active_releases = Release.objects.filter(weight__gte=0).order_by('status', '-weight', '-name')
+    old_releases    = Release.objects.filter(weight__lt=0).order_by('status', '-weight', '-name')
     if format in ('json', 'xml'):
-        data = serializers.serialize(format, all_releases)
+        from itertools import chain
+        data = serializers.serialize(format, chain(active_releases, old_releases))
         return HttpResponse(data, mimetype=MIME_TYPES[format])
     else:
         context = {
-            'pageSection':  "releases",
-            'releases': all_releases
+            'pageSection'    : "releases",
+            'active_releases': active_releases,
+            'old_releases'   : old_releases,
         }
         return render_to_response('release_list.html', context, context_instance=RequestContext(request))
 
diff --git a/templates/release_list.html b/templates/release_list.html
index 0a7a8f2..857658d 100644
--- a/templates/release_list.html
+++ b/templates/release_list.html
@@ -11,7 +11,7 @@
 <p>{% trans "Select a release or a release set below to see more details about it:" %}</p>
 
 <ul class="foot">
-{% for rel in releases %}
+{% for rel in active_releases %}
   {% ifchanged rel.status %}
     </ul>
     <ul class="foot">
@@ -20,6 +20,19 @@
     <a href="{% url stats.views.release rel.name %}">{% trans rel.description %}</a>
   </li>
 {% endfor %}
+</ul>
 
+<h2>{% trans "Older Releases" %}</h2>
+<ul class="foot">
+{% for rel in old_releases %}
+  {% ifchanged rel.status %}
+    </ul>
+    <ul class="foot">
+  {% endifchanged %}
+  <li>
+    <a href="{% url stats.views.release rel.name %}">{% trans rel.description %}</a>
+  </li>
+{% endfor %}
+</ul>
 </div>
 {% endblock %}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]