Ejemplo n.º 1
0
def setup(app):
    # The root of the repository.
    basedir = Path(__file__).resolve().parents[1]
    # `LOCALE_DIR` from `config.mk`.
    localedir = basedir / 'docs' / 'locale'

    language = app.config.overrides.get('language', 'en')

    headers = ['Title', 'Description', 'Extension']
    # The gettext domain for schema translations. Should match the domain in the `pybabel compile` command.
    schema_domain = f'{gettext_domain_prefix}schema'
    # The gettext domain for codelist translations. Should match the domain in the `pybabel compile` command.
    codelists_domain = f'{gettext_domain_prefix}codelists'

    patched_dir = basedir / 'schema' / 'patched'
    profile_dir = basedir / 'schema' / 'profile'
    patched_build_dir = basedir / 'docs' / '_static' / 'patched'
    profile_build_dir = basedir / 'build' / language

    translate([
        # The glob patterns in `babel_ocds_schema.cfg` should match these filenames.
        (glob(str(patched_dir / '*-schema.json')), patched_build_dir, schema_domain),
        (glob(str(profile_dir / '*-schema.json')), profile_build_dir, schema_domain),
        # The glob patterns in `babel_ocds_codelist.cfg` should match these.
        (glob(str(patched_dir / 'codelists' / '*.csv')), patched_build_dir / 'codelists', codelists_domain),
        (glob(str(profile_dir / 'codelists' / '*.csv')), profile_build_dir / 'codelists', codelists_domain),
    ], localedir, language, headers, version=standard_version)

    # Copy the untranslated extension.json file.
    with (profile_dir / 'extension.json').open() as f:
        extension_json = f.read()
    with (profile_build_dir / 'extension.json').open('w') as f:
        f.write(extension_json)
Ejemplo n.º 2
0
def setup(app):
    # The root of the repository.
    basedir = Path(__file__).resolve().parents[1]
    # `LOCALE_DIR` from `config.mk`.
    localedir = basedir / 'docs' / 'locale'

    language = app.config.overrides.get('language', 'en')

    headers = ['Title', 'Description', 'Extension']
    # The gettext domain for schema translations. Should match the domain in the `pybabel compile` command.
    schema_domain = f'{gettext_domain_prefix}schema'
    # The gettext domain for codelist translations. Should match the domain in the `pybabel compile` command.
    codelists_domain = f'{gettext_domain_prefix}codelists'

    standard_dir = basedir / 'schema'
    standard_build_dir = basedir / 'build' / language

    branch = os.getenv('GITHUB_REF', 'latest').rsplit('/', 1)[-1]

    translate(
        [
            # The glob patterns in `babel_ocds_schema.cfg` should match these filenames.
            (glob(str(standard_dir / '*-schema.json')), standard_build_dir,
             schema_domain),
            # The glob patterns in `babel_ocds_codelist.cfg` should match these.
            (glob(str(standard_dir / 'codelists' / '*.csv')),
             standard_build_dir / 'codelists', codelists_domain),
        ],
        localedir,
        language,
        headers,
        version=branch)
Ejemplo n.º 3
0
def setup(app):
    app.add_config_value('extension_versions', extension_versions, True)
    app.add_config_value('recommonmark_config', {'enable_eval_rst': True},
                         True)

    app.add_transform(AutoStructify)
    app.add_transform(AutoStructifyLowPriority)

    # The root of the repository.
    basedir = Path(os.path.realpath(__file__)).parents[3]
    # The `LOCALE_DIR` from `config.mk`.
    localedir = basedir / 'standard' / 'docs' / 'locale'

    language = app.config.overrides.get('language', 'en')

    # The gettext domain for schema translations. Should match the domain in the `pybabel compile` command.
    schema_domain = '{}schema'.format(gettext_domain_prefix)
    # The gettext domain for codelist translations. Should match the domain in the `pybabel compile` command.
    codelists_domain = '{}codelists'.format(gettext_domain_prefix)

    standard_dir = basedir / 'standard' / 'schema'
    standard_build_dir = basedir / 'build' / language

    translate(
        [
            # The glob patterns in `babel_ocds_schema.cfg` should match these filenames.
            (glob(str(standard_dir / '*-schema.json')), standard_build_dir,
             schema_domain),
            # The glob patterns in `babel_ocds_codelist.cfg` should match these.
            (glob(str(standard_dir / 'codelists' / '*.csv')),
             standard_build_dir / 'codelists', codelists_domain),
        ],
        localedir,
        language,
        version=os.environ.get('TRAVIS_BRANCH', 'latest'))
