Exemple #1
0
        def import_new_entries(self):
            for root, dirs, files in os.walk(settings.EXTRACT_DIRS):
                for some_file in files:
                    if some_file.endswith(".po"):
                        if os.path.normpath(os.path.join(os.path.join(root, some_file), "../..")).endswith("fr"):
                            polib_po = polib.pofile(os.path.join(root, some_file))
                            for e in polib_po:
                                occurrences = json.dumps(e.occurrences)
                                new_entry = MixedEntry.get_or_create(some_file, 
                                                                     e.msgid, 
                                                                     occurrences, 
                                                                     e.msgctxt, 
                                                                     e.msgid_plural)

                                msgstr_plural = json.dumps(e.msgstr_plural)
                                new_entry.add_french_terms(e.msgstr, msgstr_plural)

                        if os.path.normpath(os.path.join(os.path.join(root, some_file), "../..")).endswith("rw"):
                            polib_po = polib.pofile(os.path.join(root, some_file))
                            for e in polib_po:
                                occurrences = json.dumps(e.occurrences)
                                new_entry = MixedEntry.get_or_create(some_file, 
                                                                     e.msgid, 
                                                                     occurrences, 
                                                                     e.msgctxt, 
                                                                     e.msgid_plural)
                        
                                msgstr_plural = json.dumps(e.msgstr_plural)
                                new_entry.add_rwanda_terms(e.msgstr, msgstr_plural)
Exemple #2
0
    def test_export_po_file_with_empty_msgstr_in_target_lang(self):
        client = Client()
        user = User.objects.create(username='******')
        user.set_password('Admin')
        user.save()
        client.login(username='******', password='******')

        new_lang = Language.objects.create(name='Japan', code='jp')
        ProjectLanguage.objects.create(lang=new_lang, project=self.project)
        path = os.path.join(PATH, 'data/django1.po')
        import_po_file(path, self.project.id, self.project_language.id)
        SetMessage.objects.filter(msgid='test.empty', lang=self.project.lang.id).update(msgstr='NonEmpty')
        response = client.get('/project/%s/export/%s/' % (self.project.id, new_lang.id))
        po = polib.pofile(response.content)
        all_messages = SetMessage.objects.filter(
            message_set__project_id=self.project.id,
            lang=self.project.lang.id)
        self.assertFalse(SetMessage.objects.get(msgid='test.empty', lang=new_lang.id).msgstr)
        self.assertEqual(dict((i.msgid, unicode(i.msgstr, 'utf8')) for i in po)['test.empty'], 'NonEmpty')

        SetMessage.objects.filter(msgid='test.empty').update(is_translated=True)
        response = client.get('/project/%s/export/%s/' % (self.project.id, new_lang.id))
        po = polib.pofile(response.content)
        all_messages = SetMessage.objects.filter(message_set__project_id=self.project.id, lang=self.project.lang.id)
        self.assertFalse(SetMessage.objects.get(msgid='test.empty', lang=new_lang.id).msgstr)
        self.assertFalse(dict((i.msgid, unicode(i.msgstr, 'utf8')) for i in po)['test.empty'])
Exemple #3
0
def main(templ, trans, outf):
    print('Converting %s, %s' % (templ, trans), file=sys.stderr)
    templ_po = polib.pofile(templ)
    trans_po = polib.pofile(trans)

    for entry in trans_po:
        msgid = entry.msgid
        msgid_plural = entry.msgid_plural
        msgstr = entry.msgstr
        orig = templ_po.find(msgid).msgstr
        orig_plural = templ_po.find(msgid).msgstr_plural

        if msgid_plural:
            newid = msgid + '|' + msgid_plural
            entry.msgctxt = newid
            entry.msgid = orig_plural['0']
            entry.msgid_plural = orig_plural['1']
            if entry.msgstr_plural == orig_plural:
                entry.msgstr_plural = dict()
                entry.msgstr_plural[0] = ''
                entry.msgstr_plural[1] = ''
        else:
            entry.msgctxt = msgid
            entry.msgid = orig
            if msgstr == orig:
                entry.msgstr = ''

    trans_po.save(outf)
Exemple #4
0
    def test_export_po_file_with_two_lang_check_record_number(self):
        client = Client()
        user = User.objects.create(username='******')
        user.set_password('Admin')
        user.save()
        client.login(username='******', password='******')

        response = client.get('/project/%s/export/%s/' % (self.project.id, self.project_language.id))
        self.assertEqual(response.status_code, 200)
        po = polib.pofile(response.content)
        self.assertEqual(
            len(SetMessage.objects.filter(
                message_set__project_id=self.project.id,
                lang=self.project_language.id)),
            len(po.translated_entries()))
        new_lang = Language.objects.create(name='Russian', code='ru')
        ProjectLanguage.objects.create(lang=new_lang, project=self.project)
        path = os.path.join(PATH, 'data/django.po')
        import_po_file(path, self.project.id, self.project_language.id)
        response = client.get('/project/%s/export/%s/' % (self.project.id, new_lang.id))
        po = polib.pofile(response.content)
        all_messages = SetMessage.objects.filter(
            message_set__project_id=self.project.id,
            lang=new_lang.id)
        self.assertEqual(len(all_messages), len(po.translated_entries()))
        self.assertTrue(
            dict((i.msgid, unicode(i.msgstr, 'utf8')) for i in po) ==
            dict((i.msgid, i.msgstr) for i in all_messages))
        self.assertTrue(
            set(i.msgid for i in all_messages) == set(i.msgid for i in po))
Exemple #5
0
def process_po(lang_id):
    new_fn = lang_id + '_new.po'
    old_fn = lang_id + '.po'
    po_new = pofile(new_fn)
    po_old = pofile(old_fn)
    msgids = []
    for new_entry in po_new.translated_entries():
        msgids.append([new_entry.msgctxt, new_entry.msgid])
        for old_entry in po_old.translated_entries():
            if 'translator-credits' == new_entry.msgid:
                msgids.pop()
                break
            if new_entry.msgctxt == old_entry.msgctxt and \
                new_entry.msgid == old_entry.msgid and \
                    new_entry.msgstr == old_entry.msgstr:
                msgids.pop()
                break

    names = []
    for (msgctxt, msgid) in msgids:
        print "looking for msgctxt '%s' msgid '%s' for lang '%s'" % \
            (msgctxt, msgid, lang_id)
        names = names + who_translated(lang_id, msgctxt, msgid)
    lang_name = get_lang_name(po_new, lang_id)
    if len(set(names)) == 1:
        author = po_new.metadata['Last-Translator']
    else:
        author = ', '.join(set(names)) + ' <multiple-authors>'
    cmd = 'git commit %s.po -m "Update %s translation thanks to %s" --author "%s"' % \
        (lang_id, lang_name, ', '.join(set(names)), author)
    return cmd
Exemple #6
0
def make_messages(src_path, path, name, outpath=None):

    sys.argv = [None, '-a', '-d', name, '-p', path]

    for root, dirs, files in os.walk(src_path):
        for f in files:
            if f.endswith('.py'):
                p = os.path.join(root, f)
                sys.argv.append(p)
    gtext()

    wzr_filename = os.path.join(path, name+'.pot')
    for pos in os.scandir(path):
        if pos.is_dir():
            lang = pos.name
            ftmp = os.path.join(path, lang)
            if outpath:
                ftmp = os.path.join(ftmp, outpath)
            filename = os.path.join(ftmp, name + '.po')
            old_filename = filename.replace('.po', '.bak')
            mo_filename = filename.replace('.po', '.mo')
            try:
                os.remove(old_filename)
            except:
                pass
            try:
                os.rename(filename, old_filename)
            except:
                pass
            wzr = polib.pofile(wzr_filename)
            po = polib.pofile(old_filename)
            po.merge(wzr)
            po.save(filename)
            po.save_as_mofile(mo_filename)
Exemple #7
0
def main():

    parser = argparse.ArgumentParser(description='Check for mismatches in msgid and msgstr with respect to numerous formats: including file names, HTML tags, python gettext variables, and My Opera Mail variables. When no optional arguments are given, the default behavior is to check for HTML and python gettext errors.')

    parser.add_argument('po_file', nargs='+', help='PO file whose msgstr should be checked, or a newline-separated list of PO files')

    parser.add_argument("--all", help="severe checking, with all arguments", action="store_true")
    parser.add_argument("--extensions", help="check file name extensions in strings", action="store_true")
    parser.add_argument("--filenames", help="check file names in strings", action="store_true")
    parser.add_argument("--html", help="check HTML tags in strings", action="store_true")
    parser.add_argument("--urls", help="check URLs in strings", action="store_true")
    parser.add_argument("--momail", help="check My Opera Mail variables in strings", action="store_true")
    parser.add_argument("--products", help="check product names in strings", action="store_true")
    parser.add_argument("--python", help="check python gettext variables in strings", action="store_true")

    parser.add_argument("--msgctxt", help="check a single string ID, not the whole PO file", action="store")
    parser.add_argument("--strings", help="check a list of string IDs, not the whole PO file", action="store")

    args = parser.parse_args()

    for name in args.po_file:
        try:
            find_mismatched(polib.pofile(name), args)
        except:
            for line in open(name).readlines():
                try:
                    path = line.strip(' \n')
                    find_mismatched(polib.pofile(path), args)
                except IOError:
                    sys.exit('File %s is not a PO file or a list of PO files' % name)

    return None
