Example #1
0
def download(spreadsheet, sources_directory, worksheet_name=None,
             languages=None):
    """Download translations from the configured spreadsheet and merge them
    into the .po-files in the sources directory.
    """

    if worksheet_name is None:
        worksheet_name = select_worksheet(spreadsheet)

    data = spreadsheet.download(worksheet_name)
    if languages is None:
        languages = select_languages(data)

    catalog = load_translation_catalog(sources_directory)
    for row in data:
        msg = catalog.get_message(
            package=row.get('package'),
            domain=row.get('domain'),
            msgid=row.get('id'))

        for lang in languages:
            if not row['translations'].get(lang, None):
                continue
            msgstr = row['translations'][lang]
            msg.translate(lang, msgstr)

    write_catalog(sources_directory, catalog)

    return data
def upload(spreadsheet, sources_directory, languages=None,
           additional_languages=None, filter_translated=True,
           output=sys.stdout):
    """Upload the translations into the configured spreadsheet in a
    new worksheet.
    """
    include_languages = (languages or []) + (additional_languages or [])
    if len(include_languages) == 0:
        include_languages = None

    with capture_streams(stdout=output or StringIO()):
        print 'Loading translations'
        catalog = load_translation_catalog(sources_directory)

        data = catalog.get_message_dicts(include_languages)
        if filter_translated:
            data = filter(translated_languages_filterer(languages or None),
                          data)

        data.sort(key=lambda item: (item.get('package'),
                                    item.get('domain'),
                                    item.get('msgid')))

        worksheet_title = spreadsheet.upload(data)
        print 'Uploaded into worksheet "%s"' % worksheet_title
Example #3
0
def upload(spreadsheet,
           sources_directory,
           languages=None,
           additional_languages=None,
           filter_translated=True,
           output=sys.stdout):
    """Upload the translations into the configured spreadsheet in a
    new worksheet.
    """
    include_languages = (languages or []) + (additional_languages or [])
    if len(include_languages) == 0:
        include_languages = None

    with capture_streams(stdout=output or StringIO()):
        print 'Loading translations'
        catalog = load_translation_catalog(sources_directory)

        data = catalog.get_message_dicts(include_languages)
        if filter_translated:
            data = filter(translated_languages_filterer(languages or None),
                          data)

        data.sort(key=lambda item:
                  (item.get('package'), item.get('domain'), item.get('msgid')))

        worksheet_title = spreadsheet.upload(data)
        print 'Uploaded into worksheet "%s"' % worksheet_title
    def test_caches_pofiles(self):
        fshelpers.create_structure(self.tempdir, {
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po': fshelpers.asset(
                    'foo-de.po')})
        catalog = loader.load_translation_catalog(self.tempdir)
        message, = catalog.messages
        registry = writer.PofileRegistry(self.tempdir)

        self.assertIs(registry.find_pofile_for(message, 'de'),
                      registry.find_pofile_for(message, 'de'),
                      'Pofiles should be cached')
    def test_finds_pofile_paths(self):
        fshelpers.create_structure(self.tempdir, {
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po': fshelpers.asset(
                    'foo-de.po')})
        catalog = loader.load_translation_catalog(self.tempdir)
        message, = catalog.messages
        registry = writer.PofileRegistry(self.tempdir)

        expected = os.path.join(self.tempdir,
                                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')
        self.assertEquals(expected,
                          registry.find_pofile_path_for(message, 'de'))
    def test_caches_pofiles(self):
        fshelpers.create_structure(
            self.tempdir, {
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po':
                fshelpers.asset('foo-de.po')
            })
        catalog = loader.load_translation_catalog(self.tempdir)
        message, = catalog.messages
        registry = writer.PofileRegistry(self.tempdir)

        self.assertIs(registry.find_pofile_for(message, 'de'),
                      registry.find_pofile_for(message, 'de'),
                      'Pofiles should be cached')
    def test_finds_pofile_paths(self):
        fshelpers.create_structure(
            self.tempdir, {
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po':
                fshelpers.asset('foo-de.po')
            })
        catalog = loader.load_translation_catalog(self.tempdir)
        message, = catalog.messages
        registry = writer.PofileRegistry(self.tempdir)

        expected = os.path.join(self.tempdir,
                                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')
        self.assertEquals(expected,
                          registry.find_pofile_path_for(message, 'de'))
    def test_loading_package_translations(self):
        fshelpers.create_structure(self.tempdir, {
                'pyfoo/foo/locales/foo.pot': fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po': fshelpers.asset(
                    'foo-de.po')})

        catalog = loader.load_translation_catalog(self.layer[u'tempdir'])
        self.assertEquals(1, len(catalog.messages),
                          'Expected catalog to have one message')

        message, = catalog.messages
        self.assertEquals('pyfoo', message.package)
        self.assertEquals('foo', message.domain)
        self.assertEquals('Login', message.msgid)
        self.assertEquals(None, message.default)
        self.assertEquals({'de': 'Anmelden'}, message.translations)
    def test_removes_domain(self):
        # In Plone, the domain is defined through the basename of the
        # pofile. The "Domain:" header is not necessary, so we remove it.

        fshelpers.create_structure(self.tempdir, {
                'pyfoo/foo/locales/foo.pot': fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po': fshelpers.asset(
                    'foo-de.po')})

        catalog = loader.load_translation_catalog(self.tempdir)
        writer.write_catalog(self.tempdir, catalog)
        pofile = fshelpers.cat(self.tempdir,
                               'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')

        lines = pofile.split('\n')
        self.assertEquals([],
                          filter(lambda line: line.startswith('"Domain'),
                                 lines))
    def test_updating_existing_messages(self):
        fshelpers.create_structure(self.tempdir, {
                'pyfoo/foo/locales/foo.pot': fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po': fshelpers.asset(
                    'foo-de.po')})

        catalog = loader.load_translation_catalog(self.tempdir)
        message = catalog.get_message('pyfoo', 'foo', 'Login')
        message.translate('de', 'Einloggen')

        writer.write_catalog(self.tempdir, catalog)

        pofile = fshelpers.cat(self.tempdir,
                               'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')

        self.assertIn(
            '\n'.join(('msgid "Login"',
                       'msgstr "Einloggen"')),
            pofile)
