Example #1
0
def status(config):
    """
    Status is a simple task that displays the existing project configuration in a more human readable format.
    It lists all resources that have been initialized under the local project and all their associated translation
    files.
    """
    assert config
    client = POEditorAPI(api_token=_get_api_token(config))
    sections = config.sections()

    print("Api key: {}".format(config.get("main", "apikey")))

    for s in sections:
        if s.startswith("project."):
            project_id = config.get(s, "project_id")
            details = client.view_project_details(project_id)
            terms = config.get(s, 'terms', None) if config.has_option(
                s, 'terms') else None
            options = config.options(s)

            print("\nProject: {0} ({1})".format(details['name'],
                                                details['id']))
            print("Terms: {0}".format(terms))

            for option in options:
                if option.startswith("trans."):
                    import_path = config.get(s, option)
                    language = option.split('.', 1)[-1]
                    print(" - Language {0}: {1}".format(language, import_path))
Example #2
0
def run():
    api_key = configuration.get("poeditor_api_key")
    if api_key is None:
        print("Missing poeditor.com API key")
        return
    client = POEditorAPI(api_token=api_key)
    languages = client.list_project_languages("162959")
    # pull down translations
    for locale in languages:
        print("Found translation for {code}: {percent}%".format(code=locale['code'], percent=locale['percentage']))
        if locale['percentage'] > 0:
            path = os.path.join('decksite', 'translations', locale['code'].replace('-', '_'), 'LC_MESSAGES')
            if not os.path.exists(path):
                os.makedirs(path)
            pofile = os.path.join(path, 'messages.po')
            print('Saving to {0}'.format(pofile))
            if os.path.exists(pofile):
                os.remove(pofile)
            client.export("162959", locale['code'], local_file=pofile)
    # Compile .po files into .mo files
    compiler = compile_catalog()
    compiler.directory = os.path.join('decksite', 'translations')
    compiler.domain = ['messages']
    compiler.run()
    # hack for English - We need an empty folder so that Enlish shows up in the 'Known Languages' list.
    path = os.path.join('decksite', 'translations', 'en', 'LC_MESSAGES')
    if not os.path.exists(path):
        os.makedirs(path)
def run() -> None:
    api_key = configuration.get('poeditor_api_key')
    if api_key is None:
        logger.warning('Missing poeditor.com API key')
        return
    client = POEditorAPI(api_token=api_key)
    languages = client.list_project_languages('162959')
    # pull down translations
    for locale in languages:
        logger.warning('Found translation for {code}: {percent}%'.format(code=locale['code'], percent=locale['percentage']))
        if locale['percentage'] > 0:
            path = os.path.join('shared_web', 'translations', locale['code'].replace('-', '_'), 'LC_MESSAGES')
            if not os.path.exists(path):
                os.makedirs(path)
            pofile = os.path.join(path, 'messages.po')
            logger.warning('Saving to {0}'.format(pofile))
            if os.path.exists(pofile):
                os.remove(pofile)
            client.export(project_id='162959', language_code=locale['code'],
                          local_file=pofile, filters=['translated', 'not_fuzzy'])

    # Compile .po files into .mo files
    validate_translations.ad_hoc()
    compiler = compile_catalog()
    compiler.directory = os.path.join('shared_web', 'translations')
    compiler.domain = ['messages']
    compiler.run()
    # hack for English - We need an empty folder so that Enlish shows up in the 'Known Languages' list.
    path = os.path.join('shared_web', 'translations', 'en', 'LC_MESSAGES')
    if not os.path.exists(path):
        os.makedirs(path)