Ejemplo n.º 4
0
def test_translate_codelists(monkeypatch, caplog):
    class Translation(object):
        def __init__(self, *args, **kwargs):
            pass

        def gettext(self, *args, **kwargs):
            return {
                'Code':
                'Código',
                'Title':
                'Título',
                'Description':
                'Descripción',
                'Open':
                'Abierta',
                'Selective':
                'Selectiva',
                'All interested suppliers may submit a tender.':
                'Todos los proveedores interesados pueden enviar una propuesta.',  # noqa: E501
                'Only qualified suppliers are invited to submit a tender.':
                'Sólo los proveedores calificados son invitados a enviar una propuesta.',  # noqa: E501
            }[args[0]]

    monkeypatch.setattr(gettext, 'translation', Translation)

    caplog.set_level(logging.INFO)

    with TemporaryDirectory() as sourcedir:
        with open(os.path.join(sourcedir, 'method.csv'), 'w') as f:
            f.write(codelist)

        with TemporaryDirectory() as builddir:
            translate([
                (glob(os.path.join(sourcedir,
                                   '*.csv')), builddir, 'codelists'),
            ], '', 'es', headers)

            with open(os.path.join(builddir, 'method.csv')) as f:
                rows = [dict(row) for row in csv.DictReader(f)]

    assert rows == [{
        'Código': 'open',
        'Descripción':
        'Todos los proveedores interesados pueden enviar una propuesta.',
        'Título': 'Abierta'
    }, {
        'Código': 'selective',
        'Descripción':
        'Sólo los proveedores calificados son invitados a enviar una propuesta.',
        'Título': 'Selectiva'
    }]

    assert len(caplog.records) == 1
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[
        0].message == f'Translating to es using "codelists" domain, into {builddir}'
Ejemplo n.º 5
0
def setup(app):
    app.add_config_value('extension_versions', extension_versions, True)
    app.add_config_value('recommonmark_config', {
        'auto_toc_tree_section': 'Contents',
        'enable_eval_rst': True
    }, True)

    app.add_transform(AutoStructify)

    # The root of the repository.
    basedir = Path(os.path.realpath(__file__)).parents[1]
    # The `LOCALE_DIR` from `config.mk`.
    localedir = basedir / 'locale'

    language = app.config.overrides.get('language', 'en')

    headers = ['Title', 'Description', 'Extension']
    # The gettext domain for schema translations. Should match the domain in the `pybabel compile` command.
    schema_domain = '{}schema'.format(gettext_domain_prefix)
    # The gettext domain for codelist translations. Should match the domain in the `pybabel compile` command.
    codelists_domain = '{}codelists'.format(gettext_domain_prefix)

    patched_dir = basedir / 'schema' / 'patched'
    profile_dir = basedir / 'schema' / 'profile'
    patched_build_dir = basedir / 'docs' / '_static' / 'patched'
    profile_build_dir = basedir / 'build' / language

    translate(
        [
            # The glob patterns in `babel_ocds_schema.cfg` should match these filenames.
            (glob(str(patched_dir / '*-schema.json')), patched_build_dir,
             schema_domain),
            (glob(str(profile_dir / '*-schema.json')), profile_build_dir,
             schema_domain),
            # The glob patterns in `babel_ocds_codelist.cfg` should match these.
            (glob(str(patched_dir / 'codelists' / '*.csv')),
             patched_build_dir / 'codelists', codelists_domain),
            (glob(str(profile_dir / 'codelists' / '*.csv')),
             profile_build_dir / 'codelists', codelists_domain),
        ],
        localedir,
        language,
        headers,
        version=standard_version)

    # Copy the untranslated extension.json file.
    with (profile_dir / 'extension.json').open() as f:
        extension_json = f.read()
    with (profile_build_dir / 'extension.json').open('w') as f:
        f.write(extension_json)
