[damned-lies] Finished replacing hard-coded category.name



commit 9ce933f6a027791c45bea62bdf83ef8f4b452fa6
Author: Claude Paroz <claude 2xlibre net>
Date:   Wed Sep 9 18:44:44 2015 +0200

    Finished replacing hard-coded category.name

 stats/fixtures/sample_data.json              | 1598 ++++++++++++++------------
 stats/forms.py                               |   21 +-
 stats/management/commands/update-trans.py    |    6 +-
 stats/migrations/0004_remove_old_cat_name.py |   29 +
 stats/models.py                              |   38 +-
 stats/tests/fixture_factory.py               |   17 +-
 stats/tests/tests.py                         |    7 +-
 vertimus/tests/tests.py                      |    5 +-
 8 files changed, 936 insertions(+), 785 deletions(-)
---
diff --git a/stats/fixtures/sample_data.json b/stats/fixtures/sample_data.json
index 0ee8742..eb706f5 100644
--- a/stats/fixtures/sample_data.json
+++ b/stats/fixtures/sample_data.json
@@ -1,1036 +1,1162 @@
 [
 {
- "pk": 2, 
- "model": "auth.user", 
- "fields": {
-  "username": "bob", 
-  "first_name": "Robert", 
-  "last_name": "Translator", 
-  "is_active": true, 
-  "is_superuser": false, 
-  "is_staff": false, 
-  "last_login": "2014-03-24T20:43:36", 
-  "groups": [], 
-  "user_permissions": [], 
-  "password": "!bJL49Mx8IdmI30Ab8mxs5sI6HW7QXsSH8U3rpeNe", 
-  "email": "bob example org", 
-  "date_joined": "2014-03-24T20:43:36"
- }
-},
-{
- "pk": 3, 
- "model": "auth.user", 
- "fields": {
-  "username": "coord", 
-  "first_name": "John", 
-  "last_name": "Coordinator", 
-  "is_active": true, 
-  "is_superuser": false, 
-  "is_staff": false, 
-  "last_login": "2014-03-24T20:43:36", 
-  "groups": [], 
-  "user_permissions": [], 
-  "password": "!AQEpoUpRgzQnX1Q0T3LhBJUpcJaB0BYTdzV16W6r", 
-  "email": "coord example org", 
-  "date_joined": "2014-03-24T20:43:36"
- }
-},
-{
- "pk": 4, 
- "model": "auth.user", 
- "fields": {
-  "username": "alessio", 
-  "first_name": "Alessio", 
-  "last_name": "Reviewer", 
-  "is_active": true, 
-  "is_superuser": false, 
-  "is_staff": false, 
-  "last_login": "2014-03-24T20:43:36", 
-  "groups": [], 
-  "user_permissions": [], 
-  "password": "!O97A8mbIQr1a9cKPmXbN48vSH2G9agzfWkZFou8n", 
-  "email": "alessio example org", 
-  "date_joined": "2014-03-24T20:43:36"
- }
-},
-{
- "pk": 2, 
- "model": "people.person", 
- "fields": {
-  "bugzilla_account": null, 
-  "groups": [], 
-  "image": null, 
-  "activation_key": null, 
-  "irc_nick": "bobby", 
-  "svn_account": "bob1", 
-  "webpage_url": null, 
-  "user_permissions": [], 
+ "fields": {
+  "username": "bob",
+  "first_name": "Robert",
+  "last_name": "Translator",
+  "is_active": true,
+  "is_superuser": false,
+  "is_staff": false,
+  "last_login": null,
+  "groups": [],
+  "user_permissions": [],
+  "password": "!XmjxDUfBch5HinrLIWk7MUjJnVBJyHkjTi4FmXVi",
+  "email": "bob example org",
+  "date_joined": "2015-09-09T18:27:04"
+ },
+ "model": "auth.user",
+ "pk": 2
+},
+{
+ "fields": {
+  "username": "coord",
+  "first_name": "John",
+  "last_name": "Coordinator",
+  "is_active": true,
+  "is_superuser": false,
+  "is_staff": false,
+  "last_login": null,
+  "groups": [],
+  "user_permissions": [],
+  "password": "!JHtSuqoDng9UMWR9s0Mm0kt9G5kZeigdAcwmt1yJ",
+  "email": "coord example org",
+  "date_joined": "2015-09-09T18:27:04"
+ },
+ "model": "auth.user",
+ "pk": 3
+},
+{
+ "fields": {
+  "username": "alessio",
+  "first_name": "Alessio",
+  "last_name": "Reviewer",
+  "is_active": true,
+  "is_superuser": false,
+  "is_staff": false,
+  "last_login": null,
+  "groups": [],
+  "user_permissions": [],
+  "password": "!QBaPicJyWyy0eIVwoyzfKjGJp9QznzSA70j84WSq",
+  "email": "alessio example org",
+  "date_joined": "2015-09-09T18:27:04"
+ },
+ "model": "auth.user",
+ "pk": 4
+},
+{
+ "fields": {
+  "bugzilla_account": null,
+  "groups": [],
+  "image": null,
+  "activation_key": null,
+  "irc_nick": "bobby",
+  "svn_account": "bob1",
+  "webpage_url": null,
+  "user_permissions": [],
   "use_gravatar": false
- }
+ },
+ "model": "people.person",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "people.person", 
  "fields": {
-  "bugzilla_account": null, 
-  "groups": [], 
-  "image": null, 
-  "activation_key": null, 
-  "irc_nick": null, 
-  "svn_account": "coord_fr", 
-  "webpage_url": null, 
-  "user_permissions": [], 
+  "bugzilla_account": null,
+  "groups": [],
+  "image": null,
+  "activation_key": null,
+  "irc_nick": null,
+  "svn_account": "coord_fr",
+  "webpage_url": null,
+  "user_permissions": [],
   "use_gravatar": false
- }
+ },
+ "model": "people.person",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "people.person", 
  "fields": {
-  "bugzilla_account": null, 
-  "groups": [], 
-  "image": null, 
-  "activation_key": null, 
-  "irc_nick": null, 
-  "svn_account": null, 
-  "webpage_url": null, 
-  "user_permissions": [], 
+  "bugzilla_account": null,
+  "groups": [],
+  "image": null,
+  "activation_key": null,
+  "irc_nick": null,
+  "svn_account": null,
+  "webpage_url": null,
+  "user_permissions": [],
   "use_gravatar": false
- }
+ },
+ "model": "people.person",
+ "pk": 4
 },
 {
- "pk": 1, 
- "model": "teams.team", 
  "fields": {
-  "mailing_list_subscribe": "http://www.traduc.org/mailman/listinfo/gnomefr";, 
-  "name": "fr", 
-  "webpage_url": "http://gnomefr.traduc.org/";, 
-  "use_workflow": true, 
-  "presentation": "Here can come any custom description for a team", 
-  "mailing_list": "gnomefr traduc org", 
+  "mailing_list_subscribe": "http://www.traduc.org/mailman/listinfo/gnomefr";,
+  "name": "fr",
+  "webpage_url": "http://gnomefr.traduc.org/";,
+  "use_workflow": true,
+  "presentation": "Here can come any custom description for a team",
+  "mailing_list": "gnomefr traduc org",
   "description": "French"
- }
+ },
+ "model": "teams.team",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "teams.team", 
  "fields": {
-  "mailing_list_subscribe": null, 
-  "name": "it", 
-  "webpage_url": "http://www.it.gnome.org/";, 
-  "use_workflow": true, 
-  "presentation": "", 
-  "mailing_list": null, 
+  "mailing_list_subscribe": null,
+  "name": "it",
+  "webpage_url": "http://www.it.gnome.org/";,
+  "use_workflow": true,
+  "presentation": "",
+  "mailing_list": null,
   "description": "Italian"
- }
+ },
+ "model": "teams.team",
+ "pk": 2
 },
 {
- "pk": 1, 
- "model": "teams.role", 
  "fields": {
-  "is_active": true, 
-  "person": 2, 
-  "role": "translator", 
+  "is_active": true,
+  "person": 2,
+  "role": "translator",
   "team": 1
- }
+ },
+ "model": "teams.role",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "teams.role", 
  "fields": {
-  "is_active": true, 
-  "person": 3, 
-  "role": "coordinator", 
+  "is_active": true,
+  "person": 3,
+  "role": "coordinator",
   "team": 1
- }
+ },
+ "model": "teams.role",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "teams.role", 
  "fields": {
-  "is_active": true, 
-  "person": 4, 
-  "role": "reviewer", 
+  "is_active": true,
+  "person": 4,
+  "role": "reviewer",
   "team": 2
- }
+ },
+ "model": "teams.role",
+ "pk": 3
 },
 {
- "pk": 1, 
- "model": "languages.language", 
  "fields": {
-  "locale": "en", 
-  "plurals": "nplurals=2; plural=(n != 1)", 
-  "name": "en", 
+  "locale": "en",
+  "plurals": "nplurals=2; plural=(n != 1)",
+  "name": "en",
   "team": null
- }
+ },
+ "model": "languages.language",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "languages.language", 
  "fields": {
-  "locale": "fr", 
-  "plurals": "nplurals=2; plural=(n > 1)", 
-  "name": "French", 
+  "locale": "fr",
+  "plurals": "nplurals=2; plural=(n > 1)",
+  "name": "French",
   "team": 1
- }
+ },
+ "model": "languages.language",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "languages.language", 
  "fields": {
-  "locale": "it", 
-  "plurals": "nplurals=2; plural=(n != 1)", 
-  "name": "Italian", 
+  "locale": "it",
+  "plurals": "nplurals=2; plural=(n != 1)",
+  "name": "Italian",
   "team": 2
- }
+ },
+ "model": "languages.language",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "languages.language", 
  "fields": {
-  "locale": "bem", 
-  "plurals": "", 
-  "name": "Bemba", 
+  "locale": "bem",
+  "plurals": "",
+  "name": "Bemba",
   "team": null
- }
-},
-{
- "pk": 1, 
- "model": "stats.module", 
- "fields": {
-  "comment": null, 
-  "archived": false, 
-  "vcs_web": "https://git.gnome.org/browse/gnome-hello/";, 
-  "name": "gnome-hello", 
-  "vcs_root": "git://git.gnome.org/gnome-hello", 
-  "bugs_product": "test", 
-  "ext_platform": null, 
-  "maintainers": [], 
-  "bugs_component": "test", 
-  "bugs_base": "https://bugzilla.gnome.org";, 
-  "vcs_type": "git", 
-  "homepage": null, 
+ },
+ "model": "languages.language",
+ "pk": 4
+},
+{
+ "fields": {
+  "comment": null,
+  "archived": false,
+  "vcs_web": "https://git.gnome.org/browse/gnome-hello/";,
+  "name": "gnome-hello",
+  "vcs_root": "git://git.gnome.org/gnome-hello",
+  "bugs_product": "test",
+  "ext_platform": null,
+  "maintainers": [],
+  "bugs_component": "test",
+  "bugs_base": "https://bugzilla.gnome.org";,
+  "vcs_type": "git",
+  "homepage": null,
   "description": null
- }
-},
-{
- "pk": 2, 
- "model": "stats.module", 
- "fields": {
-  "comment": null, 
-  "archived": false, 
-  "vcs_web": "https://git.gnome.org/browse/zenity/";, 
-  "name": "zenity", 
-  "vcs_root": "git://git.gnome.org/zenity", 
-  "bugs_product": "zenity", 
-  "ext_platform": null, 
-  "maintainers": [], 
-  "bugs_component": "general", 
-  "bugs_base": "https://bugzilla.gnome.org";, 
-  "vcs_type": "git", 
-  "homepage": null, 
+ },
+ "model": "stats.module",
+ "pk": 1
+},
+{
+ "fields": {
+  "comment": null,
+  "archived": false,
+  "vcs_web": "https://git.gnome.org/browse/zenity/";,
+  "name": "zenity",
+  "vcs_root": "git://git.gnome.org/zenity",
+  "bugs_product": "zenity",
+  "ext_platform": null,
+  "maintainers": [],
+  "bugs_component": "general",
+  "bugs_base": "https://bugzilla.gnome.org";,
+  "vcs_type": "git",
+  "homepage": null,
   "description": null
- }
-},
-{
- "pk": 3, 
- "model": "stats.module", 
- "fields": {
-  "comment": "This is not a GNOME-specific module. Please submit your translation through the <a 
href=\"http://www.transifex.com/projects/p/shared-mime-info/c/default/\";>Transifex platform</a>.", 
-  "archived": false, 
-  "vcs_web": "http://cgit.freedesktop.org/xdg/shared-mime-info/";, 
-  "name": "shared-mime-info", 
-  "vcs_root": "git://anongit.freedesktop.org/xdg/shared-mime-info", 
-  "bugs_product": "shared-mime-info", 
-  "ext_platform": null, 
-  "maintainers": [], 
-  "bugs_component": "general", 
-  "bugs_base": "https://bugs.freedesktop.org/";, 
-  "vcs_type": "git", 
-  "homepage": null, 
+ },
+ "model": "stats.module",
+ "pk": 2
+},
+{
+ "fields": {
+  "comment": "This is not a GNOME-specific module. Please submit your translation through the <a 
href=\"http://www.transifex.com/projects/p/shared-mime-info/c/default/\";>Transifex platform</a>.",
+  "archived": false,
+  "vcs_web": "http://cgit.freedesktop.org/xdg/shared-mime-info/";,
+  "name": "shared-mime-info",
+  "vcs_root": "git://anongit.freedesktop.org/xdg/shared-mime-info",
+  "bugs_product": "shared-mime-info",
+  "ext_platform": null,
+  "maintainers": [],
+  "bugs_component": "general",
+  "bugs_base": "https://bugs.freedesktop.org/";,
+  "vcs_type": "git",
+  "homepage": null,
   "description": "Shared MIME Info"
- }
+ },
+ "model": "stats.module",
+ "pk": 3
 },
 {
- "pk": 1, 
- "model": "stats.branch", 
  "fields": {
-  "vcs_subpath": null, 
-  "file_hashes": "", 
-  "weight": 0, 
-  "name": "master", 
+  "vcs_subpath": null,
+  "file_hashes": "",
+  "weight": 0,
+  "name": "master",
   "module": 1
- }
+ },
+ "model": "stats.branch",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "stats.branch", 
  "fields": {
-  "vcs_subpath": null, 
-  "file_hashes": "", 
-  "weight": 0, 
-  "name": "gnome-3-8", 
+  "vcs_subpath": null,
+  "file_hashes": "",
+  "weight": 0,
+  "name": "gnome-3-8",
   "module": 2
- }
+ },
+ "model": "stats.branch",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "stats.branch", 
  "fields": {
-  "vcs_subpath": null, 
-  "file_hashes": "", 
-  "weight": 0, 
-  "name": "master", 
+  "vcs_subpath": null,
+  "file_hashes": "",
+  "weight": 0,
+  "name": "master",
   "module": 2
- }
+ },
+ "model": "stats.branch",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "stats.branch", 
  "fields": {
-  "vcs_subpath": null, 
-  "file_hashes": "", 
-  "weight": 0, 
-  "name": "master", 
+  "vcs_subpath": null,
+  "file_hashes": "",
+  "weight": 0,
+  "name": "master",
   "module": 3
- }
+ },
+ "model": "stats.branch",
+ "pk": 4
 },
 {
- "pk": 1, 
- "model": "stats.domain", 
  "fields": {
-  "name": "po", 
-  "dtype": "ui", 
-  "pot_method": null, 
-  "module": 1, 
-  "linguas_location": null, 
-  "red_filter": null, 
-  "directory": "po", 
+  "name": "po",
+  "dtype": "ui",
+  "pot_method": null,
+  "module": 1,
+  "linguas_location": null,
+  "red_filter": null,
+  "directory": "po",
   "description": "UI Translations"
- }
+ },
+ "model": "stats.domain",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "stats.domain", 
  "fields": {
-  "name": "help", 
-  "dtype": "doc", 
-  "pot_method": null, 
-  "module": 1, 
-  "linguas_location": null, 
-  "red_filter": null, 
-  "directory": "help", 
+  "name": "help",
+  "dtype": "doc",
+  "pot_method": null,
+  "module": 1,
+  "linguas_location": null,
+  "red_filter": null,
+  "directory": "help",
   "description": "User Guide"
- }
+ },
+ "model": "stats.domain",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "stats.domain", 
  "fields": {
-  "name": "po", 
-  "dtype": "ui", 
-  "pot_method": null, 
-  "module": 2, 
-  "linguas_location": null, 
-  "red_filter": null, 
-  "directory": "po", 
+  "name": "po",
+  "dtype": "ui",
+  "pot_method": null,
+  "module": 2,
+  "linguas_location": null,
+  "red_filter": null,
+  "directory": "po",
   "description": "UI Translations"
- }
+ },
+ "model": "stats.domain",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "stats.domain", 
  "fields": {
-  "name": "help", 
-  "dtype": "doc", 
-  "pot_method": null, 
-  "module": 2, 
-  "linguas_location": null, 
-  "red_filter": null, 
-  "directory": "help", 
+  "name": "help",
+  "dtype": "doc",
+  "pot_method": null,
+  "module": 2,
+  "linguas_location": null,
+  "red_filter": null,
+  "directory": "help",
   "description": "User Guide"
- }
+ },
+ "model": "stats.domain",
+ "pk": 4
 },
 {
- "pk": 5, 
- "model": "stats.domain", 
  "fields": {
-  "name": "po", 
-  "dtype": "ui", 
-  "pot_method": null, 
-  "module": 3, 
-  "linguas_location": null, 
-  "red_filter": null, 
-  "directory": "po", 
+  "name": "po",
+  "dtype": "ui",
+  "pot_method": null,
+  "module": 3,
+  "linguas_location": null,
+  "red_filter": null,
+  "directory": "po",
   "description": "UI Translations"
- }
+ },
+ "model": "stats.domain",
+ "pk": 5
 },
 {
- "pk": 6, 
- "model": "stats.domain", 
  "fields": {
-  "name": "help", 
-  "dtype": "doc", 
-  "pot_method": null, 
-  "module": 3, 
-  "linguas_location": null, 
-  "red_filter": null, 
-  "directory": "help", 
+  "name": "help",
+  "dtype": "doc",
+  "pot_method": null,
+  "module": 3,
+  "linguas_location": null,
+  "red_filter": null,
+  "directory": "help",
   "description": "User Guide"
- }
+ },
+ "model": "stats.domain",
+ "pk": 6
 },
 {
- "pk": 1, 
- "model": "stats.release", 
  "fields": {
-  "status": "official", 
-  "string_frozen": true, 
-  "name": "gnome-3-8", 
-  "weight": 0, 
+  "status": "official",
+  "string_frozen": true,
+  "name": "gnome-3-8",
+  "weight": 0,
   "description": "GNOME 3.8 (stable)"
- }
+ },
+ "model": "stats.release",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "stats.release", 
  "fields": {
-  "status": "official", 
-  "string_frozen": false, 
-  "name": "gnome-dev", 
-  "weight": 0, 
+  "status": "official",
+  "string_frozen": false,
+  "name": "gnome-dev",
+  "weight": 0,
   "description": "GNOME in Development"
- }
+ },
+ "model": "stats.release",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "stats.release", 
  "fields": {
-  "status": "xternal", 
-  "string_frozen": false, 
-  "name": "freedesktop-org", 
-  "weight": 0, 
+  "status": "xternal",
+  "string_frozen": false,
+  "name": "freedesktop-org",
+  "weight": 0,
   "description": "freedesktop.org (non-GNOME)"
- }
+ },
+ "model": "stats.release",
+ "pk": 3
+},
+{
+ "fields": {
+  "name": "Default"
+ },
+ "model": "stats.categoryname",
+ "pk": 1
+},
+{
+ "fields": {
+  "name": "Administration Tools"
+ },
+ "model": "stats.categoryname",
+ "pk": 2
+},
+{
+ "fields": {
+  "name": "Development Tools"
+ },
+ "model": "stats.categoryname",
+ "pk": 3
+},
+{
+ "fields": {
+  "name": "GNOME Desktop"
+ },
+ "model": "stats.categoryname",
+ "pk": 4
+},
+{
+ "fields": {
+  "name": "GNOME Developer Platform"
+ },
+ "model": "stats.categoryname",
+ "pk": 5
+},
+{
+ "fields": {
+  "name": "New Module Proposals"
+ },
+ "model": "stats.categoryname",
+ "pk": 6
+},
+{
+ "fields": {
+  "name": "Core"
+ },
+ "model": "stats.categoryname",
+ "pk": 7
+},
+{
+ "fields": {
+  "name": "Utils"
+ },
+ "model": "stats.categoryname",
+ "pk": 8
+},
+{
+ "fields": {
+  "name": "Apps"
+ },
+ "model": "stats.categoryname",
+ "pk": 9
+},
+{
+ "fields": {
+  "name": "Accessibility"
+ },
+ "model": "stats.categoryname",
+ "pk": 10
+},
+{
+ "fields": {
+  "name": "Games"
+ },
+ "model": "stats.categoryname",
+ "pk": 11
+},
+{
+ "fields": {
+  "name": "Backends"
+ },
+ "model": "stats.categoryname",
+ "pk": 12
+},
+{
+ "fields": {
+  "name": "Core Libraries"
+ },
+ "model": "stats.categoryname",
+ "pk": 13
+},
+{
+ "fields": {
+  "name": "Extra Libraries"
+ },
+ "model": "stats.categoryname",
+ "pk": 14
+},
+{
+ "fields": {
+  "name": "Legacy Desktop"
+ },
+ "model": "stats.categoryname",
+ "pk": 15
+},
+{
+ "fields": {
+  "name": "Stable Branches"
+ },
+ "model": "stats.categoryname",
+ "pk": 16
+},
+{
+ "fields": {
+  "name": "Development Branches"
+ },
+ "model": "stats.categoryname",
+ "pk": 17
+},
+{
+ "fields": {
+  "name": "Desktop"
+ },
+ "model": "stats.categoryname",
+ "pk": 18
 },
 {
- "pk": 1, 
- "model": "stats.category", 
  "fields": {
-  "release": 1, 
-  "name": "desktop", 
+  "release": 1,
+  "name": 18,
   "branch": 1
- }
+ },
+ "model": "stats.category",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "stats.category", 
  "fields": {
-  "release": 2, 
-  "name": "desktop", 
+  "release": 2,
+  "name": 18,
   "branch": 1
- }
+ },
+ "model": "stats.category",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "stats.category", 
  "fields": {
-  "release": 1, 
-  "name": "desktop", 
+  "release": 1,
+  "name": 18,
   "branch": 2
- }
+ },
+ "model": "stats.category",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "stats.category", 
  "fields": {
-  "release": 3, 
-  "name": "desktop", 
+  "release": 3,
+  "name": 18,
   "branch": 4
- }
+ },
+ "model": "stats.category",
+ "pk": 4
 },
 {
- "pk": 1, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 47, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 47,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 47, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 47,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 7, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 10, 
-  "translated": 30, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 7,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 10,
+  "translated": 30,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 20, 
-  "translated_words": 0, 
-  "figures": "[{\"path\": \"figures/gnome-hello-new.png\", \"hash\": \"8a1fcc6f46a22a1f500cfef9ca51b481\"}, 
{\"path\": \"figures/gnome-hello-logo.png\", \"hash\": \"1ae47b7a7c4fbeb1f6bb72c0cf18d389\"}]", 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 20,
+  "translated_words": 0,
+  "figures": "[{\"path\": \"figures/gnome-hello-new.png\", \"hash\": \"8a1fcc6f46a22a1f500cfef9ca51b481\"}, 
{\"path\": \"figures/gnome-hello-logo.png\", \"hash\": \"1ae47b7a7c4fbeb1f6bb72c0cf18d389\"}]",
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 4
 },
 {
- "pk": 5, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": "[{\"translated\": false, \"path\": \"figures/gnome-hello-new.png\", \"hash\": 
\"8a1fcc6f46a22a1f500cfef9ca51b481\", \"fuzzy\": true}, {\"translated\": false, \"path\": 
\"figures/gnome-hello-logo.png\", \"hash\": \"1ae47b7a7c4fbeb1f6bb72c0cf18d389\", \"fuzzy\": false}]", 
-  "fuzzy": 0, 
-  "translated": 20, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": "[{\"translated\": false, \"path\": \"figures/gnome-hello-new.png\", \"hash\": 
\"8a1fcc6f46a22a1f500cfef9ca51b481\", \"fuzzy\": true}, {\"translated\": false, \"path\": 
\"figures/gnome-hello-logo.png\", \"hash\": \"1ae47b7a7c4fbeb1f6bb72c0cf18d389\", \"fuzzy\": false}]",
+  "fuzzy": 0,
+  "translated": 20,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 5
 },
 {
- "pk": 6, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 20, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 20,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 6
 },
 {
- "pk": 7, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 136, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 136,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 7
 },
 {
- "pk": 8, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 128, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 128,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 8
 },
 {
- "pk": 9, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 136, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 136,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 9
 },
 {
- "pk": 10, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 6, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 130, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 6,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 130,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 10
 },
 {
- "pk": 11, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 28, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 100, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 28,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 100,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 11
 },
 {
- "pk": 12, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 259, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 259,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 12
 },
 {
- "pk": 13, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 259, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 259,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 13
 },
 {
- "pk": 14, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 259, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 259,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 14
 },
 {
- "pk": 15, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 149, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 149,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 15
 },
 {
- "pk": 16, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 4, 
-  "translated": 255, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 4,
+  "translated": 255,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 16
 },
 {
- "pk": 17, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 259, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 259,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 17
 },
 {
- "pk": 18, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 259, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 259,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 18
 },
 {
- "pk": 19, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 259, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 259,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 19
 },
 {
- "pk": 20, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 259, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 259,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 20
 },
 {
- "pk": 21, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 626, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 0, 
-  "translated": 0, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 626,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 0,
+  "translated": 0,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 21
 },
 {
- "pk": 22, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 2, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 20, 
-  "translated": 598, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 2,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 20,
+  "translated": 598,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 22
 },
 {
- "pk": 23, 
- "model": "stats.pofile", 
  "fields": {
-  "updated": "2014-03-24T20:43:36", 
-  "untranslated_words": 0, 
-  "fuzzy_words": 0, 
-  "untranslated": 0, 
-  "translated_words": 0, 
-  "figures": null, 
-  "fuzzy": 6, 
-  "translated": 620, 
+  "updated": "2015-09-09T18:27:04",
+  "untranslated_words": 0,
+  "fuzzy_words": 0,
+  "untranslated": 0,
+  "translated_words": 0,
+  "figures": null,
+  "fuzzy": 6,
+  "translated": 620,
   "path": null
- }
+ },
+ "model": "stats.pofile",
+ "pk": 23
 },
 {
- "pk": 1, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 1, 
-  "domain": 1, 
-  "part_po": 1, 
-  "language": null, 
+  "full_po": 1,
+  "domain": 1,
+  "part_po": 1,
+  "language": null,
   "branch": 1
- }
+ },
+ "model": "stats.statistics",
+ "pk": 1
 },
 {
- "pk": 2, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 2, 
-  "domain": 1, 
-  "part_po": 2, 
-  "language": 2, 
+  "full_po": 2,
+  "domain": 1,
+  "part_po": 2,
+  "language": 2,
   "branch": 1
- }
+ },
+ "model": "stats.statistics",
+ "pk": 2
 },
 {
- "pk": 3, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 3, 
-  "domain": 1, 
-  "part_po": 3, 
-  "language": 3, 
+  "full_po": 3,
+  "domain": 1,
+  "part_po": 3,
+  "language": 3,
   "branch": 1
- }
+ },
+ "model": "stats.statistics",
+ "pk": 3
 },
 {
- "pk": 4, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 4, 
-  "domain": 2, 
-  "part_po": 4, 
-  "language": null, 
+  "full_po": 4,
+  "domain": 2,
+  "part_po": 4,
+  "language": null,
   "branch": 1
- }
+ },
+ "model": "stats.statistics",
+ "pk": 4
 },
 {
- "pk": 5, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 5, 
-  "domain": 2, 
-  "part_po": 5, 
-  "language": 2, 
+  "full_po": 5,
+  "domain": 2,
+  "part_po": 5,
+  "language": 2,
   "branch": 1
- }
+ },
+ "model": "stats.statistics",
+ "pk": 5
 },
 {
- "pk": 6, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 6, 
-  "domain": 2, 
-  "part_po": 6, 
-  "language": 3, 
+  "full_po": 6,
+  "domain": 2,
+  "part_po": 6,
+  "language": 3,
   "branch": 1
- }
+ },
+ "model": "stats.statistics",
+ "pk": 6
 },
 {
- "pk": 7, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 7, 
-  "domain": 3, 
-  "part_po": 8, 
-  "language": null, 
+  "full_po": 7,
+  "domain": 3,
+  "part_po": 8,
+  "language": null,
   "branch": 2
- }
+ },
+ "model": "stats.statistics",
+ "pk": 7
 },
 {
- "pk": 8, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 9, 
-  "domain": 3, 
-  "part_po": 9, 
-  "language": 2, 
+  "full_po": 9,
+  "domain": 3,
+  "part_po": 9,
+  "language": 2,
   "branch": 2
- }
+ },
+ "model": "stats.statistics",
+ "pk": 8
 },
 {
- "pk": 9, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 10, 
-  "domain": 3, 
-  "part_po": 11, 
-  "language": 3, 
+  "full_po": 10,
+  "domain": 3,
+  "part_po": 11,
+  "language": 3,
   "branch": 2
- }
+ },
+ "model": "stats.statistics",
+ "pk": 9
 },
 {
- "pk": 10, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 12, 
-  "domain": 4, 
-  "part_po": 12, 
-  "language": null, 
+  "full_po": 12,
+  "domain": 4,
+  "part_po": 12,
+  "language": null,
   "branch": 2
- }
+ },
+ "model": "stats.statistics",
+ "pk": 10
 },
 {
- "pk": 11, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 13, 
-  "domain": 4, 
-  "part_po": 13, 
-  "language": 2, 
+  "full_po": 13,
+  "domain": 4,
+  "part_po": 13,
+  "language": 2,
   "branch": 2
- }
+ },
+ "model": "stats.statistics",
+ "pk": 11
 },
 {
- "pk": 12, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 14, 
-  "domain": 4, 
-  "part_po": 14, 
-  "language": 3, 
+  "full_po": 14,
+  "domain": 4,
+  "part_po": 14,
+  "language": 3,
   "branch": 2
- }
+ },
+ "model": "stats.statistics",
+ "pk": 12
 },
 {
- "pk": 13, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 15, 
-  "domain": 3, 
-  "part_po": 15, 
-  "language": null, 
+  "full_po": 15,
+  "domain": 3,
+  "part_po": 15,
+  "language": null,
   "branch": 3
- }
+ },
+ "model": "stats.statistics",
+ "pk": 13
 },
 {
- "pk": 14, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 16, 
-  "domain": 3, 
-  "part_po": 16, 
-  "language": 2, 
+  "full_po": 16,
+  "domain": 3,
+  "part_po": 16,
+  "language": 2,
   "branch": 3
- }
+ },
+ "model": "stats.statistics",
+ "pk": 14
 },
 {
- "pk": 15, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 17, 
-  "domain": 3, 
-  "part_po": 17, 
-  "language": 3, 
+  "full_po": 17,
+  "domain": 3,
+  "part_po": 17,
+  "language": 3,
   "branch": 3
- }
+ },
+ "model": "stats.statistics",
+ "pk": 15
 },
 {
- "pk": 16, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 18, 
-  "domain": 4, 
-  "part_po": 18, 
-  "language": null, 
+  "full_po": 18,
+  "domain": 4,
+  "part_po": 18,
+  "language": null,
   "branch": 3
- }
+ },
+ "model": "stats.statistics",
+ "pk": 16
 },
 {
- "pk": 17, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 19, 
-  "domain": 4, 
-  "part_po": 19, 
-  "language": 2, 
+  "full_po": 19,
+  "domain": 4,
+  "part_po": 19,
+  "language": 2,
   "branch": 3
- }
+ },
+ "model": "stats.statistics",
+ "pk": 17
 },
 {
- "pk": 18, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 20, 
-  "domain": 4, 
-  "part_po": 20, 
-  "language": 3, 
+  "full_po": 20,
+  "domain": 4,
+  "part_po": 20,
+  "language": 3,
   "branch": 3
- }
+ },
+ "model": "stats.statistics",
+ "pk": 18
 },
 {
- "pk": 19, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 21, 
-  "domain": 5, 
-  "part_po": 21, 
-  "language": null, 
+  "full_po": 21,
+  "domain": 5,
+  "part_po": 21,
+  "language": null,
   "branch": 4
- }
+ },
+ "model": "stats.statistics",
+ "pk": 19
 },
 {
- "pk": 20, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 22, 
-  "domain": 5, 
-  "part_po": 22, 
-  "language": 2, 
+  "full_po": 22,
+  "domain": 5,
+  "part_po": 22,
+  "language": 2,
   "branch": 4
- }
+ },
+ "model": "stats.statistics",
+ "pk": 20
 },
 {
- "pk": 21, 
- "model": "stats.statistics", 
  "fields": {
-  "full_po": 23, 
-  "domain": 5, 
-  "part_po": 23, 
-  "language": 3, 
+  "full_po": 23,
+  "domain": 5,
+  "part_po": 23,
+  "language": 3,
   "branch": 4
- }
+ },
+ "model": "stats.statistics",
+ "pk": 21
 },
 {
- "pk": 1, 
- "model": "stats.information", 
  "fields": {
-  "statistics": 13, 
-  "type": "error", 
+  "statistics": 13,
+  "type": "error",
   "description": "Error regenerating POT file for zenity:\n<pre>intltool-update -g 'zenity' -p\nERROR: 
xgettext failed to generate PO template file.</pre>"
- }
+ },
+ "model": "stats.information",
+ "pk": 1
 }
 ]
