예제 #1
0
def extract_relay_locations_pot(countries):
    pot = POFile(encoding='utf-8', check_for_duplicates=True)
    pot.metadata = {"Content-Type": "text/plain; charset=utf-8"}
    output_path = path.join(LOCALE_OUT_DIR, RELAY_LOCATIONS_POT_FILENAME)

    print("Generating {}".format(output_path))

    for country in countries:
        country_name = country.get("name")
        if country_name is not None:
            entry = POEntry(msgid=country_name,
                            msgstr="",
                            comment=country.get("code").upper())
            pot.append(entry)
            print("{} ({})".format(country_name, country.get("code")))

        cities = country.get("cities")
        if cities is not None:
            for city in cities:
                city_name = city.get("name")
                if city_name is not None:
                    entry = POEntry(msgid=city_name,
                                    msgstr="",
                                    comment="{} {}".format(
                                        country.get("code").upper(),
                                        city.get("code").upper()))

                    try:
                        pot.append(entry)
                    except ValueError as err:
                        print(c.orange("Cannot add an entry: {}".format(err)))

                    print("{} ({})".format(city_name, city.get("code")))

    pot.save(output_path)
예제 #2
0
def generate_po_from_tmx(f_path, entries):
    pofile = POFile()
    for tmx_entry in entries:
        po_entry = POEntry(msgid=tmx_entry.getsource(),
                           msgstr=tmx_entry.gettarget())
        pofile.append(po_entry)
    pofile.save(f_path)
예제 #3
0
    def test_success(self):
        with tempfile.NamedTemporaryFile(suffix=".pot") as potfile:
            poobj = POFile()
            poobj.append(POEntry(msgstr="test string"))
            poobj.save(potfile.name)

            self.assertTrue(testPOT(potfile.name))
예제 #4
0
    async def export_translation(lang):
        filename = f'export.{lang}.po'
        query = {'lang': lang}

        docs = await database['translations'].count_documents(query)
        res = await database['translations'].find(query).to_list(length=docs)

        po = POFile()
        po.metadata = {
            'Project-Id-Version': '1.0',
            'Report-Msgid-Bugs-To': '*****@*****.**',
            'POT-Creation-Date': '2020-10-04 21:00+0200',
            'PO-Revision-Date': '2020-10-04 21:00+0200',
            'Last-Translator': 'Support <*****@*****.**>',
            'Language-Team': 'English <*****@*****.**>',
            'MIME-Version': '1.0',
            'Content-Type': 'text/plain; charset=utf-8',
            'Content-Transfer-Encoding': '8bit'
        }

        if len(res) > 0:
            for value in res[0]['translation']:
                items = list(value.items())[0]

                entry = POEntry(msgid=items[0], msgstr=items[1])

                po.append(entry)

        po.save(f'./static/{filename}')

        if os.path.isfile(f'./static/{filename}'):
            return FileResponse(f'./static/{filename}')

        raise HTTPException(status_code=404, detail='Translation not found')
예제 #5
0
    def test_success(self):
        with tempfile.NamedTemporaryFile(suffix=".pot") as potfile:
            poobj = POFile()
            poobj.append(POEntry(msgstr="test string"))
            poobj.save(potfile.name)

            self.assertTrue(testPOT(potfile.name))
예제 #6
0
def extract_countries_po():
    input_path = get_shape_path("ne_50m_admin_0_countries")

    for locale in os.listdir(LOCALE_DIR):
        locale_dir = path.join(LOCALE_DIR, locale)
        locale_out_dir = path.join(LOCALE_OUT_DIR, locale)

        if os.path.isdir(locale_dir):
            with fiona.open(input_path) as source:
                po = POFile(encoding='UTF-8')
                po.metadata = {"Content-Type": "text/plain; charset=utf-8"}
                output_path = path.join(locale_out_dir, "countries.po")

                if not path.exists(locale_out_dir):
                    os.makedirs(locale_out_dir)

                print "Generating {}/countries.po".format(locale)

                for feat in source:
                    props = lower_dict_keys(feat["properties"])

                    name_key = "name_" + map_locale(locale)
                    name_fallback = "name"

                    country_name = props.get("name")
                    formal_country_name = props.get("formal_en", country_name)

                    if props.get(name_key) is not None:
                        translated_name = props.get(name_key)
                    elif props.get(name_fallback) is not None:
                        translated_name = props.get(name_fallback)
                        print c.orange(u" Missing translation for {}".format(
                            translated_name))
                    else:
                        raise ValueError(
                            "Cannot find the translation for {}. Probe keys: {}"
                            .format(locale, (name_key, name_fallback)))

                    entry = POEntry(msgid=country_name, msgstr=translated_name)
                    po.append(entry)

                    # add additional record for the formal country name.
                    if country_name != formal_country_name and formal_country_name is not None:
                        entry = POEntry(msgid=formal_country_name,
                                        msgstr=translated_name)
                        po.append(entry)

                    # exception for the US
                    if props.get("iso_a3") == "USA":
                        entry = POEntry(msgid="USA", msgstr=translated_name)
                        po.append(entry)

                    # exception for the UK
                    if props.get("iso_a3") == "GBR":
                        entry = POEntry(msgid="UK", msgstr=translated_name)
                        po.append(entry)

                po.save(output_path)
                print c.green("Extracted {} countries for {} to {}".format(
                    len(po), locale, output_path))