Ejemplo n.º 6
0
def test_translate_extension_metadata(monkeypatch, caplog):
    for metadata in (extension_metadata, extension_metadata_language_map):

        class Translation(object):
            def __init__(self, *args, **kwargs):
                pass

            def gettext(self, *args, **kwargs):
                return {
                    'Location':
                    'Ubicación',
                    'Communicates the location of proposed or executed contract delivery.':
                    'Comunica la ubicación de la entrega del contrato propuesto o ejecutado.',  # noqa: E501
                }[args[0]]

        monkeypatch.setattr(gettext, 'translation', Translation)

        caplog.set_level(logging.INFO)

        with TemporaryDirectory() as sourcedir:
            with open(os.path.join(sourcedir, 'extension.json'), 'w') as f:
                f.write(metadata)

            with TemporaryDirectory() as builddir:
                translate([
                    ([os.path.join(sourcedir, 'extension.json')
                      ], builddir, 'schema'),
                ], '', 'es', headers)

                with open(os.path.join(builddir, 'extension.json')) as f:
                    data = json.load(f)

        assert data == {
            "name": {
                "es": "Ubicación"
            },
            "description": {
                "es":
                "Comunica la ubicación de la entrega del contrato propuesto o ejecutado."
            },
            "compatibility": ["1.1"]
        }

        assert len(caplog.records) == 1
        assert caplog.records[0].levelname == 'INFO'
        assert caplog.records[
            0].message == f'Translating to es using "schema" domain, into {builddir}'

        caplog.clear()
Ejemplo n.º 7
0
def translate_schema_and_codelists(language='en'):
    # The root of the repository.
    basedir = Path(os.path.realpath(__file__)).parents[1]
    build_dir = basedir / 'docs' / '_build_schema'

    localedir = basedir / 'docs' / 'locale'

    # The gettext domain for schema translations. Should match the domain in the `pybabel compile` command.
    schema_domain = 'schema'
    # The gettext domain for codelist translations. Should match the domain in the `pybabel compile` command.
    codelist_domain = 'codelist'

    schema_source_dir = basedir / 'schema'
    codelist_source_dir = basedir / 'schema' / 'codelists'
    schema_target_dir = build_dir
    codelist_target_dir = build_dir / 'codelists'

    def _json_dumps(data):
        return json.dumps(
            data, ensure_ascii=False, indent=2, separators=(',', ': ')) + '\n'

    # This is a slight monkey patch on translate to make sure translated schemas follow
    # same indentation as core schemas
    translate._json_dumps = _json_dumps

    translate.translate(
        [
            # The glob patterns in `babel_bods_schema.cfg` should match these filenames.
            (glob(str(schema_source_dir / '*.json')), str(schema_target_dir),
             schema_domain),
            # The glob patterns in `babel_bods_codelist.cfg` should match these.
            (glob(str(codelist_source_dir / '*.csv')),
             str(codelist_target_dir), codelist_domain),
        ],
        str(localedir),
        language,
        version=os.environ.get('TRAVIS_BRANCH', 'latest'),
        headers='title,description,technical note')

    print("Translated schema and codelists to {}".format(language))
    def load_extensions_info(self):
        """
        Gets the core extensions from the extension registry.

        If the language is not 'en', produces the translated versions for each core extension.
        """
        extensions_dir = Path('extensions')
        if extensions_dir.exists():
            shutil.rmtree(str(extensions_dir))
        extensions_dir.mkdir()

        # download extension files according to version
        registry = ExtensionRegistry(self.extension_versions_url, self.extensions_url)
        for version in registry.filter(core=True, version=self.version):
            if version.id not in self.exclusions:
                zip_file = version.zipfile()
                zip_file.extractall(path=str(extensions_dir))
                # rename path to extension id
                path = extensions_dir / zip_file.infolist()[0].filename
                path.rename(extensions_dir / version.id)

        if self.lang is 'en':
            
            output_dir = extensions_dir

        else:
            # translate core extensions

            translation_sources_dir = Path('ocds-extensions-translations-master')
            if translation_sources_dir.exists():
                shutil.rmtree(str(translation_sources_dir))
            
            res = requests.get('https://github.com/open-contracting/ocds-extensions-translations/archive/master.zip')
            res.raise_for_status()
            content = BytesIO(res.content)
            with ZipFile(content) as zipfile:
                zipfile.extractall()

            output_dir = Path('translations') / self.lang
            if output_dir.exists():
                shutil.rmtree(str(output_dir))
            output_dir.mkdir(parents=True)
            locale = str(translation_sources_dir / 'locale')
            headers = ['Title', 'Description', 'Extension']

            for dir in [x for x in extensions_dir.iterdir() if x.is_dir()]:
                translate([
                    (glob(str(dir / 'extension.json')), output_dir / dir.parts[-1], dir.parts[-1] + '/' + self.version + '/schema'),
                    (glob(str(dir / 'release-schema.json')), 
                        output_dir / dir.parts[-1], 
                        dir.parts[-1] + '/' + self.version + '/schema')
                    ], locale, self.lang, headers)
        
        self.extension_urls = [path.resolve(strict=True).as_uri() for path in output_dir.iterdir() if path.is_dir()]
        
        # get names and descriptions for each extension
        for dir in [x for x in output_dir.iterdir() if x.is_dir()]:
            path = dir.joinpath('extension.json')
            info = {}
            with path.open() as f:
                info = json.load(f)
                self.descriptions[info['name'][self.lang]] = info['description'][self.lang]
                # mapping-schema looks for the name of the name extension in English
                if self.lang is not 'en':
                    info['name']['en'] = info['name'][self.lang]
            with path.open(mode='w') as f:
                json.dump(info, f)
        
        return self.extension_urls
