1
\$\begingroup\$

I haven't thought of a nice way to remove #, fuzzy from the files. I think process_babel_file might possibly become its own module, but on the other hand, having all methods in one script is quite nice for the mean time. I expect there to be bugs, although it works for the languages I've tried.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
setuptranslations.py
Generate and manipulate translation files for a flask app.
Assumes areas in jinja2 templates are marked with {% trans %}..{% endtrans %}
or gettext, _, or other gettext variants.
Related: flask, flask-babel, pybabel, jinja2, i18n, gobabslate
 1. Run pybabel with extract option
 pybabel extract -F babel.cfg -o messages.pot .
 2. Run pybabel with init option for each language
 pybabel init -i messages.pot -d translations -l fr
 pybabel init -i messages.pot -d translations -l de
 3. Pull translations from Google Translate API into babel files
 4. Remove #fuzzy from message.po files.
 5. Run pybabel with compile option
 pybabel compile -d translations
"""
import sys
import codecs
from subprocess import Popen
from goslate import Goslate
pybabel_extract = ['pybabel', 'extract', '-F' 'babel.cfg',
 '-o' 'messages.pot', '.']
pybabel_init_lang = ['pybabel', 'init', '-i', 'messages.pot',
 '-d', 'translations', '-l']
pybabel_compile = ['pybabel', 'compile', '-d', 'translations']
def get_language_codes():
 try:
 from config import LANGUAGES, LANGUAGE_DEFAULT
 return [lang for lang in LANGUAGES.keys() if lang != LANGUAGE_DEFAULT]
 except:
 return ['fr', 'de']
def return_code(args):
 return Popen(args).communicate()[0]
def process_babel_file(lang, remove_fuzzy=False):
 gs = Goslate()
 filename = 'translations/' + lang + '/LC_MESSAGES/messages.po'
 file_stream = codecs.open(filename, 'r', 'utf-8')
 file_output = codecs.open(filename + '.tmp', 'w', 'utf-8')
 finding_input, data = False, u''
 for line in file_stream:
 if finding_input is True and line == u'msgstr ""\n':
 finding_input = False
 new_text = gs.translate(data, lang).replace('"', '\\"')
 file_output.write(u'msgstr "' + new_text + u'"\n')
 continue
 elif finding_input is True:
 data += line.replace('\n', ' ').replace('\\n"', ' ').strip('"')\
 .replace('\\"', '"')
 elif line == u'msgid ""\n' or line[:7] == u'msgid "':
 finding_input = True
 data = u'' if line == u'msgid ""\n' else line[7:].strip()\
 .strip('"').replace('\\"', '"')
 elif line == '#, fuzzy\n' and remove_fuzzy:
 continue
 file_output.write(line)
 file_stream.close()
 file_output.close()
 Popen(['cp', filename + '.tmp', filename]).communicate()
def main():
 if return_code(pybabel_extract) is not None:
 sys.exit('pybabel failed to extract translations')
 for language_code in get_language_codes():
 if return_code(pybabel_init_lang + [language_code]) is not None:
 print('Failed to add language: %s', language_code)
 continue
 process_babel_file(language_code, remove_fuzzy=True)
 if return_code(pybabel_compile) is not None:
 sys.exit('pybabel was unable to compile translations')
if __name__ == '__main__':
 main()
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 10, 2014 at 12:14
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Nice script! Found it very helpful to get started and test flask babel and see first translations.

A few "bugs" I discovered for your consideration

  • Any string with a ' will cause problems
  • Same with other special characters, e.g. ()

The resulting po file mixes entries later on and generates strings like:

#: dedri/templates/contact.html:29
msgid "Your email"
msgstr "Aboutmsgstr \"about (modificado por Raimundo)\" #: dedri / templates / about.html: 13 msgid \"Aquí añadimos unas pocas palabras acerca de cada uno de nosotros.\" msgstr \"Aquí añadimos Unas Palabras Sobre CADA UNO de Nosotros here.\" #: Dedri / templates / contact.html: 29 msgid \"Your email\"" 
Vogel612
25.5k7 gold badges59 silver badges141 bronze badges
answered Jun 27, 2014 at 12:26
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.