Unbundled translations, added new tools to bundle and pack translations

The only translation that is going to be bundled with OctoPrint for now will be .de, if at all. The reason simply being that this is the only translation I can update myself and hence guarantee a good user experience for.

setup.py now offers two new commands, babel_bundle and babel_pack, with which translations for plugins and core OctoPrint can be automatically bundled or packed as language packs once compiled. This should make sharing translations quite easy in the future.
This commit is contained in:
Gina Häußge 2015-06-02 13:38:08 +02:00
parent 7f8a3849c7
commit 5904d01bff
15 changed files with 2409 additions and 7076 deletions

View file

@ -74,9 +74,10 @@ def get_cmdclass():
cmdclass.update(dict(clean=octoprint_setuptools.CleanCommand.for_options(source_folder="src", eggs=["OctoPrint*.egg-info"])))
# add translation commands
translation_dir = os.path.join("src", "octoprint", "translations")
translation_dir = "translations"
pot_file = os.path.join(translation_dir, "messages.pot")
cmdclass.update(octoprint_setuptools.get_babel_commandclasses(pot_file=pot_file, output_dir=translation_dir))
bundled_dir = os.path.join("src", "octoprint", "translations")
cmdclass.update(octoprint_setuptools.get_babel_commandclasses(pot_file=pot_file, output_dir=translation_dir, pack_name_prefix="OctoPrint-i18n-", pack_path_prefix="", bundled_dir=bundled_dir))
return cmdclass

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -292,14 +292,149 @@ class CompileTranslation(Command):
self.babel_compile_messages.run()
def get_babel_commandclasses(pot_file=None, mapping_file="babel.cfg", input_dirs=".", output_dir=None, mail_address="i18n@octoprint.org", copyright_holder="The OctoPrint Project"):
return dict(
class BundleTranslation(Command):
description = "bundles translations"
user_options = [
('locale=', 'l', 'locale for the translation to bundle')
]
boolean_options = []
source_dir = None
target_dir = None
@classmethod
def for_options(cls, source_dir=None, target_dir=None):
if source_dir is None:
raise ValueError("source_dir must not be None")
if target_dir is None:
raise ValueError("target_dir must not be None")
return type(cls)(cls.__name__, (cls,), dict(
source_dir=source_dir,
target_dir=target_dir
))
def initialize_options(self):
self.locale = None
def finalize_options(self):
pass
def run(self):
locale = self.locale
source_path = os.path.join(self.__class__.source_dir, locale)
target_path = os.path.join(self.__class__.target_dir, locale)
if not os.path.exists(source_path):
raise RuntimeError("source path " + source_path + " does not exist")
if os.path.exists(target_path):
if not os.path.isdir(target_path):
raise RuntimeError("target path " + target_path + " exists and is not a directory")
shutil.rmtree(target_path)
print("Copying translations for locale {locale} from {source_path} to {target_path}...".format(**locals()))
shutil.copytree(source_path, target_path)
class PackTranslation(Command):
description = "bundles translations"
user_options = [
('locale=', 'l', 'locale for the translation to bundle'),
('author=', 'a', 'author of the translation')
]
boolean_options = []
source_dir = None
pack_name_prefix = None
pack_path_prefix = None
@classmethod
def for_options(cls, source_dir=None, pack_name_prefix=None, pack_path_prefix=None):
if source_dir is None:
raise ValueError("source_dir must not be None")
if pack_name_prefix is None:
raise ValueError("pack_name_prefix must not be None")
if pack_path_prefix is None:
raise ValueError("pack_path_prefix must not be None")
return type(cls)(cls.__name__, (cls,), dict(
source_dir=source_dir,
pack_name_prefix=pack_name_prefix,
pack_path_prefix=pack_path_prefix
))
def initialize_options(self):
self.locale = None
self.author = None
def finalize_options(self):
if self.locale is None:
raise ValueError("locale must be provided")
def run(self):
locale = self.locale
locale_dir = os.path.join(self.__class__.source_dir, locale)
if not os.path.isdir(locale_dir):
raise RuntimeError("translation does not exist, please create it first")
import datetime
now = datetime.datetime.utcnow().replace(microsecond=0)
zip_path = os.path.join(self.__class__.source_dir, "{prefix}{locale}_{date}.zip".format(prefix=self.__class__.pack_name_prefix, locale=locale, date=now.strftime("%Y%m%d%H%M%S")))
print("Packing translation to {zip_path}".format(**locals()))
def add_recursively(zip, path, prefix):
if not os.path.isdir(path):
return
for entry in os.listdir(path):
entry_path = os.path.join(path, entry)
new_prefix = prefix + "/" + entry
if os.path.isdir(entry_path):
add_recursively(zip, entry_path, new_prefix)
elif os.path.isfile(entry_path):
print("Adding {entry_path} as {new_prefix}".format(**locals()))
zip.write(entry_path, new_prefix)
meta_str = "last_update: {date}\n".format(date=now.isoformat())
if self.author:
meta_str += "author: {author}\n".format(author=self.author)
zip_locale_root = self.__class__.pack_path_prefix + locale
import zipfile
with zipfile.ZipFile(zip_path, "w") as zip:
add_recursively(zip, locale_dir, zip_locale_root)
print("Adding meta.yaml as {zip_locale_root}/meta.yaml".format(**locals()))
zip.writestr(zip_locale_root + "/meta.yaml", meta_str)
def get_babel_commandclasses(pot_file=None,
mapping_file="babel.cfg",
input_dirs=".",
output_dir=None,
pack_name_prefix=None,
pack_path_prefix=None,
bundled_dir=None,
mail_address="i18n@octoprint.org",
copyright_holder="The OctoPrint Project"):
result = dict(
babel_new=NewTranslation.for_options(pot_file=pot_file, output_dir=output_dir),
babel_extract=ExtractTranslation.for_options(mapping_file=mapping_file, pot_file=pot_file, input_dirs=input_dirs, mail_address=mail_address, copyright_holder=copyright_holder),
babel_refresh=RefreshTranslation.for_options(mapping_file=mapping_file, pot_file=pot_file, input_dirs=input_dirs, output_dir=output_dir, mail_address=mail_address, copyright_holder=copyright_holder),
babel_compile=CompileTranslation.for_options(output_dir=output_dir)
babel_compile=CompileTranslation.for_options(output_dir=output_dir),
babel_pack=PackTranslation.for_options(source_dir=output_dir, pack_name_prefix=pack_name_prefix, pack_path_prefix=pack_path_prefix)
)
if bundled_dir is not None:
result["babel_bundle"] = BundleTranslation.for_options(source_dir=output_dir, target_dir=bundled_dir)
return result
def create_plugin_setup_parameters(identifier="todo", name="TODO", version="0.1", description="TODO", author="TODO",
mail="todo@example.com", url="TODO", license="AGPLv3", additional_data=None,
@ -341,10 +476,11 @@ def create_plugin_setup_parameters(identifier="todo", name="TODO", version="0.1"
clean=CleanCommand.for_options(source_folder=package, eggs=eggs)
))
translation_dir = os.path.join(package, "translations")
translation_dir = os.path.join("translations")
pot_file = os.path.join(translation_dir, "messages.pot")
bundled_dir = os.path.join(package, "translations")
if os.path.isdir(translation_dir) and os.path.isfile(pot_file):
cmdclass.update(get_babel_commandclasses(pot_file=pot_file, output_dir=translation_dir))
cmdclass.update(get_babel_commandclasses(pot_file=pot_file, output_dir=translation_dir, bundled_dir=bundled_dir, pack_name_prefix="{name}-i18n-".format(**locals()), pack_path_prefix="_plugins/{identifier}/".format(**locals())))
return dict(
name=name,

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: OctoPrint 1.2.0-dev-880-gff9765f-dirty\n"
"Project-Id-Version: OctoPrint 1.2.0-dev-884-g449dd43-dirty\n"
"Report-Msgid-Bugs-To: i18n@octoprint.org\n"
"POT-Creation-Date: 2015-05-29 17:21+0200\n"
"POT-Creation-Date: 2015-06-02 13:09+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -98,6 +98,7 @@ msgstr ""
#: src/octoprint/plugins/cura/templates/cura_settings.jinja2:68
#: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:132
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:71
msgid "Browse..."
msgstr ""
@ -385,6 +386,7 @@ msgstr ""
#: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:51
#: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:143
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:82
msgid "Close"
msgstr ""
@ -465,77 +467,77 @@ msgid ""
"\".tar.gz\", \".tgz\" or \".tar\""
msgstr ""
#: src/octoprint/server/__init__.py:224
#: src/octoprint/server/views.py:123
msgid "Connection"
msgstr ""
#: src/octoprint/server/__init__.py:225
#: src/octoprint/server/views.py:124
msgid "State"
msgstr ""
#: src/octoprint/server/__init__.py:226
#: src/octoprint/server/views.py:125
msgid "Files"
msgstr ""
#: src/octoprint/server/__init__.py:232
#: src/octoprint/server/views.py:131
msgid "Temperature"
msgstr ""
#: src/octoprint/server/__init__.py:233
#: src/octoprint/server/views.py:132
msgid "Control"
msgstr ""
#: src/octoprint/server/__init__.py:234
#: src/octoprint/server/views.py:133
msgid "Terminal"
msgstr ""
#: src/octoprint/server/__init__.py:237
#: src/octoprint/server/views.py:136
msgid "GCode Viewer"
msgstr ""
#: src/octoprint/server/__init__.py:239
#: src/octoprint/server/views.py:138
#: src/octoprint/templates/sidebar/state.jinja2:3
msgid "Timelapse"
msgstr ""
#: src/octoprint/server/__init__.py:244
#: src/octoprint/server/views.py:143
msgid "Printer"
msgstr ""
#: src/octoprint/server/__init__.py:246
#: src/octoprint/server/views.py:145
msgid "Serial Connection"
msgstr ""
#: src/octoprint/server/__init__.py:247
#: src/octoprint/server/views.py:146
#: src/octoprint/templates/dialogs/settings/printerprofiles.jinja2:1
msgid "Printer Profiles"
msgstr ""
#: src/octoprint/server/__init__.py:248
#: src/octoprint/server/views.py:147
msgid "Temperatures"
msgstr ""
#: src/octoprint/server/__init__.py:249
#: src/octoprint/server/views.py:148
msgid "Terminal Filters"
msgstr ""
#: src/octoprint/server/__init__.py:250
#: src/octoprint/server/views.py:149
msgid "GCODE Scripts"
msgstr ""
#: src/octoprint/server/__init__.py:252 src/octoprint/server/__init__.py:254
#: src/octoprint/server/views.py:151 src/octoprint/server/views.py:153
msgid "Features"
msgstr ""
#: src/octoprint/server/__init__.py:255
#: src/octoprint/server/views.py:154
msgid "Webcam"
msgstr ""
#: src/octoprint/server/__init__.py:256
#: src/octoprint/server/views.py:155
msgid "API"
msgstr ""
#: src/octoprint/server/__init__.py:258
#: src/octoprint/server/views.py:157
#: src/octoprint/static/js/app/viewmodels/appearance.js:11
#: src/octoprint/static/js/app/viewmodels/appearance.js:13
#: src/octoprint/static/js/app/viewmodels/appearance.js:18
@ -543,32 +545,32 @@ msgstr ""
msgid "OctoPrint"
msgstr ""
#: src/octoprint/server/__init__.py:260
#: src/octoprint/server/views.py:159
msgid "Folders"
msgstr ""
#: src/octoprint/server/__init__.py:261
#: src/octoprint/server/views.py:160
msgid "Appearance"
msgstr ""
#: src/octoprint/server/__init__.py:262
#: src/octoprint/server/views.py:161
#: src/octoprint/templates/dialogs/settings/logs.jinja2:2
msgid "Logs"
msgstr ""
#: src/octoprint/server/__init__.py:265
#: src/octoprint/server/views.py:164
msgid "Access Control"
msgstr ""
#: src/octoprint/server/__init__.py:271
#: src/octoprint/server/views.py:170
msgid "Access"
msgstr ""
#: src/octoprint/server/__init__.py:272
#: src/octoprint/server/views.py:171
msgid "Interface"
msgstr ""
#: src/octoprint/server/__init__.py:359
#: src/octoprint/server/views.py:258
msgid "Plugins"
msgstr ""
@ -890,44 +892,44 @@ msgid "Error"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:96
#: src/octoprint/static/js/app/viewmodels/settings.js:21
#: src/octoprint/static/js/app/viewmodels/settings.js:51
#: src/octoprint/static/js/app/viewmodels/settings.js:52
#: src/octoprint/static/js/app/viewmodels/settings.js:82
msgid "default"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:97
#: src/octoprint/static/js/app/viewmodels/settings.js:22
#: src/octoprint/static/js/app/viewmodels/settings.js:35
#: src/octoprint/static/js/app/viewmodels/settings.js:53
#: src/octoprint/static/js/app/viewmodels/settings.js:66
msgid "red"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:98
#: src/octoprint/static/js/app/viewmodels/settings.js:23
#: src/octoprint/static/js/app/viewmodels/settings.js:37
#: src/octoprint/static/js/app/viewmodels/settings.js:54
#: src/octoprint/static/js/app/viewmodels/settings.js:68
msgid "orange"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:99
#: src/octoprint/static/js/app/viewmodels/settings.js:24
#: src/octoprint/static/js/app/viewmodels/settings.js:39
#: src/octoprint/static/js/app/viewmodels/settings.js:55
#: src/octoprint/static/js/app/viewmodels/settings.js:70
msgid "yellow"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:100
#: src/octoprint/static/js/app/viewmodels/settings.js:25
#: src/octoprint/static/js/app/viewmodels/settings.js:41
#: src/octoprint/static/js/app/viewmodels/settings.js:56
#: src/octoprint/static/js/app/viewmodels/settings.js:72
msgid "green"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:101
#: src/octoprint/static/js/app/viewmodels/settings.js:26
#: src/octoprint/static/js/app/viewmodels/settings.js:43
#: src/octoprint/static/js/app/viewmodels/settings.js:57
#: src/octoprint/static/js/app/viewmodels/settings.js:74
msgid "blue"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/printerprofiles.js:102
#: src/octoprint/static/js/app/viewmodels/settings.js:28
#: src/octoprint/static/js/app/viewmodels/settings.js:47
#: src/octoprint/static/js/app/viewmodels/settings.js:59
#: src/octoprint/static/js/app/viewmodels/settings.js:78
msgid "black"
msgstr ""
@ -1033,17 +1035,17 @@ msgstr ""
msgid "This will restart the print job from the beginning."
msgstr ""
#: src/octoprint/static/js/app/viewmodels/settings.js:27
#: src/octoprint/static/js/app/viewmodels/settings.js:45
#: src/octoprint/static/js/app/viewmodels/settings.js:58
#: src/octoprint/static/js/app/viewmodels/settings.js:76
msgid "violet"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/settings.js:29
#: src/octoprint/static/js/app/viewmodels/settings.js:49
#: src/octoprint/static/js/app/viewmodels/settings.js:60
#: src/octoprint/static/js/app/viewmodels/settings.js:80
msgid "white"
msgstr ""
#: src/octoprint/static/js/app/viewmodels/settings.js:57
#: src/octoprint/static/js/app/viewmodels/settings.js:88
msgid "Autodetect from browser"
msgstr ""
@ -1398,16 +1400,46 @@ msgid "Transparent Color"
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:23
msgid "Language Packs"
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:25
msgid "Manage..."
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:29
msgid "Default Language"
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:30
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:36
msgid ""
"Changes to the default interface language will only become active after a"
" reload of the page and only be active if not overridden by the users "
"language settings."
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:44
msgid "Manage Language Packs..."
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:58
msgid "Delete"
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:76
#: src/octoprint/templates/overlays/dragndrop.jinja2:10
#: src/octoprint/templates/sidebar/files.jinja2:44
#: src/octoprint/templates/sidebar/files.jinja2:55
msgid "Upload"
msgstr ""
#: src/octoprint/templates/dialogs/settings/appearance.jinja2:78
msgid ""
"This does not look like a valid language pack. Valid language packs "
"should be either zip files or tarballs and have the extension \".zip\", "
"\".tar.gz\", \".tgz\" or \".tar\""
msgstr ""
#: src/octoprint/templates/dialogs/settings/features.jinja2:5
msgid "Enable Temperature Graph"
msgstr ""
@ -1836,12 +1868,6 @@ msgstr ""
msgid "SD not initialized"
msgstr ""
#: src/octoprint/templates/overlays/dragndrop.jinja2:10
#: src/octoprint/templates/sidebar/files.jinja2:44
#: src/octoprint/templates/sidebar/files.jinja2:55
msgid "Upload"
msgstr ""
#: src/octoprint/templates/overlays/offline.jinja2:9
msgid "Attempt to reconnect"
msgstr ""