Ejemplo n.º 9
0
def test_translate_markdown(monkeypatch, caplog):
    class Translation(object):
        def __init__(self, *args, **kwargs):
            pass

        def gettext(self, *args, **kwargs):
            return {
                'Skip Heading': 'Entête à sauter',
                'Heading 1': 'Titre 1',
                'Heading 2': 'Titre 2',
                'Heading **3**': 'Titre **3**',
                'Paragraph text and ```literal text```':
                'Texte de paragraphe et ```texte littéral```',
                '`Literal text`': '`Texte littéral`',
                'Blockquote text': 'Texte de citation',
                '![Caption](http://example.com/example.png)':
                '![Légende](http://example.com/example-fr.png)',
                'This is a [pending](examples/test.md) xref.':
                'Ceci est un xref [en suspens](examples/test.md).',
                'This is a **[bold link](http://example.com/test.md)**.':
                'Ceci est un **[lien en gras](http://example.com/test.md)**.',  # noqa: E501
                'This is <em>inline HTML</em>.':
                'Ceci est <em>HTML en ligne</em>.',
                'Bulleted list item 1': 'Élément de liste à puces 1',
                'Bulleted list item 2': 'Élément de liste à puces 2',
                'Enumerated list item 1': 'Élément de liste énumérée 1',
                'Enumerated list item 2': 'Élément de liste énumérée 2',
                '[Link list item 1](http://example.com/en/1.html)':
                '[Élément de liste de liens 1](http://example.com/fr/1.html)',  # noqa: E501
                '[Link list item 2](http://example.com/en/2.html)':
                '[Élément de liste de liens 2](http://example.com/fr/2.html)',  # noqa: E501
                '': '',
            }[args[0]]

    monkeypatch.setattr(gettext, 'translation', Translation)

    caplog.set_level(logging.INFO)

    with TemporaryDirectory() as sourcedir:
        with open(os.path.join(sourcedir, 'README.md'), 'w') as f:
            f.write(extension_readme)

        with TemporaryDirectory() as builddir:
            translate([
                ([os.path.join(sourcedir, 'README.md')], builddir, 'docs'),
            ], '', 'fr', headers)

            with open(os.path.join(builddir, 'README.md')) as f:
                text = f.read()

    assert text == """##### Entête à sauter

# Titre 1

## Titre 2

### Titre **3**

Texte de paragraphe et `texte littéral`

`Texte littéral`

> Texte de citation

```
Raw paragraph text
```

```
Literal block
```

```json
{
    "json": "block"
}
```

<h3>Subheading</h3>

![Légende](http://example.com/example-fr.png)

Ceci est un xref [en suspens](examples/test.md).

Ceci est un **[lien en gras](http://example.com/test.md)**.

Ceci est <em>HTML en ligne</em>.

- Élément de liste à puces 1
- Élément de liste à puces 2

1. Élément de liste énumérée 1
1. Élément de liste énumérée 2

- [Élément de liste de liens 1](http://example.com/fr/1.html)
- [Élément de liste de liens 2](http://example.com/fr/2.html)
"""

    assert len(caplog.records) == 1
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[
        0].message == f'Translating to fr using "docs" domain, into {builddir}'