예제 #7
0
def extract_cities_po():
    input_path = get_shape_path("ne_50m_populated_places")
    stats = []

    for locale in os.listdir(LOCALE_DIR):
        locale_dir = path.join(LOCALE_DIR, locale)
        locale_out_dir = path.join(LOCALE_OUT_DIR, locale)

        if os.path.isdir(locale_dir):
            po = POFile(encoding='UTF-8')
            po.metadata = {"Content-Type": "text/plain; charset=utf-8"}
            output_path = path.join(locale_out_dir, "cities.po")
            hits = 0
            misses = 0

            if not path.exists(locale_out_dir):
                os.makedirs(locale_out_dir)

            print "Generating {}/cities.po".format(locale)

            with fiona.open(input_path) as source:
                for feat in source:
                    props = lower_dict_keys(feat["properties"])

                    if props["pop_max"] >= POPULATION_MAX_FILTER:
                        name_key = "_".join(
                            ("name", get_locale_language(locale)))
                        name_alt_key = "_".join(
                            ("name", convert_locale_ident(locale)))
                        name_fallback = "name"

                        if props.get(name_key) is not None:
                            translated_name = props.get(name_key)
                            hits += 1
                        elif props.get(name_alt_key) is not None:
                            translated_name = props.get(name_alt_key)
                            hits += 1
                        elif props.get(name_fallback) is not None:
                            translated_name = props.get(name_fallback)
                            print c.orange(
                                u"  Missing translation for {}".format(
                                    translated_name))
                            misses += 1
                        else:
                            raise ValueError(
                                "Cannot find the translation for {}. Probe keys: {}"
                                .format(locale, (name_key, name_alt_key)))

                        entry = POEntry(msgid=props["name"],
                                        msgstr=translated_name)
                        po.append(entry)

            po.save(output_path)
            print c.green("Extracted {} cities to {}".format(
                len(po), output_path))

            stats.append((locale, hits, misses))

    print_stats_table("Cities translations", stats)
예제 #8
0
    def test_all_failure(self):
        with tempfile.NamedTemporaryFile(suffix=".pot") as potfile:
            poobj = POFile()
            poobj.append(POEntry(msgstr="pest string"))
            poobj.append(POEntry(msgstr="past string"))
            poobj.save(potfile.name)

            self.assertFalse(testPOT(potfile.name))
예제 #9
0
    def test_all_failure(self):
        with tempfile.NamedTemporaryFile(suffix=".pot") as potfile:
            poobj = POFile()
            poobj.append(POEntry(msgstr="pest string"))
            poobj.append(POEntry(msgstr="past string"))
            poobj.save(potfile.name)

            self.assertFalse(testPOT(potfile.name))
    def handle(self, *args, **options):
        """Run the command.
        """
        # Settings.
        locale_dir = settings.COLLECTMESSAGES_PATH
        languages = settings.COLLECTMESSAGES_LANGUAGES
        metadata = getattr(settings, "COLLECTMESSAGES_METADATA", {})

        # Generate a POT-file.
        if options["pot-file"]:

            # Verbose.
            if options["verbosity"]:
                self.stdout.write(
                    "collect_messages: processing POT-file")

            # Create the output directory.
            if not os.path.exists(locale_dir):
                os.makedirs(locale_dir)

            # Build the POT-file.
            potfile = POFile()
            potfile.metadata = metadata
            for message in self._find_all(verbose=options["verbosity"]):
                potfile.append(message)

            # Save the POT-file.
            potfile_path = os.path.join(locale_dir, "django.pot")
            potfile.save(potfile_path)

        # Generate PO-files for all languages.
        for language in languages:

            # Verbose.
            if options["verbosity"]:
                self.stdout.write(
                    "collect_messages: processing language '%s'" % language)

            # Create the output directory.
            message_dir = os.path.join(locale_dir, language, "LC_MESSAGES")
            if not os.path.exists(message_dir):
                os.makedirs(message_dir)

            # Build a PO-file.
            pofile = POFile()
            pofile.metadata = metadata
            for message in self._find_all(language=language,
                                          verbose=options["verbosity"]):
                pofile.append(message)

            # Save the PO-file.
            pofile_path = os.path.join(message_dir, "django.po")
            pofile.save(pofile_path)

            # Save the MO-file.
            if options["compile"]:
                mofile_path = os.path.join(message_dir, "django.mo")
                pofile.save_as_mofile(mofile_path)
