[damned-lies] Remove usage of domain.directory



commit d7b1a3d39e525ae13faf719dc5efaa035a0ac576
Author: Claude Paroz <claude 2xlibre net>
Date:   Mon Aug 20 21:52:55 2018 +0200

    Remove usage of domain.directory

 people/tests.py                 |  2 +-
 stats/fixtures/sample_data.json |  1 +
 stats/models.py                 | 97 ++++++++++++++++++++++-------------------
 stats/tests/fixture_factory.py  |  4 +-
 stats/tests/tests.py            | 44 ++++++++++++-------
 templates/stats_show.html       |  4 +-
 vertimus/tests/tests.py         |  4 +-
 7 files changed, 89 insertions(+), 67 deletions(-)
---
diff --git a/people/tests.py b/people/tests.py
index 6e15de5e..b06a80b5 100644
--- a/people/tests.py
+++ b/people/tests.py
@@ -132,7 +132,7 @@ class PeopleTestCase(TestCase):
         Branch.checkout_on_creation = False
         branch = Branch(name='gnome-2-24', module=module)
         branch.save(update_statistics=False)
-        domain = Domain.objects.create(module=module, name='po', directory='po')
+        domain = Domain.objects.create(module=module, name='po', layout='po/{lang}.po')
         team = Team.objects.create(name='fr', description='French', mailing_list='french_ml example org')
         lang = Language.objects.create(name='French', locale='fr', team=team)
 
diff --git a/stats/fixtures/sample_data.json b/stats/fixtures/sample_data.json
index 4fac5660..ecdb7729 100644
--- a/stats/fixtures/sample_data.json
+++ b/stats/fixtures/sample_data.json
@@ -303,6 +303,7 @@
   "red_filter": "",
   "branch_to": null,
   "directory": "po",
+  "layout": "po/{lang}.po",
   "description": "UI Translations"
  },
  "model": "stats.domain",
diff --git a/stats/models.py b/stats/models.py
index 54b8449d..e3567346 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -350,7 +350,7 @@ class Branch(models.Model):
         return True
 
     def domain_path(self, domain):
-        return self.co_path / domain.directory
+        return self.co_path / domain.base_dir
 
     def output_dir(self, dom_type):
         """ Directory where generated pot and po files are written on local system """
@@ -420,7 +420,7 @@ class Branch(models.Model):
                 # 2. Pre-check, if available (e.g. intltool-update -m)
                 # **************************
                 if (dom.dtype == 'ui' and
-                        (dom.pot_method == 'auto' or (dom.pot_method == 'gettext' and '/' not in 
dom.directory))):
+                        (dom.pot_method == 'auto' or (dom.pot_method == 'gettext' and dom.layout.count('/') 
< 2))):
                     # Run intltool-update -m to check for some errors
                     errors.extend(utils.check_potfiles(domain_path))
 
@@ -446,7 +446,7 @@ class Branch(models.Model):
                 previous_pot = self.output_dir(dom.dtype) / ('%s.%s.pot' % (dom.potbase(), self.name))
                 if not potfile:
                     logging.error("Can't generate POT file for %s/%s." % (
-                        self.module.name, dom.directory))
+                        self.module.name, dom.name))
                     if previous_pot.exists():
                         # Use old POT file
                         potfile = previous_pot
@@ -632,31 +632,31 @@ class Branch(models.Model):
             raise NotImplementedError("Commit is not implemented for '%s'" % vcs_type)
 
         locale = language.locale
-        commit_dir = self.co_path / domain.directory
-        prefix = '' if domain.dtype == 'ui' else locale
-        dest_filename = os.path.join(prefix, "%s.po" % locale)
-        dest_path = commit_dir / dest_filename
+        base_path = self.co_path
+        dest_path = domain.get_po_path(locale)
+        dest_full_path = base_path / dest_path
 
         with ModuleLock(self.module):
             self.update_repo()
             if vcs_type == "git":