Ejemplo n.º 10
0
def test_translate_schema(monkeypatch, caplog):
    class Translation(object):
        def __init__(self, *args, **kwargs):
            pass

        def gettext(self, *args, **kwargs):
            return {
                'Schema for an Open Contracting Record package {{version}} [{{lang}}]':
                'Esquema para un paquete de Registros de Contrataciones Abiertas {{version}} [{{lang}}]',  # noqa: E501
                'The record package contains a list of records along with some publishing…':
                'El paquete de registros contiene una lista de registros junto con algunos…',  # noqa: E501
                'Releases':
                'Entregas',
                'An array of linking identifiers or releases':
                'Una matriz de enlaces a identificadores o entregas',
                'Linked releases':
                'Entregas vinculadas',
                'A list of objects that identify the releases associated with this Open…':
                'Una lista de objetos que identifican las entregas asociadas con este Open…',  # noqa: E501
                'Embedded releases':
                'Entregas embebidas',
                'A list of releases, with all the data. The releases MUST be sorted into date…':
                'Una lista de entregas, con todos los datos. Las entregas DEBEN ordenarse…',  # noqa: E501
            }[args[0]]

    monkeypatch.setattr(gettext, 'translation', Translation)

    caplog.set_level(logging.INFO)

    with TemporaryDirectory() as sourcedir:
        with open(os.path.join(sourcedir, 'record-package-schema.json'),
                  'w') as f:
            f.write(schema)

        with open(os.path.join(sourcedir, 'untranslated.json'), 'w') as f:
            f.write(schema)

        with TemporaryDirectory() as builddir:
            translate([
                ([os.path.join(sourcedir, 'record-package-schema.json')
                  ], builddir, 'schema'),
            ],
                      '',
                      'es',
                      headers,
                      version='1.1')

            with open(os.path.join(builddir,
                                   'record-package-schema.json')) as f:
                data = json.load(f)

            assert not os.path.exists(
                os.path.join(builddir, 'untranslated.json'))

    assert data == {
        "title":
        "Esquema para un paquete de Registros de Contrataciones Abiertas 1.1 [es]",
        "description":
        "El paquete de registros contiene una lista de registros junto con algunos…",
        "definitions": {
            "record": {
                "properties": {
                    "releases": {
                        "title":
                        "Entregas",
                        "description":
                        "Una matriz de enlaces a identificadores o entregas",
                        "oneOf": [{
                            "title":
                            "Entregas vinculadas",
                            "description":
                            "Una lista de objetos que identifican las entregas asociadas con este Open…"
                        }, {
                            "title":
                            "Entregas embebidas",
                            "description":
                            "Una lista de entregas, con todos los datos. Las entregas DEBEN ordenarse…"
                        }]
                    }
                }
            }
        }
    }

    assert len(caplog.records) == 1
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[
        0].message == f'Translating to es using "schema" domain, into {builddir}'