First step in the module design
authorSverre Rabbelier <sverre@rabbelier.nl>
Sun, 24 May 2009 21:40:37 +0200
changeset 2333 221482a54238
parent 2332 2a6071255146
child 2336 58d2310330d3
First step in the module design The new module design allows modules to be registered by adding them to settings.MODULES. Currently modules cannot do a lot (they can register with the sidebar and the sitemap), but the structure is in place.
app/main.py
app/settings.py
app/soc/modules/__init__.py
app/soc/modules/callback.py
app/soc/modules/core.py
app/soc/modules/soc_core/__init__.py
app/soc/modules/soc_core/callback.py
app/soc/views/helper/responses.py
app/soc/views/models/base.py
app/soc/views/sitemap/build.py
app/soc/views/sitemap/sidebar.py
app/soc/views/sitemap/sitemap.py
app/urls.py
--- a/app/main.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/main.py	Sun May 24 21:40:37 2009 +0200
@@ -126,6 +126,12 @@
   # Create a Django application for WSGI.
   application = django.core.handlers.wsgi.WSGIHandler()
 
+  from soc.modules import callback
+  from soc.modules import core
+
+  callback.registerCore(core.Core())
+  callback.getCore().registerModuleCallbacks()
+
   # Run the WSGI CGI handler with that application.
   util.run_wsgi_app(application)
 
--- a/app/settings.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/settings.py	Sun May 24 21:40:37 2009 +0200
@@ -109,3 +109,6 @@
 #    'django.contrib.sessions',
 #    'django.contrib.sites',
 )