diff --git a/stats/forms.py b/stats/forms.py
index df5c720..3ea710d 100644
--- a/stats/forms.py
+++ b/stats/forms.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 from django import forms
-from stats.models import CATEGORY_CHOICES, Branch, Category, Release
+from stats.models import Branch, Category, CategoryName, Release
+
 
 class ReleaseField(forms.ModelChoiceField):
     def __init__(self, *args, **kwargs):
@@ -22,22 +23,28 @@ class ModuleBranchForm(forms.Form):
                     self.fields[str(cat.id)] = ReleaseField(queryset=Release.objects.all(),
                                                             label=branch.name,
                                                             initial=cat.release.pk)
-                    self.fields[str(cat.id)+'_cat'] = forms.ChoiceField(choices=CATEGORY_CHOICES,
-                                                                        initial=cat.name)
+                    self.fields[str(cat.id)+'_cat'] = forms.ModelChoiceField(
+                        queryset=CategoryName.objects.all(),
+                        initial=cat.name
+                    )
                     self.branch_fields.append((str(cat.id), str(cat.id)+'_cat'))
                 default_cat_name = cat.name
             else:
                 # Branch is not linked to any release
                 self.fields[branch.name] = ReleaseField(queryset=Release.objects.all(),
                                                         label=branch.name)
