123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- #!/usr/bin/env python3
- try:
- from deep_translator import GoogleTranslator
- except ModuleNotFoundError:
- print('You need to install deep-translator. If you have no better idea, try:')
- print('pip install deep-translator')
- exit(1)
- import argparse
- import io
- import os
- from pathlib import Path
- import polib
- import sys
- import textwrap
- import time
- # Available Translators from deep-translator
- '''
- from deep_translator import (GoogleTranslator, PonsTranslator,
- LingueeTranslator, MyMemoryTranslator,
- YandexTranslator, DeepL,
- QCRI, single_detection,
- batch_detection)
- '''
- _my_name = os.path.basename(__file__)
- _my_input_default = 'my_strings.po'
- _my_output_default = 'auto_strings.po'
- DESCRIPTION = """
- You may need to install deep-translator, e.g.
- > pip install deep-translator
- Opens the INFILE, assumed to be in 'english',
- and the needed language selected as --language
- Replace all (-r), or just fill in the missing translations ('msgstr':s),
- and save to OUTFILE
- """
- USAGE_EXAMPLE = f"""
- Examples:
- > ./{_my_name} -i input.pot -l danish -o output.da.po
- > ./{_my_name} -i input.po -l danish -o output.da.po --replace
- In case you did not get them all, or already have most of them:
- > ./{_my_name} -i test.da.po -l danish -o test.da.po
- """
- def parse_arguments():
- parser = argparse.ArgumentParser(_my_name,
- formatter_class=argparse.RawDescriptionHelpFormatter,
- description=textwrap.dedent(DESCRIPTION),
- epilog=textwrap.dedent(USAGE_EXAMPLE))
- add = parser.add_argument
- add('-r', '--replace', action='store_true',
- help='replace all translations (if using a .po file)')
- add('-q', '--quiet', action='store_true',
- help='be more quiet')
- add('-v', '--verbose', action='store_true',
- help='be more verbose')
- add('-l', '--language', metavar='LANGUAGE',
- help='select language')
- add('-i', '--input', metavar='INFILE',
- required=True,
- help='.po or .pot file for extraction')
- add('-o', '--output', metavar='OUTFILE',
- default=_my_output_default,
- help='output .po file with results')
- return parser.parse_args()
- def has_valid_text(the_string):
- if the_string.isspace():
- return False
- if len(the_string):
- return True
- return False
- def translate_gettext_file(file_name, language, options):
- '''
- Look for msgid's then translate their msgstr to language,
- note that these files are (expected to be) coded as UTF-8
- '''
- pofile = polib.pofile(file_name)
- translator = GoogleTranslator(source='english', target=language)
- # Check if language is supported -- pointless
- '''
- available_languages = translator.get_supported_languages(as_dict=True)
- if not language in available_languages.values() or available_languages.keys():
- print(f'Sorry, this imported translator do not speak {language}')
- print(f'but they know')
- for language_code,language in available_languages.items():
- print(' ' +language+':'+language_code)
- return
- '''
- translations = 0
- fails = 0
- result = 'FAIL'
- for entry in pofile:
- source = entry.msgid
- if options.verbose:
- print(f'In: "{source}"')
- else:
- print('.', end="")
- if not source:
- continue
- if not has_valid_text(source):
- result = source
- else:
- if not options.replace:
- if has_valid_text(entry.msgstr):
- result = entry.msgstr
- if options.verbose:
- print(f'Keeping: {result}\n')
- continue
- retries = 5
- untranslated = True
- while retries:
- try:
- # number-only entry somehow can't be translated :(
- result = translator.translate(source)
- except:
- retries -= 1
- print(f'Exception, will try {retries} more after sleeping')
- time.sleep(1)
- result = ""
- else:
- untranslated = False
- translations += 1
- retries = 0
- if options.verbose:
- print(f'Got: {result}\n')
- if untranslated:
- fails += 1
- entry.msgstr = result
- if not options.verbose:
- print()
- print(f'Did {translations} translations')
- if fails:
- print(f'Left {fails} translations empty, rerun with -f')
- else:
- print('Everything is translated')
- if translations:
- pofile.save(options.output)
- else:
- print(' or did you forget --replace?')
- def main(options):
- # To be able to make debug-printout
- #sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
- #sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')
- input_file_name = options.input
- if not os.path.exists(input_file_name):
- print(f'{options.input}, from the -i option, does not exist - giving up')
- exit(3)
- start = time.time()
- translate_gettext_file(input_file_name, options.language, options)
- end = time.time()
- print('Total time:', end - start, 's')
- if __name__ == '__main__':
- main(parse_arguments())
|