diff --git a/.gitignore b/.gitignore index 472e3810..87a55bc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ src/octoprint/templates/_data/AUTHORS.md src/octoprint/templates/_data/CHANGELOG.md +src/octoprint/templates/_data/SPONSORS.md src/octoprint/templates/_data/THIRDPARTYLICENSES.md +devtools + *.tar.bz2 *.tar.gz *.7z diff --git a/SPONSORS.md b/SPONSORS.md new file mode 100644 index 00000000..eac40941 --- /dev/null +++ b/SPONSORS.md @@ -0,0 +1,31 @@ +# Sponsors + +Development of this version of OctoPrint wouldn't have been possible without +[financial support by the community](http://octoprint.org/support-octoprint/) - +thanks to everyone who contributed! + +## Patreon Patrons + + * 3D Moniak + * Arnljot Arntsen + * Aurelio Bernal Ramírez + * D Brian Kimmel + * Doug Johnson + * E3D BigBox + * Erik de Bruijn + * Ernesto Martinez + * Exovite + * georgeroblesjr + * Gregor Luetolf + * Kale Stedman + * Makespace Madrid + * Masayoshi Mitsui + * Miguel Angel Salmeron + * Noe Ruiz + * Roy Cortes + * Samer Najia + * Stefan Krister + * Sven Mueller + * Tom + +and 321 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)! \ No newline at end of file diff --git a/setup.py b/setup.py index c6fc14f9..2066a24e 100644 --- a/setup.py +++ b/setup.py @@ -114,6 +114,7 @@ def get_cmdclass(): "octoprint/templates/_data": [ "AUTHORS.md", "CHANGELOG.md", + "SPONSORS.md", "THIRDPARTYLICENSES.md", ] }, cmdclass["build_py"] if "build_py" in cmdclass else _build_py) diff --git a/src/octoprint/plugins/virtual_printer/virtual.py b/src/octoprint/plugins/virtual_printer/virtual.py index 8dd1528b..ab0773f2 100644 --- a/src/octoprint/plugins/virtual_printer/virtual.py +++ b/src/octoprint/plugins/virtual_printer/virtual.py @@ -150,7 +150,12 @@ class VirtualPrinter(object): # strip checksum if "*" in data: + checksum = int(data[data.rfind("*") + 1:]) data = data[:data.rfind("*")] + if not checksum == self._calculate_checksum(data): + self._triggerResend(expected=self.currentLine + 1) + continue + self.currentLine += 1 elif settings().getBoolean(["devel", "virtualPrinter", "forceChecksum"]): self._send("Error: Missing checksum") @@ -388,6 +393,12 @@ class VirtualPrinter(object): ##~~ further helpers + def _calculate_checksum(self, line): + checksum = 0 + for c in line: + checksum ^= ord(c) + return checksum + def _kill(self): if not self._supportM112: return diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index cbd17621..2a66b477 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -112,7 +112,7 @@ def load_user(id): #~~ startup code -class Server(): +class Server(object): def __init__(self, settings=None, plugin_manager=None, host="0.0.0.0", port=5000, debug=False, allow_root=False): self._settings = settings self._plugin_manager = plugin_manager @@ -641,6 +641,37 @@ class Server(): app.jinja_env.filters["offset_html_headers"] = offset_html_headers app.jinja_env.filters["offset_markdown_headers"] = offset_markdown_headers + def regex_replace(s, find, replace): + return re.sub(find, replace, s) + + html_header_regex = re.compile("[1-6])>(?P.*?)") + def offset_html_headers(s, offset): + def repl(match): + number = int(match.group("number")) + number += offset + if number > 6: + number = 6 + elif number < 1: + number = 1 + return "{content}".format(number=number, content=match.group("content")) + return html_header_regex.sub(repl, s) + + markdown_header_regex = re.compile("^(?P#+)\s+(?P.*)$", flags=re.MULTILINE) + def offset_markdown_headers(s, offset): + def repl(match): + number = len(match.group("hashs")) + number += offset + if number > 6: + number = 6 + elif number < 1: + number = 1 + return "{hashs} {content}".format(hashs="#" * number, content=match.group("content")) + return markdown_header_regex.sub(repl, s) + + app.jinja_env.filters["regex_replace"] = regex_replace + app.jinja_env.filters["offset_html_headers"] = offset_html_headers + app.jinja_env.filters["offset_markdown_headers"] = offset_markdown_headers + # configure additional template folders for jinja2 import jinja2 import octoprint.util.jinja @@ -651,7 +682,7 @@ class Server(): loaders = [app.jinja_loader, filesystem_loader] if octoprint.util.is_running_from_source(): root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../..")) - allowed = ["AUTHORS.md", "CHANGELOG.md", "THIRDPARTYLICENSES.md"] + allowed = ["AUTHORS.md", "CHANGELOG.md", "SPONSORS.md", "THIRDPARTYLICENSES.md"] files = {"_data/" + name: os.path.join(root, name) for name in allowed} loaders.append(octoprint.util.jinja.SelectedFilesLoader(files)) diff --git a/src/octoprint/server/views.py b/src/octoprint/server/views.py index 14a8c3bc..4e8f0ffe 100644 --- a/src/octoprint/server/views.py +++ b/src/octoprint/server/views.py @@ -433,7 +433,8 @@ def _process_templates(): license=(gettext("OctoPrint License"), dict(template="dialogs/about/license.jinja2", _div="about_license", custom_bindings=False)), thirdparty=(gettext("Third Party Licenses"), dict(template="dialogs/about/thirdparty.jinja2", _div="about_thirdparty", custom_bindings=False)), authors=(gettext("Authors"), dict(template="dialogs/about/authors.jinja2", _div="about_authors", custom_bindings=False)), - changelog=(gettext("Changelog"), dict(template="dialogs/about/changelog.jinja2", _div="about_changelog", custom_bindings=False)) + changelog=(gettext("Changelog"), dict(template="dialogs/about/changelog.jinja2", _div="about_changelog", custom_bindings=False)), + sponsors = (gettext("Sponsors"), dict(template="dialogs/about/sponsors.jinja2", _div="about_sponsors", custom_bindings=False)) ) # extract data from template plugins diff --git a/src/octoprint/settings.py b/src/octoprint/settings.py index a94e9072..654f6651 100644 --- a/src/octoprint/settings.py +++ b/src/octoprint/settings.py @@ -224,7 +224,7 @@ default_settings = { ], "usersettings": ["access", "interface"], "wizard": ["access"], - "about": ["about", "license", "thirdparty", "plugin_pluginmanager", "authors", "changelog"], + "about": ["about", "sponsors", "authors", "changelog", "license", "thirdparty", "plugin_pluginmanager"], "generic": [] }, "disabled": { diff --git a/src/octoprint/templates/dialogs/about/about.jinja2 b/src/octoprint/templates/dialogs/about/about.jinja2 index 3803eba2..947c56ac 100644 --- a/src/octoprint/templates/dialogs/about/about.jinja2 +++ b/src/octoprint/templates/dialogs/about/about.jinja2 @@ -11,7 +11,7 @@

- OctoPrint is sponsored and maintained by BQ. + OctoPrint is sponsored by a lot of awesome people. Please see "Sponsors" to the left.

@@ -44,6 +44,5 @@

- The OctoPrint brand is a registered trademark of MundoReader, S.L - (Trademark Rules). + "OctoPrint" is a registered trademark

diff --git a/src/octoprint/templates/dialogs/about/sponsors.jinja2 b/src/octoprint/templates/dialogs/about/sponsors.jinja2 new file mode 100644 index 00000000..1870c618 --- /dev/null +++ b/src/octoprint/templates/dialogs/about/sponsors.jinja2 @@ -0,0 +1 @@ +{% filter markdown %}{% filter offset_markdown_headers(2) %}{% include "_data/SPONSORS.md" ignore missing %}{% endfilter %}{% endfilter %}