-                self.fields[branch.name+'_cat'] = forms.ChoiceField(choices=CATEGORY_CHOICES,
-                                                                    initial=default_cat_name)
+                self.fields[branch.name + '_cat'] = forms.ModelChoiceField(
+                    queryset=CategoryName.objects.all(),
+                    initial=default_cat_name
+                )
                 self.branch_fields.append((branch.name, branch.name+'_cat'))
 
         self.fields['new_branch'] = forms.CharField(required=False)
         self.fields['new_branch_release'] = ReleaseField(queryset=Release.objects.all())
-        self.fields['new_branch_category'] = forms.ChoiceField(choices=CATEGORY_CHOICES,
-                                                               initial=default_cat_name)
+        self.fields['new_branch_category'] = forms.ModelChoiceField(
+            queryset=CategoryName.objects.all(),
+            initial=default_cat_name
+        )
 
     def get_branches(self):
         for rel_field, cat_field in self.branch_fields:
diff --git a/stats/management/commands/update-trans.py b/stats/management/commands/update-trans.py
index c3372cc..ba6a06d 100644
--- a/stats/management/commands/update-trans.py
+++ b/stats/management/commands/update-trans.py
@@ -10,7 +10,8 @@ from django.db.models import F
 
 from teams.models import Team
 from languages.models import Language
