[damned-lies: 1/9] Add new PoFile model



commit 9ca4dadce73b694c1cc7fba63e264c23408c5db8
Author: Claude Paroz <claude 2xlibre net>
Date:   Sat Nov 14 14:17:57 2009 +0100

    Add new PoFile model

 stats/migrations/0005_add_pofile.py    |  228 ++++++++++++++++++++++++++++++++
 stats/migrations/0006_migrate_stats.py |  202 ++++++++++++++++++++++++++++
 stats/models.py                        |  183 +++++++++++++++++++-------
 stats/tests/fixture_factory.py         |   44 +++---
 stats/utils.py                         |   15 +-
 vertimus/models.py                     |    4 +-
 6 files changed, 596 insertions(+), 80 deletions(-)
---
diff --git a/stats/migrations/0005_add_pofile.py b/stats/migrations/0005_add_pofile.py
new file mode 100644
index 0000000..1d91565
--- /dev/null
+++ b/stats/migrations/0005_add_pofile.py
@@ -0,0 +1,228 @@
+# 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 model 'PoFile'
+        db.create_table('pofile', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('path', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True, null=True)),
+            ('updated', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+            ('translated', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('fuzzy', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('untranslated', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('num_figures', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('stats', ['PoFile'])
+
+        db.rename_column('statistics', 'date', 'old_date')
+        db.rename_column('statistics', 'translated', 'old_translated')
+        db.rename_column('statistics', 'fuzzy', 'old_fuzzy')
+        db.rename_column('statistics', 'untranslated', 'old_untranslated')
+        db.rename_column('statistics', 'num_figures', 'old_num_figures')
+
+        # Adding field 'Statistics.full_po'
+        db.add_column('statistics', 'full_po', self.gf('django.db.models.fields.related.OneToOneField')(related_name='stat_f', unique=True, null=True, to=orm['stats.PoFile']), keep_default=False)
+
+        # Adding field 'Statistics.part_po'
+        db.add_column('statistics', 'part_po', self.gf('django.db.models.fields.related.OneToOneField')(related_name='stat_p', unique=True, null=True, to=orm['stats.PoFile']), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting model 'PoFile'
+        db.delete_table('pofile')
+
+        # Deleting field 'Statistics.full_po'
+        db.delete_column('statistics', 'full_po_id')
+
+        # Deleting field 'Statistics.part_po'
+        db.delete_column('statistics', 'part_po_id')
+
+
+    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'})
+        },
+        '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'})
+        },
+        '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'"},
+            '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', [], {'symmetrical': 'False', 'related_name': "'maintains_modules'", 'blank': 'True', 'db_table': "'module_maintainer'", 'to': "orm['people.Person']"}),
+            '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.pofile': {
+            'Meta': {'object_name': 'PoFile', 'db_table': "'pofile'"},
+            'fuzzy': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'num_figures': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'translated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'untranslated': ('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_num_figures': ('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/migrations/0006_migrate_stats.py b/stats/migrations/0006_migrate_stats.py
new file mode 100644
index 0000000..bc27eab
--- /dev/null
+++ b/stats/migrations/0006_migrate_stats.py
@@ -0,0 +1,202 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        from stats.models import Statistics, PoFile
+        for st in Statistics.objects.all():
+            if not st.full_po:
+                st.full_po = PoFile.objects.create(path=st.po_path(), translated=st.old_translated, fuzzy=st.old_fuzzy,
+                    untranslated=st.old_untranslated, updated=st.old_date, num_figures=st.old_num_figures)
+                st.save()
+
+
+    def backwards(self, orm):
+        "Write your backwards methods here."
+
+
+    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'})
+        },
+        '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'})
+        },
+        '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'"},
+            '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', [], {'symmetrical': 'False', 'related_name': "'maintains_modules'", 'blank': 'True', 'db_table': "'module_maintainer'", 'to': "orm['people.Person']"}),
+            '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.pofile': {
+            'Meta': {'object_name': 'PoFile', 'db_table': "'pofile'"},
+            'fuzzy': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'num_figures': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'translated': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'untranslated': ('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_num_figures': ('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 9937724..f78e746 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -307,13 +307,14 @@ class Branch(models.Model):
             mandatory_langs is a list of language objects whose stats should be added even if no translation exists.
         """
         stats = SortedDict(); stats_langs = {}
-        pot_stats = Statistics.objects.select_related("language", "domain", "branch"
+        pot_stats = Statistics.objects.select_related("language", "domain", "branch", "full_po"
                         ).filter(branch=self, language__isnull=True, domain__dtype=typ
                         ).order_by('domain__name')
         for stat in pot_stats.all():
             stats[stat.domain.name] = [stat,]
             stats_langs[stat.domain.name] = []
-        tr_stats = Statistics.objects.select_related("language", "domain", "branch").filter(branch=self, language__isnull=False, domain__dtype=typ)
+        tr_stats = Statistics.objects.select_related("language", "domain", "branch", "full_po"
+                        ).filter(branch=self, language__isnull=False, domain__dtype=typ)
         for stat in tr_stats.all():
             stats[stat.domain.name].append(stat)
             stats_langs[stat.domain.name].append(stat.language)
@@ -453,7 +454,7 @@ class Branch(models.Model):
                         }
                     utils.run_shell_command(realcmd)
 
-                    langstats = utils.po_file_stats(outpo, True)
+                    langstats = utils.po_file_stats(outpo, msgfmt_checks=True, count_images=(dom.dtype == "doc"))
                     if linguas['langs'] is not None and lang not in linguas['langs']:
                         langstats['errors'].append(("warn-ext", linguas['error']))
                     if dom.dtype == "doc":
@@ -487,7 +488,7 @@ class Branch(models.Model):
                                                translated = int(langstats['translated']),
                                                fuzzy = int(langstats['fuzzy']),
                                                untranslated = int(langstats['untranslated']),
-                                               num_figures = int(langstats['num_figures']))
+                                               num_figures = int(langstats.get('num_figures', 0)))
                     for err in langstats['errors']:
                         stat.information_set.add(Information(type=err[0], description=err[1]))
             # Check if doap file changed
@@ -736,7 +737,7 @@ class Domain(models.Model):
         return flist
 
     def generate_pot_file(self, current_branch):
-        """ Return the pot file generated, and the error if any """
+        """ Return the pot file generated (in the checkout tree), and the error if any """
 
         vcs_path = os.path.join(current_branch.co_path(), self.directory)
         pot_command = self.pot_method
@@ -876,7 +877,7 @@ class Release(models.Model):
         # Uses the special statistics record where language_id is NULL to compute the sum.
         query = """
             SELECT domain.dtype,
-                   SUM(stat.untranslated)
+                   SUM(pofile.untranslated)
             FROM statistics AS stat
             LEFT JOIN domain
                    ON domain.id = stat.domain_id
@@ -886,6 +887,8 @@ class Release(models.Model):
                    ON cat.branch_id = br.id
             LEFT JOIN "release" AS rel
                    ON rel.id = cat.release_id
+            LEFT JOIN pofile
+                   ON pofile.id = stat.full_po_id
             WHERE rel.id = %s
               AND stat.language_id IS NULL
             GROUP BY domain.dtype"""
@@ -909,8 +912,8 @@ class Release(models.Model):
         total_doc, total_ui = self.total_strings()
         query = """
             SELECT domain.dtype,
-                   SUM(stat.translated),
-                   SUM(stat.fuzzy)
+                   SUM(pofile.translated),
+                   SUM(pofile.fuzzy)
             FROM statistics AS stat
             LEFT JOIN domain
                    ON stat.domain_id = domain.id
@@ -918,6 +921,8 @@ class Release(models.Model):
                    ON stat.branch_id = branch.id
             LEFT JOIN category
                    ON category.branch_id = branch.id
+            LEFT JOIN pofile
+                   ON pofile.id = stat.full_po_id
             WHERE language_id = %s
               AND category.release_id = %s
             GROUP BY domain.dtype"""
@@ -956,8 +961,8 @@ class Release(models.Model):
             SELECT MIN(lang.name),
                    MIN(lang.locale),
                    domain.dtype,
-                   SUM(stat.translated) AS trans,
-                   SUM(stat.fuzzy)
+                   SUM(pofile.translated) AS trans,
+                   SUM(pofile.fuzzy)
             FROM statistics AS stat
             LEFT JOIN domain
                    ON domain.id = stat.domain_id
@@ -967,6 +972,8 @@ class Release(models.Model):
                    ON br.id = stat.branch_id
             LEFT JOIN category
                    ON category.branch_id = br.id
+            LEFT JOIN pofile
+                   ON pofile.id = stat.full_po_id
             WHERE category.release_id = %s AND stat.language_id IS NOT NULL
             GROUP BY domain.dtype, stat.language_id
             ORDER BY domain.dtype, trans DESC"""
@@ -1071,17 +1078,66 @@ class Category(models.Model):
                 return _(entry[1])
         return key
 
+class PoFile(models.Model):
+    # File type fields of Django may not be flexible enough for our use case
+    path         = models.CharField(max_length=255, blank=True, null=True)
+    updated      = models.DateTimeField(auto_now_add=True)
+    translated   = models.IntegerField(default=0)
+    fuzzy        = models.IntegerField(default=0)
+    untranslated = models.IntegerField(default=0)
+    # Number of figures in doc templates
+    num_figures  = models.IntegerField(default=0)
+
+    class Meta:
+        db_table = 'pofile'
+
+    def __unicode__(self):
+        return "%s (%s/%s/%s)" % (self.path, self.translated, self.fuzzy, self.untranslated)
+
+    def pot_size(self):
+        return self.translated + self.fuzzy + self.untranslated
+
+    def fig_count(self):
+        """ If stat of a document type, get the number of figures in the document """
+        return self.num_figures
+
+    def tr_percentage(self):
+        if self.pot_size() == 0:
+            return 0
+        else:
+            return int(100*self.translated/self.pot_size())
+
+    def fu_percentage(self):
+        if self.pot_size() == 0:
+            return 0
+        else:
+            return int(100*self.fuzzy/self.pot_size())
+
+    def un_percentage(self):
+        if self.pot_size() == 0:
+            return 0
+        else:
+            return int(100*self.untranslated/self.pot_size())
+
+    def translation_stat(self):
+        return "%d%%&nbsp;(%d/%d/%d)" % (self.tr_percentage(), self.translated, self.fuzzy, self.untranslated)
+
+
 class Statistics(models.Model):
     branch = models.ForeignKey(Branch)
     domain = models.ForeignKey(Domain)
     language = models.ForeignKey(Language, null=True)
 
-    date = models.DateTimeField(auto_now_add=True)
-    translated = models.IntegerField(default=0)
-    fuzzy = models.IntegerField(default=0)
-    untranslated = models.IntegerField(default=0)
+    # obsolete fields (deleted after migration)
+    old_date = models.DateTimeField(auto_now_add=True) # obsolete
+    old_translated   = models.IntegerField(default=0) # obsolete
+    old_fuzzy        = models.IntegerField(default=0) # obsolete
+    old_untranslated = models.IntegerField(default=0) # obsolete
     # Number of figures in doc templates
-    num_figures = models.IntegerField(default=0)
+    old_num_figures = models.IntegerField(default=0) # obsolete
+
+    full_po = models.OneToOneField(PoFile, null=True, related_name='stat_f')
+    part_po = models.OneToOneField(PoFile, null=True, related_name='stat_p')
 
     class Meta:
         db_table = 'statistics'
@@ -1102,32 +1158,33 @@ class Statistics(models.Model):
         return "%s (%s-%s) %s (%s)" % (self.branch.module.name, self.domain.dtype, self.domain.name,
                                        self.branch.name, self.get_lang())
 
+    @property
+    def translated(self):
+        return getattr(self.full_po, 'translated', 0)
+    @property
+    def fuzzy(self):
+        return getattr(self.full_po, 'fuzzy', 0)
+    @property
+    def untranslated(self):
+        return getattr(self.full_po, 'untranslated', 0)
+
     def is_fake(self):
         return False
 
-    def is_pot_file(self):
+    def is_pot_stats(self):
         return self.language is None
 
     def tr_percentage(self):
-        if self.pot_size() == 0:
-            return 0
-        else:
-            return int(100*self.translated/self.pot_size())
+        return self.full_po and self.full_po.tr_percentage() or 0
 
     def fu_percentage(self):
-        if self.pot_size() == 0:
-            return 0
-        else:
-            return int(100*self.fuzzy/self.pot_size())
+        return self.full_po and self.full_po.fu_percentage() or 0
 
     def un_percentage(self):
-        if self.pot_size() == 0:
-            return 0
-        else:
-            return int(100*self.untranslated/self.pot_size())
+        return self.full_po and self.full_po.un_percentage() or 0
 
     def get_lang(self):
-        if not self.is_pot_file():
+        if not self.is_pot_stats():
             return _("%(lang_name)s (%(lang_locale)s)") % {
                 'lang_name': _(self.language.name),
                 'lang_locale': self.language.locale
@@ -1146,25 +1203,25 @@ class Statistics(models.Model):
         return self.moddescription
 
     def get_translationstat(self):
-        return "%d%%&nbsp;(%d/%d/%d)" % (self.tr_percentage(), self.translated, self.fuzzy, self.untranslated)
+        return self.full_po.translation_stat()
+
+    def get_reducedstat(self):
+        return self.part_po.translation_stat()
 
     def filename(self, potfile=False):
-        if not self.is_pot_file() and not potfile:
+        if not self.is_pot_stats() and not potfile:
             return "%s.%s.%s.po" % (self.domain.potbase(), self.branch.name, self.language.locale)
         else:
             return "%s.%s.pot" % (self.domain.potbase(), self.branch.name)
 
-    def pot_size(self):
-        return int(self.translated) + int(self.fuzzy) + int(self.untranslated)
-
     def pot_text(self):
+        pot_size = self.full_po.pot_size()
+        fig_count = self.full_po.fig_count()
         """ Return stat table header: 'POT file (n messages) - updated on ??-??-???? tz' """
-        pot_size = self.pot_size()
-        fig_count = self.fig_count()
         msg_text = ungettext(u"%(count)s message", "%(count)s messages", pot_size) % {'count': pot_size}
         upd_text = _(u"updated on %(date)s") % {
                         # Date format syntax is similar to PHP http://www.php.net/date
-                        'date': dateformat.format(self.date, _("Y-m-d g:i a O"))
+                        'date': dateformat.format(self.full_po.updated, _("Y-m-d g:i a O"))
                         }
         if fig_count:
             fig_text = ungettext(u"%(count)s figure", "%(count)s figures", fig_count) % {'count': fig_count}
@@ -1193,10 +1250,6 @@ class Statistics(models.Model):
                         fig['translated_file'] = True
         return self.figures
 
-    def fig_count(self):
-        """ If stat of a document type, get the number of figures in the document """
-        return self.num_figures
-
     def fig_stats(self):
         stats = {'fuzzy':0, 'translated':0, 'total':0, 'prc':0}
         for fig in self.get_figures():
@@ -1235,12 +1288,42 @@ class Statistics(models.Model):
         return self.po_url(potfile=True)
 
     def set_translation_stats(self, po_path, translated=0, fuzzy=0, untranslated=0, num_figures=0):
-        self.translated = translated
-        self.fuzzy = fuzzy
-        self.untranslated = untranslated
-        self.num_figures = num_figures
-        self.date = datetime.now()
-        self.save()
+        if not self.full_po:
+            self.full_po = PoFile.objects.create(path=po_path)
+            self.save()
+        self.full_po.path = po_path
+        self.full_po.translated = translated
+        self.full_po.fuzzy = fuzzy
+        self.full_po.untranslated = untranslated
+        self.full_po.num_figures = num_figures
+        self.full_po.updated = datetime.now()
+        self.full_po.save()
+        # Try to compute a reduced po file
+        if self.domain.dtype == "ui" and (self.full_po.fuzzy + self.full_po.untranslated) > 0:
+            # Generate partial_po and store partial stats
+            part_po_path = self.full_po.path[:-3] + ".reduced.po"
+            cmd = "pogrep --invert-match --header --search=locations \"gschema.xml.in\" %(full_po)s %(part_po)s" % {
+                'full_po': self.full_po.path,
+                'part_po': part_po_path,
+            }
+            utils.run_shell_command(cmd)
+            part_stats = utils.po_file_stats(part_po_path, msgfmt_checks=False, count_images=False)
+            if part_stats['translated'] + part_stats['fuzzy'] + part_stats['untranslated'] == translated + fuzzy + untranslated:
+                # No possible gain
+                if self.part_po:
+                    self.part_po = None
+                    self.save()
+                os.remove(part_po_path)
+                return
+            if not self.part_po:
+                self.part_po = PoFile.objects.create(path=part_po_path)
+                self.save()
+            self.part_po.path = part_po_path
+            self.part_po.translated = part_stats['translated']
+            self.part_po.fuzzy = part_stats['fuzzy']
+            self.part_po.untranslated = part_stats['untranslated']
+            self.part_po.updated = datetime.now()
+            self.part_po.save()
 
     def set_errors(self, errors):
         for err in errors:
@@ -1249,7 +1332,7 @@ class Statistics(models.Model):
     def informations(self):
         """ Returns information_set, optionally augmented by domain information """
         info_set = [i for i in self.information_set.all()]
-        if self.is_pot_file() and self.domain.pot_method:
+        if self.is_pot_stats() and self.domain.pot_method:
             # Add a dynamic (ie not saved) Information
             info_set.append(Information(
                 statistics  = self,
@@ -1310,13 +1393,13 @@ class Statistics(models.Model):
                  'totaltransperc': 0, 'totalfuzzyperc': 0, 'totaluntransperc': 0,
                  'categs':{}, 'all_errors':[]}
         # Sorted by module to allow grouping ('fake' stats)
-        pot_stats = Statistics.objects.select_related('domain', 'branch__module')
+        pot_stats = Statistics.objects.select_related('domain', 'branch__module', 'full_po')
         if release:
             pot_stats = pot_stats.extra(select={'categ_name': "category.name"}).filter(language=None, branch__releases=release, domain__dtype=dtype).order_by('branch__module__id')
         else:
             pot_stats = pot_stats.filter(language=None, domain__dtype=dtype).order_by('branch__module__id')
 
-        tr_stats = Statistics.objects.select_related('domain', 'language', 'branch__module')
+        tr_stats = Statistics.objects.select_related('domain', 'language', 'branch__module', 'full_po')
         if release:
             tr_stats = tr_stats.filter(language=lang, branch__releases=release, domain__dtype=dtype).order_by('branch__module__id')
         else:
diff --git a/stats/tests/fixture_factory.py b/stats/tests/fixture_factory.py
index ceffcdb..1fbbefe 100644
--- a/stats/tests/fixture_factory.py
+++ b/stats/tests/fixture_factory.py
@@ -6,7 +6,7 @@ from django.test import TestCase
 from languages.models import Language
 from teams.models import Team, Role
 from people.models import Person
-from stats.models import Module, Domain, Branch, Release, Category, Statistics, Information
+from stats.models import Module, Domain, Branch, Release, Category, Statistics, Information, PoFile
 
 class FixtureFactory(TestCase):
     """ Fake Test case to create fixture.
@@ -106,29 +106,29 @@ class FixtureFactory(TestCase):
 
         # Creating models: Statistics
         # gnome-hello ui, gnome-hello doc (POT, fr, it)
-        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=None, untranslated=47)
-        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=l_fr, translated=47)
-        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=l_it, translated=30, fuzzy=10, untranslated=7)
-        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=None, untranslated=20, num_figures=1)
-        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=l_fr, translated=20)
-        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=l_it, translated=20)
+        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=None, full_po=PoFile.objects.create(untranslated=47))
+        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=l_fr, full_po=PoFile.objects.create(translated=47))
+        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-ui'], language=l_it, full_po=PoFile.objects.create(translated=30, fuzzy=10, untranslated=7))
+        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=None, full_po=PoFile.objects.create(untranslated=20, num_figures=1))
+        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=l_fr, full_po=PoFile.objects.create(translated=20))
+        Statistics.objects.create(branch=b1, domain=dom['gnome-hello-doc'], language=l_it, full_po=PoFile.objects.create(translated=20))
         # zenity ui 2.30, zenity doc 2.30, zenity ui master, zenity doc master (POT, fr, it)
-        Statistics.objects.create(branch=b2, domain=dom['zenity-ui'], language=None, untranslated=136)
-        Statistics.objects.create(branch=b2, domain=dom['zenity-ui'], language=l_fr, translated=136)
-        Statistics.objects.create(branch=b2, domain=dom['zenity-ui'], language=l_it, translated=130, untranslated=6)
-        Statistics.objects.create(branch=b2, domain=dom['zenity-doc'], language=None, untranslated=259, num_figures=11)
-        Statistics.objects.create(branch=b2, domain=dom['zenity-doc'], language=l_fr, untranslated=259)
-        Statistics.objects.create(branch=b2, domain=dom['zenity-doc'], language=l_it, translated=259)
-        stat1 = Statistics.objects.create(branch=b3, domain=dom['zenity-ui'], language=None, untranslated=149)
-        Statistics.objects.create(branch=b3, domain=dom['zenity-ui'], language=l_fr, translated=255, fuzzy=4)
-        Statistics.objects.create(branch=b3, domain=dom['zenity-ui'], language=l_it, translated=259)
-        Statistics.objects.create(branch=b3, domain=dom['zenity-doc'], language=None, untranslated=259, num_figures=11)
-        Statistics.objects.create(branch=b3, domain=dom['zenity-doc'], language=l_fr, untranslated=259)
-        Statistics.objects.create(branch=b3, domain=dom['zenity-doc'], language=l_it, translated=259)
+        Statistics.objects.create(branch=b2, domain=dom['zenity-ui'], language=None, full_po=PoFile.objects.create(untranslated=136))
+        Statistics.objects.create(branch=b2, domain=dom['zenity-ui'], language=l_fr, full_po=PoFile.objects.create(translated=136))
+        Statistics.objects.create(branch=b2, domain=dom['zenity-ui'], language=l_it, full_po=PoFile.objects.create(translated=130, untranslated=6))
+        Statistics.objects.create(branch=b2, domain=dom['zenity-doc'], language=None, full_po=PoFile.objects.create(untranslated=259, num_figures=11))
+        Statistics.objects.create(branch=b2, domain=dom['zenity-doc'], language=l_fr, full_po=PoFile.objects.create(untranslated=259))
+        Statistics.objects.create(branch=b2, domain=dom['zenity-doc'], language=l_it, full_po=PoFile.objects.create(translated=259))
+        stat1 = Statistics.objects.create(branch=b3, domain=dom['zenity-ui'], language=None, full_po=PoFile.objects.create(untranslated=149))
+        Statistics.objects.create(branch=b3, domain=dom['zenity-ui'], language=l_fr, full_po=PoFile.objects.create(translated=255, fuzzy=4))
+        Statistics.objects.create(branch=b3, domain=dom['zenity-ui'], language=l_it, full_po=PoFile.objects.create(translated=259))
+        Statistics.objects.create(branch=b3, domain=dom['zenity-doc'], language=None, full_po=PoFile.objects.create(untranslated=259, num_figures=11))
+        Statistics.objects.create(branch=b3, domain=dom['zenity-doc'], language=l_fr, full_po=PoFile.objects.create(untranslated=259))
+        Statistics.objects.create(branch=b3, domain=dom['zenity-doc'], language=l_it, full_po=PoFile.objects.create(translated=259))
         # shared-mime-info ui (POT, fr, it)
-        Statistics.objects.create(branch=b4, domain=dom['shared-mime-info-ui'], language=None, untranslated=626)
-        Statistics.objects.create(branch=b4, domain=dom['shared-mime-info-ui'], language=l_fr, translated=598, fuzzy=20, untranslated=2)
-        Statistics.objects.create(branch=b4, domain=dom['shared-mime-info-ui'], language=l_it, translated=620, fuzzy=6)
+        Statistics.objects.create(branch=b4, domain=dom['shared-mime-info-ui'], language=None, full_po=PoFile.objects.create(untranslated=626))
+        Statistics.objects.create(branch=b4, domain=dom['shared-mime-info-ui'], language=l_fr, full_po=PoFile.objects.create(translated=598, fuzzy=20, untranslated=2))
+        Statistics.objects.create(branch=b4, domain=dom['shared-mime-info-ui'], language=l_it, full_po=PoFile.objects.create(translated=620, fuzzy=6))
 
         # Example of error
         stat1.information_set.add(Information(
diff --git a/stats/utils.py b/stats/utils.py
index 7f0faea..072c3ac 100644
--- a/stats/utils.py
+++ b/stats/utils.py
@@ -222,7 +222,7 @@ def pot_diff_status(pota, potb):
     else:
         return CHANGED_NO_ADDITIONS, result_all
 
-def po_file_stats(pofile, msgfmt_checks = True):
+def po_file_stats(pofile, msgfmt_checks=True, count_images=True):
     """ Compute pofile translation statistics, and proceed to some validity checks if msgfmt_checks is True """
     res = {
         'translated' : 0,
@@ -270,11 +270,11 @@ def po_file_stats(pofile, msgfmt_checks = True):
     r_fz = re.search(r"([0-9]+) fuzzy", errs)
 
     if r_tr:
-        res['translated'] = r_tr.group(1)
+        res['translated'] = int(r_tr.group(1))
     if r_un:
-        res['untranslated'] = r_un.group(1)
+        res['untranslated'] = int(r_un.group(1))
     if r_fz:
-        res['fuzzy'] = r_fz.group(1)
+        res['fuzzy'] = int(r_fz.group(1))
 
     if msgfmt_checks:
         # Check if PO file is in UTF-8
@@ -292,9 +292,10 @@ def po_file_stats(pofile, msgfmt_checks = True):
             res['errors'].append(("warn",
                               ugettext_noop("PO file '%s' is not UTF-8 encoded.") % (filename)))
     # Count number of figures in PO(T) file
-    command = "grep '^msgid \"@@image:' \"%s\" | wc -l" % pofile
-    (status, output, errs) = run_shell_command(command)
-    res['num_figures'] = int(output)
+    if count_images:
+        command = "grep '^msgid \"@@image:' \"%s\" | wc -l" % pofile
+        (status, output, errs) = run_shell_command(command)
+        res['num_figures'] = int(output)
 
     return res
 
diff --git a/vertimus/models.py b/vertimus/models.py
index df3a09a..b5db15c 100644
--- a/vertimus/models.py
+++ b/vertimus/models.py
@@ -29,7 +29,7 @@ from django.db.models import Max
 from django.db.models.signals import post_save, post_delete
 from django.utils.translation import get_language, activate, ugettext, ugettext_lazy as _
 
-from stats.models import Branch, Domain, Statistics
+from stats.models import Branch, Domain, Statistics, PoFile
 from stats.signals import pot_has_changed
 from stats.utils import run_shell_command
 from languages.models import Language
@@ -342,6 +342,8 @@ class ActionDb(models.Model):
     created = models.DateTimeField(auto_now_add=True, editable=False)
     comment = models.TextField(blank=True, null=True)
     file = models.FileField(upload_to=generate_upload_filename, blank=True, null=True)
+    #up_file     = models.OneToOneField(PoFile, null=True, related_name='action_p')
+    #merged_file = models.OneToOneField(PoFile, null=True, related_name='action_m')
 
     class Meta:
         db_table = 'action'



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