def insert_translations(args):
    """
    Insert strings from a source PO into the target PO file
    """
    source = polib.pofile(args.source_po)
    target = polib.pofile(args.target_po, wrapwidth=0)

    for line in open(args.strings).readlines():
        string = line.strip(' \n')
        source_entry = source.find(string, by='msgctxt')
        target_entry = target.find(string, by='msgctxt')
        if source_entry and target_entry:
            if not target_entry.msgstr:
                print string + color('31', ' untranslated')
            target_entry.msgstr = source_entry.msgstr
            target_entry = remove_fuzzy(target_entry)
            continue
        source_entry = source.find(string, by='msgid')
        target_entry = target.find(string, by='msgid')
        if source_entry and target_entry:
            if not target_entry.msgstr:
                print string + color('31', ' untranslated')
            target_entry.msgstr = source_entry.msgstr
            target_entry = remove_fuzzy(target_entry)
            continue

    target.save()

    return None
Exemple #9
0
    def create_po_template(self):
        django = polib.pofile(str(Path(self.locale_paths[0]).joinpath('django.pot')), check_for_duplicates = True)
        djangojs = polib.pofile(str(Path(self.locale_paths[0]).joinpath('djangojs.pot')), check_for_duplicates = True)

        self.add_po_domain(django, 'django')
        self.add_po_domain(djangojs, 'djangojs')

        for entry in djangojs:
            django.append(entry)

        django.header = "\nGNOME Shell extensions repository\n"
        django.header += "\n"
        django.header += "DO NOT EDIT!\n"
        django.header += "This file is auto generated with manage.py makemessages."
        django.header += "\n"

        django.metadata = {
            'Project-Id-Version': '1.0',
            'Report-Msgid-Bugs-To': '*****@*****.**',
            'POT-Creation-Date': datetime.now(pytz.utc).strftime('%Y-%m-%d %H:%M%z'),
            'MIME-Version': '1.0',
            'Content-Type': 'text/plain; charset=utf-8',
            'Content-Transfer-Encoding': '8bit',
        }
        django.sort()
        django.save(Path(self.po_path).joinpath("extensions-web.pot"))
Exemple #10
0
    def test_sample_data(self):
        work_file = WORK / "django.po"
        shutil.copyfile(TEST_DATA / "django_before.po", work_file)
        original_pofile = polib.pofile(work_file)

        written = segment_pofile(
            work_file,
            {
                'studio.po': [
                    'cms/*',
                    'other_cms/*',
                ],
            }
        )

        self.assertEqual(written, set([WORK / "django.po", WORK / "studio.po"]))

        pofiles = [polib.pofile(f) for f in written]
        after_entries = sum(len(pofile) for pofile in pofiles)
        self.assertEqual(len(original_pofile), after_entries)

        original_ids = set(m.msgid for m in original_pofile)
        after_ids = set(m.msgid for pofile in pofiles for m in pofile)
        self.assertEqual(original_ids, after_ids)

        self.assert_pofile_same(WORK / "django.po", TEST_DATA / "django_after.po")
        self.assert_pofile_same(WORK / "studio.po", TEST_DATA / "studio.po")
Exemple #11
0
def diff_one_file(fname, canon_name):
    po = polib.pofile(fname)
    canonical_po = polib.pofile(canon_name)
    diff_po = polib.POFile()
    po.merge(canonical_po)

    # msgids in the def. po file with no cananonical definition are
    # marked as obsolute after a merge
    for entry in po.obsolete_entries():
        entry.msgstr = ''
        entry.obsolete = False
        diff_po.append(entry)

    # Add any msgids that are untranslated in the
    # canonical catalog as well
    for entry in canonical_po.untranslated_entries():
        entry.msgstr = ''
        diff_po.append(entry)

    full_fname_path = os.path.abspath(fname)
    fname_dir = os.path.dirname(full_fname_path)
    fname_name = os.path.basename(full_fname_path).replace('.po', '')  # no extension
    diff_po_path = os.path.join(fname_dir, '%s_diff.po' % fname_name)
    diff_po.save(diff_po_path)
    return "Created %s with %s translations" % (diff_po_path, len(diff_po))
Exemple #12
0
    def _get_new(self, filepath1, filepath2):
        """ Compare two .po or .pot files and find all the entries in the
            second file that are not in the first one.

            Optionally:
                - include fuzzy and dirty non-new entries.
                - ignore new but translated entries.
                - prefill msgstr of all entries with their default values
        """
        firstpo = polib.pofile(filepath1)
        secondpo = polib.pofile(filepath2)
        entries = []
        for new_entry in secondpo:
            if new_entry.obsolete:
                # Ignore outcommented entries
                continue
            old_entry = firstpo.find(new_entry.msgid)
            if not old_entry:
                # We have a new entry
                if self.options.ignore_translated and new_entry.translated():
                    continue
                entries.append(new_entry)
            elif (
                self.options.untranslated
                and not new_entry.translated()
                or self.options.fuzzy
                and "fuzzy" in new_entry.flags
                or self.options.dirty
                and self.is_dirty(old_entry, new_entry)
            ):
                entries.append(new_entry)
        return entries
Exemple #13
0
def i18n_make_updates(is_js, suffix):
    with working_directory(ARABIC_LOCALE_DIR):
        django_edx = polib.pofile('django{}.po'.format(suffix))
        django_latest = polib.pofile('latest-django{}.po'.format(suffix))

        edx_entries = {}
        for entry in django_edx.translated_entries():
            edx_entries[entry.msgid] = entry

        for entry in reversed(django_latest):
            if not entry.translated():
                django_latest.remove(entry)
            else:
                edx_entry = edx_entries.get(entry.msgid)
                if edx_entry and edx_entry.msgstr == entry.msgstr:
                    # Remove the ones that didn't change
                    django_latest.remove(entry)

        print 'Added {} updated translations for django{}.po:'.format(
            len(django_latest),
            suffix,
        )

        django_latest.save('django{}-updates.po'.format(suffix))
        path('latest-django{}.po'.format(suffix)).remove()
Exemple #14
0
def mergepo_polib(target, source, options):
    changed = 0
    po1 = polib.pofile(target)
    po2 = polib.pofile(source)
    if options.overwrite:
        for entry in po1.entries():
            other = po2.find(entry.msgid, include_obsolete_entries=True)
            if not other:
                continue
            if options.nonnull and other.msgstr == other.msgid:
                continue
            if other.translated() and other.msgstr != entry.msgstr:
                entry.msgstr = other.msgstr
                if 'fuzzy' in other.flags:
                    if not 'fuzzy' in entry.flags:
                        entry.flags.append('fuzzy')
                else:
                    if 'fuzzy' in entry.flags:
                        entry.flags.remove('fuzzy')
                changed = changed + 1
    else:
        for entry in po1.untranslated_entries():
            other = po2.find(entry.msgid, include_obsolete_entries=True)
            if not other:
                continue
            if options.nonnull and other.msgstr == other.msgid:
                continue
            if other.translated():
                entry.msgstr = other.msgstr
                changed = changed + 1
    if changed > 0:
        po1.save(target)
    return changed
def merge_po_files(po_files, fuzzy=False):
    """Find each po file from the current directory, group them by name,
    and replicate known translations from each one to the others.
    """
    """Given a list of po files, replicate known translation from each
    file to the others.
    """
    known_translations = {}
    # Aggregate all known translations
    for po_file in tqdm(po_files, desc="Searching known translations"):
        po_file = polib.pofile(po_file)
        for entry in po_file:
            if 'fuzzy' not in entry.flags and entry.msgstr != '':
                known_translations[entry.msgid] = entry.msgstr
    # Propagate them
    done = 0
    for po_file in tqdm(po_files, desc="Replicating them"):
        po_file = polib.pofile(po_file)
        for entry in po_file:
            if entry.msgid in known_translations:
                entry.msgstr = known_translations[entry.msgid]
            elif fuzzy:
                best_match = find_best_match(list(known_translations.keys()),
                                             entry.msgid)
                if best_match is not None:
                    print("I think\n  {}\n =\n  {}".format(entry.msgid,
                                                           best_match))
                    entry.msgstr = known_translations[best_match]
                    entry.flags.append('fuzzy')
        po_file.save()
Exemple #16
0
 def __call__(self, value):
     try:
         if not os.path.isfile(value):
             raise IOError()
         polib.pofile(value)
     except IOError:
         raise ValidationError(self.message)
     return value