+
+MODULE_FMT = 'soc.modules.%s'
+MODULES = []
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/modules/__init__.py	Sun May 24 21:40:37 2009 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright 2009 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""This is the main modules module.
+"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/modules/callback.py	Sun May 24 21:40:37 2009 +0200
@@ -0,0 +1,40 @@
+# Copyright 2009 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Module containing Melange callbacks.
+"""
+
+__authors__ = [
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  '"Lennard de Rijk" <ljvderijk@gmail.com>',
+  ]
+
+
+CORE = None
+
+
+def registerCore(core):
+  """Registers the specified callback as core.
+  """
+
+  global CORE
+  CORE = core
+
+
+def getCore():
+  """Returns the Core handler.
+  """
+
+  global CORE
+  return CORE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/modules/core.py	Sun May 24 21:40:37 2009 +0200
@@ -0,0 +1,235 @@
+# Copyright 2009 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""The Melange Core module.
+"""
+
+__authors__ = [
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  '"Lennard de Rijk" <ljvderijk@gmail.com>',
+  ]
+
+
+from django.conf.urls import defaults
+
+import settings
+import soc.cache.sidebar
+
+
+class Error(Exception):
+  """Error class for the callback module.
+  """
+
+  pass
+
+
+class APIVersionMismatch(Error):
+  """Error raised when API version mismatches.
+  """
+
+  MISMATCH_MSG_FMT = "API mismatch, expected '%d', got '%d'."
+
+  def __init__(self, expected, actual):
+    """Instantiates a new exception with a customized message.
+    """
+
+    msg = self.MISMATCH_MSG_FMT % (expected, actual)
+    super(APIVersionMismatch, self).__init__(msg)
+
+
+class MissingService(Error):
+  """Error raised when a required service is missing.
+  """
+
+  MISSING_SERVICE_FMT = "Required service '%s' is not registered, known: %s"
+
+  def __init__(self, service, services):
+    """Instantiates a new exception with a customized message.
+    """
+
+    msg = self.MISSING_SERVICE_FMT % (service, services)
+    super(MissingService, self).__init__(msg)
+
+
+class NonUniqueService(Error):
+  """Error raised when a required service is missing.
+  """
+
+  NON_UNIQUE_SERVICE_FMT = "Unique service '%s' called a second time, known: %s."
+
+  def __init__(self, service, services):
+    """Instantiates a new exception with a customized message.
+    """
+
+    msg = self.NON_UNIQUE_SERVICE_FMT % (service, services)
+    super(NonUniqueService, self).__init__(msg)
+
+
+class Core(object):
+  """The core handler that controls the Melange API.
+  """
+
+  def __init__(self):
+    """Creates a new instance of the Core.
+    """
+
+    self.API_VERSION = 1
+
+    self.registered_callbacks = []
+    self.capability = []
+    self.services = []
+
+    self.sitemap = []
+    self.sidebar = []
+
+  ##
+  ## internal
+  ##
+
+  def getService(self, callback, service):
+   """Retrieves the specified service from the callback if supported.
+
+   Args:
+     callback: the callback to retrieve the capability from
+     service: the service to retrieve
+   """
+
+   if not hasattr(callback, service):
+     return False
+
+   func = getattr(callback, service)
+
+   if not callable(func):
+     return False
+
+   return func
+
+  ##
+  ## Core code
+  ##
+
+  def getPatterns(self):
+    """Returns the Django patterns for this site.
+    """
+
+    self.callService('registerWithSitemap', True)
+    return defaults.patterns(None, *self.sitemap)
+
+  @soc.cache.sidebar.cache
+  def getSidebar(self, id, user):
+    """Constructs a sidebar for the current user.
+    """
+
+    self.callService('registerWithSidebar', True)
+
+    sidebar = []
+
+    for i in self.sidebar:
+      menus = i(id, user)
+
+      for menu in (menus if menus else []):
+        sidebar.append(menu)
+
+    return sorted(sidebar, key=lambda x: x.get('group'))
+
+  def callService(self, service, unique, *args, **kwargs):
+    """Calls the specified service on all callbacks.
+    """
+
+    if unique and (service in self.services):
+      return
+
+    results = []
+
+    for callback in self.registered_callbacks:
+      func = self.getService(callback, service)
+      if not func:
+        continue
+
+      result = func(*args, **kwargs)
+      results.append(result)
+
+    self.services.append(service)
+    return results
+
+  def registerModuleCallbacks(self):
+    """Retrieves all callbacks for the modules of this site.
+
+    Callbacks for modules without a version number or the wrong API_VERSION
+    number are dropped.  They won't be called.
+    """
+
+    fmt = settings.MODULE_FMT
+    modules = ['soc_core'] + settings.MODULES
+    modules = [__import__(fmt % i, fromlist=['']) for i in modules]
+
+    for callback_class in [i.getCallback() for i in modules]:
+      if callback_class.API_VERSION != self.API_VERSION:
+        raise callback.APIVersionMismatch(self.API_VERSION,
+                                          callback_class.API_VERSION)
+
+
+      callback = callback_class(self)
+      self.registered_callbacks.append(callback)
+
+    return True
+
+  ##
+  ## Module code
+  ##
+
+  def registerCapability(self, capability):
+    """Registers the specified capability.
+    """
+
+    self.capabilities.append(capability)
+
+  def requireCapability(self, capability):
+    """Requires that the specified capability is present.
+    """
+
+    if capability in self.capabilities:
+      return True
+
+    raise MissingCapability(capability, self.capability)
+
+  def requireService(self, service):
+    """Requires that the specified service has been called.
+    """
+
+    if service in self.services:
+      return True
+
+    raise MissingService(service, self.services)
+
+  def requireUniqueService(self, service):
+    """Requires that the specified service is called exactly once.
+    """
+
+    if service not in self.services:
+      return True
+
+    raise NonUniqueService(service, self.services)
+
+  def registerSitemapEntry(self, entries):
+    """Registers the specified entries with the sitemap.
+    """
+
+    self.sitemap.extend(entries)
+
+  def registerSidebarEntry(self, entry):
+    """Registers the specified entry with the sidebar.
+    """
+
+    self.sidebar.append(entry)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/modules/soc_core/__init__.py	Sun May 24 21:40:37 2009 +0200
@@ -0,0 +1,29 @@
+#
+# Copyright 2009 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""This is the main modules module.
+"""
+
+__authors__ = [
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  '"Lennard de Rijk" <ljvderijk@gmail.com>',
+  ]
+
+
+
+from soc.modules.soc_core import callback
+
+def getCallback():
+  return callback.Callback
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/modules/soc_core/callback.py	Sun May 24 21:40:37 2009 +0200
@@ -0,0 +1,129 @@
+# Copyright 2009 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Module containing the core callback.
+"""
+
+__authors__ = [
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  '"Lennard de Rijk" <ljvderijk@gmail.com>',
+  ]
+
+
+from soc.modules import callback
+
+from soc.views.models import club
+from soc.views.models import club_app
+from soc.views.models import club_admin
+from soc.views.models import club_member
+from soc.views.models import cron
+from soc.views.models import document
+from soc.views.models import host
+from soc.views.models import job
+from soc.views.models import mentor
+from soc.views.models import notification
+from soc.views.models import organization
+from soc.views.models import org_admin
+from soc.views.models import org_app
+from soc.views.models import priority_group
+from soc.views.models import program
+from soc.views.models import request
+from soc.views.models import site
+from soc.views.models import sponsor
+from soc.views.models import student
+from soc.views.models import student_project
+from soc.views.models import student_proposal
+from soc.views.models import timeline
+from soc.views.models import user
+from soc.views.models import user_self
+
+
+class Callback(object):
+  """Callback object that handles interaction between the core.
+  """
+
+  API_VERSION = 1
+
+  def __init__(self, core):
+    """Initializes a new Callback object for the specified core.
+    """
+
+    self.core = core
+
+    # disable clubs
+    self.enable_clubs = False
+
+  def registerWithSitemap(self):
+    """Called by the server when sitemap entries should be registered.
+    """
+
+    self.core.requireUniqueService('registerWithSitemap')
+
+    if self.enable_clubs:
+      self.core.registerSitemapEntry(club.view.getDjangoURLPatterns())
+      self.core.registerSitemapEntry(club_admin.view.getDjangoURLPatterns())
+      self.core.registerSitemapEntry(club_app.view.getDjangoURLPatterns())
+      self.core.registerSitemapEntry(club_member.view.getDjangoURLPatterns())
+
+    self.core.registerSitemapEntry(cron.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(document.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(host.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(job.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(mentor.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(notification.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(organization.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(org_admin.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(org_app.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(priority_group.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(program.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(request.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(site.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(sponsor.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(student.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(student_project.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(student_proposal.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(timeline.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(user_self.view.getDjangoURLPatterns())
+    self.core.registerSitemapEntry(user.view.getDjangoURLPatterns())
+
+  def registerWithSidebar(self):
+    """Called by the server when sidebar entries should be registered.
+    """
+
+    self.core.requireUniqueService('registerWithSidebar')
+
+    if self.enable_clubs:
+      self.core.registerSidebarEntry(club.view.getSidebarMenus)
+      self.core.registerSidebarEntry(club.view.getExtraMenus)
+      self.core.registerSidebarEntry(club_admin.view.getSidebarMenus)
+      self.core.registerSidebarEntry(club_member.view.getSidebarMenus)
+      self.core.registerSidebarEntry(club_app.view.getSidebarMenus)
+
+    self.core.registerSidebarEntry(user_self.view.getSidebarMenus)
+    self.core.registerSidebarEntry(site.view.getSidebarMenus)
+    self.core.registerSidebarEntry(user.view.getSidebarMenus)
+    self.core.registerSidebarEntry(sponsor.view.getSidebarMenus)
+    self.core.registerSidebarEntry(sponsor.view.getExtraMenus)
+    self.core.registerSidebarEntry(host.view.getSidebarMenus)
+    self.core.registerSidebarEntry(request.view.getSidebarMenus)
+    self.core.registerSidebarEntry(program.view.getSidebarMenus)
+    self.core.registerSidebarEntry(program.view.getExtraMenus)
+    self.core.registerSidebarEntry(student.view.getSidebarMenus)
+    self.core.registerSidebarEntry(student_project.view.getSidebarMenus)
+    self.core.registerSidebarEntry(student_proposal.view.getSidebarMenus)
+    self.core.registerSidebarEntry(organization.view.getSidebarMenus)
+    self.core.registerSidebarEntry(organization.view.getExtraMenus)
+    self.core.registerSidebarEntry(org_admin.view.getSidebarMenus)
+    self.core.registerSidebarEntry(mentor.view.getSidebarMenus)
+    self.core.registerSidebarEntry(org_app.view.getSidebarMenus)
--- a/app/soc/views/helper/responses.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/soc/views/helper/responses.py	Sun May 24 21:40:37 2009 +0200
@@ -33,6 +33,7 @@
 from soc.logic import system
 from soc.logic.models import site
 from soc.logic.models.user import logic as user_logic
+from soc.modules import callback
 from soc.views import helper
 from soc.views.helper import redirects
 from soc.views.helper import templates
@@ -125,7 +126,7 @@
   context['sign_in'] = users.create_login_url(request.path)
   context['sign_out'] = users.create_logout_url(request.path)
 
-  context['sidebar_menu_items'] = sidebar.getSidebar(account, user)
+  context['sidebar_menu_items'] = callback.getCore().getSidebar(account, user)
 
   context['gae_version'] = system.getAppVersion()
   context['soc_release'] = system.getMelangeVersion()
--- a/app/soc/views/models/base.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/soc/views/models/base.py	Sun May 24 21:40:37 2009 +0200
@@ -41,7 +41,8 @@
 from soc.views.helper import redirects
 from soc.views.helper import requests
 from soc.views.helper import responses
-from soc.views import sitemap
+from soc.views.sitemap import sidebar
+from soc.views.sitemap import sitemap
 
 import soc.cache.logic
 import soc.logic
@@ -952,7 +953,7 @@
       of _getSidebarItems on how it uses it.
     """
 
-    return sitemap.sidebar.getSidebarMenus(id, user, params=params)
+    return sidebar.getSidebarMenus(id, user, params=params)
 
   @decorators.merge_params
   def getDjangoURLPatterns(self, params=None):
@@ -967,5 +968,5 @@
       params: a dict with params for this View
     """
 
-    return sitemap.sitemap.getDjangoURLPatterns(params)
+    return sitemap.getDjangoURLPatterns(params)
 
--- a/app/soc/views/sitemap/build.py	Fri May 22 09:40:53 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Module that constructs the sitemap.
-"""
-
-__authors__ = [
-    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
-  ]
-
-
-from django.conf.urls import defaults
-
-#from soc.views.models import club
-#from soc.views.models import club_app
-#from soc.views.models import club_admin
-#from soc.views.models import club_member
-from soc.views.models import cron
-from soc.views.models import document
-from soc.views.models import host
-from soc.views.models import job
-from soc.views.models import mentor
-from soc.views.models import notification
-from soc.views.models import organization
-from soc.views.models import org_admin
-from soc.views.models import org_app
-from soc.views.models import priority_group
-from soc.views.models import program
-from soc.views.models import request
-from soc.views.models import site
-from soc.views.models import sponsor
-from soc.views.models import student
-from soc.views.models import student_project
-from soc.views.models import student_proposal
-from soc.views.models import timeline
-from soc.views.models import user
-from soc.views.models import user_self
-
-from soc.views.sitemap import sidebar
-from soc.views.sitemap import sitemap
-
-
-# TODO: instead of commenting out club stuff, make it depend on a setting
-
-
-sidebar.addMenu(user_self.view.getSidebarMenus)
-#sidebar.addMenu(club.view.getSidebarMenus)
-#sidebar.addMenu(club.view.getExtraMenus)
-#sidebar.addMenu(club_admin.view.getSidebarMenus)
-#sidebar.addMenu(club_member.view.getSidebarMenus)
-#sidebar.addMenu(club_app.view.getSidebarMenus)
-sidebar.addMenu(site.view.getSidebarMenus)
-sidebar.addMenu(user.view.getSidebarMenus)
-#sidebar.addMenu(document.view.getSidebarMenus)
-sidebar.addMenu(sponsor.view.getSidebarMenus)
-sidebar.addMenu(sponsor.view.getExtraMenus)
-sidebar.addMenu(host.view.getSidebarMenus)
-sidebar.addMenu(request.view.getSidebarMenus)
-sidebar.addMenu(program.view.getSidebarMenus)
-sidebar.addMenu(program.view.getExtraMenus)
-sidebar.addMenu(student.view.getSidebarMenus)
-sidebar.addMenu(student_project.view.getSidebarMenus)
-sidebar.addMenu(student_proposal.view.getSidebarMenus)
-sidebar.addMenu(organization.view.getSidebarMenus)
-sidebar.addMenu(organization.view.getExtraMenus)
-sidebar.addMenu(org_admin.view.getSidebarMenus)
-sidebar.addMenu(mentor.view.getSidebarMenus)
-sidebar.addMenu(org_app.view.getSidebarMenus)
-
-#sitemap.addPages(club.view.getDjangoURLPatterns())
-#sitemap.addPages(club_admin.view.getDjangoURLPatterns())
-#sitemap.addPages(club_app.view.getDjangoURLPatterns())
-#sitemap.addPages(club_member.view.getDjangoURLPatterns())
-sitemap.addPages(cron.view.getDjangoURLPatterns())
-sitemap.addPages(document.view.getDjangoURLPatterns())
-sitemap.addPages(host.view.getDjangoURLPatterns())
-sitemap.addPages(job.view.getDjangoURLPatterns())
-sitemap.addPages(mentor.view.getDjangoURLPatterns())
-sitemap.addPages(notification.view.getDjangoURLPatterns())
-sitemap.addPages(organization.view.getDjangoURLPatterns())
-sitemap.addPages(org_admin.view.getDjangoURLPatterns())
-sitemap.addPages(org_app.view.getDjangoURLPatterns())
-sitemap.addPages(priority_group.view.getDjangoURLPatterns())
-sitemap.addPages(program.view.getDjangoURLPatterns())
-sitemap.addPages(request.view.getDjangoURLPatterns())
-sitemap.addPages(site.view.getDjangoURLPatterns())
-sitemap.addPages(sponsor.view.getDjangoURLPatterns())
-sitemap.addPages(student.view.getDjangoURLPatterns())
-sitemap.addPages(student_project.view.getDjangoURLPatterns())
-sitemap.addPages(student_proposal.view.getDjangoURLPatterns())
-sitemap.addPages(timeline.view.getDjangoURLPatterns())
-sitemap.addPages(user_self.view.getDjangoURLPatterns())
-sitemap.addPages(user.view.getDjangoURLPatterns())
-
-
-def getPatterns():
-  """Retrieves all the url patterns of this site.
-  """
-  return defaults.patterns(None, *sitemap.SITEMAP)
--- a/app/soc/views/sitemap/sidebar.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/soc/views/sitemap/sidebar.py	Sun May 24 21:40:37 2009 +0200
@@ -24,38 +24,11 @@
 
 from soc.views import out_of_band
 
-import soc.cache.sidebar
 
-
-SIDEBAR = []
 SIDEBAR_ACCESS_ARGS = ['SIDEBAR_CALLING']
 SIDEBAR_ACCESS_KWARGS = {'SIDEBAR_CALLING': True}
 
 
-def addMenu(callback):
-  """Adds a callback to the menu builder.
-
-  The callback should return a list of menu's when called.
-  """
-  global SIDEBAR
-  SIDEBAR.append(callback)
-
-
-@soc.cache.sidebar.cache
-def getSidebar(id, user):
-  """Constructs a sidebar for the current user.
-  """
-
-  sidebar = []
-
-  for callback in SIDEBAR:
-    menus = callback(id, user)
-
-    for menu in (menus if menus else []):
-      sidebar.append(menu)
-
-  return sorted(sidebar, key=lambda x: x.get('group'))
-
 
 def getSidebarItems(params):
   """Retrieves a list of sidebar entries for this view.
--- a/app/soc/views/sitemap/sitemap.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/soc/views/sitemap/sitemap.py	Sun May 24 21:40:37 2009 +0200
@@ -22,17 +22,6 @@
   ]
 
 
-SITEMAP = []
-
-
-def addPages(pages):
-  """Adds the specified pages to the sitemap.
-  """
-
-  global SITEMAP
-  SITEMAP += pages
-
-
 def getDjangoURLPatterns(params):
   """Retrieves a list of sidebar entries for this View.
 
--- a/app/urls.py	Fri May 22 09:40:53 2009 +0200
+++ b/app/urls.py	Sun May 24 21:40:37 2009 +0200
@@ -18,15 +18,15 @@
 __authors__ = [
   '"Augie Fackler" <durin42@gmail.com>',
   '"Todd Larsen" <tlarsen@google.com>',
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
   '"Lennard de Rijk" <ljvderijk@gmail.com>',
   '"Pawel Solyga" <pawel.solyga@gmail.com>',
   ]
 
 
-from soc.views.sitemap import build
+from soc.modules import callback
 
-
-urlpatterns = build.getPatterns()
+urlpatterns = callback.getCore().getPatterns()
 
 # define the error handlers
 handler404 = 'django.views.defaults.page_not_found'