Permalink
Browse files

Webassets are now written to ~/.octoprint/generated

Same holds true for cache files, so there should be no problem anymore with installs where the static folder is not writable.

Also introduced two new devel config vars to disable merging and minifying of the assets, solved the empty-less-bundle problem and made sure babel knows about the jinja extension.
  • Loading branch information...
1 parent 55650cd commit b63f84221093ebc9264e5578fcebca162328c6b3 @foosel committed Jun 3, 2015
View
@@ -1,7 +1,7 @@
[python: src/octoprint/**.py]
[jinja2: src/octoprint/templates/**.jinja2]
[jinja2: src/octoprint/plugins/**.jinja2]
-extensions=jinja2.ext.autoescape, jinja2.ext.with_
+extensions=jinja2.ext.autoescape, jinja2.ext.with_, webassets.ext.jinja2.AssetsExtension
[javascript: src/octoprint/static/js/app/**.js]
[javascript: src/octoprint/plugins/**.js]
@@ -290,11 +290,6 @@ def template_disabled(name, plugin):
# register API blueprint
self._setup_blueprints()
- def blueprint_enabled(name, plugin):
- if plugin.implementation is None or not isinstance(plugin.implementation, octoprint.plugin.BlueprintPlugin):
- return
- self._register_blueprint_plugin(plugin.implementation)
- pluginLifecycleManager.add_callback(["enabled"], blueprint_enabled)
## Tornado initialization starts here
@@ -313,7 +308,7 @@ def blueprint_enabled(name, plugin):
# camera snapshot
(r"/downloads/camera/current", util.tornado.UrlForwardHandler, dict(url=s.get(["webcam", "snapshot"]), as_attachment=True, access_validation=util.tornado.access_validation_factory(app, loginManager, util.flask.user_validator))),
# generated webassets
- (r"/static/webassets/(.*)", util.tornado.LargeResponseHandler, dict(path=s.getBaseFolder("webassets")))
+ (r"/static/webassets/(.*)", util.tornado.LargeResponseHandler, dict(path=os.path.join(s.getBaseFolder("generated"), "webassets")))
]
for name, hook in pluginManager.get_hooks("octoprint.server.http.routes").items():
try:
@@ -667,12 +662,28 @@ def _setup_assets(self):
global assets
global pluginManager
+ base_folder = settings().getBaseFolder("generated")
+
AdjustedEnvironment = type(Environment)(Environment.__name__, (Environment,), dict(
resolver_class=util.flask.PluginAssetResolver
))
- assets = AdjustedEnvironment(app)
-
- dynamic_assets = util.flask.collect_plugin_assets()
+ class CustomDirectoryEnvironment(AdjustedEnvironment):
+ @property
+ def directory(self):
+ return base_folder
+
+ assets = CustomDirectoryEnvironment(app)
+ assets.debug = not settings().getBoolean(["devel", "webassets", "bundle"])
+
+ enable_gcodeviewer = settings().getBoolean(["gcodeViewer", "enabled"])
+ enable_timelapse = (settings().get(["webcam", "snapshot"]) and settings().get(["webcam", "ffmpeg"]))
+ preferred_stylesheet = settings().get(["devel", "stylesheet"])
+
+ dynamic_assets = util.flask.collect_plugin_assets(
+ enable_gcodeviewer=enable_gcodeviewer,
+ enable_timelapse=enable_timelapse,
+ preferred_stylesheet=preferred_stylesheet
+ )
js_libs = [
"js/lib/jquery/jquery.min.js",
@@ -696,16 +707,15 @@ def _setup_assets(self):
"js/lib/jquery/jquery.fileupload.js",
"js/lib/jquery/jquery.slimscroll.min.js",
"js/lib/jquery/jquery.qrcode.min.js",
- "js/lib/sockjs-0.3.4.min.js",
"js/lib/moment-with-locales.min.js",
"js/lib/pusher.color.min.js",
"js/lib/detectmobilebrowser.js",
"js/lib/md5.min.js",
"js/lib/pnotify.min.js",
"js/lib/bootstrap-slider-knockout-binding.js",
- "js/lib/loglevel.min.js"
+ "js/lib/loglevel.min.js",
+ "js/lib/sockjs-0.3.4.min.js"
]
-
js_app = dynamic_assets["js"] + [
"js/app/dataupdater.js",
"js/app/helpers.js",
@@ -721,29 +731,24 @@ def _setup_assets(self):
"css/jquery.fileupload-ui.css",
"css/pnotify.min.css"
]
-
- css_app = []
- less_app = []
- for sheet, path in dynamic_assets["stylesheets"]:
- if sheet == "css":
- css_app.append(path)
- elif sheet == "less":
- less_app.append(path)
+ css_app = ["empty"] + dynamic_assets["css"]
+ less_app = ["empty"] + dynamic_assets["less"]
js_libs_bundle = Bundle(*js_libs, output="webassets/packed_libs.js")
- js_app_bundle = Bundle(*js_app, output="webassets/package_app.js")
- css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css")
+ if settings().getBoolean(["devel", "webassets", "minify"]):
+ js_app_bundle = Bundle(*js_app, output="webassets/package_app.js", filters="rjsmin")
+ else:
+ js_app_bundle = Bundle(*js_app, output="webassets/package_app.js")
+ all_js_bundle = Bundle(js_libs_bundle, js_app_bundle, output="webassets/packed.js")
- assets.register("js_libs", js_libs_bundle)
- assets.register("js_app", js_app_bundle)
- assets.register("css_libs", css_libs_bundle)
+ css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css")
+ css_app_bundle = Bundle(*css_app, output="webassets/packed_app.css")
+ all_css_bundle = Bundle(css_libs_bundle, css_app_bundle, output="webassets/packed.css")
+ all_less_bundle = Bundle(*less_app, output="webassets/packed_app.less")
- if len(css_app):
- css_app_bundle = Bundle(*css_app, output="webassets/packed_app.css")
- assets.register("css_app", css_app_bundle)
- if len(less_app):
- less_app_bundle = Bundle(*less_app, output="webassets/packed_app.less")
- assets.register("less_app", less_app_bundle)
+ assets.register("all_js", all_js_bundle)
+ assets.register("all_css", all_css_bundle)
+ assets.register("less_app", all_less_bundle)
class LifecycleManager(object):
@@ -431,18 +431,43 @@ def split_prefix(self, item):
return flask.ext.assets.FlaskResolver.split_prefix(self, item)
def resolve_output_to_path(self, target, bundle):
- if target.startswith("webassets/"):
- import os
- return os.path.normpath(os.path.join(settings().getBaseFolder("webassets"), target[len("webassets/"):]))
- return flask.ext.assets.FlaskResolver.resolve_output_to_path(self, target, bundle)
+ import os
+ return os.path.normpath(os.path.join(self.env.directory, target))
+
+ def resolve_source_to_url(self, filepath, item):
+ if item.startswith("plugin/"):
+ try:
+ prefix, plugin, name = item.split('/', 2)
+ blueprint = prefix + "." + plugin
+
+ self.env._app.blueprints[blueprint] # keyerror if no module
+ endpoint = '%s.static' % blueprint
+ filename = name
+ except (ValueError, KeyError):
+ endpoint = 'static'
+ filename = item
+
+ ctx = None
+ if not flask._request_ctx_stack.top:
+ ctx = self.env._app.test_request_context()
+ ctx.push()
+ try:
+ return flask.url_for(endpoint, filename=filename)
+ finally:
+ if ctx:
+ ctx.pop()
+
+ return flask.ext.assets.FlaskResolver.resolve_source_to_url(self, filepath, item)
+
##~~ plugin assets collector
def collect_plugin_assets(enable_gcodeviewer=True, enable_timelapse=True, preferred_stylesheet="css"):
supported_stylesheets = ("css", "less")
assets = dict(
js=[],
- stylesheets=[]
+ css=[],
+ less=[]
)
assets["js"] = [
'js/app/viewmodels/appearance.js',
@@ -473,9 +498,9 @@ def collect_plugin_assets(enable_gcodeviewer=True, enable_timelapse=True, prefer
assets["js"].append('js/app/viewmodels/timelapse.js')
if preferred_stylesheet == "less":
- assets["stylesheets"].append(("less", 'less/octoprint.less'))
+ assets["less"].append('less/octoprint.less')
elif preferred_stylesheet == "css":
- assets["stylesheets"].append(("css", 'css/octoprint.css'))
+ assets["css"].append('css/octoprint.css')
asset_plugins = octoprint.plugin.plugin_manager().get_implementations(octoprint.plugin.AssetPlugin)
for implementation in asset_plugins:
@@ -488,14 +513,14 @@ def collect_plugin_assets(enable_gcodeviewer=True, enable_timelapse=True, prefer
if preferred_stylesheet in all_assets:
for asset in all_assets[preferred_stylesheet]:
- assets["stylesheets"].append((preferred_stylesheet, 'plugin/{name}/{asset}'.format(**locals())))
+ assets[preferred_stylesheet].append('plugin/{name}/{asset}'.format(**locals()))
else:
for stylesheet in supported_stylesheets:
if not stylesheet in all_assets:
continue
for asset in all_assets[stylesheet]:
- assets["stylesheets"].append((stylesheet, 'plugin/{name}/{asset}'.format(**locals())))
+ assets[stylesheet].append('plugin/{name}/{asset}'.format(**locals()))
break
return assets
@@ -156,7 +156,7 @@ def settings(init=False, basedir=None, configfile=None):
"printerProfiles": None,
"scripts": None,
"translations": None,
- "webassets": None
+ "generated": None
},
"temperature": {
"profiles": [
@@ -249,6 +249,10 @@ def settings(init=False, basedir=None, configfile=None):
"cache": {
"enabled": True
},
+ "webassets": {
+ "minify": True,
+ "bundle": True
+ },
"virtualPrinter": {
"enabled": False,
"okAfterResend": False,
No changes.
@@ -1,9 +1,4 @@
-<script type="text/javascript" src="{{ url_for('static', filename='js/lib/moment-with-locales.min.js') }}"></script>
-{% assets "js_libs" %}
- <script type="text/javascript" src="{{ ASSET_URL }}"></script>
-{% endassets %}
-
-{% assets "js_app" %}
+{% assets "all_js" %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}
@@ -1,13 +1,9 @@
-{% assets "css_libs" %}
+{% assets "all_css" %}
<link href="{{ ASSET_URL }}" rel="stylesheet" media="screen">
{% endassets %}
-{% assets "css_app" %}
- <link href="{{ ASSET_URL }}" rel="stylesheet" type="text/css" media="screen">
-{% endassets %}
-
{% assets "less_app" %}
- <link href="{{ url }}" rel="stylesheet/less" type="text/css" media="screen">
+ <link href="{{ ASSET_URL }}" rel="stylesheet/less" type="text/css" media="screen">
{% endassets %}
<script src="{{ url_for('static', filename='js/lib/less.min.js') }}" type="text/javascript"></script>

0 comments on commit b63f842

Please sign in to comment.