Exemple #17
0
def main():
    
    options = parse_args()
    language_files = get_language_files(options.locale_dir, options.force_create)
    
    pot_file = polib.pofile(options.pot_file)
    warning_file = open('warning.log', 'w')
    
    for lfile in language_files:
        to_translate = polib.pofile(lfile)
        language = guess_language(lfile)
        po_list = get_files_to_translate(lfile)
        
        if language == 'en':
            continue
        
        to_translate.merge(pot_file)
        to_translate.save()
        
        #~ Now we merge in any new files
        
        for new_trans in po_list:
            os.system('/usr/bin/msgmerge %s %s -o %s' % (new_trans, lfile, lfile))
        
        to_translate = polib.pofile(lfile)
        
        total = len(to_translate.untranslated_entries())
        count = 1
        #~ Translate with Google Translate
        print '--- Working on %s : %d entries to translate.' % (language.upper(), total)
        
        for entry in to_translate.untranslated_entries():
            entry.msgstr = translate(entry.msgid.lower(), language, key=options.google_key)
            entry.flags.append(u'fuzzy')
            print '%s [%d/%d] ...%s... --> ...%s...' % (language, count, total, entry.msgid[:10], entry.msgstr[:10])
            count += 1
        #~ Clean up msgstr entries
        total = len(to_translate)
        count = 1
        for entry in to_translate:
            tmp_msgstr = entry.msgstr
            entry.msgstr = clean_msgstr(entry.msgstr)
            if tmp_msgstr != entry.msgstr:
                print 'Cleaned: %s --> %s' % (tmp_msgstr, entry.msgstr)
            if nefarious_regex.search(entry.msgstr):
                match = nefarious_regex.match(entry.msgstr).group(1)
                print 'Warning: Found improper match %s.' % match
                warning_log.write('Warning: Found improper match %s in %s' % (match, entry.msgstr))
        
        to_translate.save()
        
        if options.save_as_mo:
            filename, suffix = lfile.rsplit('.', 1)
            mo_file = filename + '.mo'
            os.system('/usr/bin/rm %s -f' % mo_file)
            print 'Saving mo as %s' % mo_file
            os.system('msgfmt -o %s --use-fuzzy %s' % (mo_file, filename))
Exemple #18
0
    def _update_po(self, target_path, source_path):
        log.info("Updating %s from %s" % (target_path, source_path))
        target = polib.pofile(target_path)
        source = polib.pofile(source_path)

        target_dict = {}
        for entry in target:
            target_dict[entry.msgid] = entry

        count = 0
        for entry in source:
            if not entry.msgid in target_dict:
                if self.options.insert_new:
                    # If it's not in the target and -n is true, add it:
                    target.append(entry)
                continue
            target_entry = target_dict[entry.msgid]
            if target_entry.msgstr != entry.msgstr:
                # The messages are different. Check if we should update.
                if not self.options.force:
                    # if force is set, skip the checks and always update.
                    if not entry.msgstr:
                        # The new message is empty, we should not update
                        continue
                    if not utils.msg_is_updated(entry):
                        # The new message is fuzzy
                        if utils.msg_is_updated(target_entry):
                            # the old message is not fuzzy and not empty
                            continue
                        elif not self.options.use_fuzzy:
                            # Never use fuzzy unless use_fuzzy is set:
                            continue
                # Update the target
                target_dict[entry.msgid].msgstr = entry.msgstr
                # Since the target has been updated with a new translation,
                # it is no longer fuzzy
                if self.options.reset_fuzzy and \
                        'fuzzy' in target_dict[entry.msgid].flags:
                    target_dict[entry.msgid].flags.remove('fuzzy')
                count += 1

        if not count:
            log.info("No entries updated")
            return

        # Update the revision date.
        source_date = source.metadata.get('PO-Revision-Date', '')
        target_date = target.metadata.get('PO-Revision-Date', '')
        if source_date > target_date:
            # In this case we use the source date as the last update
            target.metadata['PO-Revision-Date'] = source_date
        else:
            # The target has been modified after the source.
            # We set the revision date to now, to mark it as changed.
            target.metadata['PO-Revision-Date'] = po_timestamp()
        target.save(target_path)
        log.info("%s entries updated" % count)
Exemple #19
0
def merge_po_and_preserve(source, dest):
    # Merges source entries into dest, but keep old entries intact
    sourcepo = polib.pofile(source)
    destpo = polib.pofile(dest)
    for entry in sourcepo:
        if destpo.find(entry.msgid) is not None:
            # The entry is already there
            continue
        destpo.append(entry)
    destpo.save()
Exemple #20
0
def merge_pots_into_pos(folder):
    # We're going to take all pot files in `folder` and for each lang, merge it with the po file
    # with the same name.
    potfiles = files_with_ext(folder, '.pot')
    for potfile in potfiles:
        refpot = polib.pofile(potfile)
        refname = op.splitext(op.basename(potfile))[0]
        for lang in get_langs(folder):
            po = polib.pofile(op.join(folder, lang, LC_MESSAGES, refname + '.po'))
            po.merge(refpot)
            po.save()
Exemple #21
0
def main():
    parser = argparse.ArgumentParser()
    #parser.add_argument('--no-ignore-comments')

    parser.add_argument('old_file')
    parser.add_argument('new_file')
    args = parser.parse_args()

    diffs = podiff(polib.pofile(args.old_file), polib.pofile(args.new_file))

    pprint_diff(diffs)
    return exit_code(diffs)
    def update(self):
        if not getattr(self, "pot", None):
            self.pot = polib.pofile(self.potname)

        for file in os.listdir("po"):
            po = polib.pofile(os.path.join("po", file))
            po.merge(self.pot)
            po.metadata["Project-Id-Version"] = self.pot.metadata["Project-Id-Version"]
            po.metadata["POT-Creation-Date"] = self.pot.metadata["POT-Creation-Date"]
            po.save()

        print "PO files updated"
 def test_files(self):
     po_file_list = get_file_list(os.path.join(TEST_PATH, "temp_files", "docs"),["po","pot"])
     po_file_list.sort()
     write_po_files(po_file_list,os.path.join(TEST_PATH, "test_files", "doc_filler.txt"))
     f1 = polib.pofile(os.path.join(TEST_PATH, "temp_files", "docs", "aggregation.po"))
     f2 = polib.pofile(os.path.join(TEST_PATH, "test_files", "filled_docs", "aggregation.po"))
     for l1, l2 in zip(f1, f2):
         self.assertEqual(l1, l2)
     f1 = polib.pofile(os.path.join(TEST_PATH, "temp_files", "docs", "administration.po"))
     f2 = polib.pofile(os.path.join(TEST_PATH, "test_files", "filled_docs", "administration.po"))
     for l1, l2 in zip(f1, f2):
         self.assertEqual(l1, l2)
Exemple #24
0
def GenerateStringTables(out_dir, pot_file, po_files):
  """Generates string tables from .po files.

  Args:
    out_dir: The directory to put the string table files in.
    pot_file: The .pot file containing the master list of strings.
    po_files: A list of .po files to generate string tables from.
  """
  # first build map of string -> id for the master table
  master_table = {}
  master_strings = []
  pot_file = polib.pofile(pot_file)
  for entry in pot_file:
    master_strings.append(entry.msgid)
    master_table[entry.msgid] = len(master_strings)-1

  # if no .po files were given (just the .pot file), generate the master table
  if not po_files:
    # write out master table to source file
    WriteStringTable(master_strings, 'master_string_table',
                     None, out_dir, 'master.po.cc')

  # now write out a table for each locale
  locales = []
  for po_file in po_files:
    # extract the name of the locale from the filename ("fr.po" -> "fr")
    locale_name = os.path.splitext(os.path.basename(po_file))[0]
    locales.append(locale_name)

    if not os.path.exists(po_file):
      print >> sys.stderr, 'error: %s does not exist!' % po_file
      sys.exit(1)

    po = polib.pofile(po_file)

    translation_table = {}
    for entry in po:
      translation_table[entry.msgid] = entry.msgstr

    locale_strings = []
    for ms in master_strings:
      if ms in translation_table:
        locale_strings.append(translation_table[ms])
      else:
        locale_strings.append('')

    if len(locale_strings) != len(master_strings):
      print >> sys.stderr, ('warning: %s doesn\'t match master .pot file' %
                            po_file)

    WriteStringTable(locale_strings, '%s_string_table' % locale_name,
                     locale_name, out_dir, '%s.po.cc' % locale_name,
                     comments=master_strings)
Exemple #25
0
def make_messages(src_path, path, name, outpath=None, ext_locales=[]):
    backup_argv = sys.argv
    
    sys.argv = [None, '-a', '-d', name, '-p', path]

    for root, dirs, files in os.walk(src_path):
        for f in files:
            if f.endswith('.py'):
                p = os.path.join(root, f)
                sys.argv.append(p)
    gtext()

    wzr_filename = os.path.join(path, name+'.pot')
    for pos in os.scandir(path):
        if pos.is_dir():            
            lang = pos.name
            ftmp = os.path.join(path, lang)
            if outpath:
                ftmp = os.path.join(ftmp, outpath)
            filename = os.path.join(ftmp, name + '.po')
            old_filename = filename.replace('.po', '.bak')
            mo_filename = filename.replace('.po', '.mo')
            try:
                os.remove(old_filename)
            except:
                pass
            try:
                os.rename(filename, old_filename)
            except:
                pass

            wzr = polib.pofile(wzr_filename)
            if os.path.exists(old_filename):
                po = polib.pofile(old_filename)
            else:
                po = polib.POFile()
            po.merge(wzr)
            
            #for pos2 in ext_locales:
            #    ftmp = os.path.join(pos2[1],lang)
            #    if outpath:
            #        ftmp = os.path.join(ftmp, outpath)
            #    ext_filename = os.path.join(ftmp, name+'.po')
            #    if os.path.exists(ext_filename):
            #        ext_po = polib.pofile(ext_filename)
            #        po.merge(ext_po)
                
            po.save(filename)
            po.save_as_mofile(mo_filename)

    sys.argv = backup_argv