Example #4
0
def pull(config, languages=None):
    """
    Pulls translations from the POEditor API.
    """
    assert config
    client = POEditorAPI(api_token=_get_api_token(config))
    sections = config.sections()

    for s in sections:
        if s.startswith("project."):
            print("\nProject: {}".format(s))
            project_id = config.get(s, "project_id")
            file_type = config.get(s, "type")
            options = config.options(s)

            for o in options:
                if o.startswith("trans."):
                    language = o[6:]
                    if languages and language not in languages:
                        continue

                    export_path = config.get(s, o)
                    parent_dir = os.path.dirname(export_path)
                    if not os.path.exists(parent_dir):
                        os.makedirs(parent_dir)

                    print("Language: {}".format(language))
                    client.export(project_id,
                                  language_code=language,
                                  file_type=file_type,
                                  local_file=export_path)
def ad_hoc() -> int:
    dist = Distribution(dict(
        name='Penny-Dreadful-Tools'
    ))
    dist.message_extractors = { # type: ignore
        'decksite': [
            ('**.py', 'python', {}),
            ('**.mustache', extract_mustache, {})
        ],
        'logsite': [
            ('**.py', 'python', {}),
            ('**.mustache', extract_mustache, {})
        ]
    }
    compiler = frontend.extract_messages(dist)
    compiler.initialize_options()
    compiler.output_file = './shared_web/translations/messages.pot'
    compiler.input_paths = ['decksite', 'logsite']
    compiler.finalize_options()
    compiler.run()

    api_key = configuration.get('poeditor_api_key')
    if api_key is None:
        return exitcode()
    client = POEditorAPI(api_token=api_key)
    client.update_terms('162959', './shared_web/translations/messages.pot')
    return exitcode()
Example #6
0
    def tearDown(self):
        if hasattr(self, 'new_project_id'):
            client = POEditorAPI(api_token=self.API_TOKEN)
            logger.info("Deleting test project project_id={}. ".format(
                self.new_project_id))
            client.delete_project(self.new_project_id)

        if hasattr(self, 'file_path'):
            try:
                logger.info("Removing temp test file file_path={}. ".format(
                    self.file_path))
                os.remove(self.file_path)
            except:
                pass
def ad_hoc():
    dist = Distribution(dict(name='Penny-Dreadful-Tools'))
    dist.message_extractors = {
        'decksite': [('**.py', 'python', {}),
                     ('**.mustache', extract_mustache, {})]
    }
    compiler = frontend.extract_messages(dist)
    compiler.initialize_options()
    compiler.output_file = './decksite/translations/messages.pot'
    compiler.input_paths = 'decksite'
    compiler.finalize_options()
    compiler.run()

    api_key = configuration.get("poeditor_api_key")
    if api_key is None:
        return
    client = POEditorAPI(api_token=api_key)
    client.update_terms("162959", './decksite/translations/messages.pot')
Example #8
0
def pushTerms(config, sync_terms=False):
    """
    Pushes new terms to POEditor
    """
    assert config
    client = POEditorAPI(api_token=_get_api_token(config))
    sections = config.sections()

    for s in sections:
        if s.startswith("project."):
            terms = config.get(s, 'terms') if config.has_option(
                s, 'terms') else None
            if terms:
                project_id = config.get(s, "project_id")
                print(" - Project: {0}, {1}\n".format(s, terms))
                client.update_terms(project_id, terms, sync_terms=sync_terms)
                # Avoids API rate limit: https://poeditor.com/docs/error_codes#code-4048
                sleep(32)
Example #9
0
    def test_authentication(self):
        # bad token
        client = POEditorAPI(api_token="BAD_TOKEN")

        with self.assertRaises(POEditorException) as context:
            client.list_projects()
        self.assertEqual(context.exception.message,
                         "Status 'fail', code 4011: Invalid API Token")

        # good token
        client = POEditorAPI(api_token=self.API_TOKEN)
        client.list_projects()
Example #10
0
    def test_authentication(self):
        # bad token
        client = POEditorAPI(api_token="1e72d3ae2c67a2160a7e87979ae9c98d")

        with self.assertRaises(POEditorException) as context:
            client.list_projects()
        self.assertEqual(context.exception.message,
                         u"Status 'fail', code 4011: Invalid API Key")

        # good token
        client = POEditorAPI(api_token=self.API_TOKEN)
        client.list_projects()
