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:
Norman Jäckel 2013-11-29 16:47:31 +01:00
parent 863e5262a6
commit fee983045b
12 changed files with 177 additions and 67 deletions

View File

@ -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)

View File

@ -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 %}

View File

@ -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

View File

@ -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(
'',

View 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

View File

@ -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):

View File

View 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')

View 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)))

7
tests/plugin_api/urls.py Normal file
View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from openslides import urls
reload(urls)
urlpatterns = urls.urlpatterns

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from openslides.urls import urlpatterns