예제 #11
0
def main():
    out_dir = os.path.join(os.path.dirname(__file__), "archetypes", "en",
                           "LC_MESSAGES")
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    out_path = os.path.join(out_dir, "django.po")

    po = POFile()
    po.metadata = {
        "Project-Id-Version": "hsreplaynet",
        "Report-Msgid-Bugs-To": "",
        "POT-Creation-Date": datetime.now().isoformat(),
        "Last-Translator": "HearthSim <*****@*****.**>",
        "Language-Team": "English",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=utf-8",
        "Content-Transfer-Encoding": "8bit",
    }

    r = requests.get("https://api.hsreplay.net/v1/archetypes/")
    for archetype in r.json():
        name = archetype.get("name", "")
        url = archetype.get("url", "")
        if not name or not url:
            continue

        entry = POEntry(msgid=name,
                        msgstr="",
                        occurrences=[("https://hsreplay.net" + url, "")])
        po.append(entry)

    htd_r = requests.get(
        "http://www.hearthstonetopdecks.com/wp-json/hsreplay/guides")
    for archetype_desc in htd_r.json():
        desc = archetype_desc.get("hsreplay_guide_snippet", "")
        url = archetype_desc.get("url", "")

        if not desc or not url:
            continue

        entry = POEntry(msgid=desc, msgstr="", occurrences=[(url, "")])

        if entry in po:
            # upstream duplicate
            continue

        po.append(entry)

    po.save(out_path)
    print(f"Written {out_path}")
예제 #12
0
def extract_cities_pot():
    input_path = get_shape_path("ne_50m_populated_places")
    input_basename = path.basename(input_path)
    output_path = path.join(OUT_DIR, "cities.pot")

    for locale in os.listdir(LOCALE_DIR):
        locale_dir = path.join(LOCALE_DIR, locale)
        locale_out_dir = path.join(LOCALE_OUT_DIR, locale)

        if os.path.isdir(locale_dir):
            pot = POFile(encoding='UTF-8')
            output_path = path.join(locale_out_dir, "cities.po")

            if not path.exists(locale_out_dir):
                os.makedirs(locale_out_dir)

            print "Generating {}/cities.po".format(locale)

            with fiona.open(input_path) as source:
                for feat in source:
                    props = lower_dict_keys(feat["properties"])

                    if props["pop_max"] >= POPULATION_MAX_FILTER:
                        name_key = "_".join(
                            ("name", get_locale_language(locale)))
                        name_alt_key = "_".join(
                            ("name", convert_locale_ident(locale)))
                        name_fallback = "name"

                        if props.get(name_key) is not None:
                            translated_name = props.get(name_key)
                        elif props.get(name_alt_key) is not None:
                            translated_name = props.get(name_alt_key)
                        elif props.get(name_fallback) is not None:
                            translated_name = props.get(name_fallback)
                            print u"Missing translation for {}".format(
                                translated_name)
                        else:
                            raise ValueError(
                                "Cannot find the translation for {}. Probe keys: {}"
                                .format(locale, (name_key, name_alt_key)))

                        entry = POEntry(msgid=props["name"],
                                        msgstr=translated_name,
                                        occurrences=[(input_basename,
                                                      feat["id"])])
                        pot.append(entry)

            pot.save(output_path)
            print "Extracted {} cities to {}".format(len(pot), output_path)
예제 #13
0
    def save_po(self, path, json_root_key, lang):
        """
        Save Gettext PO file into directory structure as "path/lang/json_root_key.po"
        If "path/lang/json_root_key.po" already exists, it will be updated accordingly to JSON dict
        :param path: Root directory where place to files
        :param json_root_key: JSON key from RcgJsonKeys class
        :param lang: Language to translate. Should be in RcgLanguages class
        :return:
        """
        language = next(name for name in RcgLanguages
                        if name.value["iso_code"] == lang)
        save_path = join(path, lang)
        save_file = join(save_path, json_root_key.value + ".po")

        if not exists(save_path):
            makedirs(save_path)
        if exists(save_file):
            # File already exists, let's try to update it
            logging.info("Updating '{}'...".format(save_file))
            po = pofile(save_file)
            pot = self.generate_pot(json_root_key)
            po.merge(pot)
            po.save(save_file)
        else:
            # File does not exists, create it from JSON data
            logging.info("Creating '{}'...".format(save_file))
            po = POFile(check_for_duplicates=True)
            po.metadata = METADATA_ENTRY

            for entry in self.json_content[json_root_key.value]:
                if entry[RcgLanguages.LANG_ENGLISH.value["key"]] != "":
                    po_entry = POEntry(
                        msgctxt=entry[LANG_KEY],
                        msgid=entry[RcgLanguages.LANG_ENGLISH.value["key"]],
                    )
                    if language.value["key"] in entry and entry[
                            language.value["key"]] is not None:
                        po_entry.msgstr = entry[language.value["key"]]
                        po_entry.flags.append("fuzzy")
                    try:
                        po.append(po_entry)
                    except ValueError:
                        logging.debug(
                            "Entry {} already exists, skipping...".format(
                                entry[LANG_KEY]))

            po.save(save_file)

        return
