pax_global_header00006660000000000000000000000064131562003670014515gustar00rootroot0000000000000052 comment=20cd0d2d2d8f474e3aad688e8e0fc9481939a711 sphinx-intl-0.9.10/000077500000000000000000000000001315620036700140615ustar00rootroot00000000000000sphinx-intl-0.9.10/.travis.yml000066400000000000000000000010041315620036700161650ustar00rootroot00000000000000language: python python: - "3.6" - "3.5" - "3.4" - "2.7" matrix: exclude: - python: "3.6" - python: "3.5" - python: "3.4" - python: "2.7" include: - python: "3.6" env: TOXENV=flake8 - python: "3.6" env: TOXENV=sdist - python: "3.6" env: TOXENV=py36 - python: "3.5" env: TOXENV=py35 - python: "3.4" env: TOXENV=py34 - python: "2.7" env: TOXENV=py27 install: - pip install -r requirements-testing.txt cache: pip script: - tox sphinx-intl-0.9.10/CHANGES000066400000000000000000000102231315620036700150520ustar00rootroot00000000000000======= CHANGES ======= 0.9.10 (2017/09/13) =================== Environments ------------ * Drop supporting Python-3.3 and 2.6 - Add supporting Python-3.6 Bug Fixes --------- * Unit tests overwrite real .transifexrc file in HOME directory. * #7, #8: Added `tags` variable for conf.py. Thanks to Dongping Xie. * #15: default value of ``locale_dirs`` must be ``['locales']`` instead of ``['locale']``. Thanks to cocoatomo. 0.9.9 (2016/01/17) ================== Bug Fixes --------- * On Python-3 environment, 'update' command breaks po files. * #4: 'fuzzy' cause crush on 'update' command. 0.9.8 (2015/12/28) ================== Environments ------------ * Add supporting Python-3.5 * Drop supporting Python-2.5 * Use transifex-client>=0.11 for all environments * Switch test runner to py.test * BB#11 Switch to babel that is used with Sphinx. Incompatibility --------------- * 'glossary' resource name will be renamed to 'glossary_' on Transifex. Since Aug 2015, Transifex reject 'glossary' resource name because the slug is reserved. Features -------- * #2,#3: Add option to create MO files in a separate directory. Thanks to Campbell Barton. Bug Fixes --------- * #1: update_txconfig_resources command on Python 3.4/3.5 causes KeyError. 0.9.7 (2015/11/07) ================== Environments ------------ * BB#8 Drop supporting Python-3.1 and 3.2 * BB#10 Depends to click for command-line feature. 0.9.6 (2015/09/22) ================== Features -------- * BB-PR#9: Support ``fuzzy`` translations. Thanks to Guilherme Brondani Torri. * BB-PR#8: Detects pot_dir automatically if sphinx has generated. Thanks to Takeshi Komiya. Bug Fixes --------- * BB-PR#6: update_txconfig_resources command raise errors with pot filename including symbols and spaces. Thanks to Takeshi Komiya. * BB-PR#7: sphinx-intl could not find conf.py in projects separating build and source directories. Thanks to Takeshi Komiya. * BB-PR#10: Add __file__ to conf.py's namespace. * On Windows environment, now using "transifex<0.9" because "transifex>=0.9" requires unnecessary py2exe installation. 0.9.5 (2014/07/10) ================== Environments ------------ * Add supporting Python-3.4 Features -------- * BB-PR#3: Skip building process if mo file is newer than po file. Thanks to Nozomu Kaneko. Bug Fixes --------- * BB-PR#2, BB-PR#4: ``update-txconfig-resources`` disregarded ``--pot-dir`` option. Thanks to Giacomo Spettoli, Takeshi Komiya. * BB-PR#5: ``update-txconfig-resources`` command raise errors when project name includes spaces and dots. Thanks to Takeshi Komiya. 0.9.4 (2013/12/10) =================== Environments ------------ * Now using setuptools instead of distribute. Features -------- * BB#3: ``update-txconfig-resources`` command now detect project-name from ``.tx/config`` that already exists. Bug Fixes --------- * sphinx-intl didn't use SPHINXINTL_CONFIG environment value. * tox test raises a error with transifex-client-0.10 0.9.3 (2013/04/20) =================== Bug Fixes --------- * because ``--config`` option did not consider directory path, locale_dir did not contain directory path to ``conf.py`` file. 0.9.2 (2013/4/11) =================== Features -------- * Add ``stat`` command for displaying statistics like 'msgfmt --statistics'. * Documentation and error messages are improved. Bug Fixes --------- * update command did not detect pot/po difference when translated count and untranslated count are not difference. 0.9.1 (2013/4/10) =================== Environments ------------ * Add flake8 test and fix some errors. Incompatibility --------------- * Drop multiple ``locale directories`` feature. Now use only first directory of ``locale_dirs`` in conf.py. Features -------- * Add --pot-dir option. default is ``pot`` directory under ``locale_dir``. If you using Sphinx default settings, ``-p _build/locale`` is useful. * Add append/deprecated msgid count information for ``update`` command. Bug Fixes --------- * Fix: ``-c`` option is not working. Thanks @tk0miya! 0.9.0 (2013/4/7) ================= * First release that provides these commands: * update * build * create-transifexrc * create-txconfig * update-txconfig-resources sphinx-intl-0.9.10/LICENSE000066400000000000000000000025001315620036700150630ustar00rootroot00000000000000License for Sphinx ================== Copyright (c) 2013 by Takayuki SHIMIZUKAWA. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sphinx-intl-0.9.10/MANIFEST.in000066400000000000000000000000451315620036700156160ustar00rootroot00000000000000include README.rst include LICENSE sphinx-intl-0.9.10/README.rst000066400000000000000000000110561315620036700155530ustar00rootroot00000000000000====================================================== sphinx-intl: translation support utility for Sphinx ====================================================== .. image:: https://travis-ci.org/sphinx-doc/sphinx-intl.svg?branch=master :target: https://travis-ci.org/sphinx-doc/sphinx-intl `sphinx-intl` is a utility tool that provides several features that make it easy to translate and to apply translation to Sphinx_ generated document. Optional: support the Transifex service for translation with Sphinx_ . .. contents:: :local: QuickStart for sphinx translation =================================== This section describe to translate with Sphinx_ and `sphinx-intl` command. 1. Create your document by using Sphinx. 2. Add configurations to your `conf.py`:: locale_dirs = ['locale/'] #path is example but recommended. gettext_compact = False #optional. `locale_dirs` is required and `gettext_compact` is optional. 3. Extract document's translatable messages into pot files:: $ make gettext 4. Setup/Update your `locale_dir`:: $ sphinx-intl update -p _build/locale -l de -l ja Done. You got these directories that contain po files: * `./locale/de/LC_MESSAGES/` * `./locale/ja/LC_MESSAGES/` 5. Translate your po files under `./locale//LC_MESSAGES/`. 6. Build mo files and make translated document:: $ sphinx-intl build $ make -e SPHINXOPTS="-D language='ja'" html That's all! Basic Features =============== * create or update po files from pot files. * build mo files from po files. Requirements for basic ----------------------- - Python 3.6, 3.5, 3.4, 2.7, pypy. - external library: setuptools_, six_, babel_, click_ Optional features ================== These features need `transifex-client`_ library. * create .transifexrc file from environment variable, without interactive input. * create .tx/config file without interactive input. * update .tx/config file from locale/pot files automatically. * build mo files from po files in the locale directory. You need to use `tx` command for below features: * `tx push -s` : push pot (translation catalogs) to transifex. * `tx pull -l ja` : pull po (translated catalogs) from transifex. Requirements for optional -------------------------- - Your transifex_ account if you want to download po files from transifex or you want to translate on transifex. - external library: `transifex-client`_ Installation ============= Recommend strongly: use virtualenv for this procedure:: $ pip install sphinx-intl If you want to use `Optional Features`_, you need install additional library:: $ pip install sphinx-intl[transifex] Commands, options, environment variables ========================================= Commands -------- Type `sphinx-intl` without arguments, options to show command help. Setup environment variables --------------------------- All command-line options can be set with environment variables using the format SPHINXINTL_ . Dashes (-) have to replaced with underscores (_). For example, to set the languages:: export SPHINXINTL_LANGUAGE=de,ja This is the same as passing the option to sphinx-intl directly:: sphinx-intl --language=de --language=ja Setup sphinx conf.py --------------------- Add below settings to sphinx document's conf.py if not exists:: locale_dirs = ['locale/'] #for example gettext_compact = False #optional Setup Makefile / make.bat ------------------------- `make gettext` will generate pot files into `_build/locale` directory, however pot files should be generated in the `locale/pot` is convenient. You can be done by replacing `_build/locale` with `locale/pot` in your `Makefile` and/or `make.bat` that was generated by sphinx-quickstart. License ======= Licensed under the BSD license. See the LICENSE file for specific terms. Original ======== This utilty derived from these projects. * https://bitbucket.org/tk0miya/sphinx-gettext-helper * https://bitbucket.org/shimizukawa/sphinx-transifex CHANGES ======= See: https://github.com/sphinx-doc/sphinx-intl/blob/master/CHANGES .. _Sphinx: http://sphinx-doc.org .. _transifex: https://transifex.com .. _transifex-client: https://pypi.python.org/pypi/transifex-client .. _setuptools: https://pypi.python.org/pypi/setuptools .. _six: https://pypi.python.org/pypi/six .. _babel: https://pypi.python.org/pypi/babel .. _click: https://pypi.python.org/pypi/click sphinx-intl-0.9.10/TESTING.rst000066400000000000000000000004621315620036700157320ustar00rootroot00000000000000======================= Testing for sphinx-intl ======================= First, you need install testing tools:: pip install -r requirements-testing.txt And run:: tox .. note:: sphinx-intl using travis-ci service to test for all environments. https://travis-ci.org/sphinx-doc/sphinx-intl sphinx-intl-0.9.10/requirements-testing.txt000066400000000000000000000000331315620036700210140ustar00rootroot00000000000000tox pytest docutils flake8 sphinx-intl-0.9.10/setup.cfg000066400000000000000000000007631315620036700157100ustar00rootroot00000000000000[egg_info] tag_build = dev tag_date = true [build] build-base = _build [sdist] formats = gztar [bdist_wheel] universal = 1 [aliases] release = check -r -s egg_info -Db '' testupload = register -r https://testpypi.python.org/pypi upload -r https://testpypi.python.org/pypi # to test release: python setup.py release sdist bdist_wheel testupload # to release: python setup.py release sdist bdist_wheel upload [flake8] ;show-pep8=true ;show-source=true max-line-length=95 sphinx-intl-0.9.10/setup.py000066400000000000000000000034551315620036700156020ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import with_statement from setuptools import setup, find_packages import os from sphinx_intl import __version__ install_requires = [ 'setuptools', 'six', 'click', 'babel', 'sphinx', ] extras_require = { 'transifex': [ 'transifex_client>=0.11' ], 'test': [ 'pytest', 'mock', ], } here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(here, 'README.rst')) as f: README = f.read() description = \ 'Sphinx utility that make it easy to translate and to apply translation.' setup( name='sphinx-intl', version=__version__, description=description, long_description=README, classifiers=[ "Development Status :: 4 - Beta", "Environment :: Other Environment", "License :: OSI Approved :: BSD License", "Topic :: Documentation", "Topic :: Software Development :: Documentation", "Topic :: Text Processing :: General", "Topic :: Utilities", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", ], author="Takayuki SHIMIZUKAWA", author_email="shimizukawa@gmail.com", url="https://github.com/sphinx-doc/sphinx-intl", namespace_packages=[], packages=find_packages(), include_package_data=True, zip_safe=False, install_requires=install_requires, extras_require=extras_require, entry_points="""\ [console_scripts] sphinx-intl = sphinx_intl.commands:main """, ) sphinx-intl-0.9.10/sphinx_intl/000077500000000000000000000000001315620036700164205ustar00rootroot00000000000000sphinx-intl-0.9.10/sphinx_intl/__init__.py000066400000000000000000000000601315620036700205250ustar00rootroot00000000000000# -*- coding: utf-8 -*- __version__ = '0.9.10' sphinx-intl-0.9.10/sphinx_intl/__main__.py000066400000000000000000000001511315620036700205070ustar00rootroot00000000000000# -*- coding: utf-8 -*- if __name__ == '__main__': from sphinx_intl.commands import main main() sphinx-intl-0.9.10/sphinx_intl/basic.py000066400000000000000000000113021315620036700200500ustar00rootroot00000000000000# -*- coding: utf-8 -*- import os from glob import glob import click from . import catalog as c from .pycompat import relpath # ================================== # utility functions def get_lang_dirs(path): dirs = [relpath(d, path) for d in glob(path+'/[a-z]*') if os.path.isdir(d) and not d.endswith('pot')] return (tuple(dirs),) # ================================== # commands def update(locale_dir, pot_dir, languages): """ Update specified language's po files from pot. :param unicode locale_dir: path for locale directory :param unicode pot_dir: path for pot directory :param tuple languages: languages to update po files :return: {'create': 0, 'update': 0, 'notchanged': 0} :rtype: dict """ status = { 'create': 0, 'update': 0, 'notchanged': 0, } for dirpath, dirnames, filenames in os.walk(pot_dir): for filename in filenames: pot_file = os.path.join(dirpath, filename) base, ext = os.path.splitext(pot_file) if ext != ".pot": continue basename = relpath(base, pot_dir) for lang in languages: po_dir = os.path.join(locale_dir, lang, 'LC_MESSAGES') po_file = os.path.join(po_dir, basename + ".po") cat_pot = c.load_po(pot_file) if os.path.exists(po_file): cat = c.load_po(po_file) msgids = set([m.id for m in cat if m.id]) c.update_with_fuzzy(cat, cat_pot) new_msgids = set([m.id for m in cat if m.id]) if msgids != new_msgids: added = new_msgids - msgids deleted = msgids - new_msgids status['update'] += 1 click.echo('Update: {0} +{1}, -{2}'.format( po_file, len(added), len(deleted))) c.dump_po(po_file, cat) else: status['notchanged'] += 1 click.echo('Not Changed: {0}'.format(po_file)) else: # new po file status['create'] += 1 click.echo('Create: {0}'.format(po_file)) c.dump_po(po_file, cat_pot) return status def build(locale_dir, output_dir, languages): """ Update specified language's po files from pot. :param unicode locale_dir: path for locale directory :param unicode output_dir: path for mo output directory :param tuple languages: languages to update po files :return: None """ for lang in languages: lang_dir = os.path.join(locale_dir, lang) for dirpath, dirnames, filenames in os.walk(lang_dir): dirpath_output = os.path.join(output_dir, os.path.relpath(dirpath, locale_dir)) for filename in filenames: base, ext = os.path.splitext(filename) if ext != ".po": continue mo_file = os.path.join(dirpath_output, base + ".mo") po_file = os.path.join(dirpath, filename) if (os.path.exists(mo_file) and os.path.getmtime(mo_file) > os.path.getmtime(po_file)): continue click.echo('Build: {0}'.format(mo_file)) cat = c.load_po(po_file) c.write_mo(mo_file, cat) def stat(locale_dir, languages): """ Print statistics for all po files. :param unicode locale_dir: path for locale directory :param tuple languages: languages to update po files :return: {'FILENAME': {'translated': 0, 'fuzzy': 0, 'untranslated': 0}, ...} :rtype: dict """ result = {} for lang in languages: lang_dir = os.path.join(locale_dir, lang) for dirpath, dirnames, filenames in os.walk(lang_dir): for filename in filenames: po_file = os.path.join(dirpath, filename) base, ext = os.path.splitext(po_file) if ext != ".po": continue cat = c.load_po(po_file) r = result[po_file.replace('\\', '/')] = { 'translated': len(c.translated_entries(cat)), 'fuzzy': len(c.fuzzy_entries(cat)), 'untranslated': len(c.untranslated_entries(cat)), } click.echo( '{0}: {1} translated, {2} fuzzy, {3} untranslated.'.format( po_file, r['translated'], r['fuzzy'], r['untranslated'], ) ) return result sphinx-intl-0.9.10/sphinx_intl/catalog.py000066400000000000000000000037071315620036700204130ustar00rootroot00000000000000# -*- coding: utf-8 -*- import os import io from babel.messages import pofile, mofile def load_po(filename): """read po/pot file and return catalog object :param unicode filename: path to po/pot file :return: catalog object """ # pre-read to get charset with io.open(filename, 'rb') as f: cat = pofile.read_po(f) charset = cat.charset or 'utf-8' # To decode lines by babel, read po file as binary mode and specify charset for # read_po function. with io.open(filename, 'rb') as f: # FIXME: encoding VS charset return pofile.read_po(f, charset=charset) def dump_po(filename, catalog): """write po/pot file from catalog object :param unicode filename: path to po file :param catalog: catalog object :return: None """ dirname = os.path.dirname(filename) if not os.path.exists(dirname): os.makedirs(dirname) # Because babel automatically encode strings, file should be open as binary mode. with io.open(filename, 'wb') as f: pofile.write_po(f, catalog) def write_mo(filename, catalog): """write mo file from catalog object :param unicode filename: path to mo file :param catalog: catalog object :return: None """ dirname = os.path.dirname(filename) if not os.path.exists(dirname): os.makedirs(dirname) with io.open(filename, 'wb') as f: mofile.write_mo(f, catalog) def translated_entries(catalog): return [m for m in catalog if m.id and m.string] def fuzzy_entries(catalog): return [m for m in catalog if m.id and m.fuzzy] def untranslated_entries(catalog): return [m for m in catalog if m.id and not m.string] def update_with_fuzzy(catalog, catalog_source): """update catalog by template catalog with fuzzy flag. :param catalog: catalog object to be updated :param catalog_source: catalog object as a template to update 'catalog' :return: None """ catalog.update(catalog_source) sphinx-intl-0.9.10/sphinx_intl/commands.py000066400000000000000000000205141315620036700205750ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ sphinx-intl ~~~~~~~~~~~ Sphinx utility that make it easy to translate and to apply translation. :copyright: Copyright 2013 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ from __future__ import with_statement import re import os from glob import glob import click from sphinx.util.tags import Tags from . import basic from . import transifex from .pycompat import execfile_, relpath ENVVAR_PREFIX = 'SPHINXINTL' # ================================== # utility functions def read_config(path): namespace = { "__file__": os.path.abspath(path), "tags": Tags(), } olddir = os.getcwd() try: if not os.path.isfile(path): msg = "'%s' is not found (or specify --locale-dir option)." % path raise click.BadParameter(msg) os.chdir(os.path.dirname(path) or ".") execfile_(os.path.basename(path), namespace) finally: os.chdir(olddir) return namespace def get_lang_dirs(path): dirs = [relpath(d, path) for d in glob(path+'/[a-z]*') if os.path.isdir(d) and not d.endswith('pot')] return (tuple(dirs),) # ================================== # click options class LanguagesType(click.ParamType): name = 'languages' envvar_list_splitter = ',' def convert(self, value, param, ctx): langs = value.split(',') return tuple(langs) LANGUAGES = LanguagesType() option_locale_dir = click.option( '-d', '--locale-dir', envvar=ENVVAR_PREFIX + '_LOCALE_DIR', type=click.Path(exists=False, file_okay=False), default='locales', metavar='', show_default=True, help='locale directories that allow comma separated string. This option ' 'override locale_dir in conf.py setting if provided. Default is empty ' 'list.') option_pot_dir = click.option( '--pot-dir', '-p', envvar=ENVVAR_PREFIX + '_POT_DIR', type=click.Path(exists=False, file_okay=False), metavar='', show_default=True, help="pot files directory which is generated by sphinx. " "Default is 'pot' directory under '--locale-dir' path.") option_output_dir = click.option( '--output-dir', '-o', envvar=ENVVAR_PREFIX + '_OUTPUT_DIR', type=click.Path(exists=False, file_okay=False), metavar='', show_default=True, help="mo files directory where files are written. " "Default is to match the '--locale-dir' path.") option_language = click.option( '-l', '--language', envvar=ENVVAR_PREFIX + '_LANGUAGE', type=LANGUAGES, default=(), metavar='', show_default=True, multiple=True, help="Target language to update po files. Default is ALL.") option_transifex_username = click.option( '--transifex-username', envvar=ENVVAR_PREFIX + '_TRANSIFEX_USERNAME', type=str, metavar='', show_default=True, help="Your transifex username. Default is None.") option_transifex_password = click.option( '--transifex-password', envvar=ENVVAR_PREFIX + '_TRANSIFEX_PASSWORD', type=str, metavar='', show_default=True, help="Your transifex password. Default is None.") option_transifex_project_name = click.option( '--transifex-project-name', envvar=ENVVAR_PREFIX + '_TRANSIFEX_PROJECT_NAME', type=str, metavar='', show_default=True, help="Your transifex project name. default is None") # ================================== # commands @click.group() @click.option( '-c', '--config', type=click.Path(exists=True, file_okay=True, dir_okay=False), default=None, metavar='', help='Sphinx conf.py file to read a locale directory setting.') @click.pass_context def main(ctx, config): """ Environment Variables: All command-line options can be set with environment variables using the format SPHINXINTL_ . Dashes (-) have to replaced with underscores (_). For example, to set the languages: export SPHINXINTL_LANGUAGE=de,ja This is the same as passing the option to txutil directly: sphinx-intl update --language=de --language=ja """ # load conf.py ctx.config = config if ctx.config is None: for c in ('conf.py', 'source/conf.py'): if os.path.exists(c): ctx.config = c break # for locale_dir ctx.locale_dir = None if ctx.config: cfg = read_config(ctx.config) if 'locale_dirs' in cfg: ctx.locale_dir = os.path.join( os.path.dirname(ctx.config), cfg['locale_dirs'][0]) # for pot_dir ctx.pot_dir = None for d in ('_build/gettext', 'build/gettext', '_build/locale', 'build/locale'): if os.path.exists(d): ctx.pot_dir = d break # for transifex_project_name ctx.transifex_project_name = None target = os.path.normpath('.tx/config') if os.path.exists(target): matched = re.search(r'\[(.*)\..*\]', open(target, 'r').read()) if matched: ctx.transifex_project_name = matched.groups()[0] click.echo( 'Project name loaded from .tx/config: {0}'.format( ctx.transifex_project_name)) ctx.default_map = { 'update': { 'locale_dir': ctx.locale_dir, 'pot_dir': ctx.pot_dir, }, 'build': { 'locale_dir': ctx.locale_dir, }, 'stat': { 'locale_dir': ctx.locale_dir, }, 'update-txconfig-resources': { 'locale_dir': ctx.locale_dir, 'pot_dir': ctx.pot_dir, 'transifex_project_name': ctx.transifex_project_name, }, } @main.command() @option_locale_dir @option_pot_dir @option_language def update(locale_dir, pot_dir, language): """ Update specified language's po files from pot. \b For examples: sphinx-intl update -l de -l ja sphinx-intl update -l de,ja """ if not pot_dir: pot_dir = os.path.join(locale_dir, 'pot') if not os.path.exists(pot_dir): msg = ("%(pot_dir)r is not exist. Please specify pot directory with " "-p option, or preparing your pot files in %(pot_dir)r." % locals()) raise click.BadParameter(msg, param_hint='pot_dir') if not language: language = get_lang_dirs(locale_dir) languages = sum(language, ()) # flatten if not languages: msg = ("No languages are found. Please specify language with -l " "option, or preparing language directories under %(locale_dir)r " "directory." % locals()) raise click.BadParameter(msg, param_hint='language') basic.update(locale_dir, pot_dir, languages) @main.command() @option_locale_dir @option_output_dir @option_language def build(locale_dir, output_dir, language): """ Update specified language's po files from pot. """ if not language: language = get_lang_dirs(locale_dir) languages = sum(language, ()) # flatten if not output_dir or ( os.path.exists(output_dir) and os.path.samefile(locale_dir, output_dir)): output_dir = locale_dir basic.build(locale_dir, output_dir, languages) @main.command() @option_locale_dir @option_language def stat(locale_dir, language): """ Print statistics for all po files. """ if not language: language = get_lang_dirs(locale_dir) languages = sum(language, ()) # flatten basic.stat(locale_dir, languages) @main.command('create-transifexrc') @option_transifex_username @option_transifex_password def create_transifexrc(transifex_username, transifex_password): """ Create `$HOME/.transifexrc` """ transifex.create_transifexrc(transifex_username, transifex_password) @main.command('create-txconfig') def create_txconfig(): """ Create `./.tx/config` """ transifex.create_txconfig() @main.command('update-txconfig-resources') @option_transifex_project_name @option_locale_dir @option_pot_dir def update_txconfig_resources(transifex_project_name, locale_dir, pot_dir): """ Update resource sections of `./.tx/config`. """ if not pot_dir: pot_dir = os.path.join(locale_dir, 'pot') transifex.update_txconfig_resources(transifex_project_name, locale_dir, pot_dir) if __name__ == '__main__': main(auto_envvar_prefix=ENVVAR_PREFIX) sphinx-intl-0.9.10/sphinx_intl/pycompat.py000066400000000000000000000051231315620036700206270ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Python compatibility functions. """ import sys import os from six import PY3, exec_, b FS_ENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() if sys.version_info >= (2, 6): # Python >= 2.6 relpath = os.path.relpath else: from os.path import curdir def relpath(path, start=curdir): """Return a relative version of a path""" from os.path import sep, abspath, commonprefix, join, pardir if not path: raise ValueError("no path specified") start_list = abspath(start).split(sep) path_list = abspath(path).split(sep) # Work out how much of the filepath is shared by start and path. i = len(commonprefix([start_list, path_list])) rel_list = [pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: return start return join(*rel_list) del curdir if PY3: def convert_with_2to3(filepath): from lib2to3.refactor import RefactoringTool, get_fixers_from_package from lib2to3.pgen2.parse import ParseError fixers = get_fixers_from_package('lib2to3.fixes') refactoring_tool = RefactoringTool(fixers) source = refactoring_tool._read_python_source(filepath)[0] try: tree = refactoring_tool.refactor_string(source, 'conf.py') except ParseError: typ, err, tb = sys.exc_info() # do not propagate lib2to3 exceptions lineno, offset = err.context[1] # try to match ParseError details with SyntaxError details raise SyntaxError(err.msg, (filepath, lineno, offset, err.value)) return str(tree) else: convert_with_2to3 = None def execfile_(filepath, _globals): # get config source -- 'b' is a no-op under 2.x, while 'U' is # ignored under 3.x (but 3.x compile() accepts \r\n newlines) f = open(filepath, 'rbU') try: source = f.read() finally: f.close() # py25,py26,py31 accept only LF eol instead of CRLF if sys.version_info[:2] in ((2, 5), (2, 6), (3, 1)): source = source.replace(b('\r\n'), b('\n')) # compile to a code object, handle syntax errors filepath_enc = filepath.encode(FS_ENCODING) try: code = compile(source, filepath_enc, 'exec') except SyntaxError: if convert_with_2to3: # maybe the file uses 2.x syntax; try to refactor to # 3.x syntax using 2to3 source = convert_with_2to3(filepath) code = compile(source, filepath_enc, 'exec') else: raise exec_(code, _globals) sphinx-intl-0.9.10/sphinx_intl/sphinx_util.py000066400000000000000000000012121315620036700213340ustar00rootroot00000000000000# -*- coding: utf-8 -*- # port from https://github.com/sphinx-doc/sphinx/blob/ad41e0b/sphinx/util/tags.py class Tags(object): def __init__(self, tags=None): # type: (List[unicode]) -> None self.tags = dict.fromkeys(tags or [], True) def has(self, tag): # type: (unicode) -> bool return tag in self.tags __contains__ = has def __iter__(self): # type: () -> Iterator[unicode] return iter(self.tags) def add(self, tag): # type: (unicode) -> None self.tags[tag] = True def remove(self, tag): # type: (unicode) -> None self.tags.pop(tag, None) sphinx-intl-0.9.10/sphinx_intl/transifex.py000066400000000000000000000104041315620036700207740ustar00rootroot00000000000000# -*- coding: utf-8 -*- import os import re import textwrap import click from .pycompat import relpath from .catalog import load_po # ================================== # settings # To avoid using invalid resource name, append underscore to such names. # As a limitation, append `_` doesn't care about collision to other resources. # e.g. 'glossary' and 'glossary_' are pushed as a 'glossary_'. IGNORED_RESOURCE_NAMES = ( 'glossary', # transifex reject this name ) TRANSIFEXRC_TEMPLATE = """\ [https://www.transifex.com] hostname = https://www.transifex.com password = %(transifex_password)s username = %(transifex_username)s token = """ TXCONFIG_TEMPLATE = """\ [main] host = https://www.transifex.com """ # ================================== # utility functions def get_tx_root(): import txclib.utils tx_root = txclib.utils.find_dot_tx() if tx_root is None: msg = "'.tx/config' not found. You need 'create-txconfig' first." raise click.BadParameter(msg) return tx_root def normalize_resource_name(name): # replace path separator with '--' name = re.sub(r'[\\/]', '--', name) # replace unusable characters (not: -, _ ascii, digit) with '_' name = re.sub(r'[^\-\w]', '_', name) # append `_` for ignored resource names while name in IGNORED_RESOURCE_NAMES: name += '_' return name # ================================== # commands def create_transifexrc(transifex_username, transifex_password): """ Create `$HOME/.transifexrc` """ target = os.path.normpath(os.path.expanduser('~/.transifexrc')) if os.path.exists(target): click.echo('{0} already exists, skipped.'.format(target)) return if not transifex_username or not 'transifex_password': msg = textwrap.dedent("""\ You need transifex username/password by command option or environment. command option: --transifex-username, --transifex-password """) raise click.BadParameter(msg, param_hint='transifex_username,transifex_password') with open(target, 'wt') as rc: rc.write(TRANSIFEXRC_TEMPLATE % locals()) click.echo('Create: {0}'.format(target)) def create_txconfig(): """ Create `./.tx/config` """ target = os.path.normpath('.tx/config') if os.path.exists(target): click.echo('{0} already exists, skipped.'.format(target)) return if not os.path.exists('.tx'): os.mkdir('.tx') with open(target, 'wt') as f: f.write(TXCONFIG_TEMPLATE) click.echo('Create: {0}'.format(target)) def update_txconfig_resources(transifex_project_name, locale_dir, pot_dir): """ Update resource sections of `./.tx/config`. """ try: import txclib.utils except ImportError: msg = textwrap.dedent("""\ Could not import 'txclib.utils'. You need install transifex_client external library. Please install below command if you want to this action: $ pip install sphinx-intl[transifex] """) raise click.BadParameter(msg) tx_root = get_tx_root() args_tmpl = ( '--auto-local', '-r', '%(transifex_project_name)s.%(resource_name)s', '%(locale_dir)s//LC_MESSAGES/%(resource_path)s.po', '--source-lang', 'en', '--source-file', '%(pot_dir)s/%(resource_path)s.pot', '--execute' ) # convert transifex_project_name to internal name transifex_project_name = transifex_project_name.replace(' ', '-') transifex_project_name = re.sub(r'[^\-_\w]', '', transifex_project_name) for dirpath, dirnames, filenames in os.walk(pot_dir): for filename in filenames: pot_file = os.path.join(dirpath, filename) base, ext = os.path.splitext(pot_file) if ext != ".pot": continue resource_path = relpath(base, pot_dir) pot = load_po(pot_file) if len(pot): resource_name = normalize_resource_name(resource_path) l = locals() args = [arg % l for arg in args_tmpl] txclib.utils.exec_command('set', args, tx_root) else: click.echo('{0} is empty, skipped'.format(pot_file)) txclib.utils.exec_command('set', ['-t', 'PO'], tx_root) sphinx-intl-0.9.10/tests/000077500000000000000000000000001315620036700152235ustar00rootroot00000000000000sphinx-intl-0.9.10/tests/conftest.py000066400000000000000000000020231315620036700174170ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ conftest ~~~~~~~~ PyTest utilities. :copyright: Copyright 2015 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ import os import pytest from path import path __dir__ = path(os.path.dirname(os.path.abspath(__file__))) @pytest.fixture(scope="function") def temp(request, tmpdir): template_dir = 'root' tmpdir = path(tmpdir) (__dir__ / template_dir).copytree(tmpdir / template_dir) cwd = os.getcwd() temp = tmpdir / template_dir os.chdir(temp) def fin(): os.chdir(cwd) request.addfinalizer(fin) return temp @pytest.fixture(scope="function") def home_in_temp(request, tmpdir): """change HOME environment variable to temporary location To avoid real .transifexrc will be rewritten. """ home = os.environ.get('HOME') os.environ['HOME'] = tmpdir.strpath def fin(): del os.environ['HOME'] if home: os.environ['HOME'] = home request.addfinalizer(fin) return tmpdir sphinx-intl-0.9.10/tests/path.py000077500000000000000000000122501315620036700165340ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ path ~~~~ :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os import sys import shutil from codecs import open from six import text_type FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() class path(text_type): """ Represents a path which behaves like a string. """ if sys.version_info < (3, 0): def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'): if isinstance(s, str): s = s.decode(encoding, errors) return text_type.__new__(cls, s) return text_type.__new__(cls, s) @property def parent(self): """ The name of the directory the file or directory is in. """ return self.__class__(os.path.dirname(self)) def abspath(self): """ Returns the absolute path. """ return self.__class__(os.path.abspath(self)) def isabs(self): """ Returns ``True`` if the path is absolute. """ return os.path.isabs(self) def isdir(self): """ Returns ``True`` if the path is a directory. """ return os.path.isdir(self) def isfile(self): """ Returns ``True`` if the path is a file. """ return os.path.isfile(self) def islink(self): """ Returns ``True`` if the path is a symbolic link. """ return os.path.islink(self) def ismount(self): """ Returns ``True`` if the path is a mount point. """ return os.path.ismount(self) def rmtree(self, ignore_errors=False, onerror=None): """ Removes the file or directory and any files or directories it may contain. :param ignore_errors: If ``True`` errors are silently ignored, otherwise an exception is raised in case an error occurs. :param onerror: A callback which gets called with the arguments `func`, `path` and `exc_info`. `func` is one of :func:`os.listdir`, :func:`os.remove` or :func:`os.rmdir`. `path` is the argument to the function which caused it to fail and `exc_info` is a tuple as returned by :func:`sys.exc_info`. """ shutil.rmtree(self, ignore_errors=ignore_errors, onerror=onerror) def copytree(self, destination, symlinks=False): """ Recursively copy a directory to the given `destination`. If the given `destination` does not exist it will be created. :param symlinks: If ``True`` symbolic links in the source tree result in symbolic links in the destination tree otherwise the contents of the files pointed to by the symbolic links are copied. """ shutil.copytree(self, destination, symlinks=symlinks) def movetree(self, destination): """ Recursively move the file or directory to the given `destination` similar to the Unix "mv" command. If the `destination` is a file it may be overwritten depending on the :func:`os.rename` semantics. """ shutil.move(self, destination) move = movetree def unlink(self): """ Removes a file. """ os.unlink(self) def write_text(self, text, **kwargs): """ Writes the given `text` to the file. """ f = open(self, 'w', **kwargs) try: f.write(text) finally: f.close() def text(self, **kwargs): """ Returns the text in the file. """ f = open(self, mode='U', **kwargs) try: return f.read() finally: f.close() def bytes(self): """ Returns the bytes in the file. """ f = open(self, mode='rb') try: return f.read() finally: f.close() def write_bytes(self, bytes, append=False): """ Writes the given `bytes` to the file. :param append: If ``True`` given `bytes` are added at the end of the file. """ if append: mode = 'ab' else: mode = 'wb' f = open(self, mode=mode) try: f.write(bytes) finally: f.close() def exists(self): """ Returns ``True`` if the path exist. """ return os.path.exists(self) def lexists(self): """ Returns ``True`` if the path exists unless it is a broken symbolic link. """ return os.path.lexists(self) def makedirs(self, mode=int('0777', 8)): """ Recursively create directories. """ os.makedirs(self, mode) def joinpath(self, *args): """ Joins the path with the argument given and returns the result. """ return self.__class__(os.path.join(self, *map(self.__class__, args))) __div__ = __truediv__ = joinpath def __repr__(self): return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self)) sphinx-intl-0.9.10/tests/root/000077500000000000000000000000001315620036700162065ustar00rootroot00000000000000sphinx-intl-0.9.10/tests/root/_build/000077500000000000000000000000001315620036700174445ustar00rootroot00000000000000sphinx-intl-0.9.10/tests/root/_build/locale/000077500000000000000000000000001315620036700207035ustar00rootroot00000000000000sphinx-intl-0.9.10/tests/root/_build/locale/README.pot000066400000000000000000000007111315620036700223630ustar00rootroot00000000000000#, fuzzy msgid "" msgstr "" "Project-Id-Version: sphinx-intl\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-10 21:31\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ..\..\README.rst:2 msgid "sphinx-intl: translation support utility for Sphinx" msgstr "" sphinx-intl-0.9.10/tests/root/locale/000077500000000000000000000000001315620036700174455ustar00rootroot00000000000000sphinx-intl-0.9.10/tests/root/locale/.placeholder000066400000000000000000000000001315620036700217160ustar00rootroot00000000000000sphinx-intl-0.9.10/tests/test_basic.py000066400000000000000000000053361315620036700177240ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ test_basic ~~~~~~~~~~ Test functions that implements pot related features. :copyright: Copyright 2015 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ import mock from sphinx_intl import basic def test_update_simple(temp): basic.update('locale', '_build/locale', ('ja',)) def test_update_difference_detect(temp): r1 = basic.update('locale', '_build/locale', ('ja',)) assert r1 == {'create': 1, 'update': 0, 'notchanged': 0} with open('_build/locale/README.pot', 'a') as f: f.write('\nmsgid "test1"\nmsgstr ""\n') r2 = basic.update('locale', '_build/locale', ('ja',)) assert r2 == {'create': 0, 'update': 1, 'notchanged': 0} with open('_build/locale/README.pot', 'r') as f: d = f.read() d = d.replace('test1', 'test2') with open('_build/locale/README.pot', 'w') as f: f.write(d) r3 = basic.update('locale', '_build/locale', ('ja',)) assert r3 == {'create': 0, 'update': 1, 'notchanged': 0} r4 = basic.update('locale', '_build/locale', ('ja',)) assert r4 == {'create': 0, 'update': 0, 'notchanged': 1} def test_stat(temp): r1 = basic.update('locale', '_build/locale', ('ja',)) r2 = basic.stat('locale', ('ja',)) assert r2 == {'locale/ja/LC_MESSAGES/README.po': {'translated': 0, 'fuzzy': 0, 'untranslated': 1}} def test_stat_with_multiple_languages(temp): r1 = basic.update('locale', '_build/locale', ('ja','de','it')) r2 = basic.stat('locale', ('ja','de','it')) assert r2 == { 'locale/ja/LC_MESSAGES/README.po': {'translated': 0, 'fuzzy': 0, 'untranslated': 1}, 'locale/de/LC_MESSAGES/README.po': {'translated': 0, 'fuzzy': 0, 'untranslated': 1}, 'locale/it/LC_MESSAGES/README.po': {'translated': 0, 'fuzzy': 0, 'untranslated': 1}, } @mock.patch('sphinx_intl.catalog.write_mo') @mock.patch('sphinx_intl.catalog.load_po') def test_build(load_po, write_mo, temp): basic.update('locale', '_build/locale', ('ja',)) basic.build('locale', 'locale', ('ja',)) assert load_po.call_args[0][0].startswith('locale') assert load_po.call_args[0][0].endswith('README.po') assert write_mo.call_args[0][0].startswith('locale') assert write_mo.call_args[0][0].endswith('README.mo') @mock.patch('sphinx_intl.catalog.write_mo') @mock.patch('sphinx_intl.catalog.load_po') def test_build_mo_on_another_location(load_po, write_mo, temp): basic.update('locale', '_build/locale', ('ja',)) basic.build('locale', 'mo_dir', ('ja',)) assert load_po.call_args[0][0].startswith('locale') assert load_po.call_args[0][0].endswith('README.po') assert write_mo.call_args[0][0].startswith('mo_dir') assert write_mo.call_args[0][0].endswith('README.mo') sphinx-intl-0.9.10/tests/test_catalog.py000066400000000000000000000023521315620036700202500ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ test_catalog ~~~~~~~~~~~~ Test functions that implements catalog related features. :copyright: Copyright 2015 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ from babel.messages import Catalog, Message def test_write_and_read_po_file_with_non_ascii_string(temp): from sphinx_intl import catalog cat = Catalog(locale='ja', domain='domain', fuzzy=False) msg = Message('Hello World', u'こんにちは世界') cat[msg.id] = msg po_file = (temp / 'domain.po') catalog.dump_po(po_file, cat) cat2 = catalog.load_po(po_file) assert cat2[msg.id].string == msg.string def test_fuzzy_flag_on_catalog_update(): from sphinx_intl import catalog cat = Catalog(locale='ja', domain='domain', fuzzy=False) msg = Message('Hello Internationalized Sphinx World !', u'こんにちは国際化されたSphinxの世界!') cat[msg.id] = msg assert not msg.fuzzy cat_src = Catalog(locale='en', domain='domain', fuzzy=False) msg_src = Message('Hello Internationalized Sphinx World ?') cat_src[msg_src.id] = msg_src catalog.update_with_fuzzy(cat, cat_src) assert msg.id not in cat assert cat[msg_src.id].fuzzy sphinx-intl-0.9.10/tests/test_cmd_pot.py000066400000000000000000000060361315620036700202660ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ test_cmd_pot ~~~~~~~~~~~~~ Test pot related commands. :copyright: Copyright 2015 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ from __future__ import with_statement from click.testing import CliRunner from sphinx_intl import commands runner = CliRunner() def test_update_pot_notfound(temp): r1 = runner.invoke(commands.update, ['-d', 'locale']) assert r1.exit_code != 0 assert 'Please specify pot directory with -p option,' in r1.output def test_update_no_language(temp): r1 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale']) assert r1.exit_code != 0 assert 'No languages are found. Please specify language with -l' in r1.output def test_update_simple(temp): r1 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale', '-l', 'ja']) assert r1.exit_code == 0 def test_update_difference_detect(temp): r1 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale', '-l', 'ja']) assert r1.exit_code == 0 assert r1.output.count('Create:') == 1 assert r1.output.count('Update:') == 0 assert r1.output.count('Not Changed:') == 0 with open('_build/locale/README.pot', 'a') as f: f.write('\nmsgid "test1"\nmsgstr ""\n') r2 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale']) assert r2.exit_code == 0 assert r2.output.count('Create:') == 0 assert r2.output.count('Update:') == 1 assert r2.output.count('Not Changed:') == 0 with open('_build/locale/README.pot', 'r') as f: d = f.read() d = d.replace('test1', 'test2') with open('_build/locale/README.pot', 'w') as f: f.write(d) r3 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale']) assert r3.exit_code == 0 assert r3.output.count('Create:') == 0 assert r3.output.count('Update:') == 1 assert r3.output.count('Not Changed:') == 0 r4 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale']) assert r4.exit_code == 0 assert r4.output.count('Create:') == 0 assert r4.output.count('Update:') == 0 assert r4.output.count('Not Changed:') == 1 def test_stat(temp): r1 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale', '-l', 'ja']) assert r1.exit_code == 0 r2 = runner.invoke(commands.stat, ['-d', 'locale']) assert r2.exit_code == 0 assert 'README.po: 0 translated, 0 fuzzy, 1 untranslated.' in r2.output def test_stat_with_multiple_languages(temp): r1 = runner.invoke(commands.update, ['-d', 'locale', '-p', '_build/locale', '-l', 'ja,de,it']) assert r1.exit_code == 0 # r2 = runner.invoke(commands.stat, ['-d', 'locale', '-l', 'ja,de', '-l', 'it']) r2 = runner.invoke(commands.stat, ['-d', 'locale', '-l', 'ja']) assert r2.exit_code == 0 assert 'README.po: 0 translated, 0 fuzzy, 1 untranslated.' in r2.output def test_build(temp): result = runner.invoke(commands.build, ['--locale-dir', 'locale']) assert result.exit_code == 0 sphinx-intl-0.9.10/tests/test_cmd_transifex.py000066400000000000000000000113161315620036700214640ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ test_cmd_transifex ~~~~~~~~~~~~~~~~~~ Test transifex related commands. :copyright: Copyright 2015 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ import re from textwrap import dedent from click.testing import CliRunner from sphinx_intl import commands runner = CliRunner() def test_create_transifexrc(home_in_temp): r1 = runner.invoke(commands.main, [ 'create-transifexrc', '--transifex-username', 'spam-id', '--transifex-password', 'egg-pw', ]) assert r1.exit_code == 0 def test_create_txconfig(home_in_temp, temp): r1 = runner.invoke(commands.main, ['create-txconfig']) assert r1.exit_code == 0 def test_update_txconfig_resources(home_in_temp, temp): r1 = runner.invoke(commands.main, ['create-txconfig']) assert r1.exit_code == 0 r2 = runner.invoke(commands.update_txconfig_resources, [ '--transifex-project-name', 'ham-project', '-d', 'locale', ]) assert r2.exit_code == 0 def test_update_txconfig_resources_with_config(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com [ham-project.domain1] """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') r1 = runner.invoke(commands.main, ['update-txconfig-resources', '-d', 'locale']) assert r1.exit_code == 0 data = (tx_dir / 'config').text() assert re.search(r'\[ham-project\.README\]', data) def test_update_txconfig_resources_with_pot_dir_argument(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com [ham-project.domain1] """)) r1 = runner.invoke(commands.main, ['update-txconfig-resources', '-d', 'locale', '-p', '_build/locale', ]) assert r1.exit_code == 0 data = (tx_dir / 'config').text().replace('\\', '/') assert re.search(r'\[ham-project\.README\]', data) assert re.search(r'source_file = _build/locale/README.pot', data) def test_update_txconfig_resources_with_project_name_including_dots(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') r1 = runner.invoke(commands.main, ['update-txconfig-resources', '-d', 'locale', '--transifex-project-name', 'ham-project.com', ]) assert r1.exit_code == 0 data = (tx_dir / 'config').text() assert re.search(r'\[ham-projectcom\.README\]', data) def test_update_txconfig_resources_with_project_name_including_spaces(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') r1 = runner.invoke(commands.main, ['update-txconfig-resources', '-d', 'locale', '--transifex-project-name', 'ham project com', ]) assert r1.exit_code == 0 data = (tx_dir / 'config').text() assert re.search(r'\[ham-project-com\.README\]', data) def test_update_txconfig_resources_with_potfile_including_symbols(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') # copy README.pot to 'example document.pot' readme = (temp / '_build' / 'locale' / 'README.pot').text() (temp / '_build' / 'locale' / 'example document.pot').write_text(readme) # copy README.pot to 'test.document.pot' (temp / '_build' / 'locale' / 'test.document.pot').write_text(readme) r1 = runner.invoke(commands.main, ['update-txconfig-resources', '-d', 'locale', '--transifex-project-name', 'ham project com', ]) assert r1.exit_code == 0 data = (tx_dir / 'config').text() assert re.search(r'\[ham-project-com\.example_document\]', data) assert re.search(r'\[ham-project-com\.test_document\]', data) sphinx-intl-0.9.10/tests/test_transifex.py000066400000000000000000000075751315620036700206550ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ test_transifex ~~~~~~~~~~~~~~ Test functions that implements transifex related features. :copyright: Copyright 2015 by Takayuki SHIMIZUKAWA. :license: BSD, see LICENSE for details. """ import re from textwrap import dedent import pytest from sphinx_intl import transifex def test_create_transifexrc(home_in_temp): transifex.create_transifexrc('spam-id', 'egg-pw') def test_create_txconfig(home_in_temp, temp): transifex.create_txconfig() def test_update_txconfig_resources(home_in_temp, temp): transifex.create_txconfig() transifex.update_txconfig_resources('ham-project', 'locale', '_build/locale') def test_update_txconfig_resources_with_config(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com [ham-project.domain1] """)) transifex.update_txconfig_resources('ham-project', 'locale', '_build/locale') data = (tx_dir / 'config').text().replace('\\', '/') assert re.search(r'\[ham-project\.README\]', data) assert re.search(r'source_file = _build/locale/README.pot', data) def test_update_txconfig_resources_with_another_pot_dir(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com [ham-project.domain1] """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') transifex.update_txconfig_resources('ham-project', 'locale', 'locale/pot') data = (tx_dir / 'config').text() assert re.search(r'\[ham-project\.README\]', data) def test_update_txconfig_resources_with_project_name_including_dots(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') transifex.update_txconfig_resources('ham-project.com', 'locale', '_build/locale') data = (tx_dir / 'config').text() assert re.search(r'\[ham-projectcom\.README\]', data) def test_update_txconfig_resources_with_project_name_including_spaces(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') transifex.update_txconfig_resources('ham project com', 'locale', '_build/locale') data = (tx_dir / 'config').text() assert re.search(r'\[ham-project-com\.README\]', data) def test_update_txconfig_resources_with_potfile_including_symbols(home_in_temp, temp): tx_dir = temp / '.tx' tx_dir.makedirs() (tx_dir / 'config').write_text(dedent("""\ [main] host = https://www.transifex.com """)) (temp / '_build' / 'locale').copytree(temp / 'locale' / 'pot') # copy README.pot to 'example document.pot' readme = (temp / '_build' / 'locale' / 'README.pot').text() (temp / '_build' / 'locale' / 'example document.pot').write_text(readme) # copy README.pot to 'test.document.pot' (temp / '_build' / 'locale' / 'test.document.pot').write_text(readme) transifex.update_txconfig_resources('ham project com', 'locale', '_build/locale') data = (tx_dir / 'config').text() assert re.search(r'\[ham-project-com\.example_document\]', data) assert re.search(r'\[ham-project-com\.test_document\]', data) @pytest.mark.parametrize("input,expected", [ ('spam/ham', 'spam--ham'), ('spam\\ham', 'spam--ham'), ('ham egg.pot', 'ham_egg_pot'), ('spam-ham/egg.pot', 'spam-ham--egg_pot'), ('glossary', 'glossary_'), ('glossary_', 'glossary_'), ]) def test_normalize_resource_name(input, expected): _callSUT = transifex.normalize_resource_name assert _callSUT(input) == expected sphinx-intl-0.9.10/tox.ini000066400000000000000000000005721315620036700154000ustar00rootroot00000000000000[tox] envlist=py36,py35,py34,py27,flake8,sdist [testenv] deps=-e.[transifex,test] setenv = BUILD_TEST_PATH = {envdir}/tests HOME={envdir} commands= py.test {posargs} [testenv:flake8] usedevelop=True deps=flake8 commands=flake8 sphinx_intl [testenv:sdist] usedevelop=True deps= docutils wheel commands={envpython} setup.py -q check -r -s sdist bdist_wheel