Example #11
0
    def tearDown(self):
        if hasattr(self, 'new_project_id'):
            client = POEditorAPI(api_token=self.API_TOKEN)
            logger.info(
                "Deleting test project project_id={}. ".format(
                    self.new_project_id
                )
            )
            client.delete_project(self.new_project_id)

        if hasattr(self, 'file_path'):
            try:
                logger.info(
                    "Removing temp test file file_path={}. ".format(
                        self.file_path
                    )
                )
                os.remove(self.file_path)
            except:
                pass
Example #12
0
def push(config, languages=None, overwrite=False, sync_terms=False):
    """
    Push terms and languages
    """
    assert config
    client = POEditorAPI(api_token=_get_api_token(config))
    sections = config.sections()

    for section in sections:
        if not section.startswith("project."):
            continue

        print("Project: {}".format(section))
        project_id = config.get(section, "project_id")
        options = config.options(section)

        for option in options:
            if option.startswith("trans."):
                import_path = config.get(section, option)
                language = option.split('.', 1)[-1]
                if languages and language not in languages:
                    continue

                if not os.path.exists(import_path):
                    print(
                        "Error: {path} doesn't exist: ignoring language '{language}'"
                        .format(path=import_path, language=language))
                    continue

                print("    Pushing language '{}'...".format(language))
                client.update_terms_definitions(project_id,
                                                language_code=language,
                                                file_path=import_path,
                                                overwrite=overwrite,
                                                sync_terms=sync_terms)
                # Avoids API rate limit: https://poeditor.com/docs/error_codes#code-4048
                sleep(32)
Example #13
0
    def test_authentication(self):
        # bad token
        client = POEditorAPI(api_token="1e72d3ae2c67a2160a7e87979ae9c98d")

        with self.assertRaises(POEditorException) as context:
            client.list_projects()
        self.assertEqual(
            context.exception.message,
            u"Status 'fail', code 4011: Invalid API Key"
        )

        # good token
        client = POEditorAPI(api_token=self.API_TOKEN)
        client.list_projects()
Example #14
0
    def test_authentication(self):
        # bad token
        client = POEditorAPI(api_token="BAD_TOKEN")

        with self.assertRaises(POEditorException) as context:
            client.list_projects()
        self.assertEqual(
            context.exception.message,
            "Status 'fail', code 4011: Invalid API Token"
        )

        # good token
        client = POEditorAPI(api_token=self.API_TOKEN)
        client.list_projects()
Example #15
0
def init(config):
    """
    Initializes the project on POEditor based on the configuration file.
    """
    assert config
    client = POEditorAPI(api_token=_get_api_token(config))
    sections = config.sections()

    for s in sections:
        if s.startswith("project."):
            print(" - Project: {}".format(s))
            project_id = config.get(s, "project_id")

            # 1. Push terms
            terms = config.get(s, 'terms') if config.has_option(
                s, 'terms') else None
            if terms:
                project_id = config.get(s, "project_id")
                print(" - Terms: {0}".format(terms))
                client.update_terms(project_id, terms)

            # 2. Create/add languages
            options = config.options(s)
            for o in options:
                if o.startswith("trans."):
                    lang = o[6:]

                    try:
                        client.add_language_to_project(project_id, lang)
                    except POEditorException:
                        pass

                    client.update_definitions(project_id=project_id,
                                              file_path=config.get(s, o),
                                              language_code=lang,
                                              overwrite=True)
                    print(" - Language added: {}".format(lang))
