Repository: translate/pootle

Issue:
Adding a TP does not initialise its stores from Templates
If you have a template language and add a new TP then the project is not initialised i.e. it does not create stores based on the Template language.  This likely relates to our loss of `update_against_templates`.  Pootle is currently relying on initialisation of a language happening via `update_stores` which will pick up languages from the filesystem. But this then doesn't allow admins to quickly add a language to a Pootle project without having access to initialise the project from the filesystem.



Discussion:

Resolving patch:
diff --git a/pootle/apps/pootle_app/project_tree.py b/pootle/apps/pootle_app/project_tree.py
--- a/pootle/apps/pootle_app/project_tree.py
+++ b/pootle/apps/pootle_app/project_tree.py
@@ -313,6 +313,26 @@ def translation_project_should_exist(language, project):
     return False
 
 
+def init_store_from_template(translation_project, template_store):
+    """Initialize a new file for `translation_project` using `template_store`.
+    """
+    if translation_project.file_style == 'gnu':
+        target_pootle_path, target_path = get_translated_name_gnu(translation_project,
+                                                                  template_store)
+    else:
+        target_pootle_path, target_path = get_translated_name(translation_project,
+                                                              template_store)
+
+    # Create the missing directories for the new TP.
+    target_dir = os.path.dirname(target_path)
+    if not os.path.exists(target_dir):
+        os.makedirs(target_dir)
+
+    output_file = template_store.file.store
+    output_file.settargetlanguage(translation_project.language.code)
+    output_file.savefile(target_path)
+
+
 def get_translated_name_gnu(translation_project, store):
     """Given a template :param:`store` and a :param:`translation_project` return
     target filename.
diff --git a/pootle/apps/pootle_translationproject/models.py b/pootle/apps/pootle_translationproject/models.py
--- a/pootle/apps/pootle_translationproject/models.py
+++ b/pootle/apps/pootle_translationproject/models.py
@@ -245,6 +245,19 @@ def __init__(self, *args, **kwargs):
     def save(self, *args, **kwargs):
         created = self.id is None
 
+        if created:
+            from pootle_app.project_tree import translation_project_should_exist
+
+            template_tp = self.project.get_template_translationproject()
+            initialize_from_templates = False
+
+            if (not self.is_template_project and
+                template_tp is not None and
+                not translation_project_should_exist(self.language,
+                                                     self.project)):
+
+                initialize_from_templates = True
+
         self.directory = self.language.directory \
                                       .get_or_make_subdir(self.project.code)
         self.pootle_path = self.directory.pootle_path
@@ -258,8 +271,22 @@ def save(self, *args, **kwargs):
         super(TranslationProject, self).save(*args, **kwargs)
 
         if created:
+            if initialize_from_templates:
+                # We are adding a new TP and there are no files to import from
+                # disk, so initialize the TP files using the templates TP ones.
+                from pootle_app.project_tree import init_store_from_template
+
+                for template_store in template_tp.stores.iterator():
+                    init_store_from_template(self, template_store)
+
             self.scan_files()
 
+            if initialize_from_templates:
+                # Trigger stats refresh for TP added from UI.
+                # FIXME: This won't be necessary once #3547 is fixed.
+                for store in self.stores.live().iterator():
+                    store.update()
+
     def delete(self, *args, **kwargs):
         directory = self.directory
 


Test patch: