minor UI tweaks; introduced hook system for miscellaneous customizations.
authorgfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Thu, 15 Jul 2010 00:53:40 +0000 (00:53 +0000)
committergfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Thu, 15 Jul 2010 00:53:40 +0000 (00:53 +0000)
The hook system is experimental; as the name suggests, it's a
mechanism for declaring and implementing hooks into various parts of
the application. Currently, I've just added one hook for determining
which users should be entitled to create new ReadingLists. We'll see
how it plays out.

git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@906 6d9bc8c9-1ec2-4278-b937-99fde70a366f

conifer/integration/_hooksystem.py [new file with mode: 0644]
conifer/integration/hooks.py [new file with mode: 0644]
conifer/syrup/models.py
conifer/syrup/urls.py
conifer/syrup/views/__init__.py
conifer/syrup/views/courses.py
conifer/templates/my_courses.xhtml
conifer/templates/tabbar.xhtml

diff --git a/conifer/integration/_hooksystem.py b/conifer/integration/_hooksystem.py
new file mode 100644 (file)
index 0000000..43cb9ef
--- /dev/null
@@ -0,0 +1,36 @@
+# TODO: decide whether or not to use this!
+
+import warnings
+
+__all__ = ['hook', 'callhook', 'callhook_required', 'gethook']
+
+__HOOKS = {}
+
+def __register_hook(name, func):
+    assert isinstance(name, basestring)
+    assert callable(func)
+    if name in __HOOKS:
+        warnings.warn('redefining hook %r (%r)' % (name, func))
+    __HOOKS[name] = func
+    return func
+
+def hook(*args):
+    if isinstance(args[0], basestring):
+        return lambda f: __register_hook(args[0], f)
+    else:
+        f = args[0]
+        return __register_hook(f.__name__, f)
+
+def gethook(name, default=None):
+    return __HOOKS.get(name, default)
+
+def callhook_required(name, *args, **kwargs):
+    f = __HOOKS.get(name)
+    assert f, 'implementation for hook %r required but not found' % name
+    return f(*args, **kwargs)
+
+def callhook(name, *args, **kwargs):
+    f = __HOOKS.get(name)
+    if f:
+        return f(*args, **kwargs)
+
diff --git a/conifer/integration/hooks.py b/conifer/integration/hooks.py
new file mode 100644 (file)
index 0000000..81a2405
--- /dev/null
@@ -0,0 +1,8 @@
+from conifer.integration._hooksystem import *
+
+#----------------------------------------------------------------------
+# Your hooks go here.
+
+# @hook
+# def can_create_reading_lists(user):
+#     ...
index d5773e2..b880eea 100644 (file)
@@ -8,8 +8,8 @@ import re
 import random
 from django.utils import simplejson
 from conifer.middleware import genshi_locals
-
 # campus and library integration
+from conifer.integration._hooksystem import *
 from django.conf import settings
 campus = settings.CAMPUS_INTEGRATION
 # TODO: fixme, not sure if conifer.custom is a good parent.
@@ -42,8 +42,12 @@ class BaseModel(m.Model):
 # candidate).
 
 class UserExtensionMixin(object):
-    def courses(self):
-        return Course.objects.filter(member__user=self.id)
+    def reading_lists(self):
+        return ReadingList.objects.filter(group__membership__user=self.id)
+
+    def can_create_reading_lists(self):
+        return self.is_staff or \
+            bool(callhook('can_create_reading_lists', self))
 
     @classmethod
     def active_instructors(cls):
@@ -52,6 +56,8 @@ class UserExtensionMixin(object):
         return cls.objects.filter(membership__role='INSTR', is_active=True) \
             .order_by('-last_name','-first_name').distinct()
 
+
+
 for k,v in [(k,v) for k,v in UserExtensionMixin.__dict__.items() \
                 if not k.startswith('_')]:
     setattr(User, k, v)
@@ -65,6 +71,7 @@ class UserProfile(BaseModel):
 
     # When we add email notices for new items, this is how we'll set
     # the preference, and how far back we'll need to look.
+
     wants_email_notices = m.BooleanField(default=False)
     last_email_notice   = m.DateTimeField(
         default=datetime.now, blank=True, null=True)
@@ -290,7 +297,8 @@ class Group(BaseModel):
     # external_id) is unique forall external_id != NULL.
 
     reading_list = m.ForeignKey(ReadingList)
-    external_id = m.CharField(default=None, null=True, blank=True,
+    external_id = m.CharField(null=True, blank=True,
+                              db_index=True,
                               max_length=2048)
 
     def __unicode__(self):
index 74b0ef9..39c8729 100644 (file)
@@ -47,7 +47,6 @@ urlpatterns = patterns('conifer.syrup.views',
     (r'^admin/desks/' + GENERIC_REGEX, 'admin_desks'),
     (r'^admin/courses/' + GENERIC_REGEX, 'admin_courses'),
     (r'^admin/depts/' + GENERIC_REGEX, 'admin_depts'),
-    (r'^admin/news/' + GENERIC_REGEX, 'admin_news'),
     (r'^admin/config/' + GENERIC_REGEX, 'admin_configs'),
     (r'^admin/targets/' + GENERIC_REGEX, 'admin_targets'),
 
index 59d8190..0974800 100644 (file)
@@ -1,3 +1,4 @@
+from conifer.integration import hooks
 from general import *
 from courses import *
 from items import *
index 232fdad..e4b85ba 100644 (file)
@@ -38,7 +38,7 @@ if COURSE_CODE_LIST:
     
 @login_required
 def add_new_course(request):
-    if not request.user.has_perm('add_course'):
+    if not request.user.can_create_reading_lists():
         return _access_denied(_('You are not allowed to create course sites.'))
     return _add_or_edit_course(request)
 
index 115d72c..0ea3a93 100644 (file)
@@ -1,5 +1,5 @@
 <?python
-title = _('My Courses')
+title = _('My Reserves')
 ?>
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
@@ -12,18 +12,18 @@ title = _('My Courses')
   <h1>${title}</h1>
   <?python
     if user.is_authenticated():
-        my_courses = user.courses()
+        my_courses = user.reading_lists()
     else:
         my_courses = []
   ?>
-  <p py:if="not my_courses">You are not part of any courses at this time.</p>
+  <p py:if="not my_courses">You are not part of any course reserves at this time.</p>
   <p py:for="course in my_courses" style="font-size: large;">
     <a href="${course.id}/">${course.list_display()}</a>
   </p>
   <div class="gap"/>
   <div class="itemadd">
-  <p py:if="user.has_perm('add_course')"><a href="new/">Create a new course site</a></p>
-  <p><a href="invitation/">Join a course using an Invitation Code</a></p>
+  <p py:if="user.can_create_reading_lists()"><a href="new/">Create a new course reserves list</a></p>
+  <p><a href="invitation/">Join a reserves list using an Invitation Code</a></p>
   </div>
 </body>
 </html>
index eda139d..52ffe00 100644 (file)
@@ -7,9 +7,9 @@
     use one for now
 -->
 <ul id="tabbar">
-  <li><a href="${ROOT}/">Home</a></li>
+  <!-- <li><a href="${ROOT}/">Home</a></li> -->
   <li><a href="${ROOT}/browse/">Browse</a></li>
-  <li class="active"><a href="${ROOT}/course/">My Courses</a></li>
+  <li class="active"><a href="${ROOT}/course/">My Reserves</a></li>
   <div py:strip="True"
        py:if="request.user.is_staff">
     <li><a href="${ROOT}/admin/">Admin Options</a></li>