-                already_exist = dest_path.exists()
+                already_exist = dest_full_path.exists()
                 if not already_exist and domain.dtype != 'ui':
                     raise Exception("Sorry, adding new translations for documentation is not yet supported.")
 
                 # Copy file in repo
-                shutil.copyfile(str(po_file), str(dest_path))
+                shutil.copyfile(str(po_file), str(dest_full_path))
 
                 # git add file.po
                 run_shell_command(
-                    ['git', 'add', dest_filename], raise_on_error=True, cwd=commit_dir)
+                    ['git', 'add', dest_path], raise_on_error=True, cwd=base_path)
                 if not already_exist:
                     # Add locale to LINGUAS
-                    linguas_file = commit_dir / "LINGUAS"
+                    linguas_path = os.path.join(domain.base_dir, "LINGUAS")
+                    linguas_file = base_path / linguas_path
                     if linguas_file.exists():
                         utils.insert_locale_in_linguas(linguas_file, locale)
                         run_shell_command(
-                            ['git', 'add', 'LINGUAS'], raise_on_error=True, cwd=commit_dir)
+                            ['git', 'add', linguas_path], raise_on_error=True, cwd=base_path)
                     msg = "Add %s translation" % language.name
                 else:
                     msg = "Update %s translation" % language.name
@@ -664,19 +664,19 @@ class Branch(models.Model):
                 commit_cmd = ['git', 'commit', '-m', msg]
                 if author:
                     commit_cmd.extend(['--author', author])
-                run_shell_command(commit_cmd, raise_on_error=True, cwd=commit_dir)
+                run_shell_command(commit_cmd, raise_on_error=True, cwd=base_path)
                 # git push
                 try:
                     run_shell_command(
-                        ['git', 'push', 'origin', self.name], raise_on_error=True, cwd=commit_dir)
+                        ['git', 'push', 'origin', self.name], raise_on_error=True, cwd=base_path)
                 except OSError:
                     # Revert the commit
                     run_shell_command(
-                        ['git', 'reset', '--hard', 'origin/%s' % self.name], cwd=commit_dir)
+                        ['git', 'reset', '--hard', 'origin/%s' % self.name], cwd=base_path)
                     raise
                 else:
                     _, out, _ = run_shell_command(
-                        ['git', 'log', '-n1', '--format=oneline'], cwd=commit_dir)
+                        ['git', 'log', '-n1', '--format=oneline'], cwd=base_path)
                     commit_hash = out.split()[0] if out else ''
 
         # Finish by updating stats
@@ -686,7 +686,7 @@ class Branch(models.Model):
             except Statistics.DoesNotExist:
                 self.update_stats(force=False, checkout=False, domain=domain)
             else:
-                stat.update_stats(dest_path)
+                stat.update_stats(dest_full_path)
         else:
             self.update_stats(force=False, checkout=False, domain=domain)
         return force_text(commit_hash)
@@ -700,7 +700,7 @@ class Branch(models.Model):
             raise NotImplementedError("Commit cherry-pick is not implemented for '%s'" % 
self.module.vcs_type)
         with ModuleLock(self.module):
             self.update_repo()
-            commit_dir = self.co_path / domain.directory
+            commit_dir = self.co_path
             result = run_shell_command(
                 ['git', 'cherry-pick', '-x', commit_hash], cwd=commit_dir)
             if result[0] == utils.STATUS_OK:
@@ -759,6 +759,10 @@ class Domain(models.Model):
     def __str__(self):
         return "%s (%s/%s)" % (self.name, self.module.name, self.get_dtype_display())
 
