Fix ordering of plugin assets

Should be alphabetical per their identifier. As noticed by @BillyBlaze
This commit is contained in:
Gina Häußge 2017-12-01 18:13:35 +01:00
parent e064400900
commit f72dfb48e1
3 changed files with 57 additions and 9 deletions

View file

@ -15,7 +15,7 @@ from flask.ext.assets import Environment, Bundle
from babel import Locale
from watchdog.observers import Observer
from watchdog.observers.polling import PollingObserver
from collections import defaultdict
from collections import defaultdict, OrderedDict
from builtins import bytes, range
from past.builtins import basestring
@ -1268,7 +1268,7 @@ class Server(object):
# TODO remove again in 1.3.8
def js_bundles_for_plugins(collection, filters=None):
"""Produces Bundle instances"""
result = dict()
result = OrderedDict()
for plugin, assets in collection.items():
if len(assets):
result[plugin] = Bundle(*assets, filters=filters)
@ -1277,7 +1277,7 @@ class Server(object):
else:
def js_bundles_for_plugins(collection, filters=None):
"""Produces JsPluginBundle instances that output IIFE wrapped assets"""
result = dict()
result = OrderedDict()
for plugin, assets in collection.items():
if len(assets):
result[plugin] = JsPluginBundle(plugin, *assets, filters=filters)

View file

@ -28,6 +28,8 @@ import octoprint.server
import octoprint.users
import octoprint.plugin
from octoprint.util import DefaultOrderedDict
from werkzeug.contrib.cache import BaseCache
from past.builtins import basestring
@ -1348,12 +1350,12 @@ 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=collections.defaultdict(list),
css=collections.defaultdict(list),
less=collections.defaultdict(list)),
external=dict(js=collections.defaultdict(list),
css=collections.defaultdict(list),
less=collections.defaultdict(list)))
assets = dict(bundled=dict(js=DefaultOrderedDict(list),
css=DefaultOrderedDict(list),
less=DefaultOrderedDict(list)),
external=dict(js=DefaultOrderedDict(list),
css=DefaultOrderedDict(list),
less=DefaultOrderedDict(list)))
asset_plugins = octoprint.plugin.plugin_manager().get_implementations(octoprint.plugin.AssetPlugin)
for implementation in asset_plugins:

View file

@ -20,6 +20,7 @@ import threading
from functools import wraps
import warnings
import contextlib
import collections
try:
import queue
@ -737,6 +738,51 @@ def dict_filter(dictionary, filter_function):
return dict((k, v) for k, v in dictionary.items() if filter_function(k, v))
# Source: http://stackoverflow.com/a/6190500/562769
class DefaultOrderedDict(collections.OrderedDict):
def __init__(self, default_factory=None, *a, **kw):
if default_factory is not None and not callable(default_factory):
raise TypeError('first argument must be callable')
collections.OrderedDict.__init__(self, *a, **kw)
self.default_factory = default_factory
def __getitem__(self, key):
try:
return collections.OrderedDict.__getitem__(self, key)
except KeyError:
return self.__missing__(key)
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
self[key] = value = self.default_factory()
return value
def __reduce__(self):
if self.default_factory is None:
args = tuple()
else:
args = self.default_factory,
return type(self), args, None, None, self.items()
def copy(self):
return self.__copy__()
def __copy__(self):
return type(self)(self.default_factory, self)
def __deepcopy__(self, memo):
import copy
return type(self)(self.default_factory,
copy.deepcopy(self.items()))
# noinspection PyMethodOverriding
def __repr__(self):
return 'OrderedDefaultDict(%s, %s)' % (self.default_factory,
collections.OrderedDict.__repr__(self))
class Object(object):
pass