Exemple #26
0
def i18n_edraak_push(is_js, suffix):
    """
    Extracts  strings and appends it to the provided .PO file.

    It searches for translation strings that are marked
    with "# Translators: " comment.
    """

    edx_pofile = polib.pofile('conf/locale/ar/LC_MESSAGES/django{}.po'.format(suffix))

    with open("conf/locale/config.yaml", 'r') as locale_config_file:
        locale_config = yaml.load(locale_config_file)
        partial_pofiles = locale_config['generate_merge']['django{}.po'.format(suffix)]

    with working_directory('conf/locale/en/LC_MESSAGES'):
        edraak_specific_path = path('edraak{}-platform.po'.format(suffix))

        if edraak_specific_path.exists():
            edraak_specific_path.unlink()

        edraak_specific = polib.POFile()

        edraak_specific.metadata = {
            'Project-Id-Version': 'Edraak 1',
            'Report-Msgid-Bugs-To': '*****@*****.**',
            'POT-Creation-Date': '2014-12-15 11:17+0200',
            'PO-Revision-Date': 'YEAR-MO-DA HO:MI+ZONE',
            'Last-Translator': 'Edraak Dev <*****@*****.**>',
            'Language-Team': 'Edraak Dev <*****@*****.**>',
            'MIME-Version': '1.0',
            'Content-Type': 'text/plain; charset=utf-8',
            'Content-Transfer-Encoding': '8bit',
            'Generated-By': 'Paver',
        }

        for po_path in partial_pofiles:
            print 'processing', po_path

            pofile = polib.pofile(po_path)

            for entry in pofile:
                new_entry = entry not in edx_pofile
                marked_as_specific = 'edraak-specific' in entry.comment.lower()

                if new_entry or marked_as_specific:
                    edraak_specific.append(entry)

        edraak_specific.save(edraak_specific_path)

        sh('tx push -l en -s -r edraak.edraak{}-platform'.format(suffix))
Exemple #27
0
 def convert(self, value, param, ctx):
     if not os.path.exists(value) and ':' in value:
         # The user passed a <locale>:<path> value
         (locale, path) = value.split(':', 1)
         path = os.path.expanduser(path)
         real_path = super(CatalogFile, self).convert(path, param, ctx)
         return (locale, polib.pofile(real_path))
     else:
         real_path = super(CatalogFile, self).convert(value, param, ctx)
         catalog = polib.pofile(real_path)
         locale = catalog.metadata.get('Language')
         if not locale:
             locale = os.path.splitext(os.path.basename(real_path))[0]
         return (locale, catalog)
def translate_po(compendium,po):
	"""
	Simple translate tool
	"""
	compendium = polib.pofile(compendium)
	traducir = polib.pofile(po)
	temp_compendium=compendium
	temp_compendium.merge(traducir)
	potools.simple_po_creation("final.po")
	potools.set_metadata_pilarized("final.po")
	final_po=polib.pofile("final.po")
	for entry in temp_compendium:
		if not entry.obsolete:
			final_po.append(entry)
	final_po.save("final.po")
Exemple #29
0
    def translate_file(self, fname):
        """Translates the po file at fname

        Note: The translation is done in-place and saved to the
        given pofile.

        """
        po = polib.pofile(fname)

        # FIXME - This might be a bit goofy
        po.metadata['Language'] = ",".join(self.pipeline_spec)
        po.metadata['Plural-Forms'] = 'nplurals=2; plural= n != 1'
        po.metadata['Content-Type'] = 'text/plain; charset=UTF-8'
        count = 0
        for entry in po:
            if entry.msgid_plural:
                entry.msgstr_plural['0'] = self.translate_string(
                    entry.msgid)
                entry.msgstr_plural['1'] = self.translate_string(
                    entry.msgid_plural)
            else:
                entry.msgstr = self.translate_string(entry.msgid)

            if 'fuzzy' in entry.flags:
                entry.flags.remove('fuzzy')  # clear the fuzzy flag
            count += 1
        print 'Munged %d messages in %s' % (count, fname)
        po.save()
Exemple #30
0
def check_pofile(po_file_path):
    if not os.path.exists(po_file_path):
        writeout("File not found %s\n" % po_file_path)
        sys.exit(2)

    po = polib.pofile(po_file_path)

    UNTRANSLATED = 0
    for entry in po.untranslated_entries():
        UNTRANSLATED += 1
        writeout("UNTRANSLATED\t", entry.msgid)

    FUZZY = 0
    for entry in po.fuzzy_entries():
        FUZZY += 1
        writeout("FUZZY\t", entry.msgid, entry.msgstr)

    if FUZZY or UNTRANSLATED:
        writeout("\n----------")
        if FUZZY:
            writeout("%d FUZZY string found." % FUZZY)
        if UNTRANSLATED:
            writeout("%d UNTRANSLATED string found." % UNTRANSLATED)
        writeout("----------")
        writeout("Edit: %s\n\n" % os.path.abspath(po_file_path))
        sys.exit(100)

    writeout("%s: PO File OK\n\n" % po_file_path)
    sys.exit(0)
Exemple #31
0
def test_strings_complete():
    po = polib.pofile('locales/en/LC_MESSAGES/base.po')
    assert po.percent_translated() == 100
Exemple #32
0
import os
import pathlib

CURRENT_DIR = pathlib.Path(__file__).parent
trans_dir = CURRENT_DIR / "translated/pl/LC_MESSAGES"

mtg_exps = (f for f in os.listdir(trans_dir)
            if f.endswith(".po") and len(f) == 6)


def percent_translated(obj):
    total = len(
        [e for e in obj if not e.obsolete and not e.msgid.startswith(":")])
    if total == 0:
        return 100
    translated = len(obj.translated_entries())
    return int(translated * 100 / float(total))


with open("percentages.inc", "w") as outfile:
    for filename in mtg_exps:
        expansion = filename[:3]
        pofile = polib.pofile(trans_dir / filename)
        percentage = (percent_translated(pofile) // 5 * 5) or 5
        pie = f"pie{percentage:02d}" if percentage < 100 else "done"
        outfile.write(f"""
.. |{expansion}_percent| image:: images/{pie}.png        
""")
        if percentage == 100:
            outfile.write("   :alt: Tłumaczenie zakończone\n")
Exemple #33
0
            msgid=message_id.decode('utf-8'),
            msgstr='',
            occurrences=[(langfile, '')]
        )
        if message_id != '':
            try:
                pot.append(potentry)
            except ValueError:
                print 'The entry already exists'
pot.save('../../po/stellarium-desktop/stellarium-desktop.pot')

# Merge translations
for pofile in glob.glob(podir + '/*.po'):
    lang = pofile[:-3].rsplit('/', 1)[1]
    pofilename = pofile
    po = polib.pofile(pofilename)
    po.merge(pot)
    po.save(pofilename)

for langfile in files:
    # open desktop file
    with open(langfile, "r") as deskfile:
        text = deskfile.read()
    with open(langfile, "w") as deskfile:
        for transblock in tpattern.findall(text):
            text = text.replace(transblock, '')

        # Parse PO files
        for pofile in sorted(glob.glob(podir + '/*.po'), reverse=True):
            lang = pofile[:-3].rsplit('/', 1)[1]
            pofilename = pofile
    language_code = sys.argv[1]
else:
    print("Usage seed_translation.py lang")
    print("  where lang is your two letteer ISO-639-1 language code")
    exit()

po_files_dir = './translated_po/%s' % language_code

files = os.listdir(po_files_dir)
translate_all = True

translator = Translator(to_lang=language_code)

for po_file_name in files:
    print("TRANSLATE %s" % po_file_name)
    po = polib.pofile(os.path.join(po_files_dir, po_file_name))
    for entry in po:
        if translate_all or entry.msgstr == '':
            print(entry.msgid)
            sentences = entry.msgid.split('.')
            translated_sentences = []
            for sentence in sentences:
                try:
                    translated_sentences.append(translator.translate(sentence))
                except:
                    print("ERROR TRANSLATING SENTENCE '%s'" % sentence)
            translation = '. '.join(translated_sentences)
            print(translation)
            print("-" * 40)
            entry.msgstr = translation.strip()
    po.save(os.path.join(po_files_dir, po_file_name))