+    @property
+    def base_dir(self):
+        return self.layout[:self.layout.find('{lang}')]
+
     def potbase(self):
         """
         Return the name of the generated pot file, without extension.
@@ -778,6 +782,16 @@ class Domain(models.Model):
         else:
             return self.potbase()
 
+    def has_standard_location(self):
+        return (self.dtype == 'ui' and self.layout == 'po/{lang}.po') or (
+                self.dtype == 'doc' and self.layout == 'help/{lang}/{lang}.po')
+
+    def get_po_path(self, locale):
+        """
+        Return the relative filesystem path to the po file, existing or not.
+        """
+        return self.layout.format(lang=locale)
+
     @lru_cache(100)
     def doc_format(self, branch):
         """Return a DocFormat instance, or None."""
@@ -791,29 +805,19 @@ class Domain(models.Model):
         [(lang, lang_file), ...] -> lang_file as Path.
         """
         flist = []
-        dom_path = base_path / self.directory
-        for item in dom_path.iterdir():
-            if item.suffix == ".po":
-                lang = item.stem
-                flist.append((lang, item))
-            elif item.is_dir():
-                if item.name == 'po':
-                    for lang_file in item.iterdir():
-                        if lang_file.suffix == ".po":
-                            lang = lang_file.stem
-                            flist.append((lang, lang_file))
-                else:
-                    for base_name in [item.name, self.name.replace("~", "/")]:
-                        pofile = item / (base_name + ".po")
-                        if pofile.exists():
-                            flist.append((item.name, pofile))
-                            break
+        def extract_lang(path):
+            path_str = str(path)
+            start = len(str(base_path)) + self.layout.find('{lang}') + 1
+            return re.split('\.|/', path_str[start:])[0]
+
+        for item in base_path.glob(self.layout.replace('{lang}', '*')):
+            flist.append((extract_lang(item), item))
         return flist
 
     def generate_pot_file(self, current_branch):
         """ Return the pot file generated (in the checkout tree), and the error if any """
 
-        vcs_path = current_branch.co_path / self.directory
+        vcs_path = current_branch.co_path / self.base_dir
         env = None
         potfile = vcs_path / (self.potbase() + ".pot")
         pot_command = None
@@ -867,7 +871,12 @@ class Domain(models.Model):
                 p for p in vcs_path.iterdir() if p.is_file() and p.name.endswith('.srt')
             ]
             if not srt_files:
-                return "", (("error", ugettext_noop("No subtitle files found.")),)
+                # Try once more at parent level
+                srt_files = [
+                    p for p in vcs_path.parent.iterdir() if p.is_file() and p.name.endswith('.srt')
+                ]
+                if not srt_files:
+                    return "", (("error", ugettext_noop("No subtitle files found.")),)
             with srt_files[0].open(mode='r') as po_fh, potfile.open(mode='wb') as pot_fh:
                 sub2po.convertsub(po_fh, pot_fh)
 
@@ -918,7 +927,7 @@ class Domain(models.Model):
                                             for path in self.extra_its_dirs.split(':')]
             )
         # Parse and use content from: "XGETTEXT_OPTIONS = --keyword=_ --keyword=N_"
-        vcs_path = branch.co_path / self.directory
+        vcs_path = branch.co_path / self.base_dir
         makefile = utils.MakefileWrapper.find_file(branch, [vcs_path], file_name='Makevars')
         if makefile:
             kwds_vars = makefile.read_variable('XGETTEXT_OPTIONS')
@@ -986,9 +995,9 @@ class Domain(models.Model):
                             'var': variable, 'file': file_path})}
         # Standard linguas location
         if self.dtype == 'ui':
-            return utils.get_ui_linguas(branch, self.directory)
+            return utils.get_ui_linguas(branch, self.base_dir)
         elif self.dtype == 'doc':
-            return utils.get_doc_linguas(branch, self.directory)
+            return utils.get_doc_linguas(branch, self.base_dir)
         else:
             raise ValueError("Domain dtype should be one of 'ui', 'doc'")
 