Example #16
0
    def test_scenario(self):

        client = POEditorAPI(api_token=self.API_TOKEN)

        # Project:
        projects = client.list_projects()
        self.assertTrue(isinstance(projects, list))

        self.new_project_id = client.create_project(
            name='test project',
            description='Created by test_scenario method'
        )

        project_details = client.view_project_details(
            self.new_project_id
        )
        self.assertEqual(project_details['name'], "test project")
        self.assertEqual(project_details['id'], self.new_project_id)
        self.assertEqual(project_details['open'], False)
        self.assertEqual(project_details['public'], False)

        project_languages = client.list_project_languages(
            self.new_project_id
        )
        self.assertEqual(project_languages, [])

        result = client.add_language_to_project(
            project_id=self.new_project_id,
            language_code='fr'
        )
        self.assertTrue(result)

        result = client.add_language_to_project(
            project_id=self.new_project_id,
            language_code='de'
        )
        self.assertTrue(result)

        result = client.delete_language_from_project(
            project_id=self.new_project_id,
            language_code='de'
        )
        self.assertTrue(result)

        project_languages = client.list_project_languages(
            self.new_project_id
        )
        self.assertEqual(len(project_languages), 1)
        project_language_fr = project_languages[0]
        self.assertEqual(project_language_fr['percentage'], 0)
        self.assertEqual(project_language_fr['code'], 'fr')
        self.assertEqual(project_language_fr['name'], 'French')

        result = client.set_reference_language(
            project_id=self.new_project_id,
            language_code='fr'
        )
        self.assertTrue(result)

        result = client.clear_reference_language(
            project_id=self.new_project_id
        )
        self.assertTrue(result)

        # Plays with terms:
        terms = client.view_project_terms(
            project_id=self.new_project_id,
            language_code='fr'
        )
        self.assertEqual(terms, [])

        details = client.add_terms(
            project_id=self.new_project_id,
            data=[
                {
                    "term": "Welcome to my new website",
                    "context": "",
                    "reference": "Homepage title",
                    "plural": ""
                },
                {
                    "term": "There is 1 student in the band",
                    "context": "",
                    "reference": "Band count",
                    "plural": "there are {count} students in the band"
                },
            ]
        )
        self.assertEqual(details['parsed'], 2)
        self.assertEqual(details['added'], 2)

        details = client.delete_terms(
            project_id=self.new_project_id,
            data=[
                {
                    "term": "There is 1 student in the band",
                    "context": ""
                }
            ]
        )
        self.assertEqual(details['parsed'], 1)
        self.assertEqual(details['deleted'], 1)

        details = client.sync_terms(
            project_id=self.new_project_id,
            data=[
                {
                    "term": "Welcome to my new website",
                    "context": "",
                    "reference": "Homepage title",
                    "plural": ""
                },
                {
                    "term": "New term",
                    "context": "",
                    "reference": "",
                    "plural": "",
                    "tags": [
                        "first_tag",
                        "second_tag"
                    ]
                },
            ]
        )
        self.assertEqual(details['parsed'], 2)
        self.assertEqual(details['added'], 1)
        self.assertEqual(details['updated'], 0)
        self.assertEqual(details['deleted'], 0)

        # Plays with translations
        details = client.update_project_language(
            project_id=self.new_project_id,
            language_code='fr',
            data=[
                {
                    "term": "Welcome to my new website",
                    "context": "",
                    "translation": {
                        "content": "Bienvenue sur mon site",
                        "fuzzy": 1
                    }
                }
            ]
        )
        self.assertEqual(details['parsed'], 1)
        self.assertEqual(details['added'], 1)
        self.assertEqual(details['updated'], 0)

        # Export
        file_url, self.file_path = client.export(
            project_id=self.new_project_id,
            language_code='fr',
            file_type='po'
        )

        self.assertTrue(
            file_url.startswith('https://api.poeditor.com/v2/download/file/'))
        self.assertTrue(os.path.isfile(self.file_path))
        with open(self.file_path, 'r') as file_read:
            data = file_read.read()
        self.assertIn('Welcome to my new website', data)
        self.assertIn('Bienvenue sur mon site', data)

        # Export with filters
        with self.assertRaises(POEditorArgsException) as context:
            client.export(
                project_id=self.new_project_id,
                language_code='fr',
                file_type='po',
                filters=["translated", "maybe_fuzzy"]
            )
        self.assertIn("filters - filter results by", context.exception.message)

        file_url, not_fuzzy_path = client.export(
            project_id=self.new_project_id,
            language_code='fr',
            file_type='po',
            filters=["translated", "not_fuzzy"]
        )

        with open(not_fuzzy_path, 'r') as file_read:
            data = file_read.read()
        self.assertNotIn('Welcome to my new website', data)
        self.assertNotIn('Bienvenue sur mon site', data)

        # Import
        # Just a quick update before:
        with open(self.file_path, "r") as sources:
            lines = sources.readlines()
        with open(self.file_path, "w") as sources:
            for line in lines:
                sources.write(
                    re.sub(r'^msgstr "Bienvenue sur mon site"', 'msgstr "Bienvenue!"', line)
                )

        details = client.update_terms_translations(
            project_id=self.new_project_id,
            file_path=self.file_path,
            language_code='fr',
            overwrite=True,
            sync_terms=True
        )

        expected_dict = {
            'translations': {
                'added': 0,
                'parsed': 1,
                'updated': 1
            },
            'terms': {
                'added': 0,
                'deleted': 0,
                'parsed': 2
            }
        }
        self.assertDictEqual(details, expected_dict)

        # Languages:
        languages = client.available_languages()
        self.assertTrue(isinstance(languages, list))
        self.assertIn('French', [lang['name'] for lang in languages])

        # Contributors
        contributors = client.list_contributors(
            project_id=self.new_project_id)
        self.assertEqual(contributors, [])

        result = client.add_contributor(
            project_id=self.new_project_id,
            name="Peter",
            email="*****@*****.**",
            language_code='fr'
        )
        self.assertTrue(result)

        result = client.add_administrator(
            project_id=self.new_project_id,
            name="John",
            email="*****@*****.**"
        )
        self.assertTrue(result)
