[damned-lies] Add an archived flag to module objects



commit bef2008f3e72e6f928c8d6b1eba21496e75304d9
Author: Claude Paroz <claude 2xlibre net>
Date:   Fri Jan 11 15:33:19 2013 +0100

    Add an archived flag to module objects
    
    The archived flag is then used to display warnings and prevent the
    'vertimus' links for that module.

 docs/DataModel.odg                              |  Bin 31369 -> 31915 bytes
 stats/admin.py                                  |    2 +-
 stats/management/commands/update-stats.py       |   27 ++-
 stats/migrations/0012_add_module_archived.py    |  206 +++++++++++++++++++++++
 stats/models.py                                 |   38 +++--
 templates/languages/language_release_stats.html |    8 +-
 templates/module_detail.html                    |    4 +
 templates/stats_show.html                       |    4 +-
 8 files changed, 254 insertions(+), 35 deletions(-)
---
diff --git a/docs/DataModel.odg b/docs/DataModel.odg
index c96e3d2..7bd37a3 100644
Binary files a/docs/DataModel.odg and b/docs/DataModel.odg differ
diff --git a/stats/admin.py b/stats/admin.py
index 1c54d65..a6a039a 100644
--- a/stats/admin.py
+++ b/stats/admin.py
@@ -44,7 +44,7 @@ class ModuleAdmin(admin.ModelAdmin):
     fieldsets = (
         (None, {
             'fields': (('name','description'),
-                        'homepage', 'comment',
+                        'homepage', 'comment', 'archived',
                        ('bugs_base', 'bugs_product', 'bugs_component'),
                        ('vcs_type', 'vcs_root', 'vcs_web'),
                        'ext_platform', 'maintainers')
diff --git a/stats/management/commands/update-stats.py b/stats/management/commands/update-stats.py
index 1321a14..e5f0514 100644
--- a/stats/management/commands/update-stats.py
+++ b/stats/management/commands/update-stats.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 import sys, traceback
 from optparse import make_option
-from django.core.management.base import BaseCommand
+from django.core.management.base import BaseCommand, CommandError
 from django.core.mail import mail_admins
 from stats.models import Module, Branch
 
@@ -32,34 +32,41 @@ class Command(BaseCommand):
                     branch_arg = "HEAD"
                 try:
                     branch = Branch.objects.get(module__name=module_arg, name=branch_arg)
-                except:
-                    print >> sys.stderr, "Unable to find branch '%s' for module '%s' in the database." % (branch_arg, module_arg)
-                    return "Update unsuccessful."
+                except Branch.DoesNotExist:
+                    raise CommandError("Unable to find branch '%s' for module '%s' in the database." % (
+                        branch_arg, module_arg))
+                if branch.module.archived and not options['force']:
+                    raise CommandError("The module '%s' is archived." % module_arg)
                 print "Updating stats for %s.%s..." % (module_arg, branch_arg)
                 try:
                     branch.update_stats(options['force'])
-                except:
+                except Exception:
                     tbtext = traceback.format_exc()
                     mail_admins("Error while updating %s %s" % (module_arg, branch_arg), tbtext)
                     print >> sys.stderr, "Error during updating, mail sent to admins"
 
         elif len(args) == 1:
             # Update all branches of a module
-            module_arg = args[0]
-            print "Updating stats for %s..." % (module_arg)
-            branches = Branch.objects.filter(module__name=module_arg)
-            for branch in branches.all():
+            try:
+                module = Module.objects.get(name=args[0])
+            except Module.DoesNotExist:
+                raise CommandError("Unable to find a module named '%s' in the database" % args[0])
+            print "Updating stats for %s..." % (module.name)
+            for branch in module.branch_set.all():
                 try:
                     branch.update_stats(options['force'])
                 except:
                     print >> sys.stderr, traceback.format_exc()
-                    print "Error while updating stats for %s (branch '%s')" % (module_arg, branch.name)
+                    print "Error while updating stats for %s (branch '%s')" % (module.name, branch.name)
         else:
             # Update all modules
             if options['non-gnome']:
                 modules = Module.objects.exclude(vcs_root__startswith='git://git.gnome.org/')
             else:
                 modules = Module.objects.all()
+            if not options['force']:
+                modules = modules.exclude(archived=True)
+
             for mod in modules:
                 print "Updating stats for %s..." % (mod.name)
                 branches = Branch.objects.filter(module__name=mod)
diff --git a/stats/migrations/0012_add_module_archived.py b/stats/migrations/0012_add_module_archived.py
new file mode 100644
index 0000000..8c09ebd
--- /dev/null
+++ b/stats/migrations/0012_add_module_archived.py
@@ -0,0 +1,206 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding field 'Module.archived'
+        db.add_column('module', 'archived', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Module.archived'
+        db.delete_column('module', 'archived')
+
+
+    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(2013, 1, 11, 14, 9, 4, 146423)'}),
+            '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(2013, 1, 11, 14, 9, 4, 146351)'}),
+            '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'})
+        },
+        'languages.language': {
+            'Meta': {'ordering': "('name',)", 'object_name': 'Language', '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': {'ordering': "('username',)", 'object_name': 'Person', 'db_table': "'person'", '_ormbases': ['auth.User']},
+            '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': {'ordering': "('name',)", 'unique_together': "(('name', 'module'),)", 'object_name': 'Branch', 'db_table': "'branch'"},
+            'file_hashes': ('common.fields.DictionaryField', [], {'default': "''", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'module': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Module']"}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'vcs_subpath': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'weight': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'stats.category': {
+            'Meta': {'unique_together': "(('release', 'branch'),)", 'object_name': 'Category', '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': {'ordering': "('-dtype', 'name')", 'object_name': 'Domain', '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'}),
+            'red_filter': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+        },
+        'stats.information': {
+            'Meta': {'object_name': 'Information', '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': {'object_name': 'InformationArchived', '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': {'ordering': "('name',)", 'object_name': 'Module', 'db_table': "'module'"},
+            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            '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'}),
+            'ext_platform': ('django.db.models.fields.URLField', [], {'max_length': '200', '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', [], {'symmetrical': 'False', 'related_name': "'maintains_modules'", 'blank': 'True', 'db_table': "'module_maintainer'", 'to': "orm['people.Person']"}),
+            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}),
+            '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.pofile': {
+            'Meta': {'object_name': 'PoFile', 'db_table': "'pofile'"},
+            'figures': ('common.fields.JSONField', [], {'null': 'True', 'blank': 'True'}),
+            'fuzzy': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'fuzzy_words': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'translated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'translated_words': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'untranslated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'untranslated_words': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+        },
+        'stats.release': {
+            'Meta': {'ordering': "('status', '-name')", 'object_name': 'Release', 'db_table': "'release'"},
+            'branches': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'releases'", 'symmetrical': 'False', 'through': "orm['stats.Category']", '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'}),
+            'weight': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'stats.statistics': {
+            'Meta': {'unique_together': "(('branch', 'domain', 'language'),)", 'object_name': 'Statistics', 'db_table': "'statistics'"},
+            'branch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Branch']"}),
+            'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stats.Domain']"}),
+            'full_po': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'stat_f'", 'unique': 'True', 'null': 'True', 'to': "orm['stats.PoFile']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['languages.Language']", 'null': 'True'}),
+            'old_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'old_fuzzy': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'old_translated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'old_untranslated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'part_po': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'stat_p'", 'unique': 'True', 'null': 'True', 'to': "orm['stats.PoFile']"})
+        },
+        'stats.statisticsarchived': {
+            'Meta': {'object_name': 'StatisticsArchived', '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.role': {
+            'Meta': {'unique_together': "(('team', 'person'),)", 'object_name': 'Role', 'db_table': "'role'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['people.Person']"}),
+            'role': ('django.db.models.fields.CharField', [], {'default': "'translator'", 'max_length': '15'}),
+            'team': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['teams.Team']"})
+        },
+        'teams.team': {
+            'Meta': {'ordering': "('description',)", 'object_name': 'Team', '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', [], {'related_name': "'teams'", 'symmetrical': 'False', 'through': "orm['teams.Role']", 'to': "orm['people.Person']"}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+            'presentation': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'use_workflow': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            '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 2e1bad7..932c604 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -70,6 +70,7 @@ class Module(models.Model):
     vcs_web = models.URLField()
     ext_platform = models.URLField(null=True, blank=True,
         help_text="URL to external translation platform, if any")
+    archived = models.BooleanField(default=False)
 
     maintainers = models.ManyToManyField(Person, db_table='module_maintainer',
         related_name='maintains_modules', blank=True,
@@ -82,6 +83,9 @@ class Module(models.Model):
     def __unicode__(self):
         return self.name
 
+    def __cmp__(self, other):
+        return cmp(self.name, other.name)
+
     @models.permalink
     def get_absolute_url(self):
         return ('stats.views.module', [self.name])
@@ -1614,8 +1618,8 @@ class Statistics(models.Model):
                         'catfuzzy': 0,
                         'catuntrans': 0,
                         'cattransperc': 0,
-                        'modules': { # This dict is converted to a sorted list at the end of stats computation
-                            <modname>: {
+                        'modules': { # SortedDict
+                            <module>: {
                                 <branchname>:
                                     [(<domname>, <stat>), ...], # List of tuples (domain name, Statistics object)
                                            # First element is a placeholder for a FakeSummaryStatistics object
@@ -1677,12 +1681,12 @@ class Statistics(models.Model):
                 categ_key = category_choices_dict.keys().index(stat.categ_name)
             domname = stat.domain.description and _(stat.domain.description) or ""
             branchname = stat.branch.name
-            modname = stat.branch.module.name
+            module = stat.branch.module
             if categ_key not in stats['categs']:
                 stats['categs'][categ_key] = {
                     'cattrans': 0, 'catfuzzy': 0, 'catuntrans': 0, 'cattransperc': 0,
                     'catname': _(category_choices_dict[getattr(stat, 'categ_name', 'default')]),
-                    'modules': {}
+                    'modules': SortedDict(),
                 }
             # Try to get translated stat, else stick with POT stat
             br_dom_key = "%d-%d" % (stat.branch.id, stat.domain.id)
@@ -1703,20 +1707,20 @@ class Statistics(models.Model):
             stats['categs'][categ_key]['cattrans'] += stat.translated(scope)
             stats['categs'][categ_key]['catfuzzy'] += stat.fuzzy(scope)
             stats['categs'][categ_key]['catuntrans'] += stat.untranslated(scope)
-            if modname not in stats['categs'][categ_key]['modules']:
+            if module not in stats['categs'][categ_key]['modules']:
                 # first element is a placeholder for a fake stat
-                stats['categs'][categ_key]['modules'][modname] = {branchname:[[' fake', None], (domname, stat)]}
-            elif branchname not in stats['categs'][categ_key]['modules'][modname]:
+                stats['categs'][categ_key]['modules'][module] = {branchname:[[' fake', None], (domname, stat)]}
+            elif branchname not in stats['categs'][categ_key]['modules'][module]:
                 # first element is a placeholder for a fake stat
-                stats['categs'][categ_key]['modules'][modname][branchname] = [[' fake', None], (domname, stat)]
+                stats['categs'][categ_key]['modules'][module][branchname] = [[' fake', None], (domname, stat)]
             else:
                 # Here we add the 2nd or more stat to the same module-branch
-                if len(stats['categs'][categ_key]['modules'][modname][branchname]) == 2:
+                if len(stats['categs'][categ_key]['modules'][module][branchname]) == 2:
                     # Create a fake statistics object for module summary
-                    stats['categs'][categ_key]['modules'][modname][branchname][0][1] = FakeSummaryStatistics(stat.domain.module, stat.branch, dtype)
-                    stats['categs'][categ_key]['modules'][modname][branchname][0][1].trans(stats['categs'][categ_key]['modules'][modname][branchname][1][1])
-                stats['categs'][categ_key]['modules'][modname][branchname].append((domname, stat))
-                stats['categs'][categ_key]['modules'][modname][branchname][0][1].trans(stat)
+                    stats['categs'][categ_key]['modules'][module][branchname][0][1] = FakeSummaryStatistics(stat.domain.module, stat.branch, dtype)
+                    stats['categs'][categ_key]['modules'][module][branchname][0][1].trans(stats['categs'][categ_key]['modules'][module][branchname][1][1])
+                stats['categs'][categ_key]['modules'][module][branchname].append((domname, stat))
+                stats['categs'][categ_key]['modules'][module][branchname][0][1].trans(stat)
 
         # Compute percentages and sorting
         stats['total'] = stats['totaltrans'] + stats['totalfuzzy'] + stats['totaluntrans']
@@ -1730,12 +1734,10 @@ class Statistics(models.Model):
             if categ['cattotal'] > 0:
                 categ['cattransperc'] = int(100*categ['cattrans']/categ['cattotal'])
             # Sort modules
-            mods = [[name,mod] for name, mod in categ['modules'].items()]
-            mods.sort()
-            categ['modules'] = mods
+            categ['modules'].keyOrder.sort()
             # Sort domains
-            for mod in categ['modules']:
-                for branch, doms in mod[1].items():
+            for mod in categ['modules'].values():
+                for branch, doms in mod.items():
                     doms.sort()
         # Sort errors
         stats['all_errors'].sort()
diff --git a/templates/languages/language_release_stats.html b/templates/languages/language_release_stats.html
index d95d49f..36f2b1b 100644
--- a/templates/languages/language_release_stats.html
+++ b/templates/languages/language_release_stats.html
@@ -37,15 +37,15 @@
     </td></tr>
   {% endif %}
 
-  {% for module in categ.modules %}
-    {% with module.0 as modname %}
-    {% for branch, doms in module.1.items %}
+  {% for module,data in categ.modules.items %}
+    {% with module.name as modname %}
+    {% for branch, doms in data.items %}
      {% for dom in doms %}
       {% with dom.0 as domname and dom.1 as stat %}
       {% if stat and not stat.is_fake %}
         <tr id="{{ modname }}-{{ stat.domain.id }}{% if stat.tr_percentage == 100 %}-complete{% endif %}">
         <td class="leftcell">
-          {% if language %}
+          {% if language and not module.archived %}
           <a href="{% url 'vertimus_by_names' modname branch stat.domain.name language.locale %}">{{ stat.module_description }}
           {% else %}
           <a href="{% url 'module' modname %}">{{ stat.module_description }}
diff --git a/templates/module_detail.html b/templates/module_detail.html
index b600693..80e30e6 100644
--- a/templates/module_detail.html
+++ b/templates/module_detail.html
@@ -36,6 +36,10 @@ $(document).ready(function() {
 
 <h1>{{ module.get_description }}</h1>
 
+{% if module.archived %}
+  <p class="errornote">{% trans "This module has been archived. It is only kept for statistical purposes. Please don't translate it any more." %}</p>
+{% endif %}
+
 {% if module.get_comment %}
   <p>{{ module.get_comment|safe }}</p>
 {% else %}
diff --git a/templates/stats_show.html b/templates/stats_show.html
index c46eb85..1270dfc 100644
--- a/templates/stats_show.html
+++ b/templates/stats_show.html
@@ -62,13 +62,13 @@
     {% if not forloop.first %}
     <tr>
       <td class="leftcell">
-        <a href="{% url 'vertimus_by_names' module.name branch.name pot_stat.domain.name line.language.locale %}">
+        {% if not module.archived %}<a href="{% url 'vertimus_by_names' module.name branch.name pot_stat.domain.name line.language.locale %}">{% endif %}
           {% if user_language.locale == line.language.locale %}
             <b>{{ line.get_lang }}</b>
           {% else %}
             {{ line.get_lang }}
           {% endif %}
-        </a>
+        {% if not module.archived %}</a>{% endif %}
         {% with line.most_important_message as msg %}
         {% if msg %}
         <img src="{{ msg.get_icon }}" title="{{ msg.get_description }}" alt="{{ msg.type }}" />



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