Browse Source

Admin links builder #344

Rafał Pitoń 11 years ago
parent
commit
74e6f59cb3

+ 1 - 1
misago/admin/__init__.py

@@ -1 +1 @@
-from misago.admin.hierarchy import site  # noqa
+from misago.admin.hierarchy import site, urlpatterns  # noqa

+ 3 - 0
misago/admin/hierarchy.py

@@ -1,4 +1,5 @@
 from django.core.urlresolvers import reverse
+from misago.admin.urlpatterns import URLPatterns
 
 
 class Node(object):
@@ -93,6 +94,7 @@ class AdminHierarchyBuilder(object):
     def __init__(self):
         self.nodes_record = []
         self.nodes_dict = {}
+        self.urlpatterns = URLPatterns()
 
     def build_nodes_dict(self):
         nodes_dict = {'misago:admin': Node(link='misago:admin:index')}
@@ -188,3 +190,4 @@ class AdminHierarchyBuilder(object):
 
 
 site = AdminHierarchyBuilder()
+urlpatterns = site.urlpatterns

+ 71 - 0
misago/admin/urlpatterns.py

@@ -0,0 +1,71 @@
+from django.conf.urls import patterns, url, include
+from django.core.urlresolvers import reverse
+
+
+class URLPatterns(object):
+    def __init__(self):
+        self._namespaces = []
+        self._patterns = []
+
+    def namespace(self, path, namespace, parent=None):
+        self._namespaces.append({
+            'path': path,
+            'parent': parent,
+            'namespace': namespace,
+            })
+
+    def patterns(self, namespace, *urlpatterns):
+        self._patterns.append({
+            'namespace': namespace,
+            'urlpatterns': patterns('', *urlpatterns),
+            })
+
+    def subpatterns(self, namespace):
+        prefix = '%s:' % namespace if namespace else ''
+
+        urlpatterns = self.namespace_patterns.get(namespace, [])
+        for subspace in self._namespaces:
+            if subspace['parent'] == namespace:
+                subspace_name = prefix + subspace['namespace']
+                namespace_patterns = self.subpatterns(subspace_name)
+                included = include(namespace_patterns,
+                                   namespace=subspace['namespace'])
+                urlpatterns += patterns('',
+                    url(subspace['path'], included)
+                )
+
+        return urlpatterns
+
+    def sum_registered_patters(self):
+        all_patterns = {}
+        for urls in self._patterns:
+            namespace = urls['namespace']
+            urlpatterns = urls['urlpatterns']
+            all_patterns.setdefault(namespace, []).extend(urlpatterns)
+
+        self.namespace_patterns = all_patterns
+
+    def build_urlpatterns(self):
+        self.sum_registered_patters()
+
+        urlpatterns = []
+        for namespace in self._namespaces:
+            if not namespace['parent']:
+                namespace_patterns = self.subpatterns(namespace['namespace'])
+                included = include(namespace_patterns,
+                                   namespace=namespace['namespace'])
+                urlpatterns += patterns('',
+                    url(namespace['path'], included)
+                )
+
+        return urlpatterns
+
+    def __call__(self):
+        try:
+            return self._urlpatterns
+        except AttributeError:
+            self._urlpatterns = self.build_urlpatterns()
+            self._namespaces = []
+            self._patterns = []
+            return self._urlpatterns
+

+ 12 - 9
misago/admin/urls.py

@@ -1,7 +1,8 @@
+import importlib
 from django.conf import settings
 from django.conf.urls import patterns, include, url
 from django.core.exceptions import ImproperlyConfigured
-from django.utils.module_loading import import_by_path
+from misago.admin import site
 
 
 urlpatterns = patterns('misago.admin.views',
@@ -13,20 +14,22 @@ urlpatterns = patterns('misago.admin.views',
 )
 
 
-def discover_admin_urls():
+# Magic voodoo for initializing admin patterns lazily
+def initialize_admin_urls():
     SEARCH_PATTERNS = (
-        '%s.urls.adminurlpatterns',
-        '%s.urls.admin.urlpatterns',
-        '%s.adminurls.urlpatterns',
+        '%s.adminurls',
+        '%s.urls.admin',
         )
-    admin_patterns = []
 
     for app in settings.INSTALLED_APPS:
         for pattern in SEARCH_PATTERNS:
             try:
-                admin_patterns += import_by_path(pattern % app)
+                importlib.import_module(pattern % app)
                 continue
-            except ImproperlyConfigured:
+            except ImportError:
                 pass
 
-    return admin_patterns
+
+# Register discovered patterns
+initialize_admin_urls()
+urlpatterns += site.urlpatterns()

+ 10 - 0
misago/conf/adminurls.py

@@ -0,0 +1,10 @@
+from django.conf.urls import url
+from misago.admin import urlpatterns
+
+
+urlpatterns.namespace(r'^settings/', 'settings')
+
+urlpatterns.patterns('settings',
+    url(r'^$', 'misago.conf.views.index', name='index'),
+    url(r'^(?P<group_key>(\w|-)+)/$', 'misago.conf.views.group', name='group'),
+)

+ 0 - 11
misago/conf/urls.py

@@ -1,11 +0,0 @@
-from django.conf.urls import patterns, include, url
-
-
-_urlpatterns = patterns('misago.conf.views',
-    url(r'^$', 'index', name='index'),
-    url(r'^(?P<group_key>(\w|-)+)/$', 'group', name='group'),
-)
-
-adminurlpatterns = patterns('misago.conf.views',
-    url(r'^settings/', include(_urlpatterns, namespace='settings')),
-)

+ 0 - 3
misago/urls.py

@@ -1,6 +1,5 @@
 from django.conf import settings
 from django.conf.urls import patterns, include, url
-from misago.admin.urls import discover_admin_urls
 
 
 urlpatterns = patterns('misago.core.views',
@@ -23,8 +22,6 @@ if settings.MISAGO_ADMIN_PATH:
         url(r'^', include('misago.admin.urls')),
     )
 
-    adminpatterns += discover_admin_urls()
-
     admin_prefix = r'^%s/' % settings.MISAGO_ADMIN_PATH
     urlpatterns += patterns('',
         url(admin_prefix, include(adminpatterns, namespace='admin')),

+ 7 - 12
misago/users/urls/admin.py

@@ -1,18 +1,13 @@
-from django.conf.urls import patterns, url, include
+from django.conf.urls import url
+from misago.admin import urlpatterns
 from misago.users.views.useradmin import UsersList
 
 
-action_urlpatterns = patterns('',
-    url(r'^$', UsersList.as_view(), name='index'),
-    url(r'^(?P<page>\d+)/$', UsersList.as_view(), name='index'),
-)
-
-
-section_urlpatterns = patterns('',
-    url(r'^accounts/', include(action_urlpatterns, namespace='accounts')),
-)
+urlpatterns.namespace(r'^users/', 'users')
+urlpatterns.namespace(r'^accounts/', 'accounts', 'users')
 
 
-urlpatterns = patterns('',
-    url(r'^users/', include(section_urlpatterns, namespace='users')),
+urlpatterns.patterns('users:accounts',
+    url(r'^$', UsersList.as_view(), name='index'),
+    url(r'^(?P<page>\d+)/$', UsersList.as_view(), name='index'),
 )