예제 #14
0
def extract_countries_po():
  input_path = get_shape_path("ne_50m_admin_0_countries")

  for locale in os.listdir(LOCALE_DIR):
    locale_dir = path.join(LOCALE_DIR, locale)
    locale_out_dir = path.join(LOCALE_OUT_DIR, locale)

    if os.path.isdir(locale_dir):
      with fiona.open(input_path) as source:
        po = POFile(encoding='UTF-8')
        po.metadata = {"Content-Type": "text/plain; charset=utf-8"}
        output_path = path.join(locale_out_dir, "countries.po")

        if not path.exists(locale_out_dir):
          os.makedirs(locale_out_dir)

        print "Generating {}/countries.po".format(locale)

        for feat in source:
          props = lower_dict_keys(feat["properties"])
          name_key = "_".join(("name", get_locale_language(locale)))
          name_alt_key = "_".join(("name", convert_locale_ident(locale)))
          name_fallback = "name"

          if props.get(name_key) is not None:
            translated_name = props.get(name_key)
          elif props.get(name_alt_key) is not None:
            translated_name = props.get(name_alt_key)
          elif props.get(name_fallback) is not None:
            translated_name = props.get(name_fallback)
            print c.orange(u" Missing translation for {}".format(translated_name))
          else:
            raise ValueError(
              "Cannot find the translation for {}. Probe keys: {}"
              .format(locale, (name_key, name_alt_key))
              )

          entry = POEntry(
            msgid=props["name"],
            msgstr=translated_name
          )
          po.append(entry)

        po.save(output_path)
        print c.green("Extracted {} countries for {} to {}".format(len(po), locale, output_path))
예제 #15
0
def extract_relay_locations_pot(countries):
  pot = POFile(encoding='UTF-8')
  pot.metadata = {"Content-Type": "text/plain; charset=utf-8"}
  output_path = path.join(LOCALE_OUT_DIR, "relay-locations.pot")

  print "Generating relay-locations.pot"

  for country in countries:
    cities = country.get("cities")
    if cities is not None:
      for city in cities:
        city_name = city.get("name")
        if city_name is not None:
          entry = POEntry(
            msgid=city_name,
            msgstr=u"",
            comment=u"{} {}".format(country.get("code").upper(), city.get("code").upper())
          )
          pot.append(entry)
          print u"  {} ({})".format(city["name"], city["code"]).encode('utf-8')

  pot.save(output_path)
def main():
    out_dir = os.path.join(os.path.dirname(__file__), "compositions", "en",
                           "LC_MESSAGES")
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    out_path = os.path.join(out_dir, "django.po")

    po = POFile()
    po.metadata = {
        "Project-Id-Version": "hsreplaynet",
        "Report-Msgid-Bugs-To": "",
        "POT-Creation-Date": datetime.now().isoformat(),
        "Last-Translator": "HearthSim <*****@*****.**>",
        "Language-Team": "English",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=utf-8",
        "Content-Transfer-Encoding": "8bit",
    }

    r = requests.get("https://hsreplay.net/api/v1/compositions/")
    for composition in r.json():
        name = composition.get("name", "")
        if not name:
            continue

        entry = POEntry(
            msgid=name,
            msgstr="",
        )

        if entry in po:
            # duplicate
            continue

        po.append(entry)

    po.save(out_path)
    print(f"Written {out_path}")