Exemple #35
0
    def get_context_data(self, **kwargs):
        context = super(TranslationFormView, self).get_context_data(**kwargs)
        entries = self.get_entries()
        paginator = Paginator(entries, rosetta_settings.MESSAGES_PER_PAGE)

        # Handle REF_LANG setting; mark up our entries with the reg lang's
        # corresponding translations
        LANGUAGES = list(rosetta_settings.ROSETTA_LANGUAGES)
        if rosetta_settings.ENABLE_REFLANG:
            if self.ref_lang_po_file:
                for o in paginator.object_list:
                    ref_entry = self.ref_lang_po_file.find(o.msgid)
                    if ref_entry and ref_entry.msgstr:
                        o.ref_txt = ref_entry.msgstr
                    else:
                        o.ref_txt = o.msgid
            else:
                for o in paginator.object_list:
                    o.ref_txt = o.msgid
            # XXX: having "MSGID" at the end of the dropdown is really odd, no?
            # Why not instead do this?
            # LANGUAGES = [('', '----')] + list(settings.LANGUAGES)
            LANGUAGES.append(('msgid', 'MSGID'))

        # Determine page number & how pagination links should be displayed
        try:
            page = int(self._request_request('page', 1))
        except ValueError:
            page = 1  # fall back to page 1
        else:
            if not (0 < page <= paginator.num_pages):
                page = 1
        needs_pagination = paginator.num_pages > 1
        if needs_pagination:
            if paginator.num_pages >= 10:
                page_range = pagination_range(1, paginator.num_pages, page)
            else:
                page_range = range(1, 1 + paginator.num_pages)

        rosetta_messages = paginator.page(page).object_list

        # Handle MAIN_LANGUAGE setting, if applicable; mark up each entry
        # in the pagination window with the "main language"'s string.
        main_language_id = rosetta_settings.MAIN_LANGUAGE
        main_language = None
        if main_language_id and main_language_id != self.language_id:
            # Translate from id to language name
            for language in rosetta_settings.ROSETTA_LANGUAGES:
                if language[0] == main_language_id:
                    main_language = _(language[1])
                    break
        if main_language:
            main_lang_po_path = self.po_file_path.replace(
                '/%s/' % self.language_id, '/%s/' % main_language_id)
            # XXX: brittle; what if this path doesn't exist? Isn't a .po file?
            main_lang_po = pofile(main_lang_po_path)

            for message in rosetta_messages:
                message.main_lang = main_lang_po.find(message.msgid).msgstr

        # Collect some constants for the template
        rosetta_i18n_lang_name = six.text_type(
            dict(rosetta_settings.ROSETTA_LANGUAGES).get(self.language_id))
        # "bidi" as in "bi-directional"
        rosetta_i18n_lang_bidi = self.language_id.split(
            '-')[0] in settings.LANGUAGES_BIDI
        query_string_args = {}
        if self.msg_filter:
            query_string_args['msg_filter'] = self.msg_filter
        if self.query:
            query_string_args['query'] = self.query
        if self.ref_lang:
            query_string_args['ref_lang'] = self.ref_lang
        # Base for pagination links; the page num itself is added in template
        pagination_query_string_base = urlencode_safe(query_string_args)
        # Base for msg filter links; it doesn't make sense to persist page
        # numbers in these links. We just pass in ref_lang, if it's set.
        filter_query_string_base = urlencode_safe(
            {k: v
             for k, v in query_string_args.items() if k == 'ref_lang'})

        context.update({
            'version':
            get_rosetta_version(),
            'LANGUAGES':
            LANGUAGES,
            'rosetta_settings':
            rosetta_settings,
            'rosetta_i18n_lang_name':
            rosetta_i18n_lang_name,
            'rosetta_i18n_lang_code':
            self.language_id,
            'rosetta_i18n_lang_code_normalized':
            self.language_id.replace('_', '-'),
            'rosetta_i18n_lang_bidi':
            rosetta_i18n_lang_bidi,
            'rosetta_i18n_filter':
            self.msg_filter,
            'rosetta_i18n_write':
            self.po_file_is_writable,
            'rosetta_messages':
            rosetta_messages,
            'page_range':
            needs_pagination and page_range,
            'needs_pagination':
            needs_pagination,
            'main_language':
            main_language,
            'rosetta_i18n_app':
            get_app_name(self.po_file_path),
            'page':
            page,
            'query':
            self.query,
            'pagination_query_string_base':
            pagination_query_string_base,
            'filter_query_string_base':
            filter_query_string_base,
            'paginator':
            paginator,
            'rosetta_i18n_pofile':
            self.po_file,
            'ref_lang':
            self.ref_lang,
        })

        return context
Exemple #36
0
 def get_pofile(self) -> polib.POFile:
     with open(self.translation_filename(), "rb") as f:
         content = f.read()
     return polib.pofile(content.decode(), encoding="utf-8")
Exemple #37
0
Newer browsers protect you better against viruses, scams and other threats. Outdated browsers have security holes which are fixed in updates.

If you can't change your browser because of compatibility issues, think about installing a second browser for browsing and keep the old one for the compatibility.
If you can't change your browser because of compatibility issues, think about installing a second browser for browsing and keep the old one for compatibility.

If you are on a computer that is maintained by an admin and you cannot install a new browser, ask your admin about it.
Ask your admin to update your browser if you cannot install updates yourself.

blaasdasdfsdaf
faselsdfsadf"""

pairs = pairs.replace("\r", "")[1:-1].split("\n\n")
mappings = {s.split("\n")[0]: s.split("\n")[1] for s in pairs}
#%%

po = polib.pofile('lang/de_DE/LC_MESSAGES/update.po')
valid_entries = [e for e in po if not e.obsolete]
for entry in valid_entries:
    #print(entry.msgid)
    if entry.msgid in mappings:
        print("replacing", entry.msgid[:10], "with",
              mappings[entry.msgid][:10])
        entry.msgid = mappings[entry.msgid]
po.save()

po.save_as_mofile('lang/de_DE/LC_MESSAGES/update.mo')

#%%
pairs = """aaa
bbb
Exemple #38
0
def prereleaser_before(data):
    """
    1. Run the unit tests one last time before we make a release.
    2. Update the CONTRIBUTORS.txt file.

    Note: Install * polib (https://pypi.python.org/pypi/polib).
                  * pep8.

    """
    print('Running unit tests.')
    subprocess.check_output(["python", "example_project/manage.py", "test", "photologue"])

    print('Running PEP8 check.')
    # See setup.cfg for configuration options.
    subprocess.check_output(["pep8"])

    print('Checking that we have no outstanding DB migrations.')
    output = subprocess.check_output(["python", "example_project/manage.py", "makemigrations", "--dry-run",
                                      "photologue"])
    if not output == b"No changes detected in app 'photologue'\n":
        raise Exception('There are outstanding migrations for Photologue.')

    print('Updating CONTRIBUTORS.txt')

    # This command will get the author of every commit.
    output = subprocess.check_output(["git", "log", "--format='%aN'"])

    # Convert to a list.
    contributors_list = [contributor.strip("'") for contributor in output.decode('utf-8').split('\n')]

    # Now add info from the translator files. This is incomplete, we can only list
    # the 'last contributor' to each translation.
    for language in os.listdir('photologue/locale/'):
        filename = 'photologue/locale/{0}/LC_MESSAGES/django.po'.format(language)
        po = polib.pofile(filename)
        last_translator = po.metadata['Last-Translator']
        contributors_list.append(last_translator[:last_translator.find('<') - 1])

    # Now we want to only show each contributor once, and to list them by how many
    # contributions they have made - a rough guide to the effort they have put in.
    contributors_dict = {}

    for author in contributors_list:
        author_copy = copy.copy(author)

        if author_copy in ('', '(no author)', 'FULL NAME'):
            # Skip bad data.
            continue

        # The creator of this project should always appear first in the list - so
        # don't add him to this list, but hard-code his name.
        if author_copy in ('Justin Driscoll', 'justin.driscoll'):
            continue

        # Handle contributors who appear under multiple names.
        if author_copy == 'richardbarran':
            author_copy = 'Richard Barran'

        if author_copy in contributors_dict:
            contributors_dict[author_copy] += 1
        else:
            contributors_dict[author_copy] = 1

    with codecs.open('CONTRIBUTORS.txt', 'w', encoding='utf8') as f:
        f.write('Photologue is made possible by all the people who have contributed'
                ' to it. A non-exhaustive list follows:\n\n')
        f.write('Justin Driscoll\n')
        for i in sorted(contributors_dict, key=contributors_dict.get, reverse=True):
            f.write(i + '\n')

    # And commit the new contributors file.
    subprocess.check_output(["git", "commit", "-m", "Updated the list of contributors.", "CONTRIBUTORS.txt"])
Exemple #39
0
def create_pot_file (input_file, pot_file, verbose):
    """
        Create a .pot file from a translatables set of translatable strings

    Args:
        translatables:  a list of tuples, each of which contain the line number
                        at which a translatable string was found, plus the string
                        itself
        pot_file     : the filename of the .pot to create
        verbose      : whether to display progress info
    """

    translatables  = get_translatables_from_file(input_file)

    # check if the file exists. If it does, open it, otherwise create a new file
    new_file = not os.path.exists(pot_file)
    if new_file:
        pofile = polib.POFile()
        pofile.metadata= {
            "Project-Id-Version": "Budgie Welcome",
            "Report-Msgid-Bugs-To ": "*****@*****.**",
            "POT-Creation-Date": "2016-02-27 12:48+0100",
            "PO-Revision-Date": "YEAR-MO-DA HO:MI+ZONE",
            "Last-Translator": "FULL NAME <EMAIL@ADDRESS>",
            "Language-Team:": "LANGUAGE <*****@*****.**>",
            "MIME-Version": "1.0",
            "Content-Type": "text/plain; charset=UTF-8",
            "Content-Transfer-Encoding": "8bit",}
    else:
        pofile = polib.pofile(pot_file)

    source_path, source_file = os.path.split(input_file)
    for translatable in translatables:
        entry = polib.POEntry(
                msgid = translatable[1],
                msgstr = "",
                occurrences = [(source_file, "%s" %str(translatable[0]).strip("[]"))])

        if new_file:
            pofile.append (entry)
            if verbose:
                print ('Added "%s" to pot file' %translatable[1])
        else:
            # add the entry only if it isn't already present...
            present = False
            for en in pofile:
                if en.msgid == entry.msgid:
                    present = True
                    break

            if not present:
                pofile.append(entry)
                if verbose:
                    print ('Added "%s" to pot file' %translatable[1])
            else:
                if verbose:
                   print ('Did not add "%s" - already present.' %translatable[1])

    if verbose:
        print ('Saving pot file to %s' %pot_file)

    pofile.save(pot_file)
    if verbose:
        print ("Saved")