-from stats.models import Module, Domain, Release
+from stats.models import Module, Domain, Release, CategoryName
+
 
 class Command(BaseCommand):
     help = "Update translations of djamnedlies ('en' is a special case, and generate damned-lies.pot)"
@@ -49,7 +50,8 @@ class Command(BaseCommand):
                 Domain.objects.distinct().values_list('description', flat=True),
                 Module.objects.exclude(name__exact=F('description')).values_list('description', flat=True),
                 Module.objects.filter(comment__isnull=False).values_list('comment', flat=True),
-                Release.objects.values_list('description', flat=True)):
+                Release.objects.values_list('description', flat=True),
+                CategoryName.objects.values_list('name', flat=True)):
                 if value:
                     value = re.sub(r'\r\n|\r|\n', '\n', value)
                     fh.write("_(u\"\"\"%s\"\"\")\n" % value.encode('utf-8'))
diff --git a/stats/migrations/0004_remove_old_cat_name.py b/stats/migrations/0004_remove_old_cat_name.py
new file mode 100644
index 0000000..54afdcd
--- /dev/null
+++ b/stats/migrations/0004_remove_old_cat_name.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('stats', '0003_migrate_category_names'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='category',
+            name='name',
+        ),
+        migrations.RenameField(
+            model_name='category',
+            old_name='name_id',
+            new_name='name',
+        ),
+        migrations.AlterField(
+            model_name='category',
+            name='name',
+            field=models.ForeignKey(to='stats.CategoryName', on_delete=django.db.models.deletion.PROTECT),
+        ),
+    ]
diff --git a/stats/models.py b/stats/models.py
index 03f91f7..69390c0 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -1155,31 +1155,10 @@ class CategoryName(models.Model):
         return self.name
 
 