예제 #17
0
class Translator:
    def __init__(self, locale, version):
        self.pot = POFile(check_for_duplicate=True)
        self.pot.metadata = {
            'Project-Id-Version': version,
            'POT-Creation-Date': str(datetime.now()),
            'MIME-Version': '1.0',
            'Content-Type': 'text/plain; charset=utf-8',
        }

        (Path('.') / 'locale').mkdir(exist_ok=True)
        self.languages = locale.split('+')
        for lang in self.languages:
            if gettext.find('content',
                            localedir=Path('.') / 'locale',
                            languages=[lang]) is None:
                mo_path = Path(
                    '.') / 'locale' / lang / 'LC_MESSAGES' / 'content.mo'
                po_path = Path(
                    '.') / 'locale' / lang / 'LC_MESSAGES' / 'content.po'
                if po_path.exists():
                    print(
                        f'The file "{str(mo_path)}" not found.\nUsing "{str(po_path)}" instead.'
                    )
                    pofile(po_path).save_as_mofile(mo_path)
                    print(f'"{str(mo_path)}" generated.')
                else:
                    print(
                        f'The file "{str(mo_path)}" or "{str(po_path)}" not found.'
                    )
                    print(f'Using the original Lean files for "{lang}".\n')
            self.translations = [
                gettext.translation('content',
                                    localedir=Path('.') / 'locale',
                                    languages=[lang],
                                    fallback=True) for lang in self.languages
            ]

        self.original_texts = []
        self.translated_texts = [[] for lang in self.languages]

        self.occ = None

    def save_pot(self):
        pot_path = Path('.') / 'locale' / 'content.pot'
        self.pot.save(pot_path)
        proc = subprocess.run(['msguniq', str(pot_path)],
                              stdout=subprocess.PIPE)
        pot_path.write_text(proc.stdout.decode())

    def register(self,
                 text: str,
                 translatable: bool,
                 lean_lines=False,
                 occ=None) -> str:
        if not occ:
            occ = self.occ
        self.original_texts.append(text)
        if translatable and lean_lines:
            lines = text.split('\n')
            translated_lines = [text.split('\n') for lang in self.languages]
            for i, line in enumerate(lines):
                if '--' in line:
                    for l in range(len(self.languages)):
                        translated_lines[l][i] = self.translations[l].gettext(
                            line)
                    self.pot.append(
                        POEntry(msgid=line, occurrences=[(occ, '')]))
            for l in range(len(self.languages)):
                self.translated_texts[l].append('\n'.join(translated_lines[l]))
        elif translatable:
            self.pot.append(POEntry(msgid=text, occurrences=[(occ, '')]))
            for l in range(len(self.languages)):
                self.translated_texts[l].append(
                    self.translations[l].gettext(text))
        else:
            for l in range(len(self.languages)):
                self.translated_texts[l].append(text)

        return str(len(self.original_texts) - 1)
예제 #18
0
def translate_single_relay_locations(country_translator, city_translator, countries, locale):
  """
  A helper function to generate the relay-locations.po for the given locale.

  The `countries` argument is an array value that's contained within the "countries" key of the
  relay location list.
  """

  po = POFile(encoding='utf-8', check_for_duplicates=True)
  po.metadata = {"Content-Type": "text/plain; charset=utf-8"}
  locale_out_dir = path.join(LOCALE_OUT_DIR, locale)
  output_path = path.join(locale_out_dir, RELAY_LOCATIONS_PO_FILENAME)

  hits = 0
  misses = 0

  if not path.exists(locale_out_dir):
    os.makedirs(locale_out_dir)

  for country in countries:
    country_name = country.get("name")
    country_code = country.get("code")

    translated_country_name = country_translator.translate(locale, country_code)
    found_country_translation = translated_country_name is not None
    # Default to empty string if no translation was found
    if found_country_translation:
      hits += 1
    else:
      translated_country_name = ""
      misses += 1

    log_message = "{} ({}) -> \"{}\"".format(country_name, country_code, translated_country_name)
    if found_country_translation:
      print(c.green(log_message))
    else:
      print(c.orange(log_message))

    # translate country
    entry = POEntry(
      msgid=country_name,
      msgstr=translated_country_name,
      comment=country_code.upper()
    )
    po.append(entry)

    # translate cities
    cities = country.get("cities")
    if cities is None:
      print(c.orange("Skip {} ({}) because no cities were found."
        .format(country_name, country_code)))
      continue

    for city in cities:
      city_name = city.get("name")
      city_code = city.get("code")
      if city_name is None:
        raise ValueError("Missing the name field in city record.")

      # Make sure to append the US state back to the translated name of the city
      if country_code == "us":
        split = city_name.rsplit(",", 2)
        translated_name = city_translator.translate(locale, split[0].strip())

        if translated_name is not None and len(split) > 1:
          translated_name = "{}, {}".format(translated_name, split[1].strip())
      else:
        translated_name = city_translator.translate(locale, city_name)

      # Default to empty string if no translation was found
      found_translation = translated_name is not None
      if found_translation:
        hits += 1
      else:
        translated_name = ""
        misses += 1

      log_message = "{} ({}) -> \"{}\"".format(city_name, city_code, translated_name)
      if found_translation:
        print(c.green(log_message))
      else:
        print(c.orange(log_message))

      entry = POEntry(
        msgid=city_name,
        msgstr=translated_name,
        comment="{} {}".format(country_code.upper(), city_code.upper())
      )

      try:
        po.append(entry)
      except ValueError as err:
        print(c.orange("Cannot add an entry: {}".format(err)))

  po.save(output_path)

  return (hits, misses)
