[damned-lies: 1/9] Add new PoFile model
- From: Claude Paroz <claudep src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [damned-lies: 1/9] Add new PoFile model
- Date: Wed, 16 Mar 2011 09:04:48 +0000 (UTC)
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%% (%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%% (%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]