Change API for plugins, esp. for names and versions of plugins. Also enhance possibility to patch existing OpenSlides urlpatterns.
Fix some other tests by the way.
This commit is contained in:
parent
863e5262a6
commit
fee983045b
@ -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