-CATEGORY_CHOICES = (
-    ('default', ugettext_noop('Default')),
-    ('admin-tools', ugettext_noop('Administration Tools')),
-    ('dev-tools', ugettext_noop('Development Tools')),
-    ('desktop', ugettext_noop('GNOME Desktop')),
-    ('dev-platform', ugettext_noop('GNOME Developer Platform')),
-    ('proposed', ugettext_noop('New Module Proposals')),
-    ('g3-core', ugettext_noop('Core')),
-    ('g3-utils', ugettext_noop('Utils')),
-    ('g3-apps', ugettext_noop('Apps')),
-    ('g3-a11y', ugettext_noop('Accessibility')),
-    ('g3-games', ugettext_noop('Games')),
-    ('g3-backends', ugettext_noop('Backends')),
-    ('g3-dev-tools', ugettext_noop('Development Tools')),
-    ('g3-core-libs', ugettext_noop('Core Libraries')),
-    ('g3-extra-libs', ugettext_noop('Extra Libraries')),
-    ('g2-legacy', ugettext_noop('Legacy Desktop')),
-    ('stable', ugettext_noop('Stable Branches')),
-    ('dev', ugettext_noop('Development Branches')),
-)
 class Category(models.Model):
     release = models.ForeignKey(Release)
     branch = models.ForeignKey(Branch)