예제 #19
0
def translate_relay_locations(place_translator, countries, locale):
  po = POFile(encoding='UTF-8')
  po.metadata = {"Content-Type": "text/plain; charset=utf-8"}
  locale_out_dir = path.join(LOCALE_OUT_DIR, locale)
  output_path = path.join(locale_out_dir, "relay-locations.po")

  hits = 0
  misses = 0

  if not path.exists(locale_out_dir):
    os.makedirs(locale_out_dir)

  for country in countries:
    country_name = country.get("name")
    country_code = country.get("code")
    cities = country.get("cities")

    if cities is None:
      print c.orange(u"Skip {} ({}) because no cities were found.".format(
        country_name, country_code))
      continue

    for city in cities:
      city_name = city.get("name")
      city_code = city.get("code")
      if city_name is None:
        raise ValueError("Missing the name field in city record.")

      # Make sure to append the US state back to the translated name of the city
      if country_code == "us":
        split = city_name.rsplit(",", 2)
        translated_name = place_translator.translate(locale, split[0].strip())

        if translated_name is not None and len(split) > 1:
          translated_name = u"{}, {}".format(translated_name, split[1].strip())
      else:
        translated_name = place_translator.translate(locale, city_name)

      # Default to empty string if no translation was found
      found_translation = translated_name is not None
      if found_translation:
        hits += 1
      else:
        translated_name = ""
        misses += 1

      log_message = u"  {} ({}) -> \"{}\"".format(
        city_name, city_code, translated_name).encode('utf-8')
      if found_translation:
        print c.green(log_message)
      else:
        print c.orange(log_message)

      entry = POEntry(
        msgid=city_name,
        msgstr=translated_name,
        comment=u"{} {}".format(country.get("code").upper(), city.get("code").upper())
      )
      po.append(entry)

  po.save(output_path)

  return (hits, misses)
예제 #20
0
def extract_cities_po():
    input_path = get_shape_path("ne_50m_populated_places")
    stats = []

    for locale in os.listdir(LOCALE_DIR):
        locale_dir = path.join(LOCALE_DIR, locale)
        locale_out_dir = path.join(LOCALE_OUT_DIR, locale)

        if os.path.isdir(locale_dir):
            po = POFile(encoding='utf-8', check_for_duplicates=True)
            po.metadata = {"Content-Type": "text/plain; charset=utf-8"}
            output_path = path.join(locale_out_dir, CITIES_PO_FILENAME)
            hits = 0
            misses = 0

            if not path.exists(locale_out_dir):
                os.makedirs(locale_out_dir)

            print("Generating {}".format(output_path))

            with fiona.open(input_path) as source:
                for feat in source:
                    props = lower_dict_keys(feat["properties"])

                    if props["pop_max"] >= POPULATION_MAX_FILTER:
                        name_key = "name_" + map_locale(locale)
                        name_fallback = "name"

                        if props.get(name_key) is not None:
                            translated_name = props.get(name_key)
                            hits += 1
                        elif props.get(name_fallback) is not None:
                            translated_name = props.get(name_fallback)
                            print(
                                c.orange("Missing translation for {}".format(
                                    translated_name)))
                            misses += 1
                        else:
                            raise ValueError(
                                "Cannot find the translation for {}. Probe keys: {}"
                                .format(locale, (name_key, name_fallback)))

                        entry = POEntry(msgid=props.get("name"),
                                        msgstr=translated_name)

                        try:
                            po.append(entry)
                        except ValueError as err:
                            print(
                                c.orange(
                                    "Cannot add an entry: {}".format(err)))

            sort_pofile_entries(po)
            po.save(output_path)
            print(
                c.green("Extracted {} cities to {}".format(
                    len(po), output_path)))

            stats.append((locale, hits, misses))

    print_stats_table("Cities translations", stats)
예제 #21
0
def save_pofile_as_pofile_and_mofile(pofile: polib.POFile, pofile_path: str):
    """Returns pofile_abspath, mofile_abspath"""
    pofile.save(pofile_path)
    mofilepath = re.sub(r"\.po$", ".mo", pofile_path)
    pofile.save_as_mofile(mofilepath)
    return (pofile_path, mofilepath)
