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))
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)
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()
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')
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)
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()
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()
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 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)
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()
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()
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))
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)
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)