on master help sign in
[enh] plugins: client side dependency support
dd84814Adam Tauber
searx/plugins/__init__.py+6
@@ -8,6 +8,9 @@ required_attrs = (('name', str),
8 ('description', str),
8 ('description', str),
9 ('default_on', bool))
9 ('default_on', bool))
10
10
11+optional_attrs = (('js_dependencies', tuple),
12+ ('css_dependencies', tuple))
13+
11
14
12class Plugin():
15class Plugin():
13 default_on = False
16 default_on = False
@@ -30,6 +33,9 @@ class PluginStore():
30 if not hasattr(plugin, plugin_attr) or not isinstance(getattr(plugin, plugin_attr), plugin_attr_type):
33 if not hasattr(plugin, plugin_attr) or not isinstance(getattr(plugin, plugin_attr), plugin_attr_type):
31 logger.critical('missing attribute "{0}", cannot load plugin: {1}'.format(plugin_attr, plugin))
34 logger.critical('missing attribute "{0}", cannot load plugin: {1}'.format(plugin_attr, plugin))
32 exit(3)
35 exit(3)
36+ for plugin_attr, plugin_attr_type in optional_attrs:
37+ if not hasattr(plugin, plugin_attr) or not isinstance(getattr(plugin, plugin_attr), plugin_attr_type):
38+ setattr(plugin, plugin_attr, plugin_attr_type())
33 plugin.id = plugin.name.replace(' ', '_')
39 plugin.id = plugin.name.replace(' ', '_')
34 self.plugins.append(plugin)
40 self.plugins.append(plugin)
35
41
searx/templates/oscar/base.html+10−4
@@ -9,17 +9,20 @@
9 <meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" />
9 <meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" />
10 {% block meta %}{% endblock %}
10 {% block meta %}{% endblock %}
11 <title>{% block title %}{% endblock %}searx</title>
11 <title>{% block title %}{% endblock %}searx</title>
12−
12+
13 <link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" type="text/css" />
13 <link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" type="text/css" />
14− <link rel="stylesheet" href="{{ url_for('static', filename='css/oscar.min.css') }}" type="text/css" />
14+ <link rel="stylesheet" href="{{ url_for('static', filename='css/oscar.min.css') }}" type="text/css" />
15 <link rel="stylesheet" href="{{ url_for('static', filename='css/leaflet.min.css') }}" type="text/css" />
15 <link rel="stylesheet" href="{{ url_for('static', filename='css/leaflet.min.css') }}" type="text/css" />
16+ {% for css in styles %}
17+ <link rel="stylesheet" href="{{ url_for('static', filename=css) }}" type="text/css" />
18+ {% endfor %}
16
19
17 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
20 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
18 <!--[if lt IE 9]>
21 <!--[if lt IE 9]>
19 <script src="{{ url_for('static', filename='js/html5shiv.min.js') }}"></script>
22 <script src="{{ url_for('static', filename='js/html5shiv.min.js') }}"></script>
20 <script src="{{ url_for('static', filename='js/respond.min.js') }}"></script>
23 <script src="{{ url_for('static', filename='js/respond.min.js') }}"></script>
21 <![endif]-->
24 <![endif]-->
22−
25+
23 <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}" />
26 <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}" />
24
27
25 {% block styles %}
28 {% block styles %}
@@ -28,7 +31,7 @@
28 {% endblock %}
31 {% endblock %}
29
32
30 <link title="searx" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
33 <link title="searx" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
31−
34+
32 <script type="text/javascript">
35 <script type="text/javascript">
33 searx = {};
36 searx = {};
34 searx.method = "{{ method or 'POST' }}";
37 searx.method = "{{ method or 'POST' }}";
@@ -79,5 +82,8 @@
79 {% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js') }}"></script>{% endif %}
82 {% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js') }}"></script>{% endif %}
80 <script src="{{ url_for('static', filename='js/require-2.1.15.min.js') }}"></script>
83 <script src="{{ url_for('static', filename='js/require-2.1.15.min.js') }}"></script>
81 <script src="{{ url_for('static', filename='js/searx.min.js') }}"></script>
84 <script src="{{ url_for('static', filename='js/searx.min.js') }}"></script>
85+ {% for script in scripts %}
86+ <script src="{{ url_for('static', filename=script) }}"></script>
87+ {% endfor %}
82</body>
88</body>
83</html>
89</html>
searx/webapp.py+10
@@ -301,6 +301,16 @@ def render(template_name, override_theme=None, **kwargs):
301
301
302 kwargs['cookies'] = request.cookies
302 kwargs['cookies'] = request.cookies
303
303
304+ kwargs['scripts'] = set()
305+ for plugin in request.user_plugins:
306+ for script in plugin.js_dependencies:
307+ kwargs['scripts'].add(script)
308+
309+ kwargs['styles'] = set()
310+ for plugin in request.user_plugins:
311+ for css in plugin.css_dependencies:
312+ kwargs['styles'].add(css)
313+
304 return render_template(
314 return render_template(
305 '{}/{}'.format(kwargs['theme'], template_name), **kwargs)
315 '{}/{}'.format(kwargs['theme'], template_name), **kwargs)
306
316