Example #11
0
    def test_loading_package_translations(self):
        fshelpers.create_structure(
            self.tempdir, {
                'pyfoo/foo/locales/foo.pot':
                fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po':
                fshelpers.asset('foo-de.po')
            })

        catalog = loader.load_translation_catalog(self.layer[u'tempdir'])
        self.assertEquals(1, len(catalog.messages),
                          'Expected catalog to have one message')

        message, = catalog.messages
        self.assertEquals('pyfoo', message.package)
        self.assertEquals('foo', message.domain)
        self.assertEquals('Login', message.msgid)
        self.assertEquals(None, message.default)
        self.assertEquals({'de': 'Anmelden'}, message.translations)
    def test_updating_existing_messages(self):
        fshelpers.create_structure(
            self.tempdir, {
                'pyfoo/foo/locales/foo.pot':
                fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po':
                fshelpers.asset('foo-de.po')
            })

        catalog = loader.load_translation_catalog(self.tempdir)
        message = catalog.get_message('pyfoo', 'foo', 'Login')
        message.translate('de', 'Einloggen')

        writer.write_catalog(self.tempdir, catalog)

        pofile = fshelpers.cat(self.tempdir,
                               'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')

        self.assertIn('\n'.join(('msgid "Login"', 'msgstr "Einloggen"')),
                      pofile)
    def test_removes_domain(self):
        # In Plone, the domain is defined through the basename of the
        # pofile. The "Domain:" header is not necessary, so we remove it.

        fshelpers.create_structure(
            self.tempdir, {
                'pyfoo/foo/locales/foo.pot':
                fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po':
                fshelpers.asset('foo-de.po')
            })

        catalog = loader.load_translation_catalog(self.tempdir)
        writer.write_catalog(self.tempdir, catalog)
        pofile = fshelpers.cat(self.tempdir,
                               'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')

        lines = pofile.split('\n')
        self.assertEquals([],
                          filter(lambda line: line.startswith('"Domain'),
                                 lines))
    def test_removes_language_code_and_name(self):
        # In Plone, the language is defined through the location of the
        # pofile, e.g. it is obvious that locales/de/LC_MESSAGES/foo.po is
        # a German translation.
        # We therefore do not include the language-code and language-name
        # headers in the po file and remove them when i18ndude adds them,
        # so that they are no longer wrong..

        fshelpers.create_structure(self.tempdir, {
                'pyfoo/foo/locales/foo.pot': fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po': fshelpers.asset(
                    'foo-de.po')})

        catalog = loader.load_translation_catalog(self.tempdir)
        writer.write_catalog(self.tempdir, catalog)
        pofile = fshelpers.cat(self.tempdir,
                               'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')

        lines = pofile.split('\n')
        self.assertEquals(['"Language-Team: LANGUAGE <*****@*****.**>\\n"'],
                          filter(lambda line: line.startswith('"Lang'),
                                 lines))
    def test_removes_language_code_and_name(self):
        # In Plone, the language is defined through the location of the
        # pofile, e.g. it is obvious that locales/de/LC_MESSAGES/foo.po is
        # a German translation.
        # We therefore do not include the language-code and language-name
        # headers in the po file and remove them when i18ndude adds them,
        # so that they are no longer wrong..

        fshelpers.create_structure(
            self.tempdir, {
                'pyfoo/foo/locales/foo.pot':
                fshelpers.asset('foo.pot'),
                'pyfoo/foo/locales/de/LC_MESSAGES/foo.po':
                fshelpers.asset('foo-de.po')
            })

        catalog = loader.load_translation_catalog(self.tempdir)
        writer.write_catalog(self.tempdir, catalog)
        pofile = fshelpers.cat(self.tempdir,
                               'pyfoo/foo/locales/de/LC_MESSAGES/foo.po')

        lines = pofile.split('\n')
        self.assertEquals(['"Language-Team: LANGUAGE <*****@*****.**>\\n"'],
                          filter(lambda line: line.startswith('"Lang'), lines))