예제 #22
0
def command_main_po(from_language, to_language, input, output=None, po=None, pot=None, pdf=False, undetected_strings=[], fake=None):
    extension=input.split(".")[1:][0]

    if output is None:
        output=f"{input}.{to_language}.{extension}"
    if po is None:
        po=f"{input}.{to_language}.po"
    if pot is None:
        pot=f"{input}.{to_language}.pot"
        
    logfile=f"{output}.log"
    log=open(logfile, "w")


    s=_(f"Translating '{input}' from '{from_language }' to '{to_language}'")
    print(s)
    log.write(s+"\n")
    s=_(f"  - Output: {output}")
    print(s)
    log.write(s+"\n")
    s=_(f"  - File catalog pot: {pot}")
    print(s)
    log.write(s+"\n")
    s=_(f"  - File catalog po: {po}")
    print(s)
    log.write(s+"\n")
    s=_(f"  - Translation log: {logfile}")
    print(s)
    log.write(s+"\n")
    
    original_xlf="original.xlf"
    if path.exists(original_xlf) is True:
        remove(original_xlf)
    
    doc=ODT(input)
    
    
    # Creating a list of ordered document strings
    run_check(["odf2xliff", input, original_xlf])
    ##Leemos sources
    mytree = ET.parse(original_xlf)
    myroot = mytree.getroot()
    file_=myroot[0]
    body=file_[0]
    sources=set()
    for e in body:
        if e[0].text is not None:#<source>
            s=innercontent(e[0])
            arr=removeTags(s)
            for t in arr:
                sources.add(t)
                
    for s in undetected_strings:
        sources.add(s)
    sources=list(sources)

    
    
    
    if path.exists(original_xlf) is True:
        remove(original_xlf)
    
    # Creating pot file
    file_pot = POFile()
    file_pot.metadata = {
        'Project-Id-Version': '1.0',
        'Report-Msgid-Bugs-To': '*****@*****.**',
        'POT-Creation-Date': '2007-10-18 14:00+0100',
        'PO-Revision-Date': '2007-10-18 14:00+0100',
        'Last-Translator': 'you <*****@*****.**>',
        'Language-Team': 'English <*****@*****.**>',
        'MIME-Version': '1.0',
        'Content-Type': 'text/plain; charset=utf-8',
        'Content-Transfer-Encoding': '8bit',
    }
    for i,  source in enumerate(sources):
        entry = POEntry(
            msgid=source,
            msgstr='', 
            occurrences=[('string', str(i)),]
        )
        file_pot.append(entry)
    file_pot.save(pot)
    
    #Merging pot with out po file
    if path.exists(po)==False:
        run_check(["msginit", "-i", pot,  "-o", po])
    run_check(["msgmerge","-N", "--no-wrap","-U", po, pot])
    
    # Creates a dictionary of translations
    dict_po={}
    file_po = pofile(po)
    for i, entry in enumerate(file_po):
        if fake is True:
            dict_po[entry.msgid]=f"{{{entry.msgid}}}"
        else:
            if entry.msgstr == "":
                dict_po[entry.msgid]=entry.msgid
            else:
                dict_po[entry.msgid]=entry.msgstr
        
    #Converts sources to entries (list of tuples)
    entries=[]
    for source in sources:
        entries.append((source, dict_po[source] ))
    entries=sorted(entries,  key=lambda item: len(item[0]), reverse=True)
    
    
    #Creating our translated output
    log.write ("\n\n==== TRANSLATION LOGS ====\n")
    warns=""
    for i, (find, replace) in enumerate(entries):
        number=doc.findall_and_replace(find,  replace)
        rs=replaced_entries_before(find,  i,  entries)
        s=f"""
* Entry {i}

    Original: {find}

    Translation set {number} times: {replace}
"""
        log.write(s)
        if len(rs)>0:
            warns=warns + s +"    WARNING: This replacement could overwrite before replacements. Perhaps you'll need to overwrite your result later with unogenerator.\n"
            for s in rs:
                warns =warns + f"        - '{s[0]}' ==> '{s[1]}'\n"
                
    if warns!="":
        log.write ("\n\n==== WARNINGS ====\n")
        log.write(warns)
            
    doc.save(output)
    if pdf is True:
        doc.export_pdf(output+".pdf")
    doc.close()
    print(f"{len(sources)} messages found. {len(file_po.translated_entries())} translated. {len(file_po.untranslated_entries())} untranslated.")
    
    log.close()
예제 #23
0
def command_generate_po(from_language, to_language, input, output_directory, translate,  undetected_strings=[]):   
    def same_entries_to_ocurrences(l):
        l= sorted(l, key=lambda x: (x[1], x[2], x[3]))
        r=[]
        for filename, type, number,  position,  text in l:
            r.append((filename, f"{type}#{number}#{position}"))
        return r
        
        ##########################
        
    makedirs(output_directory, exist_ok=True)
    makedirs(f"{output_directory}/{to_language}", exist_ok=True)
    
    pot=f"{output_directory}/catalogue.pot"
    po=f"{output_directory}/{to_language}/{to_language}.po"
        
    entries=[]#List of ("type", numero, posicion) type=Paragraph, numero=numero parrafo y posición orden dentro del parrafo
    set_strings=set()
    # Creating pot file
    print(_("Extracting strings from:"))
    for filename in input:
        print(_(f"   - {filename}"))
        doc=ODT(filename)

        #Extract strings from paragraphs
        enumeration = doc.cursor.Text.createEnumeration()
        for i,  par in enumerate(enumeration):
            if  par.supportsService("com.sun.star.text.Paragraph") :
                for position, element in enumerate(par.createEnumeration()):
                    text_=element.getString()
                    if text_ !="" and text_!=" " and text_!="  ":
                        entries.append((filename,"Paragraph",  i,  position, text_))
                        set_strings.add(text_)
        doc.close()
    
    #Extract strings from headers
