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:
parent
7f8a3849c7
commit
5904d01bff
15 changed files with 2409 additions and 7076 deletions
5
setup.py
5
setup.py
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
|
@ -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,
|
||||
|
|
|
|||
BIN
translations/de/LC_MESSAGES/messages.mo
Normal file
BIN
translations/de/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
2186
translations/de/LC_MESSAGES/messages.po
Normal file
2186
translations/de/LC_MESSAGES/messages.po
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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 ""
|
||||
Loading…
Reference in a new issue