Exemple #40
0
def translate_file(in_file, in_po, out_file, verbose):
    """ Translate a file from English to another language

    For every translatable string in_file, replace the corresponding
    text in the input file with the appropriate translation from the .po
    file. When all  translations are done, write the resulting html to the
    output file

    Args:
        in_file: the original filename whose contents are in English within
                 &zwnj; enclosures
        in_po  : the filename of the .po file to use for the translation
        out_file : the filename that the translation gets written to

    """

    # get the translatable strings from the input file
    translatables = get_translatables_from_file(in_file, trim_strs=False)

    # read the entire contents of the file
    content = open(in_file, 'r').read()

    # read the po file
    po_file = polib.pofile(in_po)

    # for every translatable string, try to find and replace it with the appropriate
    # translated
    for translatable in translatables:

        #can we find the translatable text in the input file?
        if translatable[1] in content:

            # remove \n and redundant spaces between words from the translatable string, so that
            # it will match the entry in the .po file
            trim_text = translatable[1].replace("\n", "")
            trim_text = " ".join(trim_text.split())

            # iterate through the po entries looking for the one which matches the current translatable
            for entry in po_file:
                if (entry.msgid == trim_text):

                    if (entry.msgstr !=""):

                        # replace the English text with the tranlated text.
                        # NOTE: ALL occurrences of the English text are replaced throughout the entire
                        # file

                        content = content.replace("%s%s%s" %("&zwnj;", translatable[1], "&zwnj;"), entry.msgstr)
                        if verbose:
                            print ("Translated %s >> %s" %(trim_text, entry.msgstr))
                    else:
                        # there's no translation, so instead just remove the &zwnj; characters from the string
                        content = content.replace("%s%s%s" %("&zwnj;", translatable[1], "&zwnj;"), entry.msgid)
                        if verbose:
                            print("No translation for %s, so &zwnj; characters removed" %entry.msgid)
                    break

        else:
            if verbose:
                print ("WARNING: translatable string  %s not found" %translatable[1])

    # Post actions for i18n folder - Use relative paths.
    content = content.replace('css/', '../../css/')
    content = content.replace('js/', '../../js/')
    content = content.replace('img/', '../../img/')

    outfile = codecs.open(out_file, 'w', encoding='utf-8')
    outfile.write(content)
    outfile.close()
Exemple #41
0
def check_messages(filename, report_empty=False):
    """
    Checks messages in `filename` in various ways:

    * Translations must have the same slots as the English.

    * Messages can't have astral characters in them.

    If `report_empty` is True, will also report empty translation strings.

    Returns the problems, a list of tuples. Each is a description, a msgid, and
    then zero or more translations.

    """
    problems = []
    pomsgs = polib.pofile(filename)
    for msg in pomsgs:
        # Check for characters Javascript can't support.
        # https://code.djangoproject.com/ticket/21725
        if astral(msg.msgstr):
            problems.append(("Non-BMP char", msg.msgid, msg.msgstr))

        if is_format_message(msg):
            # LONG_DATE_FORMAT, etc, have %s etc in them, and that's ok.
            continue

        if msg.msgid_plural:
            # Plurals: two strings in, N strings out.
            source = msg.msgid + " | " + msg.msgid_plural
            translation = " | ".join(
                v for k, v in sorted(msg.msgstr_plural.items()))
            empty = any(not t.strip() for t in msg.msgstr_plural.values())
        else:
            # Singular: just one string in and one string out.
            source = msg.msgid
            translation = msg.msgstr
            empty = not msg.msgstr.strip()

        if empty:
            if report_empty:
                problems.append(("Empty translation", source))
        else:
            id_tags = tags_in_string(source)
            tx_tags = tags_in_string(translation)

            # Check if tags don't match
            if id_tags != tx_tags:
                id_has = u", ".join(u'"{}"'.format(t)
                                    for t in id_tags - tx_tags)
                tx_has = u", ".join(u'"{}"'.format(t)
                                    for t in tx_tags - id_tags)
                if id_has and tx_has:
                    diff = u"{} vs {}".format(id_has, tx_has)
                elif id_has:
                    diff = u"{} missing".format(id_has)
                else:
                    diff = u"{} added".format(tx_has)
                problems.append(("Different tags in source and translation",
                                 source, translation, diff))

    return problems
Exemple #42
0
from __future__ import absolute_import, division, print_function, unicode_literals

import sys
import os
import json
import polib

LOGDEBUG = 'Debug'
LOGERROR = 'Error'
LOGNOTICE = 'Notice'

INFO_LABELS = {
    'System.BuildVersion': '18.2',
}

PO = polib.pofile('resources/language/resource.language.en_gb/strings.po')

# Use the global_settings file
try:
    with open('test/userdata/global_settings.json') as f:
        GLOBAL_SETTINGS = json.load(f)
except OSError as e:
    print("Error using 'test/userdata/global_settings.json' : %s" % e,
          file=sys.stderr)
    GLOBAL_SETTINGS = {
        'locale.language': 'resource.language.en_gb',
        'network.bandwidth': 0,
    }


def executebuiltin(function, wait=False):  # pylint: disable=unused-argument
    if n < 4:
        continue
    f.write(line)
f.close()

print 'Complete'

# Compile language .po files to .mo

print 'Compiling PO files to MO...'
for po_file in os.listdir('languages'):
    if not po_file.endswith('.po'):
        continue
    po_path = os.path.join('languages', po_file)
    print 'Converting', po_path
    po = polib.pofile(po_path, encoding='utf-8')
    mo_path = po_path[:-3] + '.mo'
    po.save_as_mofile(mo_path)

print 'Complete'
print

print 'Creating distribution package...'
# Create release dir and move release files inside it
os.mkdir(name)
# Copy files
for p_file in REL_FILES:
    shutil.copy(p_file, os.path.join(name, p_file))
# Copy dirs
for p_dir in REL_DIRS:
    shutil.copytree(p_dir, os.path.join(name, p_dir))
Exemple #44
0
def clean_metadata(file):
    """
    Clean up redundancies in the metadata caused by merging.
    This reads in a PO file and simply saves it back out again.
    """
    pofile(file).save()
Exemple #45
0
        data = yaml.safe_load(f)
    for rule_str, production in data["rules"].items():
        yield rule_str, production


productions = set()
rule_strs_by_production = defaultdict(list)

for filename in ("urdubiometer/settings/long.yml", "urdubiometer/settings/short.yml"):
    for rule_str, production in get_rules(filename):
        productions.add(production)
        rule_strs_by_production[production].append(rule_str)

# load source translation file

po = polib.pofile("translations/urdubiometer.messages/en.po")

# check that each tag has required "<tag>__SHORT_DESCRIPTION"

for _ in sorted(productions):
    for msgid in ("{}__SHORT_DESCRIPTION", "{}__WITH_VALUES_DESCRIPTION"):
        msgid = msgid.format(_)
        if not po.find(msgid):
            comment = " | ".join([r for r in rule_strs_by_production[_]])
        print("Adding", msgid)
        po.append(polib.POEntry(msgid=msgid, msgstr="", comment=comment))

for _ in po:
    msgid = _.msgid
    m = re.match("^(.+)(__SHORT_DESCRIPTION|__WITH_VALUES_DESCRIPTION)", msgid)
    if m:
