summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2019-02-27 15:19:54 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2019-02-27 21:43:47 +0900
commit8408109a253c4f14cbb986853031951936bff637 (patch)
tree712ef33498a847e3b3c482b81242be0ed1d96e66
parent30ea7c94eb22a559934d230f1f771cb9de49bbb9 (diff)
downloadsphinx-git-8408109a253c4f14cbb986853031951936bff637.tar.gz
Add CatalogRepository class
-rw-r--r--sphinx/util/i18n.py49
-rw-r--r--tests/test_util_i18n.py44
2 files changed, 91 insertions, 2 deletions
diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py
index 9196e6fb6..6aa285f5d 100644
--- a/sphinx/util/i18n.py
+++ b/sphinx/util/i18n.py
@@ -24,14 +24,14 @@ from sphinx.errors import SphinxError
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util.matching import Matcher
-from sphinx.util.osutil import SEP, relpath
+from sphinx.util.osutil import SEP, canon_path, relpath
logger = logging.getLogger(__name__)
if False:
# For type annotation
- from typing import Callable, List, Set # NOQA
+ from typing import Callable, Generator, List, Set, Tuple # NOQA
from sphinx.environment import BuildEnvironment # NOQA
LocaleFileInfoBase = namedtuple('CatalogInfo', 'base_dir,domain,charset')
@@ -81,6 +81,51 @@ class CatalogInfo(LocaleFileInfoBase):
logger.warning(__('writing error: %s, %s'), self.mo_path, exc)
+class CatalogRepository:
+ """A repository for message catalogs."""
+
+ def __init__(self, basedir, locale_dirs, language, encoding):
+ # type: (str, List[str], str, str) -> None
+ self.basedir = basedir
+ self._locale_dirs = locale_dirs
+ self.language = language
+ self.encoding = encoding
+
+ @property
+ def locale_dirs(self):
+ # type: () -> Generator[str, None, None]
+ if not self.language:
+ return
+
+ for locale_dir in self._locale_dirs:
+ locale_dir = path.join(self.basedir, locale_dir)
+ if path.exists(path.join(locale_dir, self.language, 'LC_MESSAGES')):
+ yield locale_dir
+
+ @property
+ def pofiles(self):
+ # type: () -> Generator[Tuple[str, str], None, None]
+ for locale_dir in self.locale_dirs:
+ basedir = path.join(locale_dir, self.language, 'LC_MESSAGES')
+ for root, dirnames, filenames in os.walk(basedir):
+ # skip dot-directories
+ for dirname in dirnames:
+ if dirname.startswith('.'):
+ dirnames.remove(dirname)
+
+ for filename in filenames:
+ if filename.endswith('.po'):
+ fullpath = path.join(root, filename)
+ yield basedir, relpath(fullpath, basedir)
+
+ @property
+ def catalogs(self):
+ # type: () -> Generator[CatalogInfo, None, None]
+ for basedir, filename in self.pofiles:
+ domain = canon_path(path.splitext(filename)[0])
+ yield CatalogInfo(basedir, domain, self.encoding)
+
+
def find_catalog(docname, compaction):
# type: (str, bool) -> str
if compaction:
diff --git a/tests/test_util_i18n.py b/tests/test_util_i18n.py
index b25e29575..5208689e8 100644
--- a/tests/test_util_i18n.py
+++ b/tests/test_util_i18n.py
@@ -255,3 +255,47 @@ def test_get_filename_for_language(app):
app.env.config.figure_language_filename = '{root}.{invalid}{ext}'
with pytest.raises(SphinxError):
i18n.get_image_filename_for_language('foo.png', app.env)
+
+
+def test_CatalogRepository(tempdir):
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test3.po').write_text('#')
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / '.dotdir').makedirs()
+ (tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / '.dotdir' / 'test5.po').write_text('#')
+ (tempdir / 'loc1' / 'yy' / 'LC_MESSAGES').makedirs()
+ (tempdir / 'loc1' / 'yy' / 'LC_MESSAGES' / 'test6.po').write_text('#')
+ (tempdir / 'loc2' / 'xx' / 'LC_MESSAGES').makedirs()
+ (tempdir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
+ (tempdir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test7.po').write_text('#')
+
+ # for language xx
+ repo = i18n.CatalogRepository(tempdir, ['loc1', 'loc2'], 'xx', 'utf-8')
+ assert list(repo.locale_dirs) == [str(tempdir / 'loc1'),
+ str(tempdir / 'loc2')]
+ assert all(isinstance(c, i18n.CatalogInfo) for c in repo.catalogs)
+ assert sorted(c.domain for c in repo.catalogs) == ['sub/test3', 'sub/test4',
+ 'test1', 'test1', 'test2', 'test7']
+
+ # for language yy
+ repo = i18n.CatalogRepository(tempdir, ['loc1', 'loc2'], 'yy', 'utf-8')
+ assert sorted(c.domain for c in repo.catalogs) == ['test6']
+
+ # unknown languages
+ repo = i18n.CatalogRepository(tempdir, ['loc1', 'loc2'], 'zz', 'utf-8')
+ assert sorted(c.domain for c in repo.catalogs) == []
+
+ # no languages
+ repo = i18n.CatalogRepository(tempdir, ['loc1', 'loc2'], None, 'utf-8')
+ assert sorted(c.domain for c in repo.catalogs) == []
+
+ # unknown locale_dirs
+ repo = i18n.CatalogRepository(tempdir, ['loc3'], None, 'utf-8')
+ assert sorted(c.domain for c in repo.catalogs) == []
+
+ # no locale_dirs
+ repo = i18n.CatalogRepository(tempdir, [], None, 'utf-8')
+ assert sorted(c.domain for c in repo.catalogs) == []