-    name = models.CharField(max_length=30, choices=CATEGORY_CHOICES, default='default')
-    name_id = models.ForeignKey(CategoryName, db_column='name_id', on_delete=models.PROTECT, null=True)
+    name = models.ForeignKey(CategoryName, on_delete=models.PROTECT)
 
     class Meta:
         db_table = 'category'
@@ -1187,7 +1166,7 @@ class Category(models.Model):
         unique_together = ('release', 'branch')
 
     def __unicode__(self):
-        return "%s (%s, %s)" % (self.get_name_display(), self.release, self.branch)
+        return "%s (%s, %s)" % (self.name, self.release, self.branch)
 
 
 class PoFile(models.Model):
@@ -1598,7 +1577,7 @@ class Statistics(models.Model):
                 'totaluntransperc': 0,
                 'categs': {  # OrderedDict
                     <categkey>: {
-                        'catname': <catname>, # translated category name (see CATEGORY_CHOICES)
+                        'catname': <catname>, # translated category name
                         'cattotal': 0,
                         'cattrans': 0,
                         'catfuzzy': 0,
@@ -1632,7 +1611,9 @@ class Statistics(models.Model):
         # Sorted by module to allow grouping ('fake' stats)
         pot_stats = Statistics.objects.select_related('domain', 'branch__module', 'full_po', 'part_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__name')
+            pot_stats = pot_stats.filter(language=None, branch__releases=release, 
domain__dtype=dtype).order_by('branch__module__name')
+            categ_names = dict([(cat.branch_id, cat.name.name)
+                                for cat in Category.objects.select_related('branch', 
'name').filter(release=release)])
         else:
             pot_stats = pot_stats.filter(language=None, domain__dtype=dtype).order_by('branch__module__name')
 
@@ -1660,18 +1641,17 @@ class Statistics(models.Model):
             if vt_state.id in actions_dict:
                 vt_state.last_comment = actions_dict[vt_state.id].comment
 
-        category_choices_dict = OrderedDict(CATEGORY_CHOICES)
         for stat in pot_stats:
-            categ_key = "default"
+            categ_key = "Default"
             if release:
-                categ_key = category_choices_dict.keys().index(stat.categ_name)
+                categ_key = categ_names.get(stat.branch_id)
             domname = stat.domain.description and _(stat.domain.description) or ""
             branchname = stat.branch.name
             module = stat.branch.module
             if categ_key not in stats['categs']:
                 stats['categs'][categ_key] = {
                     'cattrans': 0, 'catfuzzy': 0, 'catuntrans': 0, 'cattransperc': 0,
-                    'catname': _(category_choices_dict[getattr(stat, 'categ_name', 'default')]),
+                    'catname': _(categ_key),
                     'modules': OrderedDict(),
                 }
             # Try to get translated stat, else stick with POT stat
diff --git a/stats/tests/fixture_factory.py b/stats/tests/fixture_factory.py
index e3b7b58..27edd0f 100644
--- a/stats/tests/fixture_factory.py
+++ b/stats/tests/fixture_factory.py
@@ -7,12 +7,16 @@ 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, PoFile
+from stats.models import (
+    Module, Domain, Branch, Release, Category, CategoryName, Statistics,
+    Information, PoFile,
+)
+
 
 class FixtureFactory(TestCase):
     """ Fake Test case to create fixture.
         To create a JSON fixture, run:
-        python manage.py test stats.FixtureFactory.make_fixture
+        python manage.py test stats.tests.FixtureFactory.make_fixture
     """
 
     def make_fixture(self):
@@ -102,10 +106,11 @@ class FixtureFactory(TestCase):
                      description='freedesktop.org (non-GNOME)',
                      string_frozen=False)
 
-        cat1 = Category.objects.create(release=rel1, branch=b1, name='desktop')
-        cat2 = Category.objects.create(release=rel2, branch=b1, name='desktop')
-        cat3 = Category.objects.create(release=rel1, branch=b2, name='desktop')
-        cat4 = Category.objects.create(release=rel3, branch=b4, name='desktop')
+        cat_name = CategoryName.objects.create(name='Desktop')
+        cat1 = Category.objects.create(release=rel1, branch=b1, name=cat_name)
+        cat2 = Category.objects.create(release=rel2, branch=b1, name=cat_name)
+        cat3 = Category.objects.create(release=rel1, branch=b2, name=cat_name)
+        cat4 = Category.objects.create(release=rel3, branch=b4, name=cat_name)
 
         # Creating models: Statistics
         # gnome-hello ui, gnome-hello doc (POT, fr, it)
diff --git a/stats/tests/tests.py b/stats/tests/tests.py
index 274c299..ba78bf8 100644
--- a/stats/tests/tests.py
+++ b/stats/tests/tests.py
@@ -163,10 +163,11 @@ class ModuleTestCase(TestCase):
         coord.is_superuser = True
         coord.save()
         # Duplicate data
+        cat_name = CategoryName.objects.get(name='Desktop')
         response = self.client.post(reverse('module_edit_branches', args=[self.mod]), {
-            '1': '1', '1_cat': 'desktop',
-            '2': '2', '2_cat': 'desktop',
-            'new_branch': 'master', 'new_branch_release': '2', 'new_branch_category': 'desktop'}
+            '1': '1', '1_cat': str(cat_name.pk),
+            '2': '2', '2_cat': str(cat_name.pk),
+            'new_branch': 'master', 'new_branch_release': '2', 'new_branch_category': str(cat_name.pk)}
         )
         self.assertContains(response, "the form is not valid")
 
diff --git a/vertimus/tests/tests.py b/vertimus/tests/tests.py
index 216e4c3..aab6e1f 100644
--- a/vertimus/tests/tests.py
+++ b/vertimus/tests/tests.py
@@ -28,7 +28,7 @@ from django.http import QueryDict
 from django.utils.datastructures import MultiValueDict
 
 from teams.tests import TeamsAndRolesTests
-from stats.models import Module, Branch, Release, Category, Domain, Statistics
+from stats.models import Module, Branch, Release, Category, CategoryName, Domain, Statistics
 from stats.tests import patch_shell_command, test_scratchdir
 from vertimus.models import *
 from vertimus.forms import ActionForm
@@ -53,7 +53,8 @@ class VertimusTest(TeamsAndRolesTests):
             description='GNOME 2.24 (stable)',
             string_frozen=True)
 
-        self.c = Category.objects.create(release=self.r, branch=self.b, name='desktop')
+        self.c = Category.objects.create(
+            release=self.r, branch=self.b, name=CategoryName.objects.create(name='Desktop'))
 
         self.d = Domain.objects.create(module=self.m, name='po',
             description='UI translations',


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