Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Some initial work on multiple views for plugins

  • Loading branch information...
commit 2a05dbd4953f9eb63571934954329a0164c1522c 1 parent 535bb40
@dcramer dcramer authored
View
89 src/sentry/plugins/base.py
@@ -53,6 +53,20 @@ def all(self):
continue
yield plugin
+ def get_urls(self):
+ from django.conf.urls.defaults import patterns, url, include
+
+ urlpatterns = patterns('')
+
+ for plugin in self.all():
+ urlpatterns += patterns('',
+ url(r'^%s/' % plugin.slug, include(plugin.urls)),
+ )
+
+ return urlpatterns
+
+ urls = property(get_urls)
+
def for_project(self, project):
for plugin in self.all():
if not plugin.is_enabled(project):
@@ -149,6 +163,9 @@ class IPlugin(local):
site_conf_form = None
site_conf_template = 'sentry/plugins/site_configuration.html'
+ urls_app_name = None
+ urls_name = None
+
# Global enabled state
enabled = True
@@ -302,31 +319,67 @@ def get_resource_links(self):
"""
return self.resource_links
- def get_view_response(self, request, group):
- from sentry.permissions import can_admin_group
+ def as_view(self, view_func):
+ """
+ Wraps a view function in the required permissions and validation logic
+ for generic pages.
+ """
+ from django.shortcuts import get_object_or_404
+ from sentry.constants import MEMBER_USER
+ from sentry.models import Group
+ from sentry.web.decorators import has_access, login_required
+
+ @login_required
+ @has_access(MEMBER_USER)
+ def get_view_response(request, project, group_id, **kwargs):
+ from sentry.permissions import can_admin_group
- self.selected = request.path == self.get_url(group)
+ group = get_object_or_404(Group, pk=group_id, project=project)
- if not self.selected:
- return
+ if not self.is_enabled(project=project):
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER') or reverse('sentry', kwargs={'project_id': project.slug}))
- response = self.view(request, group)
+ response = view_func(request, group, **kwargs)
+
+ if not response:
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER') or reverse('sentry', kwargs={'project_id': project.slug}))
+
+ if isinstance(response, HttpResponseRedirect):
+ return response
+
+ elif not isinstance(response, Response):
+ raise NotImplementedError('You must use self.render() when returning responses.')
+
+ return response.respond(request, {
+ 'plugin': self,
+ 'project': group.project,
+ 'group': group,
+ 'can_admin_event': can_admin_group(request.user, group),
+ })
+
+ return get_view_response
+
+ def get_urls(self):
+ """
+ Returns a urlpatterns object.
+
+ Views (unless otherwise nescesary) should be decorated via ``self.as_view(callable)``
+ within the urlpatterns.
+ """
+ from django.conf.urls.defaults import patterns, url
- if not response:
- return
+ urlpatterns = patterns('',
+ url(r'^$', self.as_view(self.view)),
+ )
- if isinstance(response, HttpResponseRedirect):
- return response
+ return urlpatterns
- if not isinstance(response, Response):
- raise NotImplementedError('Please use self.render() when returning responses.')
+ def urls(self):
+ if self.urls_app_name and self.urls_name:
+ return self.get_urls(), self.urls_app_name, self.urls_name
+ return self.get_urls()
- return response.respond(request, {
- 'plugin': self,
- 'project': group.project,
- 'group': group,
- 'can_admin_event': can_admin_group(request.user, group),
- })
+ urls = property(urls)
def view(self, request, group, **kwargs):
"""
View
5 src/sentry/web/urls.py
@@ -31,6 +31,9 @@ def init_all_applications():
init_all_applications()
+from sentry.plugins import plugins
+
+
urlpatterns = patterns('',
url(r'^_static/(?P<module>[^/]+)/(?P<path>.*)$', generic.static_media, name='sentry-media'),
@@ -145,7 +148,7 @@ def init_all_applications():
url(r'^(?P<project_id>[\w_-]+)/group/(?P<group_id>\d+)/events/json/$', groups.group_event_list_json, name='sentry-group-events-json'),
url(r'^(?P<project_id>[\w_-]+)/group/(?P<group_id>\d+)/events/(?P<event_id>\d+)/$', groups.group_event_details, name='sentry-group-event'),
url(r'^(?P<project_id>[\w_-]+)/group/(?P<group_id>\d+)/events/(?P<event_id_or_latest>(\d+|latest))/json/$', groups.group_event_details_json, name='sentry-group-event-json'),
- url(r'^(?P<project_id>[\w_-]+)/group/(?P<group_id>\d+)/actions/(?P<slug>[\w_-]+)/', groups.group_plugin_action, name='sentry-group-plugin-action'),
+ url(r'^(?P<project_id>[\w_-]+)/group/(?P<group_id>\d+)/plugins/', include(plugins.urls), name='sentry-group-plugin-action'),
url(r'^(?P<project_id>[\w_-]+)/group/(?P<group_id>\d+)/tags/(?P<tag_name>[^/]+)/$', groups.group_tag_details, name='sentry-group-tag-details'),
url(r'^(?P<project_id>[\w_-]+)/events/$', events.event_list, name='sentry-events'),
View
0  tests/sentry/plugins/base/__init__.py
No changes.
View
39 tests/sentry/plugins/base/tests.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import
+
+from sentry.plugins.base import Plugin
+from sentry.testutils import TestCase
+
+
+class DummyPluginWithUrls(Plugin):
+ urls_app_name = 'dummy'
+ urls_name = 'dummy'
+
+ def get_urls(self):
+ """
+ Returns a urlpatterns object.
+
+ Views (unless otherwise nescesary) should be decorated via ``self.as_view(callable)``
+ within the urlpatterns.
+ """
+ from django.conf.urls.defaults import patterns, url
+
+ urlpatterns = patterns('',
+ url(r'^one/$', self.as_view(self.view_one)),
+ url(r'^two/$', self.as_view(self.view_one)),
+ )
+
+ return urlpatterns
+
+ def view_one(self):
+ return self.render('view_one.html')
+
+ def view_two(self):
+ return self.render('view_two.html')
+
+
+# class SentryPluginTest(TestCase):
+# def test_does_manage_urls(self):
+# return ''
+#
Please sign in to comment.
Something went wrong with that request. Please try again.