Merge branch 'maintenance' into devel
# Conflicts: # CHANGELOG.md # docs/plugins/concepts.rst # src/octoprint/__init__.py # src/octoprint/server/__init__.py # src/octoprint/templates/javascripts.jinja2 # src/octoprint/timelapse.py Merge branch 'devel' into dev/wizard # Conflicts: # octoprint_octobullet/__init__.py # octoprint_octobullet/templates/octobullet_settings.jinja2 Merge branch 'devel' into dev/wizard # Conflicts: # octoprint_octobullet/__init__.py # octoprint_octobullet/templates/octobullet_settings.jinja2
This commit is contained in:
commit
9de78001dd
15 changed files with 217 additions and 67 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -74,6 +74,20 @@
|
|||
* [#1047](https://github.com/foosel/OctoPrint/issues/1047) - Fixed 90 degree
|
||||
webcam rotation for iOS Safari.
|
||||
|
||||
## 1.2.17rc2 (2016-10-13)
|
||||
|
||||
### Improvements
|
||||
|
||||
* Improved the `serial.log` logging handler to roll over serial log on new connections to the printer instead of continuously appending to the same file. Please note that `serial.log` is a debugging tool only and should *not* be left enabled unless you are trying to troubleshoot something in your printer communication.
|
||||
* Split JS/CSS/LESS asset bundles according into asset bundles for core + bundled plugins ("packed_core.{js|css|less}") and third party plugins ("packed_plugins.{js|css|less}"). That will allow the core UI to still function properly even if an installed third party plugin produces invalid JS and therefore causes a parser error for the whole plugin JS file. See [#1544](https://github.com/foosel/OctoPrint/issues/1544) for an example of such a situation.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Fixed a bug causing the update of OctoPrint to not work under certain circumstances: If 1.2.16 was installed and the settings were *never* saved via the "Settings" dialog's "Save", the update of OctoPrint would fail due to a `KeyError` in the updater. Reason is a renamed property, properly switched to when saving the settings.
|
||||
* Fixed the logging subsystem to not properly clean up after itself.
|
||||
|
||||
([Commits](https://github.com/foosel/OctoPrint/compare/1.2.17rc1...1.2.17rc2))
|
||||
|
||||
## 1.2.17rc1 (2016-10-06)
|
||||
|
||||
### Improvements
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ An overview of these properties follows.
|
|||
The plugin's name, as taken from either the ``__plugin_name__`` control property or the package info.
|
||||
``self._plugin_version``
|
||||
The plugin's version, as taken from either the ``__plugin_version__`` control property or the package info.
|
||||
``self._plugin_info``
|
||||
The :class:`octoprint.plugin.core.PluginInfo` object associated with the plugin.
|
||||
``self._basefolder``
|
||||
The plugin's base folder where it's installed. Can be used to refer to files relative to the plugin's installation
|
||||
location, e.g. included scripts, templates or assets.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import sys
|
||||
import logging
|
||||
import logging as log
|
||||
|
||||
#~~ version
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ del get_versions
|
|||
|
||||
#~~ sane logging defaults
|
||||
|
||||
logging.basicConfig()
|
||||
log.basicConfig()
|
||||
|
||||
#~~ try to ensure a sound SSL environment
|
||||
|
||||
|
|
@ -108,6 +108,9 @@ def init_logging(settings, use_logging_file=True, logging_file=None, default_con
|
|||
"formatters": {
|
||||
"simple": {
|
||||
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
},
|
||||
"serial": {
|
||||
"format": "%(asctime)s - %(message)s"
|
||||
}
|
||||
},
|
||||
"handlers": {
|
||||
|
|
@ -118,18 +121,18 @@ def init_logging(settings, use_logging_file=True, logging_file=None, default_con
|
|||
"stream": "ext://sys.stdout"
|
||||
},
|
||||
"file": {
|
||||
"class": "logging.handlers.TimedRotatingFileHandler",
|
||||
"class": "octoprint.logging.handlers.CleaningTimedRotatingFileHandler",
|
||||
"level": "DEBUG",
|
||||
"formatter": "simple",
|
||||
"when": "D",
|
||||
"backupCount": "1",
|
||||
"backupCount": 6,
|
||||
"filename": os.path.join(settings.getBaseFolder("logs"), "octoprint.log")
|
||||
},
|
||||
"serialFile": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"class": "octoprint.logging.handlers.SerialLogHandler",
|
||||
"level": "DEBUG",
|
||||
"formatter": "simple",
|
||||
"maxBytes": 2 * 1024 * 1024, # let's limit the serial log to 2MB in size
|
||||
"formatter": "serial",
|
||||
"backupCount": 3,
|
||||
"filename": os.path.join(settings.getBaseFolder("logs"), "serial.log")
|
||||
}
|
||||
},
|
||||
|
|
@ -180,11 +183,11 @@ def init_logging(settings, use_logging_file=True, logging_file=None, default_con
|
|||
config = default_config
|
||||
|
||||
# configure logging globally
|
||||
import logging.config
|
||||
logging.config.dictConfig(config)
|
||||
import logging.config as logconfig
|
||||
logconfig.dictConfig(config)
|
||||
|
||||
# make sure we log any warnings
|
||||
logging.captureWarnings(True)
|
||||
log.captureWarnings(True)
|
||||
|
||||
import warnings
|
||||
|
||||
|
|
@ -197,9 +200,9 @@ def init_logging(settings, use_logging_file=True, logging_file=None, default_con
|
|||
|
||||
# make sure we also log any uncaught exceptions
|
||||
if uncaught_logger is None:
|
||||
logger = logging.getLogger(__name__)
|
||||
logger = log.getLogger(__name__)
|
||||
else:
|
||||
logger = logging.getLogger(uncaught_logger)
|
||||
logger = log.getLogger(uncaught_logger)
|
||||
|
||||
if uncaught_handler is None:
|
||||
def exception_logger(exc_type, exc_value, exc_tb):
|
||||
|
|
@ -216,7 +219,7 @@ def init_pluginsystem(settings):
|
|||
from octoprint.plugin import plugin_manager
|
||||
pm = plugin_manager(init=True, settings=settings)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger = log.getLogger(__name__)
|
||||
settings_overlays = dict()
|
||||
disabled_from_overlays = dict()
|
||||
|
||||
|
|
|
|||
4
src/octoprint/logging/__init__.py
Normal file
4
src/octoprint/logging/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
from . import handlers
|
||||
83
src/octoprint/logging/handlers.py
Normal file
83
src/octoprint/logging/handlers.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging.handlers
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
|
||||
class CleaningTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
logging.handlers.TimedRotatingFileHandler.__init__(self, *args, **kwargs)
|
||||
|
||||
# clean up old files on handler start
|
||||
if self.backupCount > 0:
|
||||
for s in self.getFilesToDelete():
|
||||
os.remove(s)
|
||||
|
||||
|
||||
class SerialLogHandler(logging.handlers.RotatingFileHandler):
|
||||
|
||||
_do_rollover = False
|
||||
_suffix_template = "%Y-%m-%d_%H-%M-%S"
|
||||
_file_pattern = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}$")
|
||||
|
||||
@classmethod
|
||||
def on_open_connection(cls):
|
||||
cls._do_rollover = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
logging.handlers.RotatingFileHandler.__init__(self, *args, **kwargs)
|
||||
self.cleanupFiles()
|
||||
|
||||
def emit(self, record):
|
||||
logging.handlers.RotatingFileHandler.emit(self, record)
|
||||
|
||||
def shouldRollover(self, record):
|
||||
return self.__class__._do_rollover
|
||||
|
||||
def getFilesToDelete(self):
|
||||
"""
|
||||
Determine the files to delete when rolling over.
|
||||
"""
|
||||
dirName, baseName = os.path.split(self.baseFilename)
|
||||
fileNames = os.listdir(dirName)
|
||||
result = []
|
||||
prefix = baseName + "."
|
||||
plen = len(prefix)
|
||||
for fileName in fileNames:
|
||||
if fileName[:plen] == prefix:
|
||||
suffix = fileName[plen:]
|
||||
if self.__class__._file_pattern.match(suffix):
|
||||
result.append(os.path.join(dirName, fileName))
|
||||
result.sort()
|
||||
if len(result) < self.backupCount:
|
||||
result = []
|
||||
else:
|
||||
result = result[:len(result) - self.backupCount]
|
||||
return result
|
||||
|
||||
def cleanupFiles(self):
|
||||
if self.backupCount > 0:
|
||||
for path in self.getFilesToDelete():
|
||||
os.remove(path)
|
||||
|
||||
def doRollover(self):
|
||||
self.__class__._do_rollover = False
|
||||
|
||||
if self.stream:
|
||||
self.stream.close()
|
||||
self.stream = None
|
||||
|
||||
if os.path.exists(self.baseFilename):
|
||||
# figure out creation date/time to use for file suffix
|
||||
t = time.localtime(os.stat(self.baseFilename).st_mtime)
|
||||
dfn = self.baseFilename + "." + time.strftime(self.__class__._suffix_template, t)
|
||||
if os.path.exists(dfn):
|
||||
os.remove(dfn)
|
||||
os.rename(self.baseFilename, dfn)
|
||||
|
||||
self.cleanupFiles()
|
||||
if not self.delay:
|
||||
self.stream = self._open()
|
||||
|
|
@ -1000,6 +1000,7 @@ class PluginManager(object):
|
|||
identifier=name,
|
||||
plugin_name=plugin.name,
|
||||
plugin_version=plugin.version,
|
||||
plugin_info=plugin,
|
||||
basefolder=os.path.realpath(plugin.location),
|
||||
logger=logging.getLogger(self.logging_prefix + name),
|
||||
))
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
|
|||
|
||||
def on_startup(self, host, port):
|
||||
# setup our custom logger
|
||||
cura_logging_handler = logging.handlers.RotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="engine"), maxBytes=2*1024*1024)
|
||||
from octoprint.logging.handlers import CleaningTimedRotatingFileHandler
|
||||
cura_logging_handler = CleaningTimedRotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="engine"), when="D", backupCount=3)
|
||||
cura_logging_handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
|
||||
cura_logging_handler.setLevel(logging.DEBUG)
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin,
|
|||
##~~ StartupPlugin
|
||||
|
||||
def on_startup(self, host, port):
|
||||
console_logging_handler = logging.handlers.RotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="console"), maxBytes=2*1024*1024)
|
||||
from octoprint.logging.handlers import CleaningTimedRotatingFileHandler
|
||||
console_logging_handler = CleaningTimedRotatingFileHandler(self._settings.get_plugin_logfile_path(postfix="console"), when="D", backupCount=3)
|
||||
console_logging_handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
|
||||
console_logging_handler.setLevel(logging.DEBUG)
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ def perform_update(target, check, target_version, log_cb=None):
|
|||
update_script = check["update_script"]
|
||||
update_branch = check.get("update_branch", "")
|
||||
force_exact_version = check.get("force_exact_version", False)
|
||||
folder = check.get("update_folder", check["checkout_folder"])
|
||||
folder = check.get("update_folder", check.get("checkout_folder")) # either should be set, tested above
|
||||
pre_update_script = check.get("pre_update_script", None)
|
||||
post_update_script = check.get("post_update_script", None)
|
||||
|
||||
|
|
|
|||
|
|
@ -197,6 +197,10 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
|
|||
|
||||
eventManager().fire(Events.CONNECTING)
|
||||
self._printerProfileManager.select(profile)
|
||||
|
||||
from octoprint.logging.handlers import SerialLogHandler
|
||||
SerialLogHandler.on_open_connection()
|
||||
|
||||
self._comm = comm.MachineCom(port, baudrate, callbackObject=self, printerProfileManager=self._printerProfileManager)
|
||||
|
||||
def disconnect(self):
|
||||
|
|
|
|||
|
|
@ -177,7 +177,6 @@ class Server(object):
|
|||
if self._settings.getBoolean(["serial", "log"]):
|
||||
# enable debug logging to serial.log
|
||||
logging.getLogger("SERIAL").setLevel(logging.DEBUG)
|
||||
logging.getLogger("SERIAL").debug("Enabling serial logging")
|
||||
|
||||
# start the intermediary server
|
||||
self._start_intermediary_server()
|
||||
|
|
@ -981,7 +980,8 @@ class Server(object):
|
|||
preferred_stylesheet = self._settings.get(["devel", "stylesheet"])
|
||||
minify = self._settings.getBoolean(["devel", "webassets", "minify"])
|
||||
|
||||
dynamic_assets = util.flask.collect_plugin_assets(
|
||||
dynamic_core_assets = util.flask.collect_core_assets(enable_gcodeviewer=enable_gcodeviewer)
|
||||
dynamic_plugin_assets = util.flask.collect_plugin_assets(
|
||||
enable_gcodeviewer=enable_gcodeviewer,
|
||||
preferred_stylesheet=preferred_stylesheet
|
||||
)
|
||||
|
|
@ -1038,11 +1038,13 @@ class Server(object):
|
|||
"js/app/client/util.js",
|
||||
"js/app/client/wizard.js"
|
||||
]
|
||||
js_app = dynamic_assets["js"] + [
|
||||
"js/app/dataupdater.js",
|
||||
"js/app/helpers.js",
|
||||
"js/app/main.js",
|
||||
]
|
||||
js_core = dynamic_core_assets["js"] + \
|
||||
dynamic_plugin_assets["bundled"]["js"] + \
|
||||
["js/app/dataupdater.js",
|
||||
"js/app/helpers.js",
|
||||
"js/app/main.js"]
|
||||
js_plugins = dynamic_plugin_assets["external"]["js"]
|
||||
js_app = js_core + js_plugins
|
||||
|
||||
css_libs = [
|
||||
"css/bootstrap.min.css",
|
||||
|
|
@ -1053,8 +1055,13 @@ class Server(object):
|
|||
"css/jquery.fileupload-ui.css",
|
||||
"css/pnotify.min.css"
|
||||
]
|
||||
css_app = list(dynamic_assets["css"])
|
||||
less_app = list(dynamic_assets["less"])
|
||||
css_core = list(dynamic_core_assets["css"]) + list(dynamic_plugin_assets["bundled"]["css"])
|
||||
css_plugins = list(dynamic_plugin_assets["external"]["css"])
|
||||
css_app = css_core + css_plugins
|
||||
|
||||
less_core = list(dynamic_core_assets["less"]) + list(dynamic_plugin_assets["bundled"]["less"])
|
||||
less_plugins = list(dynamic_plugin_assets["external"]["less"])
|
||||
less_app = less_core + less_plugins
|
||||
|
||||
from webassets.filter import register_filter, Filter
|
||||
from webassets.filter.cssrewrite.base import PatternRewriter
|
||||
|
|
@ -1075,7 +1082,7 @@ class Server(object):
|
|||
|
||||
return "{import_with_options}\"{import_url}\";".format(**locals())
|
||||
|
||||
class JsDelimiterBundle(Filter):
|
||||
class JsDelimiterBundler(Filter):
|
||||
name = "js_delimiter_bundler"
|
||||
options = {}
|
||||
def input(self, _in, out, **kwargs):
|
||||
|
|
@ -1083,34 +1090,68 @@ class Server(object):
|
|||
out.write("\n;\n")
|
||||
|
||||
register_filter(LessImportRewrite)
|
||||
register_filter(JsDelimiterBundle)
|
||||
register_filter(JsDelimiterBundler)
|
||||
|
||||
# JS
|
||||
js_libs_bundle = Bundle(*js_libs, output="webassets/packed_libs.js", filters="js_delimiter_bundler")
|
||||
if minify:
|
||||
js_client_bundle = Bundle(*js_client, output="webassets/packed_client.js", filters="rjsmin, js_delimiter_bundler")
|
||||
js_core_bundle = Bundle(*js_core, output="webassets/packed_core.js", filters="rjsmin, js_delimiter_bundler")
|
||||
js_plugins_bundle = Bundle(*js_plugins, output="webassets/packed_plugins.js", filters="rjsmin, js_delimiter_bundler")
|
||||
js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="rjsmin, js_delimiter_bundler")
|
||||
else:
|
||||
js_client_bundle = Bundle(*js_client, output="webassets/packed_client.js", filters="js_delimiter_bundler")
|
||||
js_core_bundle = Bundle(*js_core, output="webassets/packed_core.js", filters="js_delimiter_bundler")
|
||||
js_plugins_bundle = Bundle(*js_plugins, output="webassets/packed_plugins.js", filters="js_delimiter_bundler")
|
||||
js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="js_delimiter_bundler")
|
||||
|
||||
# CSS
|
||||
css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css")
|
||||
|
||||
if len(css_core) == 0:
|
||||
css_core_bundle = Bundle(*[])
|
||||
else:
|
||||
css_core_bundle = Bundle(*css_app, output="webassets/packed_core.css", filters="cssrewrite")
|
||||
|
||||
if len(css_plugins) == 0:
|
||||
css_plugins_bundle = Bundle(*[])
|
||||
else:
|
||||
css_plugins_bundle = Bundle(*css_app, output="webassets/packed_plugins.css", filters="cssrewrite")
|
||||
|
||||
if len(css_app) == 0:
|
||||
css_app_bundle = Bundle(*[])
|
||||
else:
|
||||
css_app_bundle = Bundle(*css_app, output="webassets/packed_app.css", filters="cssrewrite")
|
||||
|
||||
if len(less_app) == 0:
|
||||
all_less_bundle = Bundle(*[])
|
||||
# LESS
|
||||
if len(less_core) == 0:
|
||||
less_core_bundle = Bundle(*[])
|
||||
else:
|
||||
all_less_bundle = Bundle(*less_app, output="webassets/packed_app.less", filters="cssrewrite, less_importrewrite")
|
||||
less_core_bundle = Bundle(*less_app, output="webassets/packed_core.less", filters="cssrewrite, less_importrewrite")
|
||||
|
||||
if len(less_plugins) == 0:
|
||||
less_plugins_bundle = Bundle(*[])
|
||||
else:
|
||||
less_plugins_bundle = Bundle(*less_app, output="webassets/packed_plugins.less", filters="cssrewrite, less_importrewrite")
|
||||
|
||||
if len(less_app) == 0:
|
||||
less_app_bundle = Bundle(*[])
|
||||
else:
|
||||
less_app_bundle = Bundle(*less_app, output="webassets/packed_app.less", filters="cssrewrite, less_importrewrite")
|
||||
|
||||
# asset registration
|
||||
assets.register("js_libs", js_libs_bundle)
|
||||
assets.register("js_client", js_client_bundle)
|
||||
assets.register("js_core", js_core_bundle)
|
||||
assets.register("js_plugins", js_plugins_bundle)
|
||||
assets.register("js_app", js_app_bundle)
|
||||
assets.register("css_libs", css_libs_bundle)
|
||||
assets.register("css_core", css_core_bundle)
|
||||
assets.register("css_plugins", css_plugins_bundle)
|
||||
assets.register("css_app", css_app_bundle)
|
||||
assets.register("less_app", all_less_bundle)
|
||||
assets.register("less_core", less_core_bundle)
|
||||
assets.register("less_plugins", less_plugins_bundle)
|
||||
assets.register("less_app", less_app_bundle)
|
||||
|
||||
def _start_intermediary_server(self):
|
||||
import BaseHTTPServer
|
||||
|
|
|
|||
|
|
@ -1234,12 +1234,8 @@ class SettingsCheckUpdater(webassets.updater.BaseUpdater):
|
|||
cache_value = webassets.utils.hash_func(json.dumps(settings().effective_yaml))
|
||||
ctx.cache.set(cache_key, cache_value)
|
||||
|
||||
##~~ plugin assets collector
|
||||
|
||||
def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"):
|
||||
logger = logging.getLogger(__name__ + ".collect_plugin_assets")
|
||||
|
||||
supported_stylesheets = ("css", "less")
|
||||
##~~ core assets collector
|
||||
def collect_core_assets(enable_gcodeviewer=True, preferred_stylesheet="css"):
|
||||
assets = dict(
|
||||
js=[],
|
||||
css=[],
|
||||
|
|
@ -1288,9 +1284,24 @@ def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"):
|
|||
elif preferred_stylesheet == "css":
|
||||
assets["css"].append('css/octoprint.css')
|
||||
|
||||
return assets
|
||||
|
||||
##~~ plugin assets collector
|
||||
|
||||
def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"):
|
||||
logger = logging.getLogger(__name__ + ".collect_plugin_assets")
|
||||
|
||||
supported_stylesheets = ("css", "less")
|
||||
assets = dict(bundled=dict(js=[], css=[], less=[]),
|
||||
external=dict(js=[], css=[], less=[]))
|
||||
|
||||
asset_plugins = octoprint.plugin.plugin_manager().get_implementations(octoprint.plugin.AssetPlugin)
|
||||
for implementation in asset_plugins:
|
||||
name = implementation._identifier
|
||||
is_bundled = implementation._plugin_info.bundled
|
||||
|
||||
asset_key = "bundled" if is_bundled else "external"
|
||||
|
||||
try:
|
||||
all_assets = implementation.get_assets()
|
||||
basefolder = implementation.get_asset_folder()
|
||||
|
|
@ -1308,13 +1319,13 @@ def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"):
|
|||
for asset in all_assets["js"]:
|
||||
if not asset_exists("js", asset):
|
||||
continue
|
||||
assets["js"].append('plugin/{name}/{asset}'.format(**locals()))
|
||||
assets[asset_key]["js"].append('plugin/{name}/{asset}'.format(**locals()))
|
||||
|
||||
if preferred_stylesheet in all_assets:
|
||||
for asset in all_assets[preferred_stylesheet]:
|
||||
if not asset_exists(preferred_stylesheet, asset):
|
||||
continue
|
||||
assets[preferred_stylesheet].append('plugin/{name}/{asset}'.format(**locals()))
|
||||
assets[asset_key][preferred_stylesheet].append('plugin/{name}/{asset}'.format(**locals()))
|
||||
else:
|
||||
for stylesheet in supported_stylesheets:
|
||||
if not stylesheet in all_assets:
|
||||
|
|
@ -1323,7 +1334,7 @@ def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"):
|
|||
for asset in all_assets[stylesheet]:
|
||||
if not asset_exists(stylesheet, asset):
|
||||
continue
|
||||
assets[stylesheet].append('plugin/{name}/{asset}'.format(**locals()))
|
||||
assets[asset_key][stylesheet].append('plugin/{name}/{asset}'.format(**locals()))
|
||||
break
|
||||
|
||||
return assets
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
{% assets "js_libs" %}
|
||||
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
|
||||
{% assets "js_client" %}
|
||||
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
|
||||
{% assets "js_app" %}
|
||||
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
|
||||
{% if g.locale %}
|
||||
<script type="text/javascript" src="{{ url_for('localeJs', locale=g.locale, domain='messages') }}"></script>
|
||||
{% endif %}
|
||||
{% assets "js_libs" %}<script type="text/javascript" src="{{ ASSET_URL }}"></script>{% endassets %}
|
||||
{% assets "js_client" %}<script type="text/javascript" src="{{ ASSET_URL }}"></script>{% endassets %}
|
||||
{% assets "js_core" %}<script type="text/javascript" src="{{ ASSET_URL }}"></script>{% endassets %}
|
||||
{% assets "js_plugins" %}<script type="text/javascript" src="{{ ASSET_URL }}"></script>{% endassets %}
|
||||
{% if g.locale %}<script type="text/javascript" src="{{ url_for('localeJs', locale=g.locale, domain='messages') }}"></script>{% endif %}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
{% assets "css_libs" %}
|
||||
<link href="{{ ASSET_URL }}" rel="stylesheet" media="screen">
|
||||
{% endassets %}
|
||||
|
||||
{% assets "css_app" %}
|
||||
<link href="{{ ASSET_URL }}" rel="stylesheet" media="screen">
|
||||
{% endassets %}
|
||||
|
||||
{% assets "less_app" %}
|
||||
<link href="{{ ASSET_URL }}" rel="stylesheet/less" type="text/css" media="screen">
|
||||
{% endassets %}
|
||||
|
||||
{% assets "css_libs" %}<link href="{{ ASSET_URL }}" rel="stylesheet" media="screen">{% endassets %}
|
||||
{% assets "css_core" %}<link href="{{ ASSET_URL }}" rel="stylesheet" media="screen">{% endassets %}
|
||||
{% assets "css_plugins" %}<link href="{{ ASSET_URL }}" rel="stylesheet" media="screen">{% endassets %}
|
||||
{% assets "less_core" %}<link href="{{ ASSET_URL }}" rel="stylesheet/less" type="text/css" media="screen">{% endassets %}
|
||||
{% assets "less_plugins" %}<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>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
"""
|
||||
This module bundles commonly used utility methods or helper classes that are used in multiple places withing
|
||||
OctoPrint's source code.
|
||||
|
|
|
|||
Loading…
Reference in a new issue