@@ -1530,7 +1539,7 @@ class Statistics(models.Model):
             # something like: "https://gitlab.gnome.org/GNOME/vinagre / raw / master / help / %s / %s"
             url_model = utils.url_join(
                 self.branch.get_vcs_web_url(), self.branch.img_url_prefix,
-                self.branch.name, self.domain.directory, '%s', '%s'
+                self.branch.name, self.domain.base_dir, '%s', '%s'
             )
             for fig in self.full_po.figures:
                 fig2 = fig.copy()
@@ -1538,7 +1547,7 @@ class Statistics(models.Model):
                 fig2['translated_file'] = False
                 # Check if a translated figure really exists or if the English one is used
                 if (self.language and
-                        (self.branch.co_path / self.domain.directory / self.language.locale
+                        (self.branch.co_path / self.domain.base_dir / self.language.locale
                          / fig['path']).exists()):
                     fig2['trans_remote_url'] = url_model % (self.language.locale, fig['path'])
                     fig2['translated_file'] = True
@@ -1560,11 +1569,11 @@ class Statistics(models.Model):
 
     def vcs_path(self):
         """ Return the VCS path of file on remote vcs """
-        return utils.url_join(self.branch.get_vcs_url(), self.domain.directory)
+        return utils.url_join(self.branch.get_vcs_url(), self.domain.base_dir)
 
     def vcs_web_path(self):
         """ Return the Web interface path of file on remote vcs """
-        return utils.url_join(self.branch.get_vcs_web_url(), self.domain.directory)
+        return utils.url_join(self.branch.get_vcs_web_url(), self.domain.base_dir)
 
     def po_path(self, potfile=False, reduced=False):
         """ Return path of po file on local filesystem """
diff --git a/stats/tests/fixture_factory.py b/stats/tests/fixture_factory.py
index 3c250c4c..d102dce3 100644
--- a/stats/tests/fixture_factory.py
+++ b/stats/tests/fixture_factory.py
@@ -80,8 +80,8 @@ class FixtureFactory(TestCase):
         # Creating models: Domains
         dom = {}
         for mod in (gnome_hello, zenity, s_m_i):
-            dom['%s-ui' % mod.name] = Domain.objects.create(module=mod, name='po', description='UI 
Translations', dtype='ui', directory='po')
-            dom['%s-doc' % mod.name] = Domain.objects.create(module=mod, name='help', description='User 
Guide', dtype='doc', directory='help')
+            dom['%s-ui' % mod.name] = Domain.objects.create(module=mod, name='po', description='UI 
Translations', dtype='ui', directory='po', layout='po/{lang}.po')
+            dom['%s-doc' % mod.name] = Domain.objects.create(module=mod, name='help', description='User 
Guide', dtype='doc', directory='help', layout='help/{lang}/{lang}.po')
 
         # Creating models: Branches
         Branch.checkout_on_creation = False
diff --git a/stats/tests/tests.py b/stats/tests/tests.py
index c9ce4212..6fddc1cd 100644
--- a/stats/tests/tests.py
+++ b/stats/tests/tests.py
@@ -297,7 +297,7 @@ class ModuleTestCase(TestCase):
         )
         # User interface (existing language)
         git_ops = update_repo_sequence + (
-            'git add fr.po',
+            'git add po/fr.po',
             # Quoting is done at the Popen level
             'git commit -m Update French translation --author Author <someone example org>',
             'git push origin master', 'git log -n1 --format=oneline',
@@ -310,7 +310,7 @@ class ModuleTestCase(TestCase):
         # User interface (new language)
         bem_lang = Language.objects.get(locale='bem')
         git_ops = update_repo_sequence + (
-            'git add bem.po', 'git add LINGUAS',
+            'git add po/bem.po', 'git add po/LINGUAS',
             'git commit -m Add Bemba translation --author Author <someone example org>',
             'git push origin master'
         )
@@ -326,7 +326,7 @@ class ModuleTestCase(TestCase):
         # Documentation
         domain = self.mod.domain_set.get(name='help')
         git_ops = update_repo_sequence + (
-            'git add fr/fr.po',
+            'git add help/fr/fr.po',
             'git commit -m Update French translation --author Author <someone example org>',
             'git push origin master'
         )
@@ -424,9 +424,18 @@ class DomainTests(TestCase):
         super().setUp()
         Domain.doc_format.cache_clear()
 
+    def test_get_po_path(self):
+        # Standard UI
+        dom = Domain(module=self.mod, dtype='ui', layout='po/{lang}.po')
+        self.assertEqual(dom.get_po_path('fr'), 'po/fr.po')
+        # Standard Doc
+        dom.dtype = 'doc'
+        dom.layout = 'help/{lang}/{lang}.po'
+        self.assertEqual(dom.get_po_path('fr'), 'help/fr/fr.po')
+
     def test_domain_linguas(self):
-        help_domain = Domain.objects.create(
-            module=self.mod, name='help', dtype='doc', directory='help_mallard'
+        help_domain = Domain(
+            module=self.mod, name='help', dtype='doc', layout='help_mallard/{lang}/{lang}.po'
         )
         help_domain.linguas_location = "help_mallard/Makefile.am"
         self.assertEqual(help_domain.get_linguas(self.branch), {
@@ -447,8 +456,8 @@ class DomainTests(TestCase):
         })
 
     def test_domain_xgettext_command(self):
-        domain = Domain.objects.create(
-            module=self.mod, name='po', dtype='ui', directory='po'
+        domain = Domain(
+            module=self.mod, name='po', dtype='ui', layout='po/{lang}.po'
         )
         self.assertEqual(
             domain.get_xgettext_command(self.branch),
@@ -466,7 +475,8 @@ class DomainTests(TestCase):
         Test Docbook-style help
         """
         domain = Domain.objects.create(
-            module=self.mod, name='release-notes', dtype='doc', directory='help_docbook'
+            module=self.mod, name='release-notes', dtype='doc',
+            layout='help_docbook/{lang}/{lang}.po'
         )
         potfile, errs = utils.generate_doc_pot_file(self.branch, domain)
         self.assertEqual(errs, [])
@@ -486,7 +496,8 @@ class DomainTests(TestCase):
         Test Mallard-style help (with itstool)
         """
         domain = Domain.objects.create(
-            module=self.mod, name='release-notes', dtype='doc', directory='help_mallard'
+            module=self.mod, name='release-notes', dtype='doc',
+            layout='help_mallard/{lang}/{lang}.po'
         )
         potfile, errs = utils.generate_doc_pot_file(self.branch, domain)
         self.assertEqual(errs, [])
@@ -524,7 +535,7 @@ class DomainTests(TestCase):
     @skipUnless(has_translate_subtitle_support, "This test needs translate-toolkit subtitles support.")
     def test_subtitles_pot(self):
         dom = Domain.objects.create(
-            module=self.mod, name='po', dtype='ui', directory='subtitles',
+            module=self.mod, name='po', dtype='ui', layout='subtitles/po/{lang}.po',
             pot_method='subtitles',
         )
         potfile, errs = dom.generate_pot_file(self.branch)
@@ -537,7 +548,7 @@ class DomainTests(TestCase):
 
     def test_repository_pot(self):
         dom = Domain.objects.create(
-            module=self.mod, name='po', dtype='ui', directory='inrepo',
+            module=self.mod, name='po', dtype='ui', layout='inrepo/{lang}.po',
             pot_method='in_repo',
         )
         potfile, errs = dom.generate_pot_file(self.branch)
@@ -677,7 +688,7 @@ class FigureTests(TestCase):
         branch = Branch.objects.get(module__name='gnome-hello', name='master')
         pot_stat = Statistics.objects.get(branch=branch, domain__name='help', language__isnull=True)
         fig_path = str(
-            pot_stat.branch.co_path / pot_stat.domain.directory / 'C' /
+            pot_stat.branch.co_path / pot_stat.domain.base_dir / 'C' /
             pot_stat.get_figures()[0]['path']
         )
         shutil.copyfile(fig_path, fig_path.replace('/C/', '/fr/'))
@@ -701,7 +712,7 @@ class UtilsTests(TestCase):
 
     def test_read_makefile_variable(self):
         domain = Domain.objects.create(
-            module=self.mod, name='help', dtype='doc', directory='help_docbook'
+            module=self.mod, name='help', dtype='doc', layout='help_docbook/{lang}/{lang}.po'
         )
         makefile = utils.MakefileWrapper.find_file(
             self.branch, [self.branch.domain_path(domain)])
@@ -713,7 +724,8 @@ class UtilsTests(TestCase):
 
     def test_read_meson_variables(self):
         domain = Domain.objects.create(
-            module=self.mod, name='help', dtype='doc', directory='help_mallard_meson'
+            module=self.mod, name='help', dtype='doc',
+            layout='help_mallard_meson/{lang}/{lang}.po'
         )
         meson_file = utils.MakefileWrapper.find_file(self.branch, [self.branch.domain_path(domain)])
         self.assertEqual(meson_file.read_variable('yelp.languages'), ['es', 'fr'])
@@ -738,7 +750,7 @@ class UtilsTests(TestCase):
 
     def test_read_cmake_variables(self):
         domain = Domain.objects.create(
-            module=self.mod, name='help', dtype='doc', directory='help_mallard'
+            module=self.mod, name='help', dtype='doc', layout='help_mallard/{lang}/{lang}.po'
         )
         cmake_file = utils.MakefileWrapper.find_file(
             self.branch, [self.branch.domain_path(domain)], file_name='CMakeLists.txt')
@@ -749,7 +761,7 @@ class UtilsTests(TestCase):
 
     def test_doc_format_source_files(self):
         domain = Domain.objects.create(
-            module=self.mod, name='help', dtype='doc', directory='help_mallard_meson'
+            module=self.mod, name='help', dtype='doc', layout='help_mallard_meson/{lang}/{lang}.po'
         )
         df = utils.DocFormat(domain, self.branch)
         self.assertEqual(
diff --git a/templates/stats_show.html b/templates/stats_show.html
index 9fb9f28b..2ef36296 100644
--- a/templates/stats_show.html
+++ b/templates/stats_show.html
@@ -17,8 +17,8 @@
 
     </h3>
 
-    {% if pot_stat.domain.directory != 'help' and pot_stat.domain.directory != 'po' %}
-    <p class="path">{{ pot_stat.domain.directory }}</p>
+    {% if not pot_stat.domain.has_standard_location %}
+    <p class="path">{{ pot_stat.domain.base_dir }}</p>
     {% endif %}
 
     <p class="pot_information">{{ pot_stat.pot_text }}</p>
diff --git a/vertimus/tests/tests.py b/vertimus/tests/tests.py
index 4c70ed9b..33045c30 100644
--- a/vertimus/tests/tests.py
+++ b/vertimus/tests/tests.py
@@ -60,7 +60,7 @@ class VertimusTest(TeamsAndRolesTests):
         self.d = Domain.objects.create(
             module=self.m, name='po',
             description='UI translations',
-            dtype='ui', directory='po'
+            dtype='ui', layout='po/{lang}.po'
         )
         Statistics.objects.create(language=None, branch=self.b, domain=self.d)
         self.files_to_clean = []
@@ -626,7 +626,7 @@ class VertimusTest(TeamsAndRolesTests):
         dom_alt = Domain.objects.create(
             module=self.m, name='po',
             description='UI translations',
-            dtype='ui', directory='po'
+            dtype='ui', layout='po/{lang}.po'
         )
         StateNone.objects.create(branch=master, domain=self.d, language=self.l)
         StateNone.objects.create(branch=self.b, domain=dom_alt, language=self.l)


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