From 2b22d26eaca3e54b7090d20bc59fce8c564ef5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 7 Sep 2016 18:25:17 +0200 Subject: [PATCH 1/7] Fixed a small issue with RFC 5987 headers arriving as unicode in parser Also added API docs regarding header encoding, incl support for RFC 5987 for filename fields in Content-Disposition headers in multipart/form-data parts, incl. an example of an upload request with a utf-8 encoded filename. --- docs/api/fileops.rst | 54 ++++++++++++++++++++++------ docs/api/general.rst | 14 +++++++- src/octoprint/server/util/tornado.py | 6 ++-- tests/server/util/tornado.py | 7 +++- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/docs/api/fileops.rst b/docs/api/fileops.rst index 7cadb8c4..759dc69d 100644 --- a/docs/api/fileops.rst +++ b/docs/api/fileops.rst @@ -161,18 +161,10 @@ Upload file Content-Disposition: form-data; name="file"; filename="whistle_v2.gcode" Content-Type: application/octet-stream - ;Generated with Cura_SteamEngine 13.11.2 M109 T0 S220.000000 T0 - ;Sliced at: Wed 11-12-2013 16:53:12 - ;Basic settings: Layer height: 0.2 Walls: 0.8 Fill: 20 - ;Print time: #P_TIME# - ;Filament used: #F_AMNT#m #F_WGHT#g - ;Filament cost: #F_COST# - ;M190 S70 ;Uncomment to add your own bed temperature line - ;M109 S220 ;Uncomment to add your own temperature line - G21 ;metric values - G90 ;absolute positioning + G21 + G90 ... ------WebKitFormBoundaryDeC2E3iWbTv1PwMC Content-Disposition: form-data; name="select" @@ -188,7 +180,7 @@ Upload file HTTP/1.1 200 OK Content-Type: application/json - Location: http://example.com/api/files/sdcard/whistle_.gcode + Location: http://example.com/api/files/sdcard/whistle_v2.gcode { "files": { @@ -208,6 +200,46 @@ Upload file } } }, + "done": false + } + + **Example with UTF-8 encoded filename following RFC 5987** + + .. sourcecode:: http + + POST /api/files/local HTTP/1.1 + Host: example.com + X-Api-Key: abcdef... + Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDeC2E3iWbTv1PwMC + + ------WebKitFormBoundaryDeC2E3iWbTv1PwMC + Content-Disposition: form-data; name="file"; filename*=utf-8''20mm-%C3%BCml%C3%A4ut-b%C3%B6x.gcode + Content-Type: application/octet-stream + + M109 T0 S220.000000 + T0 + G21 + G90 + ... + ------WebKitFormBoundaryDeC2E3iWbTv1PwMC-- + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + Location: http://example.com/api/files/local/20mm-umlaut-box.gcode + + { + "files": { + "local": { + "name": "20mm-umlaut-box", + "origin": "local", + "refs": { + "resource": "http://example.com/api/files/local/whistle_v2.gcode", + "download": "http://example.com/downloads/files/local/whistle_v2.gcode" + } + } + }, "done": true } diff --git a/docs/api/general.rst b/docs/api/general.rst index 9e6a67fc..91e67357 100644 --- a/docs/api/general.rst +++ b/docs/api/general.rst @@ -74,7 +74,19 @@ Encoding OctoPrint uses UTF-8 as charset. -.. _sec-api-cross-origin: +That also includes headers in ``multipart/form-data`` requests, in order to allow the full UTF-8 range of characters +for uploaded filenames. If a ``multipart/form-data`` sub header cannot be decoded as UTF-8, OctoPrint will also attempt +to decode it as ISO-8859-1. + +Additionally, OctoPrint supports replacing the ``filename`` field in the ``Content-Disposition`` header of a +multipart field with a ``filename*`` field following `RFC 5987, Section 3.2 `_, +which allows defining the charset used for encoding the filename. If both ``filename`` and ``filename*`` fields are +present, following the recommendation of the RFC ``filename*`` will be used. + +For an example on how to send a request utilizing RFC 5987 for the ``filename*`` attribute, see the second example +in :ref:`Upload file `. + +.. _sec-api-general-crossorigin: Cross-origin requests ===================== diff --git a/src/octoprint/server/util/tornado.py b/src/octoprint/server/util/tornado.py index 3638ac45..ed9aca2d 100644 --- a/src/octoprint/server/util/tornado.py +++ b/src/octoprint/server/util/tornado.py @@ -303,7 +303,7 @@ class UploadStorageFallbackHandler(tornado.web.RequestHandler): filename = _extended_header_value(filename) except: # parse error, this is not RFC 5987 compliant after all - self._logger.warn("extended filename* value {!r} is not RFC 5987 compliant") + self._logger.warn("extended filename* value {!r} is not RFC 5987 compliant".format(filename)) self.send_error(400) return else: @@ -494,11 +494,11 @@ def _extended_header_value(value): # RFC 5987 section 3.2 from urllib import unquote encoding, _, value = value.split("'", 2) - return unquote(value).decode(encoding) + return unquote(octoprint.util.to_str(value, encoding="iso-8859-1")).decode(encoding) else: # no encoding provided, strip potentially present quotes and call it a day - return _strip_value_quotes(value) + return octoprint.util.to_unicode(_strip_value_quotes(value), encoding="utf-8") class WsgiInputContainer(object): diff --git a/tests/server/util/tornado.py b/tests/server/util/tornado.py index e6ab47a0..a765d66d 100644 --- a/tests/server/util/tornado.py +++ b/tests/server/util/tornado.py @@ -76,9 +76,14 @@ class StripValueQuotesTest(unittest.TestCase): class ExtendedHeaderValueTest(unittest.TestCase): @data( - ("", u""), + (u"", u""), (None, None), + (u'"quoted-string"', u"quoted-string"), + (u'"qüöted-string"', u"qüöted-string"), + (u"iso-8859-1'en'%A3%20rates", u"£ rates"), + (u"UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", u"£ and € rates"), ('"quoted-string"', u"quoted-string"), + ('"qüöted-string"', u"qüöted-string"), ("iso-8859-1'en'%A3%20rates", u"£ rates"), ("UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", u"£ and € rates") ) From a7bd770180fa00f4228a766cc8d567f0d9af9433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 8 Sep 2016 12:50:04 +0200 Subject: [PATCH 2/7] Allow overriding file name sanitization by sub classes of LocalStorage --- src/octoprint/filemanager/storage.py | 61 ++++++++++++++++------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/octoprint/filemanager/storage.py b/src/octoprint/filemanager/storage.py index 5041a804..11b2c299 100644 --- a/src/octoprint/filemanager/storage.py +++ b/src/octoprint/filemanager/storage.py @@ -391,7 +391,7 @@ class LocalFileStorage(StorageInterface): path = self.sanitize_path(path) else: path = self.basefolder - return self._list_folder(path, filter=filter, recursive=recursive) + return self._list_folder(path, entry_filter=filter, recursive=recursive) def add_folder(self, path, ignore_existing=True): path, name = self.sanitize(path) @@ -650,6 +650,30 @@ class LocalFileStorage(StorageInterface): raise ValueError("path not contained in base folder: {path}".format(**locals())) return path + def _sanitize_entry(self, entry, path, entry_path): + sanitized = self.sanitize_name(entry) + if sanitized != entry: + # entry is not sanitized yet, let's take care of that + sanitized_path = os.path.join(path, sanitized) + sanitized_name, sanitized_ext = os.path.splitext(sanitized) + + counter = 1 + while os.path.exists(sanitized_path): + counter += 1 + sanitized = self.sanitize_name("{}_({}){}".format(sanitized_name, counter, sanitized_ext)) + sanitized_path = os.path.join(path, sanitized) + + try: + shutil.move(entry_path, sanitized_path) + + self._logger.info("Sanitized \"{}\" to \"{}\"".format(entry_path, sanitized_path)) + return sanitized, sanitized_path + except: + self._logger.exception("Error while trying to rename \"{}\" to \"{}\", ignoring file".format(entry_path, sanitized_path)) + raise + + return entry, entry_path + def path_in_storage(self, path): if isinstance(path, (tuple, list)): path = self.join_path(*path) @@ -889,7 +913,10 @@ class LocalFileStorage(StorageInterface): if metadata_dirty: self._save_metadata(path, metadata) - def _list_folder(self, path, filter=None, recursive=True): + def _list_folder(self, path, entry_filter=None, recursive=True, **kwargs): + if entry_filter is None: + entry_filter = kwargs.get("filter", None) + metadata = self._get_metadata(path) if not metadata: metadata = dict() @@ -903,27 +930,11 @@ class LocalFileStorage(StorageInterface): entry_path = os.path.join(path, entry) - sanitized = self.sanitize_name(entry) - if sanitized != entry: - # entry is not sanitized yet, let's take care of that - sanitized_path = os.path.join(path, sanitized) - sanitized_name, sanitized_ext = os.path.splitext(sanitized) - - counter = 1 - while os.path.exists(sanitized_path): - counter += 1 - sanitized = self.sanitize_name("{}_({}){}".format(sanitized_name, counter, sanitized_ext)) - sanitized_path = os.path.join(path, sanitized) - - try: - shutil.move(entry_path, sanitized_path) - - self._logger.info("Sanitized \"{}\" to \"{}\"".format(entry_path, sanitized_path)) - entry = sanitized - entry_path = sanitized_path - except: - self._logger.exception("Error while trying to rename \"{}\" to \"{}\", ignoring file".format(entry_path, sanitized_path)) - continue + try: + entry, entry_path = self._sanitize_entry(entry, path, entry_path) + except: + # error while trying to rename the file, we'll continue here and ignore it + continue # file handling if os.path.isfile(entry_path): @@ -942,7 +953,7 @@ class LocalFileStorage(StorageInterface): # TODO extract model hash from source if possible to recreate link - if not filter or filter(entry, entry_data): + if not entry_filter or entry_filter(entry, entry_data): # only add files passing the optional filter extended_entry_data = dict() extended_entry_data.update(entry_data) @@ -957,7 +968,7 @@ class LocalFileStorage(StorageInterface): # folder recursion elif os.path.isdir(entry_path) and recursive: - sub_result = self._list_folder(entry_path, filter=filter) + sub_result = self._list_folder(entry_path, entry_filter=entry_filter) result[entry] = dict( name=entry, type="folder", From 53b74f9caaf492b005cbdbb93d20064851341cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 8 Sep 2016 15:18:09 +0200 Subject: [PATCH 3/7] Only construct HTTP_HOST header from SERVER_NAME and _PORT if it's unset If HTTP_HOST is set, following PEP333 it takes precedence over SERVER_NAME and _PORT, so we set those from it. --- src/octoprint/server/util/flask.py | 23 +-- tests/server/util/flask.py | 237 ++++++++++++++++++++--------- 2 files changed, 177 insertions(+), 83 deletions(-) diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index fe48c7f7..0afc0715 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -321,6 +321,14 @@ class ReverseProxiedEnvironment(object): environ["HTTP_HOST"] = host environ["SERVER_NAME"] = server environ["SERVER_PORT"] = port + + elif environ.get("HTTP_HOST", None) is not None: + # if we have a Host header, we use that and make sure our server name and port properties match it + host = environ["HTTP_HOST"] + server, port = host_to_server_and_port(host, url_scheme) + environ["SERVER_NAME"] = server + environ["SERVER_PORT"] = port + else: # else we take a look at the server and port headers and if we have # something there we derive the host from it @@ -335,15 +343,12 @@ class ReverseProxiedEnvironment(object): if port is not None: environ["SERVER_PORT"] = port - # make sure HTTP_HOST matches SERVER_NAME and SERVER_PORT - expected_server, expected_port = host_to_server_and_port(environ.get("HTTP_HOST", None), url_scheme) - if expected_server != environ["SERVER_NAME"] or expected_port != environ["SERVER_PORT"]: - # there's a difference, fix it! - if url_scheme == "http" and environ["SERVER_PORT"] == "80" or url_scheme == "https" and environ["SERVER_PORT"] == "443": - # default port for scheme, can be skipped - environ["HTTP_HOST"] = environ["SERVER_NAME"] - else: - environ["HTTP_HOST"] = environ["SERVER_NAME"] + ":" + environ["SERVER_PORT"] + # reconstruct host header + if url_scheme == "http" and environ["SERVER_PORT"] == "80" or url_scheme == "https" and environ["SERVER_PORT"] == "443": + # default port for scheme, can be skipped + environ["HTTP_HOST"] = environ["SERVER_NAME"] + else: + environ["HTTP_HOST"] = environ["SERVER_NAME"] + ":" + environ["SERVER_PORT"] # call wrapped app with rewritten environment return environ diff --git a/tests/server/util/flask.py b/tests/server/util/flask.py index e18e2dfb..52491243 100644 --- a/tests/server/util/flask.py +++ b/tests/server/util/flask.py @@ -103,27 +103,29 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): "wsgi.url_scheme": "https" }), - # server and port headers set -> host derived with port + # host set, server and port differ -> updated, standard port ({ - "HTTP_X_FORWARDED_SERVER": "example2.com", - "HTTP_X_FORWARDED_PORT": "444", - "HTTP_X_FORWARDED_PROTO": "https" - }, { - "HTTP_HOST": "example2.com:444", - "SERVER_NAME": "example2.com", - "SERVER_PORT": "444", - "wsgi.url_scheme": "https" - }), + "HTTP_HOST": "example.com", + "wsgi.url_scheme": "https", + "SERVER_NAME": "localhost", + "SERVER_PORT": "80" + }, { + "HTTP_HOST": "example.com", + "SERVER_NAME": "example.com", + "SERVER_PORT": "443", + }), - # server and port headers set, standard port -> host derived, no port + # host set, server and port differ -> updated, non standard port ({ - "HTTP_X_FORWARDED_SERVER": "example.com", - "HTTP_X_FORWARDED_PORT": "80", - }, { - "HTTP_HOST": "example.com", + "HTTP_HOST": "example.com:444", + "wsgi.url_scheme": "https", + "SERVER_NAME": "localhost", + "SERVER_PORT": "80" + }, { + "HTTP_HOST": "example.com:444", "SERVER_NAME": "example.com", - "SERVER_PORT": "80", - }), + "SERVER_PORT": "444", + }), # multiple scheme entries -> only use first one ({ @@ -132,7 +134,7 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): "wsgi.url_scheme": "https" }), - # host = none -> should never happen but you never know... + # host = none (should never happen but you never know) -> server & port used for reconstruction ({ "HTTP_HOST": None, "HTTP_X_FORWARDED_SERVER": "example.com", @@ -158,6 +160,67 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): self.assertDictEqual(merged_expected, actual) + @data( + # server and port headers set -> host derived with port + ({ + "SERVER_NAME": "example2.com", + "SERVER_PORT": "444", + "HTTP_X_FORWARDED_PROTO": "https" + }, { + "HTTP_HOST": "example2.com:444", + "SERVER_NAME": "example2.com", + "SERVER_PORT": "444", + "wsgi.url_scheme": "https" + }), + + # server and port headers set, standard port -> host derived, no port + ({ + "SERVER_NAME": "example.com", + "SERVER_PORT": "80", + }, { + "HTTP_HOST": "example.com", + "SERVER_NAME": "example.com", + "SERVER_PORT": "80", + }), + + # server and port forwarded headers set -> host derived with port + ({ + "HTTP_X_FORWARDED_SERVER": "example2.com", + "HTTP_X_FORWARDED_PORT": "444", + "HTTP_X_FORWARDED_PROTO": "https" + }, { + "HTTP_HOST": "example2.com:444", + "SERVER_NAME": "example2.com", + "SERVER_PORT": "444", + "wsgi.url_scheme": "https" + }), + + # server and port forwarded headers set, standard port -> host derived, no port + ({ + "HTTP_X_FORWARDED_SERVER": "example.com", + "HTTP_X_FORWARDED_PORT": "80", + }, { + "HTTP_HOST": "example.com", + "SERVER_NAME": "example.com", + "SERVER_PORT": "80", + }), + ) + @unpack + def test_nohost(self, environ, expected): + reverse_proxied = ReverseProxiedEnvironment() + + merged_environ = dict(standard_environ) + merged_environ.update(environ) + del merged_environ["HTTP_HOST"] + + actual = reverse_proxied(merged_environ) + + merged_expected = dict(standard_environ) + merged_expected.update(environ) + merged_expected.update(expected) + + self.assertDictEqual(merged_expected, actual) + @data( # prefix overridden ({ @@ -195,57 +258,7 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): "SERVER_PORT": "81" }), - # server overridden - ({ - "server": "example.com" - }, { - }, { - "HTTP_HOST": "example.com:5000", - "SERVER_NAME": "example.com", - "SERVER_PORT": "5000" - }), - - # port overridden, standard port - ({ - "port": "80" - }, { - }, { - "HTTP_HOST": "localhost", - "SERVER_PORT": "80" - }), - - # port overridden, non standard port - ({ - "port": "81" - }, { - }, { - "HTTP_HOST": "localhost:81", - "SERVER_PORT": "81" - }), - - # server and port overridden, default port - ({ - "server": "example.com", - "port": "80" - }, { - }, { - "HTTP_HOST": "example.com", - "SERVER_NAME": "example.com", - "SERVER_PORT": "80" - }), - - # server and port overridden, non default port - ({ - "server": "example.com", - "port": "81" - }, { - }, { - "HTTP_HOST": "example.com:81", - "SERVER_NAME": "example.com", - "SERVER_PORT": "81" - }), - - # prefix not really overridden + # prefix not really overridden, forwarded headers take precedence ({ "prefix": "/octoprint" }, { @@ -253,7 +266,7 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): }, { }), - # scheme not really overridden + # scheme not really overridden, forwarded headers take precedence ({ "scheme": "https" }, { @@ -261,7 +274,7 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): }, { }), - # scheme 2 not really overridden + # scheme 2 not really overridden, forwarded headers take precedence ({ "scheme": "https" }, { @@ -269,7 +282,7 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): }, { }), - # host not really overridden + # host not really overridden, forwarded headers take precedence ({ "host": "example.com:444" }, { @@ -277,7 +290,7 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): }, { }), - # server not really overridden + # server not really overridden, forwarded headers take precedence ({ "server": "example.com" }, { @@ -285,12 +298,20 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): }, { }), - # port not really overridden + # port not really overridden, forwarded headers take precedence ({ "port": "444" }, { "HTTP_X_FORWARDED_PORT": "5000" }, { + }), + + # server and port not really overridden, Host header wins + ({ + "server": "example.com", + "port": "80" + }, { + }, { }) ) @unpack @@ -308,6 +329,74 @@ class ReverseProxiedEnvironmentTest(unittest.TestCase): self.assertDictEqual(merged_expected, actual) + @data( + # server overridden + ({ + "server": "example.com" + }, { + }, { + "HTTP_HOST": "example.com:5000", + "SERVER_NAME": "example.com", + "SERVER_PORT": "5000" + }), + + # port overridden, standard port + ({ + "port": "80" + }, { + }, { + "HTTP_HOST": "localhost", + "SERVER_PORT": "80" + }), + + # port overridden, non standard port + ({ + "port": "81" + }, { + }, { + "HTTP_HOST": "localhost:81", + "SERVER_PORT": "81" + }), + + # server and port overridden, default port + ({ + "server": "example.com", + "port": "80" + }, { + }, { + "HTTP_HOST": "example.com", + "SERVER_NAME": "example.com", + "SERVER_PORT": "80" + }), + + # server and port overridden, non default port + ({ + "server": "example.com", + "port": "81" + }, { + }, { + "HTTP_HOST": "example.com:81", + "SERVER_NAME": "example.com", + "SERVER_PORT": "81" + }), + + ) + @unpack + def test_fallbacks_nohost(self, fallbacks, environ, expected): + reverse_proxied = ReverseProxiedEnvironment(**fallbacks) + + merged_environ = dict(standard_environ) + merged_environ.update(environ) + del merged_environ["HTTP_HOST"] + + actual = reverse_proxied(merged_environ) + + merged_expected = dict(standard_environ) + merged_expected.update(environ) + merged_expected.update(expected) + + self.assertDictEqual(merged_expected, actual) + def test_header_config_ok(self): result = ReverseProxiedEnvironment.to_header_candidates(["prefix-header1", "prefix-header2"]) self.assertEquals(result, ["HTTP_PREFIX_HEADER1", "HTTP_PREFIX_HEADER2"]) From bbe6e44d442a319c5e47774a5c19c3c69956d0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 8 Sep 2016 15:42:51 +0200 Subject: [PATCH 4/7] Only use non-postfixed cookie if no postfixed one exists Example: * both "session" and "session_P5000" cookies available: "session" value from "session_P5000" * only "session" cookie available: "session" value from "session" * only "session_P5000" cookie available: "session" value from "session_P5000" --- src/octoprint/server/util/flask.py | 12 +++++++++--- tests/server/util/flask.py | 18 +++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index 0afc0715..6ed17dcd 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -369,10 +369,16 @@ class OctoPrintFlaskRequest(flask.Request): # strip cookie_suffix from all cookies in the request, return result cookies = flask.Request.cookies.__get__(self) - def cookie_name_converter(key): - return key[:-len(self.cookie_suffix)] if key.endswith(self.cookie_suffix) else key + result = dict() + desuffixed = dict() + for key, value in cookies.items(): + if key.endswith(self.cookie_suffix): + desuffixed[key[:-len(self.cookie_suffix)]] = value + else: + result[key] = value - return dict((cookie_name_converter(key), value) for key, value in cookies.items()) + result.update(desuffixed) + return result @cached_property def server_name(self): diff --git a/tests/server/util/flask.py b/tests/server/util/flask.py index 52491243..b732416c 100644 --- a/tests/server/util/flask.py +++ b/tests/server/util/flask.py @@ -433,28 +433,32 @@ class OctoPrintFlaskRequestTest(unittest.TestCase): def test_server_name(self): request = OctoPrintFlaskRequest(standard_environ) - self.assertEquals(request.server_name, "localhost") + self.assertEquals("localhost", request.server_name) def test_server_port(self): request = OctoPrintFlaskRequest(standard_environ) - self.assertEquals(request.server_port, "5000") + self.assertEquals("5000", request.server_port) def test_cookie_suffix(self): request = OctoPrintFlaskRequest(standard_environ) - self.assertEquals(request.cookie_suffix, "_P5000") + self.assertEquals("_P5000", request.cookie_suffix) def test_cookies(self): environ = dict(standard_environ) environ["HTTP_COOKIE"] = "postfixed_P5000=postfixed_value; " \ "postfixed_wrong_P5001=postfixed_wrong_value; " \ - "unpostfixed=unpostfixed_value" + "unpostfixed=unpostfixed_value; " \ + "both_P5000=both_postfixed_value; " \ + "both=both_unpostfixed_value;" request = OctoPrintFlaskRequest(environ) cookies = request.cookies - self.assertDictEqual(cookies, {"postfixed": "postfixed_value", - "postfixed_wrong_P5001": "postfixed_wrong_value", - "unpostfixed": "unpostfixed_value"}) + self.assertDictEqual({"postfixed": u"postfixed_value", + "postfixed_wrong_P5001": u"postfixed_wrong_value", + "unpostfixed": u"unpostfixed_value", + "both": u"both_postfixed_value"}, + cookies) ##~~ From c6d95751273d4f8b134dee64aa905f029825c591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 9 Sep 2016 11:33:56 +0200 Subject: [PATCH 5/7] Added link to "Using Release Channels" to the SWU settings dialog --- .../softwareupdate/templates/softwareupdate_settings.jinja2 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2 b/src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2 index fc90e531..afab51cf 100644 --- a/src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2 +++ b/src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2 @@ -90,6 +90,7 @@
+ {{ _('Make sure you have read "Using Release Channels" before switching to a release channel other than "Stable"', url="https://github.com/foosel/OctoPrint/wiki/Using-Release-Channels") }}
From 7efa311b04e12edbce12f0e9037e3a19aea11d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 9 Sep 2016 11:52:36 +0200 Subject: [PATCH 6/7] Updated the german translation again after adding a sentence --- .../translations/de/LC_MESSAGES/messages.mo | Bin 67053 -> 68129 bytes .../translations/de/LC_MESSAGES/messages.po | 22 +++++++++++++----- translations/de/LC_MESSAGES/messages.mo | Bin 67053 -> 68129 bytes translations/de/LC_MESSAGES/messages.po | 22 +++++++++++++----- translations/messages.pot | 18 ++++++++++---- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/octoprint/translations/de/LC_MESSAGES/messages.mo b/src/octoprint/translations/de/LC_MESSAGES/messages.mo index 0b6c61170793d640c0c8d1fc72536607af0b4624..389721a923e4dda866107b157b5670f38f893f0d 100644 GIT binary patch delta 11484 zcmbu_d3aPsy2tTqLI??jB`kp$;Sj?XAR#0mAWLMC0D`QtFP)@AT0$Drogg^Spr9fm z$f6*Mz=*)$s1QY95JgY~L>*;QSrkRY5fnGvx!+&caprpO{qOqB7z}4r=@~rWzAAmuS>rpiY*(kb<@8w{!cw zunzrUSPzTb@mZ*eA4CPd3VY#pjK<%v3Pxoc6N_;ehjm>WW8+F;W72565oJuj4#qrA zHOyho$r% zP@nb9RT_1$N;msp5>}<(618wURLbUI16+=Y_zY^{*RdA9iJXo(g$=Q4cbl0MRKGjw zzEPNiw_&(0jmtOe&wq>B!0$Pnzs|J&jrKxo)Wp}j{Xtln{umsG6LBQ&#(tRCgTll-)X}_yB-40$ z+6{Ea3i`RIBl{JvK^2MuNbVIjhQc-345&y7P-j(wsaTGBU=`|YUql7G8񿴈{ zuSfN^8;C<4*>!jwX5m^Kfy419REBN|-(({#z-R`hpcV?c{TZm#&Bpe)5vfaa8n4Hs zKKA(`sQbp?0K6Oh_)n~YH{{yDd!RBr5><2I+iAqmn1?Ekg>HW}>a3n}-GT}9cVSh0 z8}-}?RO&xMEm*s+t${mH_svITVhJj9>##9yN7f6Q6ErF_aKR3kOQ?viqF$pa9JG$0 z9#+Fl*RH4l`l13Gj9Q=o>*Ea6!VjV5S&L2aIgG<&SdaD1$29n#xx&BVut$GBDmVaj zBqvcjIg1|r7itF=QEx~5&GsylP=RNl7VLm3vfi%aFr9uG>MeN^YqP%DN<(L|53A!T z)WTn&cJeiW&3x2?kD~(IhI;-mMrs1J^N;X8{1Nr~&bfuf@eJyN)OZm2 z*O_!0WK2h#fYopXD#9mGfow*7NS?!Zd>d=vDOAS3L@oRiY97yEJ5OiS^_x%u4n-Z^ zcq9fhYcTm&3g2QtCJeC|xD^$^1h-%4_5(PE@p9CJ@1inr3LmC8zC-?J77QauJdNr< zGu+PSxz&D9S30Jmdn{0lb0O_+v< zP-p%Fk`z;Ir2TG;#aQ|)P)8kJM`I$5%{U6H^DjPTrVy3l&DaTdqF%%AumRQ@Z6|1n zy00D9#2Zm5AM83FRXdYWM|-qM*xc_9EJvO7I@E+4>`p1yC6(N6mL1YT<>b@54$|=AOmsdjEIQ_!|TJkyqN3j%h`e~CKN7@pF?iKzF#7dF9>s0_`(hB()CHR}287=`bliugF{h|ZvnspAK zcP^^PSB7cmY&T*I?!ai=gWAD<)Xv_;7(DCxg**NY>iJ4Vc87IP{bbbrZQOo)_xerv z2;;Z7*Td)C##i_kE?hySHsrUj%WTwy52N0K4Va8OunHc-SUiO)#`CBY*T2nv`PyJt z`m<31?M7wnbtD5}bA*O=_z7ylZ!r#kMgW9qxb(88roS@vAv<5YbwrUJPTXm7F2*AqKft`YDYg}8tOMueX?7* zc5@w!8H^WTWn6{|a3xk_eY1&%KB+IDcK#N|WECaQ0f44s# zHO~xGM&_XwUWr+_8g>7>7}n0u(Wr)3upFZTd`58w|I&`XK;3s4qjY_$J>wWuY8#;z zY>x5R4r^i#X5b*KjH=CiCnx7}Q2W#KS8-nj)YkZTB%xL@x`|H+W zykj>pum+XF^RCTj*&i~KuoL6+@k88;0epg0=3>p+{Njqsa5#SH_Iu1RrVIT?aXlW# z4LI{I`xZ34n_pHG>L?lmxUdRG;sxp9?*L|>qVak5>|^h-uVGD0WV|6N^_i%%?t%4i zFzVl)wQ5)EbG59_zfR7iFf8Fpk101=zg6jX| z_VtIL`jt=_ipBPrgw1gfDz$fDJ}$yc{1!W4(?$0CG8Q#|8EU?1sQG4vX(*+OP?7%? zWASNJ4Q#{8xC<5e9*n~S7==er_nkmJe;Rcp=iTc+VA)WmnY-iz1JUw}8`1{{UoVM`qNkbUkB)XrwR{d-Y?Epo?~<9<@`7`7s!f~EXg z@8SFxFK2NEjy=quR^0H_3eJ@W`#;L=u#vlhh|{iqlX>l!ZEquCBT0 zu#ustGYhTd=LvzAtvBXghKe>YH-3%!U_G^wuWOjb?=+P1j7>I`S*QhWaQnTnF8u+h z6z8GN+K&pX6raXBQ1dkXoBbuUCF=F=iK>ZFI1YX;W=0X7d_4SYbUE2sD&Fa4Yy+! zeu6r)#J}6?&9N!{j;`ZTnVE|Yu5|l5Q479}4e$f3hToz#comB<`Wf=i4=PjgjQx3h z0TP?7zLZLl&WI~d#H5}b=F!o+R1xEi5qA=~YbKrJ{0>*91&1|CEm z^$JvAYcYZK&C~9{%cvUz&E+=kluG^~SR)a$bpb#|Lj3mrlgROp zVmv;NZ{e$``ySe916qk5);H^D=*#saYG(&92|q-o>IYQho`2XKCtx!DH0*?ZP{lUK z9bb%k{_m(j-#{JN32cC8Q0x4N;W;$ocG-y^K%MoI*cg96MO^)CAw7Qg{^=Q2cIwfM6T+ z<3SvU*)Q87T!PBv3)mk&Kn2$96`O%f)Z5V!uf?vfgzW-j7|=p~R4q(H1uz%8;e)7% z52I3g6t%N+*c>lmF4o^;f4iN4{pjyR-533;4WI_9U(f9~3e&iQfu>jqSEEw27EgNk z{T+SuSMB5XHuSt^e+(Z%?X1b`{Ff|jjau*|reO2^ws`xYHZ&2H*(q*+9x4OjB{cM& zKIdL|4O`QH7n|T!Ovff~*a-)rmwqAk#y3!zs&T;D0ChbD^KdTezVoPBX>-v2THXnp z>isXLp~xP?7su^57~_*p~f>X8oQ#Zy(j9q;W!+} zVQMLkgWO?zg|P}SZBRXjPUx1cxb`!Ecv;cZwS%W*v}#9^3q*pA6hDQB=+B55g&FDXc+TmgBjwi7*CR2fBI09pJ9RqkAZ^b_E z*&U&U(s^)vJF>XTrhI0UQ zmWNT9IEtG1Bu}*Q@}EFs3j>;HA6CUfSPPG!7Cwh@ z7=7GY3w7T$cnzka=E*^2ZYZjz@=*5`VLiMZhvU6?8c&63w5GA^g#C@=0&3?&-nZ{( zF=~PP-TqUkfcCk5igoB${=im!15_Z*P#NmvdLt^JzNnhG1r=C$jC(@?#xqci+QAG| zM&`TYi%}U^jmpd>)B-zkGrsEfOFpy{m*X17!>H$+llH^b3UxHO*0Ax?XvDw_)PgHf z0j$Avd=?Y&G#20w*ayd)vH|=R75HY2^~85?1ZkJxaS zMjINsF&j0(&6t71P-iPaH;waSpOHlJXi8}M`xCr;+QXKk; zeeOJJo=cyQe@ztqsa>c#D&m%?39m<`zAx(a8HJe`Kpn+eRK~WU=Gl#1@HMwz>71>F zSk#V_Q5$N8TBqkZ@~?>pGoXkj;dGpZDwZEn0YrbsLmuwMhV;9fw-erqdTt_W=hLtm zETK`AVfZNO3-%RiqB<9B z(I%ljFw?OzzKxpi2x=o|Pyu~~3OF41h23c*tja(uR6yC-343A(oQb3Gc^ro|{$>A= zD8>==AI33w37ccTFYT|{rC3gX70$qfi}p{vg~)i=Y^R|M8JFyZzo8~NiW4yND|`JR zyiC9P*QA`I_#Io*ulEgqzF`ma;uh5Nb-tzGFo4R)Ud+OV-`S!afT#8T-$UbGF8ID@ z7kCkKaqbWHKSCYG0rV5Eu!!!%7jYx*z==QF36p-ZznTrj(TuM_9n~+mjerOJY{z4M zwY8Inajb8OX(Zw_tcQzGXSE)i;0vg?;W)O!3mDn?Z?+hFU^L@nu|MWvIzEFs(o?7! z`3yDhMbv!1VOXEan!nprr=TLf3rFH{Ou@ESZD2#OF?~NO;Q2TN*J6A84joK0p2%C$ zAN6JRx&3l%M1L{1#b@>RPh%P%F;EAM#}oMg)x`|DZBfNE5f%A;sGY1p?cfPa#VuF^ zk6|@D=X%-oH`EcvR`QsGI09#4N>tcms0*_u$`kogEvsw;NsYD(cSNOdBGyMg#^7w! z4(@aNJ5Zn4J*WUbK#tse>|X!G?f=W|Uqof*`!J2pG^$kbM9%g`)I?M8ZoCKkVqAQ&ZFg ztxz>`y?ebMR-!-9?GHxncsT0*vG@cQp%$nbYv--)S`U*LZ-}}2|0HD77|y^4CCR$9IQ681k1) za;BCB3jM`Cr%QgIz}GF^U*hkQ5otOa4myRUfhkVUvQn?pqTE*+^ao0uvZ+oe;CM?4 z;{I4c`b+YQ%L+7QX8ZKE*)5%Lk+0O3?hGpSd4oPD&*yljc}smxsK^^~N__qhm+Aa_ z<=cXRl0TOIBdEea=@f71Ps{u#9ygqz6AXDvBYT;~q>1`DMY-AA9=qLcu?+6bUp`r9UKF60nDcu?3o9YYs*+qV- z&l~ck|NChZX;q9)JCaey36`;Ga_$s)%Y6=a7AzgNDkV&-xN8b=`3ildrA$&12u$^r z_)1f{r3?=$jYE7kb3Kc^B_+P%U`m$^Z#VKtQhZL3z2+C`HXVf~i)1<9-s=S1>~iWU zLqp!YVqc0G;GN8Q-jW{*3@Y_kTt9kF`O;N zHswqn%r7eT`}RIj?9VT9!nTCcogV&BNVVh5FADiuI|bfg(3$2dAhZJi|5-UUCTgwB z&aBFH3x)N(d2V@>m4pZ)w0Bo%Mu-VZ*^Y{Yr73G)X^zhsrh|{1yR8vhiaw`2P!c)a zVUc2(MievBd;GUr$PENT>2Vc3m+opGXQO9Z!T;xxms7q4Wo)X@(K)aYMT!5TMjS5% Y`p1E@ul%AQg%dK7L$9cO;6j)G0yu|)pa1{> delta 10452 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 z zxN7^Yi3%tVr(h4%Uis>($FBWp8tQxT^%|>jA>b$5;UlOAV^A~ig!OSCD!|vVIxa&6 z`mt-@jSBb}Y7Z5l0=JVupGD2|SJbAyj|#|Kx8Er}6)3c(-W>P+xAmz8Y+;>*bftaw;5T4an!G&Hf^;#_7&V0-=g09E zRL6T!{T)GVy7Ne?&23b`z5llVH_dwV=tc5?f+CCj$A0*+zx$8NuzQ@(~VhGm{VmmBAEp7QSwx726CiT7^3f(E3#kLsb z?Nz$AgHZ#_MFlh;)!{PK8gD>lVyE*9)P2X%2hX7PMj@8PAJH3cp)cM=J@2_sL7T+e z$KFsG%TTZG>NQa_u8n%20j|N8r~%HPI=<+s9)~>W&SluE9Y31_?OA z6xf3K0TtPgs2LRb=B70WDU*A@@tLN%8AIo_@^2H>yhXcat(W;Pt?kNfbDJ(5?VVe= NVrQ$|xD&S%{}1r^P9y*T diff --git a/src/octoprint/translations/de/LC_MESSAGES/messages.po b/src/octoprint/translations/de/LC_MESSAGES/messages.po index a17b2b1e..bd7cd773 100644 --- a/src/octoprint/translations/de/LC_MESSAGES/messages.po +++ b/src/octoprint/translations/de/LC_MESSAGES/messages.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: OctoPrint\n" "Report-Msgid-Bugs-To: i18n@octoprint.org\n" -"POT-Creation-Date: 2016-09-07 12:06+0200\n" -"PO-Revision-Date: 2016-09-07 12:09+0100\n" +"POT-Creation-Date: 2016-09-09 11:35+0200\n" +"PO-Revision-Date: 2016-09-09 11:48+0100\n" "Last-Translator: Gina Häußge \n" "Language: de\n" "Language-Team: German (http://www.transifex.com/projects/p/octoprint/" @@ -190,7 +190,6 @@ msgid "Overwrite existing file" msgstr "Vorhandene Datei überschreiben" #: src/octoprint/plugins/cura/templates/cura_settings.jinja2:113 -#, fuzzy msgid "" "\n" " You can import your existing profile .ini files " @@ -738,7 +737,7 @@ msgstr "Repository-Cache TTL" #: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:239 #: src/octoprint/plugins/softwareupdate/templates/softwareupdate.jinja2:26 -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:107 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:108 #: src/octoprint/templates/dialogs/confirmation.jinja2:11 #: src/octoprint/templates/dialogs/slicing.jinja2:50 #: src/octoprint/templates/sidebar/state.jinja2:25 @@ -746,7 +745,7 @@ msgid "Cancel" msgstr "Abbruch" #: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:240 -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:108 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:109 msgid "Save" msgstr "Speichern" @@ -1063,7 +1062,18 @@ msgstr "Versionstracking für OctoPrint" msgid "OctoPrint Release Channel" msgstr "OctoPrint Release Channel" -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:96 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:93 +#, python-format +msgid "" +"Make sure you have read \"Using Release Channels\" before switching to a " +"release channel other than \"Stable\"" +msgstr "" +"Bitte lies " +"\"Using Release Channels\" bevor du auf einen anderen Release Channel " +"als \"Stable\" wechselst" + +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:97 msgid "Version cache TTL" msgstr "TTL des Versionscaches" diff --git a/translations/de/LC_MESSAGES/messages.mo b/translations/de/LC_MESSAGES/messages.mo index 0b6c61170793d640c0c8d1fc72536607af0b4624..389721a923e4dda866107b157b5670f38f893f0d 100644 GIT binary patch delta 11484 zcmbu_d3aPsy2tTqLI??jB`kp$;Sj?XAR#0mAWLMC0D`QtFP)@AT0$Drogg^Spr9fm z$f6*Mz=*)$s1QY95JgY~L>*;QSrkRY5fnGvx!+&caprpO{qOqB7z}4r=@~rWzAAmuS>rpiY*(kb<@8w{!cw zunzrUSPzTb@mZ*eA4CPd3VY#pjK<%v3Pxoc6N_;ehjm>WW8+F;W72565oJuj4#qrA zHOyho$r% zP@nb9RT_1$N;msp5>}<(618wURLbUI16+=Y_zY^{*RdA9iJXo(g$=Q4cbl0MRKGjw zzEPNiw_&(0jmtOe&wq>B!0$Pnzs|J&jrKxo)Wp}j{Xtln{umsG6LBQ&#(tRCgTll-)X}_yB-40$ z+6{Ea3i`RIBl{JvK^2MuNbVIjhQc-345&y7P-j(wsaTGBU=`|YUql7G8񿴈{ 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 Y`p1E@ul%AQg%dK7L$9cO;6j)G0yu|)pa1{> delta 10452 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 z zxN7^Yi3%tVr(h4%Uis>($FBWp8tQxT^%|>jA>b$5;UlOAV^A~ig!OSCD!|vVIxa&6 z`mt-@jSBb}Y7Z5l0=JVupGD2|SJbAyj|#|Kx8Er}6)3c(-W>P+xAmz8Y+;>*bftaw;5T4an!G&Hf^;#_7&V0-=g09E zRL6T!{T)GVy7Ne?&23b`z5llVH_dwV=tc5?f+CCj$A0*+zx$8NuzQ@(~VhGm{VmmBAEp7QSwx726CiT7^3f(E3#kLsb z?Nz$AgHZ#_MFlh;)!{PK8gD>lVyE*9)P2X%2hX7PMj@8PAJH3cp)cM=J@2_sL7T+e z$KFsG%TTZG>NQa_u8n%20j|N8r~%HPI=<+s9)~>W&SluE9Y31_?OA z6xf3K0TtPgs2LRb=B70WDU*A@@tLN%8AIo_@^2H>yhXcat(W;Pt?kNfbDJ(5?VVe= NVrQ$|xD&S%{}1r^P9y*T diff --git a/translations/de/LC_MESSAGES/messages.po b/translations/de/LC_MESSAGES/messages.po index a17b2b1e..bd7cd773 100644 --- a/translations/de/LC_MESSAGES/messages.po +++ b/translations/de/LC_MESSAGES/messages.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: OctoPrint\n" "Report-Msgid-Bugs-To: i18n@octoprint.org\n" -"POT-Creation-Date: 2016-09-07 12:06+0200\n" -"PO-Revision-Date: 2016-09-07 12:09+0100\n" +"POT-Creation-Date: 2016-09-09 11:35+0200\n" +"PO-Revision-Date: 2016-09-09 11:48+0100\n" "Last-Translator: Gina Häußge \n" "Language: de\n" "Language-Team: German (http://www.transifex.com/projects/p/octoprint/" @@ -190,7 +190,6 @@ msgid "Overwrite existing file" msgstr "Vorhandene Datei überschreiben" #: src/octoprint/plugins/cura/templates/cura_settings.jinja2:113 -#, fuzzy msgid "" "\n" " You can import your existing profile .ini files " @@ -738,7 +737,7 @@ msgstr "Repository-Cache TTL" #: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:239 #: src/octoprint/plugins/softwareupdate/templates/softwareupdate.jinja2:26 -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:107 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:108 #: src/octoprint/templates/dialogs/confirmation.jinja2:11 #: src/octoprint/templates/dialogs/slicing.jinja2:50 #: src/octoprint/templates/sidebar/state.jinja2:25 @@ -746,7 +745,7 @@ msgid "Cancel" msgstr "Abbruch" #: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:240 -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:108 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:109 msgid "Save" msgstr "Speichern" @@ -1063,7 +1062,18 @@ msgstr "Versionstracking für OctoPrint" msgid "OctoPrint Release Channel" msgstr "OctoPrint Release Channel" -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:96 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:93 +#, python-format +msgid "" +"Make sure you have read \"Using Release Channels\" before switching to a " +"release channel other than \"Stable\"" +msgstr "" +"Bitte lies " +"\"Using Release Channels\" bevor du auf einen anderen Release Channel " +"als \"Stable\" wechselst" + +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:97 msgid "Version cache TTL" msgstr "TTL des Versionscaches" diff --git a/translations/messages.pot b/translations/messages.pot index c20926a1..66a24c1e 100644 --- a/translations/messages.pot +++ b/translations/messages.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: OctoPrint 1.2.16.dev36+g2256a1e\n" +"Project-Id-Version: OctoPrint 1.2.16.dev44+ge19ecb0\n" "Report-Msgid-Bugs-To: i18n@octoprint.org\n" -"POT-Creation-Date: 2016-09-07 12:06+0200\n" +"POT-Creation-Date: 2016-09-09 11:35+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -655,7 +655,7 @@ msgstr "" #: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:239 #: src/octoprint/plugins/softwareupdate/templates/softwareupdate.jinja2:26 -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:107 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:108 #: src/octoprint/templates/dialogs/confirmation.jinja2:11 #: src/octoprint/templates/dialogs/slicing.jinja2:50 #: src/octoprint/templates/sidebar/state.jinja2:25 @@ -663,7 +663,7 @@ msgid "Cancel" msgstr "" #: src/octoprint/plugins/pluginmanager/templates/pluginmanager_settings.jinja2:240 -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:108 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:109 msgid "Save" msgstr "" @@ -935,7 +935,15 @@ msgstr "" msgid "OctoPrint Release Channel" msgstr "" -#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:96 +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:93 +#, python-format +msgid "" +"Make sure you have read \"Using Release Channels\" before " +"switching to a release channel other than \"Stable\"" +msgstr "" + +#: src/octoprint/plugins/softwareupdate/templates/softwareupdate_settings.jinja2:97 msgid "Version cache TTL" msgstr "" From 079430e3c8000a5292ce90b409890b55e3d1c7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 8 Sep 2016 12:19:50 +0200 Subject: [PATCH 7/7] Preparing release of 1.2.16rc1 --- .github/ISSUE_TEMPLATE.md | 27 ++++++++++++++++++--------- CHANGELOG.md | 21 +++++++++++++++++++++ CONTRIBUTING.md | 25 ++++++++++++++++--------- SUPPORTERS.md | 12 ++++++++---- 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index d4c79c2e..bfb6508a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,7 +5,10 @@ This is a bug and feature tracker, please only use it to report bugs or request features within OctoPrint (not OctoPi, not any OctoPrint plugins and not unofficial OctoPrint versions). Mark requests with a [Request] prefix in the title please. Fully fill out the bug reporting -template for bug reports. +template for bug reports. Do not delete any lines from the template but +those enclosed in [ and ] - and those please do delete, they are only +provided for your information and removing them makes your ticket more +readable :) Do not seek support here ("I need help with ..."), that belongs on the mailing list or the G+ community (both linked in the "guidelines @@ -17,11 +20,12 @@ Thank you! #### What were you doing? -[Please be as specific as possible here. The maintainers will need to reproduce -your issue in order to fix it and that is not possible if they don't know -what you did to get it to happen in the first place. If you encountered -a problem with specific files of any sorts, make sure to also include a link to a file -with which to reproduce the problem.] +[Please be as specific as possible here. The maintainers will need to +reproduce your issue in order to fix it and that is not possible if they +don't know what you did to get it to happen in the first place. + +If you encountered a problem with specific files of any sorts, make sure +to also include a link to a file with which to reproduce the problem.] #### What did you expect to happen? @@ -29,7 +33,7 @@ with which to reproduce the problem.] #### Branch & Commit or Version of OctoPrint -[Can be found in the lower left corner of the web interface.] +[Can be found in the lower left corner of the web interface. ALWAYS INCLUDE.] #### Printer model & used firmware incl. version @@ -41,12 +45,17 @@ with which to reproduce the problem.] #### Link to octoprint.log -[On gist.github.com or pastebin.com. Always include and never truncate.] +[On gist.github.com or pastebin.com. ALWAYS INCLUDE and never truncate.] #### Link to contents of terminal tab or serial.log [On gist.github.com or pastebin.com. If applicable, always include if unsure or -reporting communication issues. Never truncate.] +reporting communication issues. Never truncate. + +serial.log is usually not written due to performance reasons and must be +enabled explicitly. Provide at the very least the contents of your +terminal tab at the time of the bug occurence, even if you do not have +a serial.log.] #### Link to contents of Javascript console in the browser diff --git a/CHANGELOG.md b/CHANGELOG.md index 8830c0cd..33a55f01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # OctoPrint Changelog +## 1.2.16rc1 (2016-09-08) + +### Improvements + + * [#1434](https://github.com/foosel/OctoPrint/issues/1434): Make sure to sanitize any file names in the upload folder that do not match OctoPrint's file name "sanitization standard" automatically when creating a file listing. This should solve issues with UI functionality like selecting a file for printing or deleting a file to not work with files that were uploaded manually to the ``uploads`` folder. As a side note: Please don't do this, use the ``watched`` folder if you want to SCP/FTP/copy files directly to OctoPrint. + * [#1434](https://github.com/foosel/OctoPrint/issues/1434): Allow `[` and `]` in uploaded file names. + * [#1481](https://github.com/foosel/OctoPrint/issues/1481): Bring back non-fuzzy layer time estimates in the GCODE viewer. + * Improved fuzzy print time displays in the frontend. Rounding now takes overall duration into account - durations over a day will be rounded up/down to half days, durations over an hour will be rounded up/down to half hours, durations over 30min will be rounded to 10min segments, durations below 30min will be rounded up or down to the next minute depending on the seconds and finally if we are talking about less than a minute, durations over 30s will return "less than a minute", durations under 30s will return "a couple of seconds". + * Improved intermediary loading page: Don't report server as ready and reload until preliminary caching has been done, IF preliminary caching will be done. + * Added release channels to OctoPrint's bundled Software Update plugin. You will now be able to subscribe to OctoPrint's `maintenance` or `devel` release candidates in addition to stable versions. [Read more about Release Channels on the wiki](https://github.com/foosel/OctoPrint/wiki/Using-Release-Channels). + +### Bug Fixes + + * [#1448](https://github.com/foosel/OctoPrint/issues/1448): Don't "eat" first line of the pause script after a pause triggering `M0` but send it to the printer instead + * [#1477](https://github.com/foosel/OctoPrint/issues/1477): Only report files enqueued for analysis which actually are (as in, don't claim to have queued STL files for GCODE analysis) + * [#1478](https://github.com/foosel/OctoPrint/issues/1478): Don't display inaccurate linear estimate ("6 days remaining") until 30 *minutes* have passed, even if nothing else is available. Potentially related to [#1428](https://github.com/foosel/OctoPrint/issues/1428). + * [#1479](https://github.com/foosel/OctoPrint/issues/1479): Make sure set cookies are post fixed with a port specific suffix and that the path they are set on takes the script root from the request into account. + * [#1483](https://github.com/foosel/OctoPrint/issues/1483): Filenames in file uploads may also now be encoded in ISO-8859-1, as defined in [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2.4). Solves an issue when sending files with non-ASCII-characters in the file name from Slic3r. + +([Commits](https://github.com/foosel/OctoPrint/compare/1.2.15...1.2.16rc1)) + ## 1.2.15 (2016-07-30) ### Improvements diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d466a21..f6349926 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -123,17 +123,18 @@ following section *completely*. Thank you! :) ### What should I include in a bug report? -Always use the following template (you can remove what's within `[...]`, that's +Always use the following template (please remove what's within `[...]`, that's only provided here as some additional information for you), **even if only adding a "me too" to an existing ticket**: #### What were you doing? - [Please be as specific as possible here. The maintainers will need to reproduce - your issue in order to fix it and that is not possible if they don't know - what you did to get it to happen in the first place. If you encountered - a problem with specific files of any sorts, make sure to also include a link to a file - with which to reproduce the problem.] + [Please be as specific as possible here. The maintainers will need to + reproduce your issue in order to fix it and that is not possible if they + don't know what you did to get it to happen in the first place. + + If you encountered a problem with specific files of any sorts, make sure + to also include a link to a file with which to reproduce the problem.] #### What did you expect to happen? @@ -141,7 +142,7 @@ only provided here as some additional information for you), **even if only addin #### Branch & Commit or Version of OctoPrint - [Can be found in the lower left corner of the web interface.] + [Can be found in the lower left corner of the web interface. ALWAYS INCLUDE.] #### Printer model & used firmware incl. version @@ -153,12 +154,17 @@ only provided here as some additional information for you), **even if only addin #### Link to octoprint.log - [On gist.github.com or pastebin.com. Always include and never truncate.] + [On gist.github.com or pastebin.com. ALWAYS INCLUDE and never truncate.] #### Link to contents of terminal tab or serial.log [On gist.github.com or pastebin.com. If applicable, always include if unsure or - reporting communication issues. Never truncate.] + reporting communication issues. Never truncate. + + serial.log is usually not written due to performance reasons and must be + enabled explicitly. Provide at the very least the contents of your + terminal tab at the time of the bug occurence, even if you do not have + a serial.log.] #### Link to contents of Javascript console in the browser @@ -376,6 +382,7 @@ the local version identifier to allow for an exact determination of the active c tickets as well, explained issue with "me too" red herrings. * 2016-03-14: Some more requirements for PRs, and a PR template. * 2016-06-08: New `prerelease` and `rc` branches explained. + * 2016-09-09: New `rc/*` branches explained. ## Footnotes * [1] - If you are wondering why, the problem is that anything that you add diff --git a/SUPPORTERS.md b/SUPPORTERS.md index 659d13df..9c51ca64 100644 --- a/SUPPORTERS.md +++ b/SUPPORTERS.md @@ -1,4 +1,4 @@ -# Supporters +# Supporters Development of this version of OctoPrint wouldn't have been possible without [financial support by the community](http://octoprint.org/support-octoprint/) - @@ -12,11 +12,13 @@ thanks to everyone who contributed! * Arnljot Arntsen * Aurelio Bernal Ramírez * Bart Zudell + * Boris Hussein * Brad Jackson * Brad Mooneyham * Brent Fiegle * Brian E. Tyler * Charles Mitchell + * Christopher Day * Christian Petropolis * COLLE+McVOY * CreativeTools @@ -33,6 +35,7 @@ thanks to everyone who contributed! * J. Eckert * Jason Galarneau * Joe Korzeniewski + * Josh Daniels * Joshua Gregory * Kaile Riser * Kale Stedman @@ -45,11 +48,11 @@ thanks to everyone who contributed! * Mark Walker * Masayoshi Mitsui * Michael McDargh - * Miguel Angel Salmeron * Mikey * Miles Flavel * Mohammed Khorakiwala * Noe Ruiz + * Patrick McGinnis * Paul Generes * Peter Grace * Peter Schmehl @@ -64,8 +67,9 @@ thanks to everyone who contributed! * stefi davis * Steven Pearson * Sven Mueller + * Terrance Shaw * Thomas Hatley - * Thomas Sanladerer * Trent Shumay + * Xpandedreality -and 844 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)! \ No newline at end of file +and 905 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)!