Merge pull request #1143 from normanjaeckel/PluginAPI
Change API for plugins, esp. for names and versions of plugins. Also enh...
This commit is contained in:
commit
399ab5a96c
@ -14,6 +14,7 @@ Files:
|
||||
- Enabled update and delete view for uploader refering to his own files.
|
||||
Other:
|
||||
- Changed widget api. Used new metaclass.
|
||||
- Changed api for plugins.
|
||||
|
||||
|
||||
Version 1.5.1 (unreleased)
|
||||
|
@ -7,8 +7,14 @@
|
||||
{% block content %}
|
||||
<h1>{% trans 'Version' %}</h1>
|
||||
<ul>
|
||||
{% for version in versions %}
|
||||
<li>{{ version.0 }} – {% trans 'Version' %} {{ version.1 }}</li>
|
||||
{% for module in modules %}
|
||||
<li>
|
||||
{{ module.verbose_name }}
|
||||
{% if module.description %}
|
||||
({{ module.description }})
|
||||
{% endif %}
|
||||
– {% trans 'Version' %} {{ module.version }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
@ -5,8 +5,10 @@ from django.core.exceptions import PermissionDenied
|
||||
from django.utils.importlib import import_module
|
||||
from haystack.views import SearchView as _SearchView
|
||||
|
||||
from openslides import get_git_commit_id, get_version, RELEASE
|
||||
from openslides import get_version as get_openslides_version
|
||||
from openslides import get_git_commit_id, RELEASE
|
||||
from openslides.config.api import config
|
||||
from openslides.utils.plugins import get_plugin_description, get_plugin_verbose_name, get_plugin_version
|
||||
from openslides.utils.signals import template_manipulation
|
||||
from openslides.utils.views import TemplateView
|
||||
|
||||
@ -22,41 +24,19 @@ class VersionView(TemplateView):
|
||||
Adds version strings to the context.
|
||||
"""
|
||||
context = super(VersionView, self).get_context_data(**kwargs)
|
||||
|
||||
# OpenSlides version. During development the git commit id is added.
|
||||
openslides_version_string = get_version()
|
||||
if not RELEASE:
|
||||
openslides_version_string += ' – Commit %s' % get_git_commit_id()
|
||||
context['versions'] = [('OpenSlides', openslides_version_string)]
|
||||
|
||||
if RELEASE:
|
||||
description = ''
|
||||
else:
|
||||
description = 'Commit %s' % get_git_commit_id()
|
||||
context['modules'] = [{'verbose_name': 'OpenSlides',
|
||||
'description': description,
|
||||
'version': get_openslides_version()}]
|
||||
# Versions of plugins.
|
||||
for plugin in settings.INSTALLED_PLUGINS:
|
||||
# Get plugin
|
||||
try:
|
||||
mod = import_module(plugin)
|
||||
except ImportError:
|
||||
continue
|
||||
|
||||
# Get version.
|
||||
try:
|
||||
plugin_version = mod.get_version()
|
||||
except AttributeError:
|
||||
try:
|
||||
plugin_version = mod.VERSION
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
# Get name.
|
||||
try:
|
||||
plugin_name = mod.get_name()
|
||||
except AttributeError:
|
||||
try:
|
||||
plugin_name = mod.NAME
|
||||
except AttributeError:
|
||||
plugin_name = mod.__name__.split('.')[0]
|
||||
|
||||
context['versions'].append((plugin_name, plugin_version))
|
||||
|
||||
context['modules'].append({'verbose_name': get_plugin_verbose_name(plugin),
|
||||
'description': get_plugin_description(plugin),
|
||||
'version': get_plugin_version(plugin)})
|
||||
return context
|
||||
|
||||
|
||||
|
@ -2,11 +2,22 @@
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls import include, patterns, url
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
from openslides.utils.plugins import get_urlpatterns
|
||||
|
||||
handler500 = 'openslides.utils.views.server_error'
|
||||
|
||||
urlpatterns = patterns(
|
||||
urlpatterns = []
|
||||
|
||||
js_info_dict = {'packages': []}
|
||||
|
||||
for plugin in settings.INSTALLED_PLUGINS:
|
||||
plugin_urlpatterns = get_urlpatterns(plugin)
|
||||
if plugin_urlpatterns:
|
||||
urlpatterns += plugin_urlpatterns
|
||||
js_info_dict['packages'].append(plugin)
|
||||
|
||||
urlpatterns += patterns(
|
||||
'',
|
||||
(r'^agenda/', include('openslides.agenda.urls')),
|
||||
(r'^motion/', include('openslides.motion.urls')),
|
||||
@ -18,19 +29,6 @@ urlpatterns = patterns(
|
||||
(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
)
|
||||
|
||||
js_info_dict = {'packages': []}
|
||||
|
||||
for plugin in settings.INSTALLED_PLUGINS:
|
||||
try:
|
||||
mod = import_module(plugin + '.urls')
|
||||
except ImportError:
|
||||
continue
|
||||
|
||||
plugin_name = mod.__name__.split('.')[0]
|
||||
urlpatterns += patterns('', (r'^%s/' % plugin_name, include('%s.urls'
|
||||
% plugin)))
|
||||
js_info_dict['packages'].append(plugin)
|
||||
|
||||
# TODO: move this patterns into core or the participant app
|
||||
urlpatterns += patterns(
|
||||
'',
|
||||
|
82
openslides/utils/plugins.py
Normal file
82
openslides/utils/plugins.py
Normal file
@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
plugins = {}
|
||||
|
||||
|
||||
def get_plugin(plugin):
|
||||
"""
|
||||
Returns the imported module. The plugin argument must be a python dotted
|
||||
module path.
|
||||
"""
|
||||
try:
|
||||
plugin = plugins[plugin]
|
||||
except KeyError:
|
||||
plugins[plugin] = import_module(plugin)
|
||||
plugin = get_plugin(plugin)
|
||||
return plugin
|
||||
|
||||
|
||||
def get_plugin_verbose_name(plugin):
|
||||
"""
|
||||
Returns the verbose name of a plugin. The plugin argument must be a python
|
||||
dotted module path.
|
||||
"""
|
||||
plugin = get_plugin(plugin)
|
||||
try:
|
||||
verbose_name = plugin.get_verbose_name()
|
||||
except AttributeError:
|
||||
try:
|
||||
verbose_name = plugin.__verbose_name__
|
||||
except AttributeError:
|
||||
verbose_name = plugin.__name__
|
||||
return verbose_name
|
||||
|
||||
|
||||
def get_plugin_description(plugin):
|
||||
"""
|
||||
Returns the short descrption of a plugin. The plugin argument must be a
|
||||
python dotted module path.
|
||||
"""
|
||||
plugin = get_plugin(plugin)
|
||||
try:
|
||||
description = plugin.get_description()
|
||||
except AttributeError:
|
||||
try:
|
||||
description = plugin.__description__
|
||||
except AttributeError:
|
||||
description = ''
|
||||
return description
|
||||
|
||||
|
||||
def get_plugin_version(plugin):
|
||||
"""
|
||||
Returns the version string of a plugin. The plugin argument must be a#
|
||||
python dotted module path.
|
||||
"""
|
||||
plugin = get_plugin(plugin)
|
||||
try:
|
||||
version = plugin.get_version()
|
||||
except AttributeError:
|
||||
try:
|
||||
version = plugin.__version__
|
||||
except AttributeError:
|
||||
version = 'unknown'
|
||||
return version
|
||||
|
||||
|
||||
def get_urlpatterns(plugin):
|
||||
"""
|
||||
Returns the urlpatterns object for a plugin. The plugin argument must be
|
||||
a python dotted module path.
|
||||
"""
|
||||
plugin = get_plugin(plugin)
|
||||
try:
|
||||
urlpatterns = plugin.urlpatterns
|
||||
except AttributeError:
|
||||
try:
|
||||
urlpatterns = plugin.urls.urlpatterns
|
||||
except AttributeError:
|
||||
urlpatterns = None
|
||||
return urlpatterns
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.test.client import Client
|
||||
from mock import MagicMock, patch
|
||||
from mock import patch
|
||||
|
||||
from openslides import get_version
|
||||
from openslides.agenda.models import Item
|
||||
@ -23,24 +23,10 @@ class VersionViewTest(TestCase):
|
||||
@patch('openslides.core.views.settings')
|
||||
def test_with_missing_plugin(self, mock_settings):
|
||||
"""
|
||||
Tests that an not existing app does not appear on the version view.
|
||||
Tests that a not existing app does not appear on the version view.
|
||||
"""
|
||||
mock_settings.INSTALLED_PLUGINS = ('unexisting_app_nvhbkdfgmnsd',)
|
||||
response = self.client.get('/version/')
|
||||
self.assertNotContains(response, 'unexisting_app_nvhbkdfgmnsd', status_code=200)
|
||||
|
||||
@patch('openslides.core.views.settings')
|
||||
@patch('openslides.core.views.import_module')
|
||||
def test_with_plugin_without_version(self, mock_import_module, mock_settings):
|
||||
"""
|
||||
Tests that an exisiting app does not appear in the version view if
|
||||
there are no version data.
|
||||
"""
|
||||
mock_settings.INSTALLED_PLUGINS = ('existing_app_without_version',)
|
||||
mock_module = MagicMock(spec=['some_useless_attribute_ghbnckj756j36'])
|
||||
mock_import_module.configure_mock(return_value=mock_module)
|
||||
response = self.client.get('/version/')
|
||||
self.assertNotContains(response, 'unexisting_app_nvhbkdfgmnsd', status_code=200)
|
||||
self.assertRaises(ImportError, self.client.get, '/version/')
|
||||
|
||||
|
||||
class SearchViewTest(TestCase):
|
||||
|
0
tests/plugin_api/__init__.py
Normal file
0
tests/plugin_api/__init__.py
Normal file
35
tests/plugin_api/test_plugin_api.py
Normal file
35
tests/plugin_api/test_plugin_api.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.test.client import Client
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from openslides.utils.test import TestCase
|
||||
|
||||
|
||||
@override_settings(INSTALLED_PLUGINS=('tests.plugin_api.test_plugin_one',))
|
||||
class TestPluginOne(TestCase):
|
||||
urls = 'tests.plugin_api.urls' # Use reloaded urlpatterns for this TestCase
|
||||
|
||||
def setUp(self):
|
||||
self.admin_client = Client()
|
||||
self.admin_client.login(username='admin', password='admin')
|
||||
|
||||
def test_version_page(self):
|
||||
response = self.admin_client.get('/version/')
|
||||
self.assertContains(response, 'Test Plugin ta3Ohmaiquee2phaf9ei')
|
||||
self.assertContains(response, '(Short description of test plugin Sah9aiQuae5hoocai7ai)')
|
||||
self.assertContains(response, '– Version test_version_string_MoHonepahfofiree6Iej')
|
||||
|
||||
def test_url_patterns(self):
|
||||
response = self.admin_client.get('/test_plugin_one_url_Eexea4nie1fexaax3oX7/')
|
||||
self.assertRedirects(response, '/version/')
|
||||
|
||||
|
||||
@override_settings(INSTALLED_PLUGINS=('tests.plugin_api.test_plugin_two',))
|
||||
class TestPluginTwo(TestCase):
|
||||
def test_version_page(self):
|
||||
admin_client = Client()
|
||||
admin_client.login(username='admin', password='admin')
|
||||
response = admin_client.get('/version/')
|
||||
self.assertContains(response, 'tests.plugin_api.test_plugin_two')
|
||||
self.assertContains(response, '– Version unknown')
|
13
tests/plugin_api/test_plugin_one/__init__.py
Normal file
13
tests/plugin_api/test_plugin_one/__init__.py
Normal file
@ -0,0 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
from django.views.generic import RedirectView
|
||||
|
||||
__verbose_name__ = 'Test Plugin ta3Ohmaiquee2phaf9ei'
|
||||
__version__ = 'test_version_string_MoHonepahfofiree6Iej'
|
||||
__description__ = 'Short description of test plugin Sah9aiQuae5hoocai7ai'
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^test_plugin_one_url_Eexea4nie1fexaax3oX7/$',
|
||||
RedirectView.as_view(pattern_name='core_version', permanent=False)))
|
0
tests/plugin_api/test_plugin_two/__init__.py
Normal file
0
tests/plugin_api/test_plugin_two/__init__.py
Normal file
7
tests/plugin_api/urls.py
Normal file
7
tests/plugin_api/urls.py
Normal file
@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openslides import urls
|
||||
|
||||
reload(urls)
|
||||
|
||||
urlpatterns = urls.urlpatterns
|
@ -1,3 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from openslides.urls import urlpatterns
|
||||
|
Loading…
Reference in New Issue
Block a user