diff options
author | Niklas | 2017-08-12 19:06:52 +0200 |
---|---|---|
committer | Niklas | 2017-08-12 19:06:52 +0200 |
commit | ec78392b29cd0be677362ae081c7b62f3c06ecb1 (patch) | |
tree | 961e4ba59d542823170c9c6773959ec21461a427 | |
parent | 5ec8a605f9ffc1d37ee2c858f76954110a5aac89 (diff) | |
download | aur-ec78392b29cd0be677362ae081c7b62f3c06ecb1.tar.gz |
update to 1.3.4
-rw-r--r-- | .SRCINFO | 55 | ||||
-rw-r--r-- | PKGBUILD | 111 | ||||
-rw-r--r-- | octoprint-deps.patch | 641 | ||||
-rw-r--r-- | octoprint-jinja29.patch | 148 | ||||
-rwxr-xr-x | octoprint.install | 4 | ||||
-rw-r--r-- | octoprint.run | 5 | ||||
-rw-r--r-- | octoprint.service | 5 |
7 files changed, 865 insertions, 104 deletions
@@ -1,51 +1,54 @@ -# Generated by mksrcinfo v8 -# Thu Oct 20 16:25:19 UTC 2016 pkgbase = octoprint - pkgdesc = OctoPrint provides a responsive web interface for controlling a 3D printer (RepRap, Ultimaker, ...) - pkgver = 1.2.16 + pkgdesc = Responsive web interface for controlling a 3D printer (RepRap, Ultimaker, ...) + pkgver = 1.3.4 pkgrel = 1 - url = https://github.com/foosel/OctoPrint + url = http://octoprint.org/ install = octoprint.install arch = any - license = GPL - makedepends = git + license = AGPL3 + depends = python2-awesome-slugify depends = python2-blinker + depends = python2-chainmap + depends = python2-click + depends = python2-dateutil + depends = python2-feedparser depends = python2-flask + depends = python2-flask-assets depends = python2-flask-babel depends = python2-flask-login depends = python2-flask-principal + depends = python2-future + depends = python2-markdown depends = python2-netaddr - depends = python2-numpy + depends = python2-netifaces depends = python2-pkginfo - depends = python2-pylru-git + depends = python2-psutil + depends = python2-pylru depends = python2-pyserial + depends = python2-requests depends = python2-rsa - depends = python2-sarge-git + depends = python2-sarge + depends = python2-scandir + depends = python2-semanticversion + depends = python2-sockjs-tornado depends = python2-tornado - depends = python2-tornadio2 - depends = python2-sockjs-tornado-git - depends = python2-webassets depends = python2-watchdog + depends = python2-websocket-client depends = python2-yaml - depends = python2-flask-assets - depends = python2-psutil - depends = python2-requests - depends = polkit - depends = python2-netifaces - depends = python2-awesome-slugify optdepends = ffmpeg: timelapse support optdepends = mjpg-streamer: stream images from webcam optdepends = v4l-mjpg-stream: stream images from a Video4Linux capable camera provides = octoprint - conflicts = octoprint - source = octoprint-1.2.16.tar.gz::https://github.com/foosel/OctoPrint/archive/1.2.16.tar.gz + source = https://github.com/foosel/OctoPrint/archive/1.3.4.tar.gz source = octoprint.run source = octoprint.service - source = octoprint-tornado401.patch - md5sums = SKIP - md5sums = 3bee9901c9eabed94b7f9236f83bf053 - md5sums = ec5e51f876bb5fb223801bf28850908a - md5sums = 88d6fb3a61a4ab990fb6cca39c830a6c + source = octoprint-deps.patch + source = octoprint-jinja29.patch + sha512sums = df22247796b46f270f7525777194e983a12be3c5f719ffc4ed864d6012d2050b813df9e8f9ee95bdc7687838c96f7c102327a7b802d42abd84481ddd77c8ebea + sha512sums = 5c22c76e4089958ff42e2627f29c360fa0f9a73b849f1fe5092cdd9ae800323263b75ac7e23d7189badac9baa7daa850183bf2491680a0ac01c605531728da62 + sha512sums = 89a8703cbc8b8802eb6a360359f92904357a99bf5b1174c85d4555f88a816d4c008d077fe4f3fed4db0b23e8a662359bcfafaf7750a2ed50a81104f04d04c056 + sha512sums = cb4190c0a24499fdac2d48e89ba20229ac7d11df0d6bb56b8930fadde3595e70387868374d93c49aa0230b276f7bc061969ca64d92de995aea403150d156969f + sha512sums = 41e03bcc2111d1000ca0d62634009dc2030bae52b6623cd58a595f570e0f99e524613d52785b50098fe044fe5355b26221ce7a286148d9bdd95fb3f220bb5568 pkgname = octoprint @@ -1,112 +1,81 @@ -# Maintainer: Yunhui Fu <yhfudev@gmail.com> +# Maintainer: Niklas <dev@n1klas.net> +# Contributor: Yunhui Fu <yhfudev@gmail.com> # Contributor: Doug Richardson <dougie.richardson@gmail.com> # Contributor: feilen <feilen1000@gmail.com> # Contributor: Thermionix <thermionix@gmail.com> pkgname=octoprint -pkgver=1.2.16 +_reponame=OctoPrint +pkgver=1.3.4 pkgrel=1 -pkgdesc="OctoPrint provides a responsive web interface for controlling a 3D printer (RepRap, Ultimaker, ...)" +pkgdesc="Responsive web interface for controlling a 3D printer (RepRap, Ultimaker, ...)" arch=(any) -url="https://github.com/foosel/OctoPrint" -license=('GPL') +url="http://octoprint.org/" +license=('AGPL3') depends=( + 'python2-awesome-slugify' 'python2-blinker' + 'python2-chainmap' + 'python2-click' + 'python2-dateutil' + 'python2-feedparser' 'python2-flask' + 'python2-flask-assets' 'python2-flask-babel' 'python2-flask-login' - #'python2-flask-markdown' 'python2-flask-principal' + 'python2-future' + 'python2-markdown' 'python2-netaddr' - 'python2-numpy' + 'python2-netifaces' 'python2-pkginfo' - 'python2-pylru-git' # 'python2-pylru' + 'python2-psutil' + 'python2-pylru' 'python2-pyserial' + 'python2-requests' 'python2-rsa' - 'python2-sarge-git' # 'python2-sarge' + 'python2-sarge' + 'python2-scandir' + 'python2-semanticversion' + 'python2-sockjs-tornado' 'python2-tornado' - 'python2-tornadio2' - 'python2-sockjs-tornado-git' - 'python2-webassets' 'python2-watchdog' + 'python2-websocket-client' 'python2-yaml' - 'python2-flask-assets' - 'python2-psutil' - 'python2-requests' - 'polkit' - 'python2-netifaces' - 'python2-awesome-slugify' - ) -makedepends=( 'git' ) -optdepends=( +) +optdepends=( 'ffmpeg: timelapse support' 'mjpg-streamer: stream images from webcam' 'v4l-mjpg-stream: stream images from a Video4Linux capable camera' ) -provides=( 'octoprint' ) -conflicts=( 'octoprint' ) +provides=('octoprint') install="octoprint.install" source=( - #"${pkgname}::git+https://github.com/foosel/OctoPrint.git#commit=${pkgver}" - "${pkgname}-${pkgver}.tar.gz::https://github.com/foosel/OctoPrint/archive/${pkgver}.tar.gz" + "https://github.com/foosel/OctoPrint/archive/${pkgver}.tar.gz" octoprint.run octoprint.service - octoprint-tornado401.patch - ) -md5sums=('SKIP' - '3bee9901c9eabed94b7f9236f83bf053' - 'ec5e51f876bb5fb223801bf28850908a' - '88d6fb3a61a4ab990fb6cca39c830a6c' - ) - -pkgver_git() { - cd "${srcdir}/${pkgname}" - #local ver="$(git show | grep commit | awk '{print $2}' )" - #printf "r%s" "${ver//[[:alpha:]]}" - echo "r$(git rev-list --count HEAD).$(git rev-parse --short HEAD)" -} - -pkgver_svn() { - cd "${srcdir}/${pkgname}" - local ver="$(svn info | grep Revision | awk '{print $2}' )" - #printf "r%s" "${ver//[[:alpha:]]}" - echo ${ver:0:7} -} + octoprint-deps.patch + octoprint-jinja29.patch +) +sha512sums=('df22247796b46f270f7525777194e983a12be3c5f719ffc4ed864d6012d2050b813df9e8f9ee95bdc7687838c96f7c102327a7b802d42abd84481ddd77c8ebea' + '5c22c76e4089958ff42e2627f29c360fa0f9a73b849f1fe5092cdd9ae800323263b75ac7e23d7189badac9baa7daa850183bf2491680a0ac01c605531728da62' + '89a8703cbc8b8802eb6a360359f92904357a99bf5b1174c85d4555f88a816d4c008d077fe4f3fed4db0b23e8a662359bcfafaf7750a2ed50a81104f04d04c056' + 'cb4190c0a24499fdac2d48e89ba20229ac7d11df0d6bb56b8930fadde3595e70387868374d93c49aa0230b276f7bc061969ca64d92de995aea403150d156969f' + '41e03bcc2111d1000ca0d62634009dc2030bae52b6623cd58a595f570e0f99e524613d52785b50098fe044fe5355b26221ce7a286148d9bdd95fb3f220bb5568') -#pkgver() { -# pkgver_git -#} prepare() { - cd ${srcdir}/OctoPrint-${pkgver} + cd ${srcdir}/${_reponame}-${pkgver} - # check the version of python2-tornado required by the OctoPrint - # if it not python2-tornado 4.0.1, we need to switch back to new version! - # If use the latest tornado, you don't need to patch the octoprint. - VER=$(grep -Hrn '"tornado==' setup.py | awk -F= '{print $3}' | awk -F\" '{print $1}') - VAL=$(echo $VER | awk -F. '{print 10000 * $1 + 100 * $2 + $3}') - if (( $VAL <= 40001 )) ; then - patch -p1 < "$srcdir/octoprint-tornado401.patch" - else - echo "The required version of tornado is now changed." 1>&2 - fi + patch -p1 < "$srcdir/octoprint-deps.patch" + patch -p1 < "$srcdir/octoprint-jinja29.patch" } package() { - #cd ${srcdir}/${pkgname} - cd ${srcdir}/OctoPrint-${pkgver} + cd ${srcdir}/${_reponame}-${pkgver} python2 setup.py install --root="$pkgdir/" --optimize=1 - mkdir -p ${pkgdir}/usr/share/octoprint/ - cp -a * ${pkgdir}/usr/share/octoprint/ - #install -D -m755 run ${pkgdir}/usr/share/octoprint/run - rm -rf ${pkgdir}/usr/share/octoprint/src/ - rm -rf ${pkgdir}/usr/share/octoprint/build/ - rm -rf ${pkgdir}/usr/share/octoprint/docs/ - rm -rf ${pkgdir}/usr/share/octoprint/tests/ - rm -rf ${pkgdir}/usr/share/octoprint/translations/ - install -D -m755 ${srcdir}/octoprint.run ${pkgdir}/usr/bin/octoprint install -D -m644 ${srcdir}/octoprint.service ${pkgdir}/usr/lib/systemd/system/octoprint.service } diff --git a/octoprint-deps.patch b/octoprint-deps.patch new file mode 100644 index 000000000000..73e2fde4e003 --- /dev/null +++ b/octoprint-deps.patch @@ -0,0 +1,641 @@ +diff --git a/setup.py b/setup.py +index c6eabbd0..24ed0f8b 100644 +--- a/setup.py ++++ b/setup.py +@@ -14,34 +14,34 @@ import octoprint_setuptools + + # Requirements for our application + INSTALL_REQUIRES = [ +- "flask>=0.9,<0.11", ++ "flask>=0.11,<0.12", + "Jinja2>=2.8,<2.9", # Jinja 2.9 has breaking changes WRT template scope - we can't + # guarantee backwards compatibility for plugins and such with that + # version, hence we need to pin to a lower version for now. See #1697 +- "werkzeug>=0.8.3,<0.9", +- "tornado==4.0.2", # pinned for now, we need to migrate to a newer tornado, but due ++ "werkzeug>=0.11.1,<0.12", ++ "tornado>=4.4.2,<4.5", # pinned for now, we need to migrate to a newer tornado, but due + # to some voodoo needed to get large streamed uploads and downloads + # to work that is probably not completely straightforward and therefore + # something for post-1.3.0-stable release + "sockjs-tornado>=1.0.2,<1.1", +- "PyYAML>=3.10,<3.11", +- "Flask-Login>=0.2.2,<0.3", +- "Flask-Principal>=0.3.5,<0.4", +- "Flask-Babel>=0.9,<0.10", +- "Flask-Assets>=0.10,<0.11", ++ "PyYAML>=3.12,<3.13", ++ "Flask-Login>=0.3,<0.4", ++ "Flask-Principal>=0.4,<0.5", ++ "Flask-Babel>=0.11,<0.12", ++ "Flask-Assets>=0.12,<0.13", + "markdown>=2.6.4,<2.7", +- "pyserial>=2.7,<2.8", ++ "pyserial>=3.1.1,<3.2", + "netaddr>=0.7.17,<0.8", + "watchdog>=0.8.3,<0.9", + "sarge>=0.1.4,<0.2", + "netifaces>=0.10,<0.11", + "pylru>=1.0.9,<1.1", +- "rsa>=3.2,<3.3", +- "pkginfo>=1.2.1,<1.3", +- "requests>=2.7,<2.8", +- "semantic_version>=2.4.2,<2.5", +- "psutil>=3.2.1,<3.3", +- "Click>=6.2,<6.3", ++ "rsa>=3.4,<3.5", ++ "pkginfo>=1.3.2,<1.4", ++ "requests>=2.11.1,<2.12", ++ "semantic_version>=2.6.0,<2.7", ++ "psutil>=4.3.1,<4.4", ++ "Click>=6.6,<6.7", + "awesome-slugify>=1.6.5,<1.7", + "feedparser>=5.2.1,<5.3", + "chainmap>=1.0.2,<1.1", +diff --git a/src/octoprint/plugin/types.py b/src/octoprint/plugin/types.py +index 098688f6..be69dbc6 100644 +--- a/src/octoprint/plugin/types.py ++++ b/src/octoprint/plugin/types.py +@@ -1417,7 +1417,7 @@ class SettingsPlugin(OctoPrintPlugin): + + :return: the current settings of the plugin, as a dictionary + """ +- from flask.ext.login import current_user ++ from flask_login import current_user + import copy + + data = copy.deepcopy(self._settings.get_all_data(merged=True)) +@@ -1462,8 +1462,8 @@ class SettingsPlugin(OctoPrintPlugin): + else: + node[key] = None + +- conditions = dict(user=lambda: current_user is not None and not current_user.is_anonymous(), +- admin=lambda: current_user is not None and not current_user.is_anonymous() and current_user.is_admin(), ++ conditions = dict(user=lambda: current_user is not None and not current_user.is_anonymous, ++ admin=lambda: current_user is not None and not current_user.is_anonymous and current_user.is_admin, + never=lambda: False) + + for level, condition in conditions.items(): +@@ -1937,4 +1937,3 @@ class AppPlugin(OctoPrintPlugin): + + def get_additional_apps(self): + return [] +- +diff --git a/src/octoprint/plugins/announcements/__init__.py b/src/octoprint/plugins/announcements/__init__.py +index 74bc192a..7f73efb2 100644 +--- a/src/octoprint/plugins/announcements/__init__.py ++++ b/src/octoprint/plugins/announcements/__init__.py +@@ -22,7 +22,7 @@ from collections import OrderedDict + + from octoprint.server import admin_permission + from octoprint.server.util.flask import restricted_access, with_revalidation_checking, check_etag +-from flask.ext.babel import gettext ++from flask_babel import gettext + + class AnnouncementPlugin(octoprint.plugin.AssetPlugin, + octoprint.plugin.SettingsPlugin, +diff --git a/src/octoprint/plugins/corewizard/__init__.py b/src/octoprint/plugins/corewizard/__init__.py +index d9c61f67..77c89a05 100644 +--- a/src/octoprint/plugins/corewizard/__init__.py ++++ b/src/octoprint/plugins/corewizard/__init__.py +@@ -9,7 +9,7 @@ __copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms + import octoprint.plugin + + +-from flask.ext.babel import gettext ++from flask_babel import gettext + + + class CoreWizardPlugin(octoprint.plugin.AssetPlugin, +diff --git a/src/octoprint/plugins/discovery/__init__.py b/src/octoprint/plugins/discovery/__init__.py +index 988d4840..7d5b5f44 100644 +--- a/src/octoprint/plugins/discovery/__init__.py ++++ b/src/octoprint/plugins/discovery/__init__.py +@@ -12,7 +12,7 @@ The SSDP/UPNP implementations has been largely inspired by https://gist.github.c + import logging + import os + import flask +-from flask.ext.babel import gettext ++from flask_babel import gettext + from builtins import range + + import octoprint.plugin +diff --git a/src/octoprint/plugins/pluginmanager/__init__.py b/src/octoprint/plugins/pluginmanager/__init__.py +index 47365b2e..03b81a40 100644 +--- a/src/octoprint/plugins/pluginmanager/__init__.py ++++ b/src/octoprint/plugins/pluginmanager/__init__.py +@@ -15,7 +15,7 @@ from octoprint.server import admin_permission, VERSION + from octoprint.util.pip import LocalPipCaller, UnknownPip + + from flask import jsonify, make_response +-from flask.ext.babel import gettext ++from flask_babel import gettext + from collections import OrderedDict + + import logging +diff --git a/src/octoprint/plugins/softwareupdate/__init__.py b/src/octoprint/plugins/softwareupdate/__init__.py +index 507c5593..bd46a054 100644 +--- a/src/octoprint/plugins/softwareupdate/__init__.py ++++ b/src/octoprint/plugins/softwareupdate/__init__.py +@@ -18,7 +18,7 @@ import hashlib + + from . import version_checks, updaters, exceptions, util, cli + +-from flask.ext.babel import gettext ++from flask_babel import gettext + + from octoprint.server.util.flask import restricted_access, with_revalidation_checking, check_etag + from octoprint.server import admin_permission, VERSION, REVISION, BRANCH +@@ -549,7 +549,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin, + ##~~ TemplatePlugin API + + def get_template_configs(self): +- from flask.ext.babel import gettext ++ from flask_babel import gettext + return [ + dict(type="settings", name=gettext("Software Update")) + ] +@@ -882,7 +882,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin, + result = dict(check) + + if target == "octoprint": +- from flask.ext.babel import gettext ++ from flask_babel import gettext + + result["displayName"] = to_unicode(check.get("displayName"), errors="replace") + if result["displayName"] is None: +@@ -1074,5 +1074,3 @@ def __plugin_load__(): + __plugin_hooks__ = { + "octoprint.cli.commands": cli.commands + } +- +- +diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py +index 94b9bab5..e418d594 100644 +--- a/src/octoprint/server/__init__.py ++++ b/src/octoprint/server/__init__.py +@@ -8,10 +8,10 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms + import uuid + from sockjs.tornado import SockJSRouter + from flask import Flask, g, request, session, Blueprint, Request, Response +-from flask.ext.login import LoginManager, current_user +-from flask.ext.principal import Principal, Permission, RoleNeed, identity_loaded, UserNeed +-from flask.ext.babel import Babel, gettext, ngettext +-from flask.ext.assets import Environment, Bundle ++from flask_login import LoginManager, current_user ++from flask_principal import Principal, Permission, RoleNeed, identity_loaded, UserNeed ++from flask_babel import Babel, gettext, ngettext ++from flask_assets import Environment, Bundle + from babel import Locale + from watchdog.observers import Observer + from watchdog.observers.polling import PollingObserver +@@ -89,9 +89,9 @@ def on_identity_loaded(sender, identity): + return + + identity.provides.add(UserNeed(user.get_id())) +- if user.is_user(): ++ if user.is_user: + identity.provides.add(RoleNeed("user")) +- if user.is_admin(): ++ if user.is_admin: + identity.provides.add(RoleNeed("admin")) + + def load_user(id): +@@ -170,8 +170,7 @@ class Server(object): + self._logger = logging.getLogger(__name__) + pluginManager = self._plugin_manager + +- # monkey patch a bunch of stuff +- util.tornado.fix_ioloop_scheduling() ++ # monkey patch some stuff + util.flask.enable_additional_translations(additional_folders=[self._settings.getBaseFolder("translations")]) + + # setup app +diff --git a/src/octoprint/server/api/__init__.py b/src/octoprint/server/api/__init__.py +index 35401e45..6d056fe0 100644 +--- a/src/octoprint/server/api/__init__.py ++++ b/src/octoprint/server/api/__init__.py +@@ -10,8 +10,8 @@ import netaddr + import sarge + + from flask import Blueprint, request, jsonify, abort, current_app, session, make_response, g +-from flask.ext.login import login_user, logout_user, current_user +-from flask.ext.principal import Identity, identity_changed, AnonymousIdentity ++from flask_login import login_user, logout_user, current_user ++from flask_principal import Identity, identity_changed, AnonymousIdentity + + import octoprint.util as util + import octoprint.users +@@ -62,7 +62,7 @@ def pluginData(name): + return make_response("More than one api provider registered for {name}, can't proceed".format(name=name), 500) + + api_plugin = api_plugins[0] +- if api_plugin.is_api_adminonly() and not current_user.is_admin(): ++ if api_plugin.is_api_adminonly() and not current_user.is_admin: + return make_response("Forbidden", 403) + + response = api_plugin.on_api_get(request) +@@ -89,7 +89,7 @@ def pluginCommand(name): + if valid_commands is None: + return make_response("Method not allowed", 405) + +- if api_plugin.is_api_adminonly() and not current_user.is_admin(): ++ if api_plugin.is_api_adminonly() and not current_user.is_admin: + return make_response("Forbidden", 403) + + command, data, response = get_json_command_from_request(request, valid_commands) +diff --git a/src/octoprint/server/api/languages.py b/src/octoprint/server/api/languages.py +index e0749658..3d5f1f2c 100644 +--- a/src/octoprint/server/api/languages.py ++++ b/src/octoprint/server/api/languages.py +@@ -26,7 +26,7 @@ from octoprint.server.util.flask import restricted_access + + from octoprint.plugin import plugin_manager + +-from flask.ext.babel import Locale ++from flask_babel import Locale + + @api.route("/languages", methods=["GET"]) + @restricted_access +diff --git a/src/octoprint/server/api/settings.py b/src/octoprint/server/api/settings.py +index 02880093..b53e889f 100644 +--- a/src/octoprint/server/api/settings.py ++++ b/src/octoprint/server/api/settings.py +@@ -8,7 +8,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms + import logging + + from flask import request, jsonify, make_response +-from flask.ext.login import current_user ++from flask_login import current_user + from werkzeug.exceptions import BadRequest + + from octoprint.events import eventManager, Events +@@ -39,7 +39,7 @@ def _etag(lm=None): + for key in sorted(plugin_settings.keys()): + sorted_plugin_settings[key] = plugin_settings.get(key, dict()) + +- if current_user is not None and not current_user.is_anonymous(): ++ if current_user is not None and not current_user.is_anonymous: + roles = sorted(current_user.roles) + else: + roles = [] +diff --git a/src/octoprint/server/api/system.py b/src/octoprint/server/api/system.py +index 058476d3..14a0e084 100644 +--- a/src/octoprint/server/api/system.py ++++ b/src/octoprint/server/api/system.py +@@ -9,7 +9,7 @@ import logging + import sarge + + from flask import request, make_response, jsonify, url_for +-from flask.ext.babel import gettext ++from flask_babel import gettext + + from octoprint.settings import settings as s + +diff --git a/src/octoprint/server/api/users.py b/src/octoprint/server/api/users.py +index 73233f5e..fbee5c16 100644 +--- a/src/octoprint/server/api/users.py ++++ b/src/octoprint/server/api/users.py +@@ -7,7 +7,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms + + from flask import request, jsonify, abort, make_response + from werkzeug.exceptions import BadRequest +-from flask.ext.login import current_user ++from flask_login import current_user + + import octoprint.users as users + +@@ -72,7 +72,7 @@ def getUser(username): + if not userManager.enabled: + return jsonify(SUCCESS) + +- if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): ++ if current_user is not None and not current_user.is_anonymous and (current_user.get_name() == username or current_user.is_admin): + user = userManager.findUser(username) + if user is not None: + return jsonify(user.asDict()) +@@ -133,7 +133,7 @@ def changePasswordForUser(username): + if not userManager.enabled: + return jsonify(SUCCESS) + +- if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): ++ if current_user is not None and not current_user.is_anonymous and (current_user.get_name() == username or current_user.is_admin): + if not "application/json" in request.headers["Content-Type"]: + return make_response("Expected content-type JSON", 400) + +@@ -161,7 +161,7 @@ def getSettingsForUser(username): + if not userManager.enabled: + return jsonify(SUCCESS) + +- if current_user is None or current_user.is_anonymous() or (current_user.get_name() != username and not current_user.is_admin()): ++ if current_user is None or current_user.is_anonymous or (current_user.get_name() != username and not current_user.is_admin): + return make_response("Forbidden", 403) + + try: +@@ -175,7 +175,7 @@ def changeSettingsForUser(username): + if not userManager.enabled: + return jsonify(SUCCESS) + +- if current_user is None or current_user.is_anonymous() or (current_user.get_name() != username and not current_user.is_admin()): ++ if current_user is None or current_user.is_anonymous or (current_user.get_name() != username and not current_user.is_admin): + return make_response("Forbidden", 403) + + try: +@@ -195,7 +195,7 @@ def deleteApikeyForUser(username): + if not userManager.enabled: + return jsonify(SUCCESS) + +- if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): ++ if current_user is not None and not current_user.is_anonymous and (current_user.get_name() == username or current_user.is_admin): + try: + userManager.deleteApikey(username) + except users.UnknownUser: +@@ -211,7 +211,7 @@ def generateApikeyForUser(username): + if not userManager.enabled: + return jsonify(SUCCESS) + +- if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): ++ if current_user is not None and not current_user.is_anonymous and (current_user.get_name() == username or current_user.is_admin): + try: + apikey = userManager.generateApiKey(username) + except users.UnknownUser: +diff --git a/src/octoprint/server/util/__init__.py b/src/octoprint/server/util/__init__.py +index 5d202d16..0a084325 100644 +--- a/src/octoprint/server/util/__init__.py ++++ b/src/octoprint/server/util/__init__.py +@@ -13,6 +13,7 @@ from octoprint.users import ApiUser + from octoprint.util import deprecated + + import flask as _flask ++import flask_login + + from . import flask + from . import sockjs +@@ -58,7 +59,7 @@ def loginFromApiKeyRequestHandler(): + + if apikey and apikey != octoprint.server.UI_API_KEY and not octoprint.server.appSessionManager.validate(apikey): + user = get_user_for_apikey(apikey) +- if user is not None and _flask.ext.login.login_user(user, remember=False): ++ if user is not None and flask_login.login_user(user, remember=False): + _flask.ext.principal.identity_changed.send(_flask.current_app._get_current_object(), + identity=_flask.ext.principal.Identity(user.get_id())) + else: +diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py +index 5f41d661..9fc0defd 100644 +--- a/src/octoprint/server/util/flask.py ++++ b/src/octoprint/server/util/flask.py +@@ -8,9 +8,9 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms + + import tornado.web + import flask +-import flask.ext.login +-import flask.ext.principal +-import flask.ext.assets ++import flask_login ++import flask_principal ++import flask_assets + import webassets.updater + import webassets.utils + import functools +@@ -40,7 +40,7 @@ def enable_additional_translations(default_locale="en", additional_folders=None) + import os + from flask import _request_ctx_stack + from babel import support, Locale +- import flask.ext.babel ++ import flask_babel + + if additional_folders is None: + additional_folders = [] +@@ -91,7 +91,7 @@ def enable_additional_translations(default_locale="en", additional_folders=None) + return None + translations = getattr(ctx, 'babel_translations', None) + if translations is None: +- locale = flask.ext.babel.get_locale() ++ locale = flask_babel.get_locale() + translations = support.Translations() + + if str(locale) != default_locale: +@@ -129,8 +129,8 @@ def enable_additional_translations(default_locale="en", additional_folders=None) + ctx.babel_translations = translations + return translations + +- flask.ext.babel.Babel.list_translations = fixed_list_translations +- flask.ext.babel.get_translations = fixed_get_translations ++ flask_babel.Babel.list_translations = fixed_list_translations ++ flask_babel.get_translations = fixed_get_translations + + def fix_webassets_cache(): + from webassets import cache +@@ -478,12 +478,12 @@ class OctoPrintFlaskResponse(flask.Response): + + def passive_login(): + if octoprint.server.userManager.enabled: +- user = octoprint.server.userManager.login_user(flask.ext.login.current_user) ++ user = octoprint.server.userManager.login_user(flask_login.current_user) + else: +- user = flask.ext.login.current_user ++ user = flask_login.current_user + +- if user is not None and not user.is_anonymous(): +- flask.ext.principal.identity_changed.send(flask.current_app._get_current_object(), identity=flask.ext.principal.Identity(user.get_id())) ++ if user is not None and not user.is_anonymous: ++ flask_principal.identity_changed.send(flask.current_app._get_current_object(), identity=flask_principal.Identity(user.get_id())) + if hasattr(user, "get_session"): + flask.session["usersession.id"] = user.get_session() + flask.g.user = user +@@ -505,8 +505,8 @@ def passive_login(): + user = octoprint.server.userManager.login_user(user) + flask.session["usersession.id"] = user.get_session() + flask.g.user = user +- flask.ext.login.login_user(user) +- flask.ext.principal.identity_changed.send(flask.current_app._get_current_object(), identity=flask.ext.principal.Identity(user.get_id())) ++ flask_login.login_user(user) ++ flask_principal.identity_changed.send(flask.current_app._get_current_object(), identity=flask_principal.Identity(user.get_id())) + return flask.jsonify(user.asDict()) + except: + logger = logging.getLogger(__name__) +@@ -1023,7 +1023,7 @@ def admin_validator(request): + """ + + user = _get_flask_user_from_request(request) +- if user is None or not user.is_authenticated() or not user.is_admin(): ++ if user is None or not user.is_authenticated or not user.is_admin: + raise tornado.web.HTTPError(403) + + +@@ -1038,7 +1038,7 @@ def user_validator(request): + """ + + user = _get_flask_user_from_request(request) +- if user is None or not user.is_authenticated(): ++ if user is None or not user.is_authenticated: + raise tornado.web.HTTPError(403) + + +@@ -1051,14 +1051,14 @@ def _get_flask_user_from_request(request): + :return: the user or None if no user could be determined + """ + import octoprint.server.util +- import flask.ext.login ++ import flask_login + from octoprint.settings import settings + + apikey = octoprint.server.util.get_api_key(request) + if settings().getBoolean(["api", "enabled"]) and apikey is not None: + user = octoprint.server.util.get_user_for_apikey(apikey) + else: +- user = flask.ext.login.current_user ++ user = flask_login.current_user + + return user + +@@ -1103,7 +1103,7 @@ def restricted_access(func): + if settings().getBoolean(["server", "firstRun"]) and settings().getBoolean(["accessControl", "enabled"]) and (octoprint.server.userManager is None or not octoprint.server.userManager.hasBeenCustomized()): + return flask.make_response("OctoPrint isn't setup yet", 403) + +- return flask.ext.login.login_required(func)(*args, **kwargs) ++ return flask_login.login_required(func)(*args, **kwargs) + + return decorated_view + +@@ -1201,7 +1201,7 @@ def get_json_command_from_request(request, valid_commands): + + ##~~ Flask-Assets resolver with plugin asset support + +-class PluginAssetResolver(flask.ext.assets.FlaskResolver): ++class PluginAssetResolver(flask_assets.FlaskResolver): + + def split_prefix(self, ctx, item): + app = ctx.environment._app +@@ -1210,14 +1210,14 @@ class PluginAssetResolver(flask.ext.assets.FlaskResolver): + prefix, plugin, name = item.split("/", 2) + blueprint = prefix + "." + plugin + +- directory = flask.ext.assets.get_static_folder(app.blueprints[blueprint]) ++ directory = flask_assets.get_static_folder(app.blueprints[blueprint]) + item = name + endpoint = blueprint + ".static" + return directory, item, endpoint + except (ValueError, KeyError): + pass + +- return flask.ext.assets.FlaskResolver.split_prefix(self, ctx, item) ++ return flask_assets.FlaskResolver.split_prefix(self, ctx, item) + + def resolve_output_to_path(self, ctx, target, bundle): + import os +diff --git a/src/octoprint/server/util/tornado.py b/src/octoprint/server/util/tornado.py +index 12ba3b9b..8325bcaf 100644 +--- a/src/octoprint/server/util/tornado.py ++++ b/src/octoprint/server/util/tornado.py +@@ -29,36 +29,6 @@ import tornado.util + import octoprint.util + + +-#~~ Monkey patching +- +- +-def fix_ioloop_scheduling(): +- """ +- This monkey patches tornado's :meth:``tornado.ioloop.PeriodicCallback._schedule_next`` method so it no longer +- blocks for long times on slow machines (RPi) when the system time happens to change by a large amount (e.g. due to +- the first ever contact to an NTP server). +- +- Patch by @nosyjoe on Github. See this PR against tornado: https://github.com/tornadoweb/tornado/pull/1290 +- """ +- +- import math +- +- # patched implementation taken from PR +- def _schedule_next(self): +- if self._running: +- current_time = self.io_loop.time() +- +- if self._next_timeout <= current_time: +- callback_time_sec = self.callback_time / 1000.0 +- self._next_timeout += (math.floor((current_time - self._next_timeout) / callback_time_sec) + 1) * callback_time_sec +- +- self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run) +- +- # replace original implementation with patched version +- import tornado.ioloop +- tornado.ioloop.PeriodicCallback._schedule_next = _schedule_next +- +- + #~~ WSGI middleware + + +@@ -672,8 +642,10 @@ class CustomHTTPServer(tornado.httpserver.HTTPServer): + + ``default_max_body_size`` is the default maximum body size to apply if no specific one from ``max_body_sizes`` matches. + """ ++ def __init__(self, *args, **kwargs): ++ pass + +- def __init__(self, request_callback, no_keep_alive=False, io_loop=None, ++ def initialize(self, request_callback, no_keep_alive=False, io_loop=None, + xheaders=False, ssl_options=None, protocol=None, + decompress_request=False, + chunk_size=None, max_header_size=None, +diff --git a/src/octoprint/users.py b/src/octoprint/users.py +index cec5a48f..a99e0582 100644 +--- a/src/octoprint/users.py ++++ b/src/octoprint/users.py +@@ -5,8 +5,8 @@ __author__ = "Gina Häußge <osd@foosel.net>" + __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' + __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms of the AGPLv3 License" + +-from flask.ext.login import UserMixin +-from flask.ext.principal import Identity ++from flask_login import UserMixin ++from flask_principal import Identity + from werkzeug.local import LocalProxy + import hashlib + import os +@@ -431,9 +431,9 @@ class User(UserMixin): + def asDict(self): + return { + "name": self._username, +- "active": self.is_active(), +- "admin": self.is_admin(), +- "user": self.is_user(), ++ "active": self.is_active, ++ "admin": self.is_admin, ++ "user": self.is_user, + "apikey": self._apikey, + "settings": self._settings + } +@@ -447,12 +447,15 @@ class User(UserMixin): + def get_name(self): + return self._username + ++ @property + def is_active(self): + return self._active + ++ @property + def is_user(self): + return "user" in self._roles + ++ @property + def is_admin(self): + return "admin" in self._roles + +@@ -503,7 +506,7 @@ class User(UserMixin): + return True + + def __repr__(self): +- return "User(id=%s,name=%s,active=%r,user=%r,admin=%r)" % (self.get_id(), self.get_name(), self.is_active(), self.is_user(), self.is_admin()) ++ return "User(id=%s,name=%s,active=%r,user=%r,admin=%r)" % (self.get_id(), self.get_name(), self.is_active, self.is_user, self.is_admin) + + class SessionUser(User): + def __init__(self, user): +@@ -535,7 +538,7 @@ class SessionUser(User): + self._user = user + + def __repr__(self): +- return "SessionUser(id=%s,name=%s,active=%r,user=%r,admin=%r,session=%s,created=%s)" % (self.get_id(), self.get_name(), self.is_active(), self.is_user(), self.is_admin(), self._session, self._created) ++ return "SessionUser(id=%s,name=%s,active=%r,user=%r,admin=%r,session=%s,created=%s)" % (self.get_id(), self.get_name(), self.is_active, self.is_user, self.is_admin, self._session, self._created) + + ##~~ DummyUser object to use when accessControl is disabled + diff --git a/octoprint-jinja29.patch b/octoprint-jinja29.patch new file mode 100644 index 000000000000..26b6d21a6361 --- /dev/null +++ b/octoprint-jinja29.patch @@ -0,0 +1,148 @@ +diff --git a/src/octoprint/templates/dialogs/about.jinja2 b/src/octoprint/templates/dialogs/about.jinja2 +index dc94bb2c..0d484c99 100644 +--- a/src/octoprint/templates/dialogs/about.jinja2 ++++ b/src/octoprint/templates/dialogs/about.jinja2 +@@ -8,7 +8,7 @@ + <div class="tabbable row-fluid"> + <div class="span3 scrollable" id="about_dialog_menu"> + <ul class="nav nav-list" id="about_dialog_tabs"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.about.order %} + {% set entry, data = templates.about.entries[key] %} + {% if data is none %} +@@ -17,7 +17,7 @@ + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <li id="{{ data._div }}_link" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="{% if mark_active %}active{% set mark_active = False %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="{% if mark_active[0] %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + <a href="#{{ data._div }}" data-toggle="tab">{{ entry }}</a> +@@ -28,14 +28,14 @@ + </ul> + </div> + <div class="tab-content span9 scrollable" id="about_dialog_content"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.about.order %} + {% set entry, data = templates.about.entries[key] %} + {% if data is not none %} + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <div id="{{ data._div }}" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="tab-pane {% if mark_active %}active{% set mark_active = False %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="tab-pane {% if mark_active[0] %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + {% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %} +diff --git a/src/octoprint/templates/dialogs/settings.jinja2 b/src/octoprint/templates/dialogs/settings.jinja2 +index 62790a0a..e86a1367 100644 +--- a/src/octoprint/templates/dialogs/settings.jinja2 ++++ b/src/octoprint/templates/dialogs/settings.jinja2 +@@ -8,7 +8,7 @@ + <div class="tabbable row-fluid"> + <div class="span3 scrollable" id="settings_dialog_menu"> + <ul class="nav nav-list" id="settingsTabs"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.settings.order %} + {% set entry, data = templates.settings.entries[key] %} + {% if data is none %} +@@ -17,7 +17,7 @@ + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <li id="{{ data._div }}_link" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="{% if mark_active %}active{% set mark_active = False %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="{% if mark_active[0] %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + <a href="#{{ data._div }}" data-toggle="tab">{{ entry|e }}</a> +@@ -28,7 +28,7 @@ + </ul> + </div> + <div class="tab-content span9 scrollable" id="settings_dialog_content"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.settings.order %} + {% set entry, data = templates.settings.entries[key] %} + {% if data is not none %} +diff --git a/src/octoprint/templates/dialogs/usersettings.jinja2 b/src/octoprint/templates/dialogs/usersettings.jinja2 +index d34da7b4..770c173b 100644 +--- a/src/octoprint/templates/dialogs/usersettings.jinja2 ++++ b/src/octoprint/templates/dialogs/usersettings.jinja2 +@@ -5,7 +5,7 @@ + </div> + <div class="modal-body"> + <ul class="nav nav-pills"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.usersettings.order %} + {% set entry, data = templates.usersettings.entries[key] %} + {% if data is none %} +@@ -14,7 +14,7 @@ + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <li id="{{ data._div }}_link" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="{% if mark_active %}active{% set mark_active = False %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="{% if mark_active[0] %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + <a href="#{{ data._div }}" data-toggle="tab">{{ entry|e }}</a> +@@ -25,14 +25,14 @@ + </ul> + + <div class="tab-content"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.usersettings.order %} + {% set entry, data = templates.usersettings.entries[key] %} + {% if data is not none %} + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <div id="{{ data._div }}" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="tab-pane {% if mark_active %}active{% set mark_active = False %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="tab-pane {% if mark_active[0] %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + {% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %} +diff --git a/src/octoprint/templates/dialogs/wizard.jinja2 b/src/octoprint/templates/dialogs/wizard.jinja2 +index c0023a28..41fcc6bd 100644 +--- a/src/octoprint/templates/dialogs/wizard.jinja2 ++++ b/src/octoprint/templates/dialogs/wizard.jinja2 +@@ -7,7 +7,7 @@ + <div class="tabbable row-fluid"> + <div class="span3 scrollable" id="wizard_dialog_menu"> + <ul class="nav nav-list" id="wizardTabs"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.wizard.order %} + {% set entry, data = templates.wizard.entries[key] %} + {% if data is none %} +@@ -16,7 +16,7 @@ + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <li id="{{ data._div }}_link" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="{% if mark_active %}active{% set mark_active = False %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="{% if mark_active[0] %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + <a href="#{{ data._div }}" data-toggle="tab">{% if "mandatory" in data and data.mandatory %}<strong>{{ entry }}</strong>{% else %}{{ entry }}{% endif %}</a> +@@ -27,14 +27,14 @@ + </ul> + </div> + <div class="tab-content span9 scrollable" id="wizard_dialog_content"> +- {% set mark_active = True %} ++ {% set mark_active = [True] %} + {% for key in templates.wizard.order %} + {% set entry, data = templates.wizard.entries[key] %} + {% if data is not none %} + {% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %} + <div id="{{ data._div }}" + {% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %} +- class="tab-pane {% if mark_active %}active{% set mark_active = False %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}" ++ class="tab-pane {% if mark_active %}active{% do mark_active.pop() %}{% do mark_active.append(False) %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}" + {% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %} + > + {% if "mandatory" in data and data.mandatory %} diff --git a/octoprint.install b/octoprint.install index cdb6d888c8b7..bf46ee24163c 100755 --- a/octoprint.install +++ b/octoprint.install @@ -1,7 +1,7 @@ post_install() { local HOMEDIR=/var/lib/octoprint - getent group octoprint > /dev/null || groupadd octoprint - getent passwd octoprint > /dev/null || useradd -d $HOMEDIR -g octoprint -s /usr/bin/nologin octoprint + getent group octoprint > /dev/null || groupadd -r octoprint + getent passwd octoprint > /dev/null || useradd -d $HOMEDIR -r -g octoprint -s /usr/bin/nologin octoprint usermod -a -G octoprint,network,uucp,tty octoprint mkdir -p $HOMEDIR chmod 700 $HOMEDIR diff --git a/octoprint.run b/octoprint.run index eebe74ef7cc4..f5bc4b64b86d 100644 --- a/octoprint.run +++ b/octoprint.run @@ -1,3 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env python2 -exec /usr/bin/env python2 /usr/share/octoprint/run $@ +import octoprint +octoprint.main() diff --git a/octoprint.service b/octoprint.service index b064adab9fcd..b358aecc54ec 100644 --- a/octoprint.service +++ b/octoprint.service @@ -1,13 +1,12 @@ [Unit] -Description=Octoprint 3d Printing Web Server +Description=Responsive web interface for controlling a 3D printer After=network.target [Service] User=octoprint Group=octoprint Type=simple -ExecStart=/usr/bin/octoprint -Restart=on-failure +ExecStart=/usr/bin/octoprint serve [Install] WantedBy=multi-user.target |