Checks if the original string and the translation both end with dot or 
not. """
parser = optparse.OptionParser(usage=USAGE)

(options, args) = parser.parse_args()

# Error checking (the pattern must be specified)
if len(args) < 1:
    print >> sys.stderr, 'ERROR: Not enough arguments, the PO file must be specified'
    sys.exit(1)

pofile = args[0]
print "Reading PO file: {0}".format(pofile)

po = polib.pofile(pofile)
for entry in po:

    if entry.msgid.strip().endswith("..."):
        if not (entry.msgstr.strip().endswith("...")
                or entry.msgstr.strip().endswith("…".decode("utf-8"))):
            print_error(entry)
    elif entry.msgid.strip().endswith(
            ".") and not entry.msgstr.strip().endswith("."):
        print_error(entry)
#    elif not entry.msgid.strip().endswith(".") and entry.msgstr.strip().endswith("."):
#        print_error(entry)
    elif entry.msgid.strip().endswith(
            ":") and not entry.msgstr.strip().endswith(":"):
        print_error(entry)
    elif not entry.msgid.strip().endswith(":") and entry.msgstr.strip(
Exemple #47
0
    optparser.add_option(
        "",
        "--doctest",
        help="run doctest of this tool, instead of check",
        action="store_true",
    )
    (options, args) = optparser.parse_args()

    if options.doctest:
        import os

        if 'TERM' in os.environ:
            del os.environ['TERM']
        import doctest

        failures, tests = doctest.testmod()
        sys.exit(failures and 1 or 0)

    detected = []
    warning = options.warning
    for f in args:
        detected.extend(
            (f, pe, errors)
            for pe, errors in check(polib.pofile(f), warning=warning))
    if detected:
        for f, pe, errors in detected:
            for level, checker, error in errors:
                sys.stderr.write('%s:%d:%s(%s): %s\n' %
                                 (f, pe.linenum, level, checker, error))
        sys.exit(1)
Exemple #48
0
def set_new_translation(request):
    """
    Post to include a new translation for a msgid
    """
    if not get_user_can_translate(request.user):
        return HttpResponseForbidden(
            _('You have no permission to update translation catalogs'))
    if not request.POST:
        return HttpResponseBadRequest(
            render_to_response('inlinetrans/response.html',
                               {'message': _('Invalid request method')},
                               context_instance=RequestContext(request)))
    else:
        result = {
            'errors': True,
            'question': False,
            'message': _('Unknow error')
        }
        selected_pofile = None
        msgid = smart_str(request.POST['msgid'])
        msgstr = smart_str(request.POST['msgstr'])
        retry = smart_str(request.POST['retry'])
        lang = get_language()

        # We try to update the catalog
        if retry != 'false':
            root_path = os.path.dirname(
                os.path.normpath(
                    os.sys.modules[settings.SETTINGS_MODULE].__file__))
            locale_path = os.path.dirname(
                os.path.normpath(
                    os.sys.modules[settings.SETTINGS_MODULE].__file__))
            makemessages(lang,
                         extensions=['.html'],
                         root_path=root_path,
                         locale_path=locale_path)

        pos = find_pos(lang, include_djangos=True)
        if pos:
            for file_po in pos:
                candidate = pofile(file_po)
                poentry = candidate.find(msgid)
                if poentry:
                    selected_pofile = candidate
                    poentry.msgstr = msgstr
                    if 'fuzzy' in poentry.flags:
                        poentry.flags.remove('fuzzy')
                    po_filename = file_po
                    break
            # We can not find the msgid in any of the catalogs
            if not selected_pofile:
                result['message'] = _('"%(msgid)s" not found in any catalog' %
                                      {'msgid': msgid})
                if retry == 'false':
                    result['question'] = _(
                        'Do you want to update the catalog (this could take longer) and try again?'
                    )
                return HttpResponse(simplejson.dumps(result),
                                    mimetype='text/plain')

            format_errors = validate_format(selected_pofile)
            if format_errors:
                result['message'] = format_errors
                return HttpResponse(simplejson.dumps(result),
                                    mimetype='text/plain')

            if poentry and not format_errors:
                try:
                    selected_pofile.metadata['Last-Translator'] = smart_str(
                        "%s %s <%s>" %
                        (request.user.first_name, request.user.last_name,
                         request.user.email))
                    selected_pofile.metadata['X-Translated-Using'] = smart_str(
                        "inlinetrans %s" % inlinetrans.get_version(False))
                    selected_pofile.metadata[
                        'PO-Revision-Date'] = datetime.datetime.now().strftime(
                            '%Y-%m-%d %H:%M%z')
                except UnicodeDecodeError:
                    pass
                selected_pofile.save()
                selected_pofile.save_as_mofile(
                    po_filename.replace('.po', '.mo'))
                result['errors'] = False
                result['message'] = _('Catalog updated successfully')
            elif not poentry:
                result['message'] = _('PO entry not found')
    return HttpResponse(simplejson.dumps(result), mimetype='text/plain')
Exemple #49
0
if "top_srcdir" not in os.environ:
    sys.stderr.write("$top_srcdir must be defined in the test environment\n")
    sys.exit(99)

if "top_builddir" not in os.environ:
    sys.stderr.write("$top_builddir must be defined in the test environment\n")
    sys.exit(99)

# Update the .pot file with the latest strings
if os.system('make -C %s anaconda.pot-update' %
             (os.environ['top_builddir'] + "/po")) != 0:
    sys.stderr.write("Unable to update anaconda.pot")
    sys.exit(1)

# Parse anaconda.pot and rearrange the POFile object into a dict of {msgid: POEntry}
pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
msgs = {e.msgid: e for e in pofile}

# Look for each of the bad regexes
success = True
for badre in bad_strings.keys():
    regex = re.compile(badre)
    for msg in msgs.keys():
        # Remove underscores to avoid trouble with underline-based accelerators
        match = re.search(regex, msg.replace('_', ''))
        if match:
            # If this is something expected, decrement the occurrence count in expected_badness
            badstr = match.group(0)
            remainder = []
            for occur in msgs[msg].occurrences:
                if occur[0] in expected_badness and badstr in expected_badness[
        print >> stream
    program = os.path.basename(sys.argv[0])
    print >> stream, __doc__ % {"program": program}
    sys.exit(0)


if len(sys.argv) < 2:
    usage(sys.stderr, "\nERROR: Not enough arguments")
filename = sys.argv[1]

debug = False
for i in range(1, len(sys.argv)):
    arg = sys.argv.pop()
    if arg == "--debug":
        debug = True

po = polib.pofile(filename)
counter = 0

for entry in po:
    counter += 1
    match = patt.match(entry.comment)
    if match:
        default = match.group(1).replace('\n', ' ')
        if "Default:" in default:
            print "ERROR! There seems to be a duplicate Default entry for msgid '%s'" % entry.msgid
    else:
        if debug:
            print "WARNING! No Default translation for msgid '%s'." % entry.msgid

sys.exit('Finished, checked all %d entries.' % counter)
Exemple #51
0
#!/usr/bin/env python3
"""Append Welcome dialog strings to COOL UI pot file"""

import sys
import polib

welcome = polib.pofile(sys.argv[1],
                       autodetect_encoding=False,
                       encoding="utf-8",
                       wrapwidth=-1)
coolui = polib.pofile(sys.argv[2],
                      autodetect_encoding=False,
                      encoding="utf-8",
                      wrapwidth=78)
# Filter out unnecessary strings of meta tags from html2po output
for entry in welcome:
    if 'html.head.meta' in entry.occurrences[0][0]:
        continue
    if entry.msgid == '':
        continue
    coolui.append(entry)
coolui.metadata['Content-Type'] = 'text/plain; charset=UTF-8'
coolui.save(sys.argv[2])
Exemple #52
0
# require's polib from https://bitbucket.org/izi/polib/wiki/Home
#
# from top level of tree:
#    check_translations.py /path/to/source/file
#
#  Should output any untranslated or fuzzy lines from the file in a "lint" style

# NEEDS polib from http://pypi.python.org/pypi/polib
# or easy_install polib
import glob
import polib

#FIXME
PO_PATH = "po/"

po_files = glob.glob("%s/*.po" % PO_PATH)

for po_file in po_files:
    print()
    print(po_file)
    p = polib.pofile(po_file)
    for entry in p.untranslated_entries():
        for line in entry.occurrences:
            print("%s:%s" % (line[0], line[1]))
        print("\t%s" % entry.msgid)

    for entry in p.fuzzy_entries():
        for line in entry.occurrences:
            print("%s:%s" % (line[0], line[1]))
        print("\t%s" % entry.msgid)
PLUGIN_LIVE_BRIDGE_PATH = "plugin://plugin.video.catchuptvandmore/resources/lib/main/"

M3U_ENTRY = '#EXTINF:-1 tvg-id="%s" tvg-logo="%s" group-title="%s",%s\n%s'
# arg0: tgv_id
# arg1: tgv_logo
# arg2: group_title
# arg3: label
# arg4: URL

# Parse english strings.po
# in order to recover labels
# Key format: "#30500"
# Value format: "France"
en_strings_po = {}
po = polib.pofile(EN_STRINGS_PO_FILEPATH)
for entry in po:
    en_strings_po[entry.msgctxt] = entry.msgid

MANUAL_LABELS = {
    'la_1ere': 'La 1ère',
    'france3regions': 'France 3 Régions',
    'euronews': 'Euronews',
    'arte': 'Arte',
    'dw': 'DW',
    'france24': 'France 24',
    'qvc': 'QVC',
    'nhkworld': 'NHK World',
    'cgtn': 'CGTN',
    'paramountchannel': 'Paramount Channel',
    'rt': 'RT',
def import_language(language):
    ''' Process the language.po file '''
    return polib.pofile(
        'resources/language/{language}/strings.po'.format(language=language))
Exemple #55
0
def check_messages(filename, report_empty=False):
    """
    Checks messages in various ways:

    Translations must have the same slots as the English. Messages can't have astral
    characters in them.

    If report_empty is True, will also report empty translation strings.

    """
    # Don't check English files.
    if "/locale/en/" in filename:
        return

    # problems will be a list of tuples.  Each is a description, and a msgid,
    # and then zero or more translations.
    problems = []
    pomsgs = polib.pofile(filename)
    for msg in pomsgs:
        # Check for characters Javascript can't support.
        # https://code.djangoproject.com/ticket/21725
        if astral(msg.msgstr):
            problems.append(("Non-BMP char", msg.msgid, msg.msgstr))

        if msg.msgid_plural:
            # Plurals: two strings in, N strings out.
            source = msg.msgid + " | " + msg.msgid_plural
            translation = " | ".join(v for k, v in sorted(msg.msgstr_plural.items()))
            empty = any(not t.strip() for t in msg.msgstr_plural.values())
        else:
            # Singular: just one string in and one string out.
            source = msg.msgid
            translation = msg.msgstr
            empty = not msg.msgstr.strip()

        if empty:
            if report_empty:
                problems.append(("Empty translation", source))
        else:
            id_tags = tags_in_string(source)
            tx_tags = tags_in_string(translation)

            # Check if tags don't match
            if id_tags != tx_tags:
                id_has = u", ".join(u'"{}"'.format(t) for t in id_tags - tx_tags)
                tx_has = u", ".join(u'"{}"'.format(t) for t in tx_tags - id_tags)
                if id_has and tx_has:
                    diff = u"{} vs {}".format(id_has, tx_has)
                elif id_has:
                    diff = u"{} missing".format(id_has)
                else:
                    diff = u"{} added".format(tx_has)
                problems.append((
                    "Different tags in source and translation",
                    source,
                    translation,
                    diff
                ))

    if problems:
        problem_file = filename.replace(".po", ".prob")
        id_filler = textwrap.TextWrapper(width=79, initial_indent="  msgid: ", subsequent_indent=" " * 9)
        tx_filler = textwrap.TextWrapper(width=79, initial_indent="  -----> ", subsequent_indent=" " * 9)
        with codecs.open(problem_file, "w", encoding="utf8") as prob_file:
            for problem in problems:
                desc, msgid = problem[:2]
                prob_file.write(u"{}\n{}\n".format(desc, id_filler.fill(msgid)))
                for translation in problem[2:]:
                    prob_file.write(u"{}\n".format(tx_filler.fill(translation)))
                prob_file.write(u"\n")

        log.error(" {0} problems in {1}, details in .prob file".format(len(problems), filename))
    else:
        log.info(" No problems found in {0}".format(filename))
Exemple #56
0
 def setUpClass(cls):
     gettextutil.check_version()
     pot_path = gettextutil.update_pot(PODIR, "quodlibet")
     cls.pot = polib.pofile(pot_path)
    def __init__(self):

        usage = """
            Usage:

            cinnamon-json-makepot -i | -r | [-js] <potfile name>

            -js, --js - Runs xgettext on any javascript files in your directory before
                  scanning the settings-schema.json file.  This allows you to generate
                  a .pot file for your entire applet at once.

                ***
                The following two options should only be run in your applet, desklet, or
                extension's directory
                ***

            -i, --install - Compiles and installs any .po files contained in a po folder
                  to the system locale store.  Use this option to test your translations
                  locally before uploading to Spices.  It will use the applet, desklet,
                  or extension UUID as the translation domain

            -r, --remove - The opposite of install, removes translations from the store.
                  Again, it uses the UUID to find the correct files to remove

            <potfile name> - name of the .pot file to work with.  This can be pre-existing,
            or the name of a new file to use.  If you leave off the .pot extension, it will
            be automatically appended to the file name.

            For instance:

            cinnamon-json-makepot myapplet

            Will generate a file called myapplet.pot, or append
            to a file of that name.  This can then be used by translators to be
            made into a po file.

            For example:

            msginit --locale=fr --input=myapplet.pot

            Will create "fr.po" for the French language.  A translator can use a utility
            such as poedit to add translations to this file, or edit the file manually.

            .po files can be added to a "po" folder in your applet's directory,
            and will be compiled and installed into the system when the applet is installed
            via Cinnamon Settings.
        """

        parser = OptionParser(usage=usage)
        parser.add_option("-j",
                          "--js",
                          action="store_true",
                          dest="js",
                          default=False)
        parser.add_option("-i",
                          "--install",
                          action="store_true",
                          dest="install",
                          default=False)
        parser.add_option("-r",
                          "--remove",
                          action="store_true",
                          dest="remove",
                          default=False)

        (options, args) = parser.parse_args()

        if options.install:
            self.do_install()

        if options.remove:
            self.do_remove()

        if not args:
            parser.print_help()
            quit()

        self.potname = args[0]

        if not self.potname.endswith(".pot"):
            self.potname = self.potname + ".pot"

        self.domain = self.potname.replace(".pot", "")
        self.potpath = os.path.join(os.getcwd(), self.potname)

        if options.js:
            try:
                import subprocess
                subprocess.call(["xgettext", "--version"])
            except OSError:
                print "xgettext not found, you may need to install the gettext package"
                quit()
            print " "
            print "Running xgettext on JavaScript files..."
            os.system("xgettext --language=C --keyword=_ --output=%s *.js" %
                      (self.potname))

        self.current_parent_dir = ""

        append = False
        if os.path.exists(self.potpath):
            append = True

        if append:
            self.po = polib.pofile(self.potpath)
        else:
            self.po = polib.POFile()

        print "Scanning metadata.json and settings-schema.json..."
        self.scan_dirs()

        if append:
            self.po.save()
        else:
            self.po.save(fpath=self.potpath)

        print "Extraction complete"
        quit()
Exemple #58
0
translationCache = {}

# The purpose of this loop is to go to the podir scanning for PO files for each locale name
# Once we've found a PO file, we use PO lib to read every translated entry
# Using this, for each each language, we store a dict of entries - { nsilabel (comment) : translation (msgstr) }
# For untranslated entries, we use msgid instead of msgstr (i.e. default English string)
for root,dirs,files in os.walk(options.podir):
    for file in files:
        filename,ext = os.path.splitext(file)
        if ext == ".po":
            # Valid locale filename (fr.po, de.po etc)?
            if filename in localeToName:
                language = localeToName[filename]
                translationCache[language] = collections.OrderedDict()
                
                po = polib.pofile(os.path.join(root,file))
                for entry in po.translated_entries():
                    # Loop through all our labels and add translation (each translation may have multiple labels)
                    for label in entry.comment.split():
                        translationCache[language][label] = escapeNSIS(entry.msgstr)
                # For untranslated strings, let's add the English entry
                for entry in po.untranslated_entries():
                    for label in entry.comment.split():
                        print("Warning: Label '%s' for language '%s' remains untranslated"%(label,language))
                        translationCache[language][label] = escapeNSIS(entry.msgid)

def tostr(obj):
    if type(obj) == unicode:
        return obj.encode("utf-8")
    else:
        return obj
import sys
import polib
import langdetect
#import goslate
from google.cloud import translate_v2 as translate
import time
from urllib.error import HTTPError

#gs = goslate.Goslate()
translate_client = translate.Client()

podata = polib.pofile(sys.argv[1])

podata.metadata['PO-Revision-Date'] = time.strftime("%Y-%m-%d %H:%M%z")

for entry in podata:
    langs = {}
    for l in langdetect.detect_langs(entry.msgid):
        langs[l.lang] = l.prob
    print(entry.msgid, langs)
    if entry.msgstr == '' and not langs.get('ja'):
        try:
            #entry.msgstr = gs.translate(entry.msgid, 'ja')
            entry.msgstr = translate_client.translate(
                entry.msgid, target_language='ja')['translatedText']
        except HTTPError as e:
            print(e)
            break
        print(entry.msgstr)
        #time.sleep(3)
Exemple #60
0
    def translate(self, src_file, src_lang, dest_file, dest_lang):
        pofile = polib.pofile(src_file)

        entries = []
        ids = []
        tokens = dict()
        lastnum = 0

        dcregex = re.compile('Default: "([^"]*)"', re.DOTALL)

        for entry in pofile:
            if entry.translated():
                continue
            entries.append(entry)

            # Sorry folks, this will get squashed
            txt = entry.msgid.replace('_', '')
            if entry.comment and entry.comment.startswith('Default: '):
                dcmatches = dcregex.findall(entry.comment)
                if dcmatches and len(dcmatches) > 0:
                    txt = dcmatches[0]
            if len(txt) > 500:
                #We must skip entries longer than this, because google translate complains for these?
                continue

            tokenlist = re.findall('(\$\{[^\}]+\})', txt)
            if tokenlist and len(tokenlist) > 0:
                #There are $tokens in the msgid string.We will put this into our tokens dict and
                #replace them with (numeric ids) so that when they come back translated we can replace the $tokens back
                for token in tokenlist:
                    lastnum = lastnum + 1
                    id = "GT" + str(lastnum)
                    tokens[id] = token
                    txt = txt.replace(token, id)
            ids.append(txt)

            if len(ids) > self.STRINGS_PER_REQUEST:
                print len(ids), ids
                try:
                    strs = self.api.translate_many(ids, src_lang, dest_lang)
                except Exception as inst:
                    print "Caught Exception: %s" % inst

                    strs = []
                    for id in ids:
                        try:
                            print "Translating: %s" % id
                            ret = self.api.translate(id, src_lang, dest_lang)
                            strs.append(ret)
                        except Exception as inst2:
                            strs.append('')
                            print "Caught Exception %s" % inst2

                strs_replaced = []
                for astr in strs:
                    ttokens = re.findall('(GT\d*)', astr)
                    if ttokens and len(ttokens) > 0:
                        for ttoken in ttokens:
                            print "Finding %s" % ttoken
                            if ttoken in tokens:
                                astr = astr.replace(ttoken, tokens[ttoken])
                    strs_replaced.append(astr)
                assert len(ids) == len(strs_replaced) == len(entries)

                for msg_str, e in zip(strs_replaced, entries):
                    e.msgstr = msg_str.strip()

                ids = []
                entries = []
                tokens = dict()
                lastnum = 0

        pofile.save(dest_file)