Example #17
0
    def test_scenario(self):

        client = POEditorAPI(api_token=self.API_TOKEN)

        # Project:
        projects = client.list_projects()
        self.assertTrue(isinstance(projects, list))

        self.new_project_id = client.create_project(
            name='test project', description='Created by test_scenario method')

        project_details = client.view_project_details(self.new_project_id)
        self.assertEqual(project_details['name'], "test project")
        self.assertEqual(project_details['id'], self.new_project_id)
        self.assertEqual(project_details['open'], False)
        self.assertEqual(project_details['public'], False)

        project_languages = client.list_project_languages(self.new_project_id)
        self.assertEqual(project_languages, [])

        result = client.add_language_to_project(project_id=self.new_project_id,
                                                language_code='fr')
        self.assertTrue(result)

        result = client.add_language_to_project(project_id=self.new_project_id,
                                                language_code='de')
        self.assertTrue(result)

        result = client.delete_language_from_project(
            project_id=self.new_project_id, language_code='de')
        self.assertTrue(result)

        project_languages = client.list_project_languages(self.new_project_id)
        self.assertEqual(len(project_languages), 1)
        project_language_fr = project_languages[0]
        self.assertEqual(project_language_fr['percentage'], 0)
        self.assertEqual(project_language_fr['code'], 'fr')
        self.assertEqual(project_language_fr['name'], 'French')

        result = client.set_reference_language(project_id=self.new_project_id,
                                               language_code='fr')
        self.assertTrue(result)

        result = client.clear_reference_language(
            project_id=self.new_project_id)
        self.assertTrue(result)

        # Plays with terms:
        terms = client.view_project_terms(project_id=self.new_project_id,
                                          language_code='fr')
        self.assertEqual(terms, [])

        details = client.add_terms(
            project_id=self.new_project_id,
            data=[
                {
                    "term": "Welcome to my new website",
                    "context": "",
                    "reference": "Homepage title",
                    "plural": ""
                },
                {
                    "term": "There is 1 student in the band",
                    "context": "",
                    "reference": "Band count",
                    "plural": "there are {count} students in the band"
                },
            ])
        self.assertEqual(details['parsed'], 2)
        self.assertEqual(details['added'], 2)

        details = client.delete_terms(project_id=self.new_project_id,
                                      data=[{
                                          "term":
                                          "There is 1 student in the band",
                                          "context": ""
                                      }])
        self.assertEqual(details['parsed'], 1)
        self.assertEqual(details['deleted'], 1)

        details = client.sync_terms(project_id=self.new_project_id,
                                    data=[
                                        {
                                            "term":
                                            "Welcome to my new website",
                                            "context": "",
                                            "reference": "Homepage title",
                                            "plural": ""
                                        },
                                        {
                                            "term": "New term",
                                            "context": "",
                                            "reference": "",
                                            "plural": "",
                                            "tags":
                                            ["first_tag", "second_tag"]
                                        },
                                    ])
        self.assertEqual(details['parsed'], 2)
        self.assertEqual(details['added'], 1)
        self.assertEqual(details['updated'], 0)
        self.assertEqual(details['deleted'], 0)

        # Plays with translations
        details = client.update_project_language(
            project_id=self.new_project_id,
            language_code='fr',
            data=[{
                "term": "Welcome to my new website",
                "context": "",
                "translation": {
                    "content": "Bienvenue sur mon site",
                    "fuzzy": 1
                }
            }])
        self.assertEqual(details['parsed'], 1)
        self.assertEqual(details['added'], 1)
        self.assertEqual(details['updated'], 0)

        # Export
        file_url, self.file_path = client.export(
            project_id=self.new_project_id, language_code='fr', file_type='po')

        self.assertTrue(
            file_url.startswith('https://api.poeditor.com/v2/download/file/'))
        self.assertTrue(os.path.isfile(self.file_path))
        with open(self.file_path, 'r') as file_read:
            data = file_read.read()
        self.assertIn('Welcome to my new website', data)
        self.assertIn('Bienvenue sur mon site', data)

        # Export with filters
        with self.assertRaises(POEditorArgsException) as context:
            client.export(project_id=self.new_project_id,
                          language_code='fr',
                          file_type='po',
                          filters=["translated", "maybe_fuzzy"])
        self.assertIn("filters - filter results by", context.exception.message)

        file_url, not_fuzzy_path = client.export(
            project_id=self.new_project_id,
            language_code='fr',
            file_type='po',
            filters=["translated", "not_fuzzy"])

        with open(not_fuzzy_path, 'r') as file_read:
            data = file_read.read()
        self.assertNotIn('Welcome to my new website', data)
        self.assertNotIn('Bienvenue sur mon site', data)

        # Import
        # Just a quick update before:
        with open(self.file_path, "r") as sources:
            lines = sources.readlines()
        with open(self.file_path, "w") as sources:
            for line in lines:
                sources.write(
                    re.sub(r'^msgstr "Bienvenue sur mon site"',
                           'msgstr "Bienvenue!"', line))

        details = client.update_terms_translations(
            project_id=self.new_project_id,
            file_path=self.file_path,
            language_code='fr',
            overwrite=True,
            sync_terms=True)

        expected_dict = {
            'translations': {
                'added': 0,
                'parsed': 1,
                'updated': 1
            },
            'terms': {
                'added': 0,
                'deleted': 0,
                'parsed': 2
            }
        }
        self.assertDictEqual(details, expected_dict)

        # Languages:
        languages = client.available_languages()
        self.assertTrue(isinstance(languages, list))
        self.assertIn('French', [lang['name'] for lang in languages])

        # Contributors
        contributors = client.list_contributors(project_id=self.new_project_id)
        self.assertEqual(contributors, [])

        result = client.add_contributor(project_id=self.new_project_id,
                                        name="Peter",
                                        email="*****@*****.**",
                                        language_code='fr')
        self.assertTrue(result)

        result = client.add_administrator(project_id=self.new_project_id,
                                          name="John",
                                          email="*****@*****.**")
        self.assertTrue(result)