def handle(self, *args, **options): if args: # mimics puente.management.commands.extract for a list of files outputdir = os.path.join(settings.ROOT, 'locale', 'templates', 'LC_MESSAGES') if not os.path.isdir(outputdir): os.makedirs(outputdir) catalog = Catalog( header_comment='', project=get_setting('PROJECT'), version=get_setting('VERSION'), msgid_bugs_address=get_setting('MSGID_BUGS_ADDRESS'), charset='utf-8', ) for filename, lineno, msg, cmts, ctxt in extract_from_files(args): catalog.add(msg, None, [(filename, lineno)], auto_comments=cmts, context=ctxt) with open(os.path.join(outputdir, '%s.pot' % DOMAIN), 'wb') as fp: write_po(fp, catalog, width=80) else: # This is basically a wrapper around the puente extract # command, we might want to do some things around this in the # future gettext_extract() pot_to_langfiles(DOMAIN)
def test_write(): """Test writing a basic catalog. """ catalog = Catalog() catalog.add('green', context='colors:0') catalog.add('red', context='colors:1') assert po2xml(catalog) == {'colors': ['green', 'red']}
def test_no_wrap_and_width_behaviour_on_comments(self): catalog = Catalog() catalog.add("Pretty dam long message id, which must really be big " "to test this wrap behaviour, if not it won't work.", locations=[("fake.py", n) for n in range(1, 30)]) buf = BytesIO() pofile.write_po(buf, catalog, width=None, omit_header=True) self.assertEqual(b"""\ #: fake.py:1 fake.py:2 fake.py:3 fake.py:4 fake.py:5 fake.py:6 fake.py:7 #: fake.py:8 fake.py:9 fake.py:10 fake.py:11 fake.py:12 fake.py:13 fake.py:14 #: fake.py:15 fake.py:16 fake.py:17 fake.py:18 fake.py:19 fake.py:20 fake.py:21 #: fake.py:22 fake.py:23 fake.py:24 fake.py:25 fake.py:26 fake.py:27 fake.py:28 #: fake.py:29 msgid "pretty dam long message id, which must really be big to test this wrap behaviour, if not it won't work." msgstr "" """, buf.getvalue().lower()) buf = BytesIO() pofile.write_po(buf, catalog, width=100, omit_header=True) self.assertEqual(b"""\ #: fake.py:1 fake.py:2 fake.py:3 fake.py:4 fake.py:5 fake.py:6 fake.py:7 fake.py:8 fake.py:9 fake.py:10 #: fake.py:11 fake.py:12 fake.py:13 fake.py:14 fake.py:15 fake.py:16 fake.py:17 fake.py:18 fake.py:19 #: fake.py:20 fake.py:21 fake.py:22 fake.py:23 fake.py:24 fake.py:25 fake.py:26 fake.py:27 fake.py:28 #: fake.py:29 msgid "" "pretty dam long message id, which must really be big to test this wrap behaviour, if not it won't" " work." msgstr "" """, buf.getvalue().lower())
def _build(self, locale, messages, path, pathGlobal=None): ''' Builds a catalog based on the provided locale paths, the path is used as the main source any messages that are not found in path locale but are part of messages will attempt to be extracted from the global path locale. @param locale: Locale The locale. @param messages: Iterable(Message) The messages to build the PO file on. @param path: string The path of the targeted PO file from the locale repository. @param pathGlobal: string|None The path of the global PO file from the locale repository. @return: file like object File like object that contains the PO file content ''' assert isinstance(locale, Locale), 'Invalid locale %s' % locale assert isinstance(messages, Iterable), 'Invalid messages %s' % messages assert isinstance(path, str), 'Invalid path %s' % path assert pathGlobal is None or isinstance(pathGlobal, str), 'Invalid global path %s' % pathGlobal if isfile(path): with open(path) as fObj: catalog = read_po(fObj, locale) else: catalog = Catalog(locale, creation_date=datetime.now(), **self.catalog_config) if pathGlobal and isfile(pathGlobal): with open(pathGlobal) as fObj: catalogGlobal = read_po(fObj, locale) else: catalogGlobal = None self._processCatalog(catalog, messages, fallBack=catalogGlobal) catalog.revision_date = datetime.now() return catalog
def test_po_with_multiline_obsolete_message(self): catalog = Catalog() catalog.add(u'foo', u'Voh', locations=[('main.py', 1)]) msgid = r"""Here's a message that covers multiple lines, and should still be handled correctly. """ msgstr = r"""Here's a message that covers multiple lines, and should still be handled correctly. """ catalog.obsolete[msgid] = Message(msgid, msgstr, locations=[('utils.py', 3)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True) self.assertEqual(b'''#: main.py:1 msgid "foo" msgstr "Voh" #~ msgid "" #~ "Here's a message that covers\\n" #~ "multiple lines, and should still be handled\\n" #~ "correctly.\\n" #~ msgstr "" #~ "Here's a message that covers\\n" #~ "multiple lines, and should still be handled\\n" #~ "correctly.\\n"''', buf.getvalue().strip())
def test_write_incomplete_plural(): """Test behaviour with incompletely translated plurals in .po.""" catalog = Catalog() catalog.language = Language('bs') # Bosnian catalog.add(('foo', 'foos'), ('one', '', 'many', ''), context='foo') assert po2xml(catalog) == {'foo': { 'few': '', 'many': 'many', 'other': '', 'one': 'one'}}
def run(self): mappings = self._get_mappings() with open(self.output_file, 'wb') as outfile: catalog = Catalog(project=self.project, version=self.version, msgid_bugs_address=self.msgid_bugs_address, copyright_holder=self.copyright_holder, charset=self.charset) for path, method_map, options_map in mappings: def callback(filename, method, options): if method == 'ignore': return # If we explicitly provide a full filepath, just use that. # Otherwise, path will be the directory path and filename # is the relative path from that dir to the file. # So we can join those to get the full filepath. if os.path.isfile(path): filepath = path else: filepath = os.path.normpath(os.path.join(path, filename)) optstr = '' if options: optstr = ' (%s)' % ', '.join(['%s="%s"' % (k, v) for k, v in options.items()]) self.log.info('extracting messages from %s%s', filepath, optstr) if os.path.isfile(path): current_dir = os.getcwd() extracted = check_and_call_extract_file( path, method_map, options_map, callback, self.keywords, self.add_comments, self.strip_comments, current_dir ) else: extracted = extract_from_dir( path, method_map, options_map, keywords=self.keywords, comment_tags=self.add_comments, callback=callback, strip_comment_tags=self.strip_comments ) for fname, lineno, msg, comments, context, flags in extracted: if os.path.isfile(path): filepath = fname # already normalized else: filepath = os.path.normpath(os.path.join(path, fname)) catalog.add(msg, None, [(filepath, lineno)], flags=flags, auto_comments=comments, context=context) self.log.info('writing PO template file to %s', self.output_file) write_po(outfile, catalog, width=self.width, no_location=self.no_location, omit_header=self.omit_header, sort_output=self.sort_output, sort_by_file=self.sort_by_file, include_lineno=self.include_lineno)
def test_write_missing_translations(): """[Regression] Specifically test that arrays are not written to the XML in an incomplete fashion if parts of the array are not translated. """ catalog = Catalog() catalog.add('green', context='colors:0') # does not have a translation catalog.add('red', 'rot', context='colors:1') assert po2xml(catalog) == {'colors': ['green', 'rot']}
def test_write(): """Test writing a basic catalog. """ catalog = Catalog() catalog.add('green', context='colors:0') catalog.add('red', context='colors:1') assert etree.tostring(po2xml(catalog, with_untranslated=True)) == \ '<resources><string-array name="colors"><item>green</item><item>red</item></string-array></resources>'
def test_write_po_file_with_specified_charset(self): catalog = Catalog(charset='iso-8859-1') catalog.add('foo', u'äöü', locations=[('main.py', 1)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=False) po_file = buf.getvalue().strip() assert b'"Content-Type: text/plain; charset=iso-8859-1\\n"' in po_file assert u'msgstr "äöü"'.encode('iso-8859-1') in po_file
def test_write_po_file_with_specified_charset(self): catalog = Catalog(charset="iso-8859-1") catalog.add("foo", "\xe4\xf6\xfc", locations=[("main.py", 1)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=False) po_file = buf.getvalue().strip() assert br'"Content-Type: text/plain; charset=iso-8859-1\n"' in po_file assert 'msgstr "\xe4\xf6\xfc"'.encode("iso-8859-1") in po_file
def test_file_sorted_po(self): catalog = Catalog() catalog.add(u'bar', locations=[('utils.py', 3)]) catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'), locations=[('main.py', 1)]) buf = BytesIO() pofile.write_po(buf, catalog, sort_by_file=True) value = buf.getvalue().strip() assert value.find(b'main.py') < value.find(b'utils.py')
def test_duplicate_comments(self): catalog = Catalog() catalog.add(u'foo', auto_comments=['A comment']) catalog.add(u'foo', auto_comments=['A comment']) buf = StringIO() pofile.write_po(buf, catalog, omit_header=True) self.assertEqual('''#. A comment msgid "foo" msgstr ""''', buf.getvalue().strip())
def test_no_include_lineno(self): catalog = Catalog() catalog.add(u'foo', locations=[('main.py', 1)]) catalog.add(u'foo', locations=[('utils.py', 3)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True, include_lineno=False) self.assertEqual(b'''#: main.py utils.py msgid "foo" msgstr ""''', buf.getvalue().strip())
def test_write_po_file_with_specified_charset(self): catalog = Catalog(charset='iso-8859-1') catalog.add('foo', u('\xe4\xf6\xfc'), locations=[('main.py', 1)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=False) po_file = buf.getvalue().strip() assert b( r'"Content-Type: text/plain; charset=iso-8859-1\n"') in po_file assert u('msgstr "\xe4\xf6\xfc"').encode('iso-8859-1') in po_file
def test_duplicate_comments(self): catalog = Catalog() catalog.add(u'foo', auto_comments=['A comment']) catalog.add(u'foo', auto_comments=['A comment']) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True) self.assertEqual(b'''#. A comment msgid "foo" msgstr ""''', buf.getvalue().strip())
def test_join_locations(self): catalog = Catalog() catalog.add(u'foo', locations=[('main.py', 1)]) catalog.add(u'foo', locations=[('utils.py', 3)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True) self.assertEqual(b'''#: main.py:1 utils.py:3 msgid "foo" msgstr ""''', buf.getvalue().strip())
def test_write(): """Test writing a basic catalog. """ catalog = Catalog() catalog.add("green", context="colors:0") catalog.add("red", context="colors:1") assert ( etree.tostring(po2xml(catalog, with_untranslated=True)) == '<resources><string-array name="colors"><item>green</item><item>red</item></string-array></resources>' )
def test_write(): """Test a basic po2xml() call. (what the import command does). """ catalog = Catalog() catalog.language = Language('bs') # Bosnian catalog.add(('foo', 'foos'), ('few', 'many', 'one', 'other'), context='foo') assert po2xml(catalog) == {'foo': { 'few': 'few', 'many': 'many', 'one': 'one', 'other': 'other'}}
def test_copy_catalog_replaces_messages(self): old_catalog = Catalog() old_catalog.add("id", string="Text1") # Copy catalog new_catalog = copy_catalog(old_catalog) # And then change strings in the old catalog for message in old_catalog: message.string = "Text2" # Copy should be unaffected self.assertEqual(new_catalog.get("id").string, "Text1")
def test_po_with_previous_msgid(self): catalog = Catalog() catalog.add(u'foo', u'Voh', locations=[('main.py', 1)], previous_id=u'fo') buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True, include_previous=True) self.assertEqual(b'''#: main.py:1 #| msgid "fo" msgid "foo" msgstr "Voh"''', buf.getvalue().strip())
def test_message_invalid_parameter_syntax(self): catalog = Catalog() catalog.add("id", string="Hey {a b}!") with self.assertRaises(ICUError): result = MessageTranslator( "en", catalog).get_and_format_html_message("id", arguments={ "a": "you", "b": "!" })
def extract_and_update_locale_dir(dirname, mapping): locale_dir = os.path.join(dirname, 'locale') for domain in ('django', 'djangojs'): extracted_catalog = Catalog() extracted = extract_from_dir( dirname=dirname, method_map=mapping[domain]['method_map'], options_map=mapping[domain]['options_map'] ) for filename, lineno, message, comments, context in extracted: extracted_catalog.add(message, None, [(filename, lineno)], auto_comments=comments, context=context) for locale, language in settings.LANGUAGES: po_path = os.path.join(locale_dir, locale, 'LC_MESSAGES', '%s.po' % domain) if os.path.exists(po_path): with open(po_path, 'rb') as po_fileobj: catalog = read_po(po_fileobj, locale=locale, domain=domain) if catalog._messages != extracted_catalog._messages: catalog.update(extracted_catalog, no_fuzzy_matching=True, update_header_comment=False) with open(po_path, 'wb') as po_fileobj: write_po(po_fileobj, catalog, ignore_obsolete=True) elif extracted_catalog._messages: extracted_catalog.locale = Locale(locale) extracted_catalog.domain = domain extracted_catalog.project = 'Mesto.UA' extracted_catalog.copyright_holder = 'Mesto.UA' extracted_catalog.fuzzy = False touch_directory(po_path) with open(po_path, 'wb') as po_fileobj: write_po(po_fileobj, extracted_catalog)
def create_i18n_files(lang, quiet=True): sql = """ SELECT * FROM translation WHERE lang = ? and active=1; """ result = conn.execute(sql, lang) catalog = Catalog(locale=lang) for row in result: if row.plural: key = (row.id, row.plural) values = [ row.trans1, row.trans2, row.trans3, row.trans4, ] value = [] for v in values: if v: value.append(v) if len(value) == 1: value = value[0] else: value = tuple(value) else: key = row.id value = row.trans1 catalog.add(key, value) path = os.path.join(DIR, 'translations', lang, 'LC_MESSAGES') try: os.makedirs(path) except OSError: pass outfile = open(os.path.join(path, 'messages.po'), 'wb') try: if not quiet: print 'writing PO for', lang write_po(outfile, catalog) finally: outfile.close() outfile = open(os.path.join(path, 'messages.mo'), 'wb') try: if not quiet: print 'writing MO for', lang write_mo(outfile, catalog) finally: outfile.close()
def _update_piglatin(): from babel.messages.pofile import read_po, write_po from babel.messages.catalog import Catalog with open('app/messages.pot', 'r') as f: template = read_po(f) catalog = Catalog() for message in template: trans = ' '.join([_piglatin_translate(w) for w in message.id.split(' ')]) catalog.add(message.id, trans, locations=message.locations) with open('app/translations/aa/LC_MESSAGES/messages.po', 'w') as f: write_po(f, catalog)
def test_write_skipped_ids(): """Test that arrays were ids are missing are written properly out as well. """ # TODO: Indices missing at the end of the array will not be noticed, # because we are not aware of the arrays full length. # TODO: If we where smart enough to look in the original resource XML, # we could fill in missing array strings with the untranslated value. catalog = Catalog() catalog.add('red', context='colors:3') catalog.add('green', context='colors:1') assert po2xml(catalog) == {'colors': [None, 'green', None, 'red']}
def test_gettext_disallow_fuzzy_translations(app): locale_dir = app.srcdir / 'locales' / 'de' / 'LC_MESSAGES' locale_dir.makedirs() with (locale_dir / 'index.po').open('wb') as f: catalog = Catalog() catalog.add('features', 'FEATURES', flags=('fuzzy',)) pofile.write_po(f, catalog) app.build() content = (app.outdir / 'index.html').read_text() assert 'FEATURES' not in content
def test_write_incomplete_plural(): """Test behaviour with incompletely translated plurals in .po.""" catalog = Catalog() catalog.language = Language('bs') # Bosnian catalog.add(('foo', 'foos'), ('one', '', ''), context='foo') assert_equal(po2xml(catalog), {'foo': { 'few': '', 'one': 'one', 'other': '' }})
def test_no_html_escape(self): catalog = Catalog() catalog.add( "id", string= 'Hello <a href="/you?a=n&b=e">you > {param_b}</a> my & friend') self.assertEqual( MessageTranslator("en", catalog).get_and_format_message( "id", arguments={"param_b": "> there"}), 'Hello <a href="/you?a=n&b=e">you > > there</a> my & friend', )
def test_find_corresponding_message_with_context_exists(self): catalog = Catalog() catalog.add("id", string="Text", context="ctxt") corresponding = find_corresponding_message( catalog, Message("id", context="ctxt")) self.assertTrue(corresponding) assert_messages_deeply_equal(corresponding, catalog.get("id", context="ctxt")) self.assertEqual( find_corresponding_string(catalog, Message("id", context="ctxt")), "Text")
def test_po_with_obsolete_message_ignored(self): catalog = Catalog() catalog.add(u'foo', u'Voh', locations=[('main.py', 1)]) catalog.obsolete['bar'] = Message(u'bar', u'Bahr', locations=[('utils.py', 3)], user_comments=['User comment']) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True, ignore_obsolete=True) self.assertEqual(b'''#: main.py:1 msgid "foo" msgstr "Voh"''', buf.getvalue().strip())
def _update_english(): from babel.messages.pofile import read_po, write_po from babel.messages.catalog import Catalog with open('app/messages.pot', 'r') as f: template = read_po(f) catalog = Catalog() for message in template: catalog.add(message.id, message.id, locations=message.locations) with open('app/translations/en/LC_MESSAGES/messages.po', 'w') as f: write_po(f, catalog) with open('app/translations/en_US/LC_MESSAGES/messages.po', 'w') as f: write_po(f, catalog)
def test_message_different_arguments(self): catalog = Catalog() catalog.add("id", string="Hey {a} {0} {c}") self.assertEqual( MessageTranslator("en", catalog).get_and_format_message("id", arguments={ "a": "you", "b": "!" }), "Hey you {0} {c}", )
def test_write_order(): """Test that when writing a catalog with string-arrays, order is maintained; both of the string-array tag in the list of all strings, as well as the array strings themselves. """ catalog = Catalog() catalog.add('foo', context='before') catalog.add('red', context='colors:1') catalog.add('green', context='colors:0') catalog.add('bar', context='after') assert etree.tostring(po2xml(catalog, with_untranslated=True)) == \ '<resources><string name="before">foo</string><string-array name="colors"><item>green</item><item>red</item></string-array><string name="after">bar</string></resources>'
def test_add_or_update_add_message_add_with_context(self): target_catalog = Catalog() target_catalog.add("id1", string="Text1") add_or_update_message(target_catalog, Message("id2", string="Text2", context="ctxt2")) expected_catalog = Catalog() expected_catalog.add("id1", string="Text1") expected_catalog.add("id2", string="Text2", context="ctxt2") assert_catalogs_deeply_equal(target_catalog, expected_catalog)
def test_po_with_obsolete_message_ignored(self): catalog = Catalog() catalog.add("foo", "Voh", locations=[("main.py", 1)]) catalog.obsolete["bar"] = Message("bar", "Bahr", locations=[("utils.py", 3)], user_comments=["User comment"]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True, ignore_obsolete=True) self.assertEqual( b'''#: main.py:1 msgid "foo" msgstr "Voh"''', buf.getvalue().strip(), )
def test_write_ignore_untranslated_plural(): """An untranslated plural is not included in the XML. """ catalog = Catalog() catalog.language = Language('en') catalog.add(('foo', 'foos'), context='foo') assert po2xml(catalog) == {} # Even with ``with_untranslated``, we still do not include # empty plural (they would just block access to the untranslated # master version, which we cannot copy into the target). assert po2xml(catalog) == {}
def test_write_skipped_ids(): """Test that catalogs were ids are missing are written properly out as well. """ # TODO: We currently simply maintain order, but shouldn't we instead # write out missing ids as empty strings? If the source file says # colors:9, that likely means the dev. expects 8 strings before it. catalog = Catalog() catalog.add('red', context='colors:9') catalog.add('green', context='colors:4') assert etree.tostring(po2xml(catalog, with_untranslated=True)) == \ '<resources><string-array name="colors"><item>green</item><item>red</item></string-array></resources>'
def init_catalog(self, language): """ initialize a new catalog, only one catalog is managed at a time """ print('initializing catalog with language {}...'.format(language)) self.language = language self.catalog = Catalog( project=self.config.get('name', 'PROJECT NAME'), version=self.config.get('version', 'PROJECT VERSION'), copyright_holder=self.config.get('copyright_holder', ''), language_team=self.config.get('author', ''), )
def test_trans_params(self): catalog = Catalog() catalog.add("id", string="Hey {a} {param_b} {c}!") self.assertEqual( MessageTranslator("en", catalog).get_and_format_html_message( "id", arguments={ "param_b": "there", "a": "you", "d": "tester" }), "Hey you there {c}!", )
def fake_extract_command(filename, fileobj, method, options=generate_options_map(), keywords=get_setting('KEYWORDS'), comment_tags=get_setting('COMMENT_TAGS')): catalog = Catalog(charset='utf-8') extracted = fake_extract_from_dir(filename, fileobj, method, options, keywords, comment_tags) for filename, lineno, msg, cmts, ctxt in extracted: catalog.add(msg, None, [(filename, lineno)], auto_comments=cmts, context=ctxt) po_out = StringIO() write_po(po_out, catalog, width=80, omit_header=True) return unicode(po_out.getvalue())
def test_po_with_previous_msgid_plural(self): catalog = Catalog() catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'), locations=[('main.py', 1)], previous_id=(u'fo', u'fos')) buf = StringIO() pofile.write_po(buf, catalog, omit_header=True, include_previous=True) self.assertEqual('''#: main.py:1 #| msgid "fo" #| msgid_plural "fos" msgid "foo" msgid_plural "foos" msgstr[0] "Voh" msgstr[1] "Voeh"''', buf.getvalue().strip())
def test_wrap_locations_with_hyphens(self): catalog = Catalog() catalog.add("foo", locations=[("doupy/templates/base/navmenu.inc.html.py", 60)]) catalog.add("foo", locations=[("doupy/templates/job-offers/helpers.html", 22)]) buf = BytesIO() pofile.write_po(buf, catalog, omit_header=True) self.assertEqual( b'''#: doupy/templates/base/navmenu.inc.html.py:60 #: doupy/templates/job-offers/helpers.html:22 msgid "foo" msgstr ""''', buf.getvalue().strip(), )
def test_escapes_text(self): catalog = Catalog() catalog.add("id", string="<a0>Hello &<b>&</b></a0>>") self.assertEqual( MessageTranslator("en", catalog).get_and_format_html_message( "id", tags={"a0": { "tag": "a", "attrs": { "href": "/you" } }}), '<a href="/you">Hello &&</a>>', )
def run_gettext(dirname, for_js): catalog = Catalog() for filename, lineno, message, comments, context in extract_from_dir( dirname, method_map=[('**.js', 'javascript')] if for_js else [('**.py', 'python')] ): catalog.add(message, None, [(filename, lineno)], auto_comments=comments, context=context) sio = cStringIO.StringIO() write_po(sio, catalog) return sio.getvalue()
def extract_module_messages(directory: pathlib.Path): with directory_loaded_as_zipfile_path(directory) as zip_path: module_zipfile = ModuleZipfile(zip_path) # may be invalid source_catalog = _build_source_catalog(module_zipfile) po_path = _po_path(directory, default_locale) try: old_source_catalog = read_po_catalog(po_path) except FileNotFoundError: old_source_catalog = Catalog(default_locale) # Update file for default locale if not catalogs_are_same(source_catalog, old_source_catalog): write_po_catalog(po_path, source_catalog) # Update template catalog # We will have no specific locale in the template catalog template_catalog = copy_catalog(source_catalog, locale=None) move_strings_to_comments(template_catalog, comment_tag="default-message") pot_path = _pot_path(directory) try: old_template_catalog = read_po_catalog(pot_path) except FileNotFoundError: old_template_catalog = Catalog() if not catalogs_are_same(template_catalog, old_template_catalog): write_po_catalog( pot_path, template_catalog, ignore_obsolete=True, width= 10000000, # we set a huge value for width, so that special comments do not wrap omit_header= True, # removes locale and other info from the output file ) fuzzy = find_fuzzy_messages(old_catalog=old_source_catalog, new_catalog=source_catalog) for locale_id in supported_locales: if locale_id != default_locale: po_path = _po_path(directory, locale_id) try: old_catalog = read_po_catalog(po_path) except FileNotFoundError: old_catalog = Catalog(locale_id) catalog = _merge_nonsource_catalog(locale_id, old_catalog, source_catalog, fuzzy) if not catalogs_are_same(catalog, old_catalog): write_po_catalog(po_path, catalog)
def cmd_extract(args): pkginfo = load_pkginfo(args) for cident, cdefn in pkginfo['components'].items(): if args.component is not None and cident not in args.component: continue if isinstance(cdefn, six.string_types): cmod = cdefn else: cmod = cdefn['module'] module = import_module(cmod) modpath = module.__path__[0] dist = get_distribution(args.package) meta = dict(message_from_string(dist.get_metadata('PKG-INFO'))) catalog = Catalog(project=args.package, version=dist.version, copyright_holder=meta.get('Author'), msgid_bugs_address=meta.get('Author-email'), fuzzy=False, charset='utf-8') method_map, options_map = get_mappings() def log_callback(filename, method, options): if method != 'ignore': filepath = os.path.normpath(os.path.join(modpath, filename)) logger.debug('Extracting messages from %s', filepath) extracted = extract_from_dir(modpath, method_map, options_map, callback=log_callback) for filename, lineno, message, comments, context in extracted: catalog.add(message, None, [(filename, lineno)], auto_comments=comments, context=context) logger.info("%d messages extracted from component [%s]", len(catalog), cident) locale_path = Path(module.__path__[0]) / 'locale' if locale_path.is_dir(): outfn = str(locale_path / '.pot') else: outfn = resource_filename(args.package, 'locale/%s.pot' % cident) with io.open(outfn, 'wb') as outfd: write_po(outfd, catalog, ignore_obsolete=True)
def test_file_with_no_lineno(self): catalog = Catalog() catalog.add(u'bar', locations=[('utils.py', None)], user_comments=['Comment About `bar` with', 'multiple lines.']) buf = BytesIO() pofile.write_po(buf, catalog, sort_output=True) value = buf.getvalue().strip() assert b'''\ # Comment About `bar` with # multiple lines. #: utils.py msgid "bar" msgstr ""''' in value
def test_sorted_po_context(self): catalog = Catalog() catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'), locations=[('main.py', 1)], context='there') catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'), locations=[('main.py', 1)]) catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'), locations=[('main.py', 1)], context='here') buf = BytesIO() pofile.write_po(buf, catalog, sort_output=True) value = buf.getvalue().strip() # We expect the foo without ctx, followed by "here" foo and "there" foo assert b'''\ #: main.py:1 msgid "foo" msgid_plural "foos" msgstr[0] "Voh" msgstr[1] "Voeh" #: main.py:1 msgctxt "here" msgid "foo" msgid_plural "foos" msgstr[0] "Voh" msgstr[1] "Voeh" #: main.py:1 msgctxt "there" msgid "foo" msgid_plural "foos" msgstr[0] "Voh" msgstr[1] "Voeh"''' in value
def test_trans_tag_without_attributes(self): catalog = Catalog() catalog.add("id", string="Hello <b0>{param_b}</b0>!") with mock_app_catalogs({"en": catalog}): self.assertEqual( trans_html( mock_context(), "id", default="Hello <b0>{param_b}</b0>!", arg_param_b="there", tag_b0="", ), "Hello <b>there</b>!", )
def test_fill_catalog_preserve_old(self): target_catalog = Catalog() target_catalog.add("id1", string="Text1") source_catalog = Catalog() string_source_catalog = Catalog() fill_catalog(target_catalog, source_catalog, string_source_catalog) expected_catalog = Catalog() expected_catalog.add("id1", string="Text1") assert_catalogs_deeply_equal(target_catalog, expected_catalog)