#    ' Turn headers on and then make them shared!
#oPstyle.HeaderOn = True
#oPstyle.HeaderShared = True
#' The is also a RightText and a LeftText
#oHeader = oPstyle.RightPageHeaderContent
#oText = oHeader.CenterText
#' You may now set the text object to be anything you desire
#' Use setSTring() from the text object to set simple text.
#' Use a cursor to insert a field (such as the current sheet name).
#' First, clear any existing text!
#oText.setString("")
#oCursor = oText.createTextCursor()
#oText.insertString(oCursor, "Sheet: ", False)
#' This will have the sheet name of the current sheet!
#sService = "com.sun.star.text.TextField.SheetName"
#oField = oDoc.createInstance(sService)
#oText.insertTextContent(oCursor, oField, False)
    
        
    file_pot = POFile()
    file_pot.metadata = {
        'Project-Id-Version': '1.0',
        'Report-Msgid-Bugs-To': '*****@*****.**',
        'POT-Creation-Date': '2007-10-18 14:00+0100',
        'PO-Revision-Date': '2007-10-18 14:00+0100',
        'Last-Translator': 'you <*****@*****.**>',
        'Language-Team': 'English <*****@*****.**>',
        'MIME-Version': '1.0',
        'Content-Type': 'text/plain; charset=utf-8',
        'Content-Transfer-Encoding': '8bit',
    }
    for s in set_strings:
        same_entries=[] #Join seame text entries
        for filename, type, number, position, string_ in entries:
            if string_==s:
                same_entries.append((filename, type, number, position, string_))

        entry = POEntry(
            msgid=s,
            msgstr='', 
            occurrences=same_entries_to_ocurrences(same_entries)
        )
        file_pot.append(entry)
    file_pot.save(pot)
    
    #Merging pot with out po file
    if path.exists(po)==False:
        run_check(["msginit", "-i", pot,  "-o", po])
    run_check(["msgmerge","-N", "--no-wrap","-U", po, pot])
    
    print(f"{len(set_strings)} different strings detected")
    
    
    if translate is True:
        print(_("Translating files to:"))
        for filename in input:
            doc=ODT(filename)
            output=f"{output_directory}/{to_language}/{path.basename(filename)}"
            print(_(f"   - {output}"))
            doc.save(output)
            doc.close()
예제 #24
0
def mergepo(o, a, b):
    workingpath = os.getcwd()

    ofile = pofile(os.path.join(workingpath, o))
    odict = makedict(ofile)
    afile = pofile(os.path.join(workingpath, a))
    adict = makedict(afile)
    bfile = pofile(os.path.join(workingpath, b))
    bdict = makedict(bfile)

    temp_dir = tempfile.mkdtemp('', 'gitmergepo-')
    #temp_file = tempfile.mkstemp(dir=temp_dir)
    temp_po = POFile()
    conflicts = 0

    # Process all the ancestor entries
    for oentry in ofile:
        aentry = adict.get(oentry.msgid, None)
        bentry = bdict.get(oentry.msgid, None)
        result = merge_entry(oentry, aentry, bentry, b)
        odict[oentry.msgid] = result[0]
        delete_key(oentry.msgid, adict)
        delete_key(oentry.msgid, bdict)

        if result[1]:
            conflicts += 1

    # Process newly created entries in a & b
    for key, value in adict.iteritems():
        bentry = bdict.get(key, None)
        result = merge_entry(None, value, bentry, b)
        odict[key] = result[0]
        delete_key(key, bdict)

        if result[1]:
            conflicts += 1

    # Process newly created entries in b
    for key, value in bdict.iteritems():
        odict[value.msgid] = value

    # Append all entries to the temp po file
    for item in sorted(odict.iteritems()):
        temp_po.append(item[1])

    # Export the merged po file
    temp_po.metadata = afile.metadata
    temp_po.header = 'Merged by git-mergepo ...' + temp_po.header
    #temp_po.save(fpath=temp_file[1])
    temp_po.save(fpath=a)
    shutil.rmtree(temp_dir)

    #print 'Dicts: ', len(odict), ', ', len(adict), ', ', len(bdict)
    #print 'Path: ', workingpath
    #print 'Conflicts: ', conflicts

    # If conflicts were found we exit with status 1
    if conflicts > 0:
        print '\n!!! TRANSLATION CONFLICTS: %s !!!\n' % conflicts
        sys.exit(1)
    sys.exit(0)