first steps to getting navigation and admin-options working again.
authorgfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Thu, 15 Jul 2010 00:53:11 +0000 (00:53 +0000)
committergfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Thu, 15 Jul 2010 00:53:11 +0000 (00:53 +0000)
git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@903 6d9bc8c9-1ec2-4278-b937-99fde70a366f

12 files changed:
.gitignore
conifer/syrup/admin.py
conifer/syrup/models.py
conifer/syrup/urls.py
conifer/syrup/views/_common.py
conifer/syrup/views/admin.py
conifer/syrup/views/courses.py
conifer/syrup/views/general.py
conifer/syrup/views/items.py
conifer/syrup/views/search.py
conifer/templates/admin/index.xhtml
conifer/templates/welcome.xhtml [deleted file]

index 74f5041..b365b13 100644 (file)
@@ -10,4 +10,5 @@ TAGS
 private_local_settings.py
 /conifer/.dired
 /conifer/local_settings.py
+/conifer/remodel.sqlite3
 *~
\ No newline at end of file
index a0c04d7..29c6e7a 100644 (file)
@@ -10,13 +10,7 @@ for m in [ServiceDesk, Group, Membership, Course,
           UserProfile, Config, Z3950Target]:
     admin.site.register(m)
 
-
-class MetadataInline(admin.StackedInline):
-    model = Metadata
-    extra = 3
-
 class ItemAdmin(admin.ModelAdmin):
     model = Item
-    inlines = [MetadataInline]
 
 admin.site.register(Item, ItemAdmin)
index 8f716ca..7028328 100644 (file)
@@ -49,7 +49,7 @@ class UserExtensionMixin(object):
     def active_instructors(cls):
         """Return a queryset of all active instructors."""
         # We are using the Django is_active flag to model activeness.
-        return cls.objects.filter(member__role='INSTR', is_active=True) \
+        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() \
index 66c50f5..74b0ef9 100644 (file)
@@ -44,8 +44,11 @@ urlpatterns = patterns('conifer.syrup.views',
 
     (r'^admin/$', 'admin_index'),
     (r'^admin/terms/' + GENERIC_REGEX, 'admin_terms'),
+    (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'),
 
     (r'^phys/$', 'phys_index'),
index 9a77e4d..f09d844 100644 (file)
@@ -20,7 +20,8 @@ import re
 import sys
 from django.forms.models import modelformset_factory
 from conifer.custom import lib_integration
-from conifer.libsystems.z3950.marcxml import marcxml_to_dictionary, marcxml_dictionary_to_dc
+from conifer.libsystems.z3950.marcxml import (marcxml_to_dictionary,
+                                              marcxml_dictionary_to_dc)
 from conifer.syrup.fuzzy_match import rank_pending_items
 from django.core.urlresolvers import reverse
 from conifer.here import HERE
@@ -45,7 +46,7 @@ try:
     except ImportError:
         sys.modules['profile'] = sys # just get something called 'profile';
                                      # it's not actually used.
-        import ply.lex              
+        import ply.lex
         import ply.yacc             # pyz3950 thinks these are toplevel modules.
         sys.modules['lex'] = ply.lex
         sys.modules['yacc'] = ply.yacc
@@ -73,7 +74,7 @@ def auth_handler(request, path):
             if request.user.is_authenticated():
                 return HttpResponseRedirect(next)
             else:
-                return g.render('auth/login.xhtml', 
+                return g.render('auth/login.xhtml',
                                 next=request.GET.get('next'))
         else:
             userid, password = request.POST['userid'], request.POST['password']
@@ -95,7 +96,8 @@ def auth_handler(request, path):
                 except models.UserProfile.DoesNotExist:
                     profile = models.UserProfile.objects.create(user=user)
                     profile.save()
-                return HttpResponseRedirect(request.POST.get('next', default_url))
+                return HttpResponseRedirect(
+                    request.POST.get('next', default_url))
     elif path == 'logout':
         logout(request)
         return HttpResponseRedirect(default_url)
@@ -119,11 +121,12 @@ def _fast_user_membership_query(user_id, course_id, where=None):
     cursor.close()
     allowed = bool(res[0][0])
     return allowed
-    
+
 def _access_denied(request, message):
     if request.user.is_anonymous():
         # then take them to login screen....
-        dest = request.META['SCRIPT_NAME'] + '/accounts/login/?next=' + request.META['PATH_INFO']
+        dest = (request.META['SCRIPT_NAME'] + \
+                    '/accounts/login/?next=' + request.META['PATH_INFO'])
         return HttpResponseRedirect(dest)
     else:
         return simple_message(_('Access denied.'), message,
@@ -141,7 +144,8 @@ def instructors_only(handler):
         if allowed:
             return handler(request, course_id, *args, **kwargs)
         else:
-            return _access_denied(request, _('Only instructors are allowed here.'))
+            return _access_denied(request,
+                                  _('Only instructors are allowed here.'))
     return hdlr
 
 # decorator
@@ -150,7 +154,7 @@ def members_only(handler):
         user = request.user
         allowed = user.is_superuser
         if not allowed:
-            course = models.Course.objects.get(pk=course_id)
+            course = models.ReadingList.objects.get(pk=course_id)
             allowed = course.access=='ANON' or \
                 (user.is_authenticated() and course.access=='LOGIN')
         if not allowed:
@@ -174,7 +178,8 @@ def admin_only(handler):
         if allowed:
             return handler(request, *args, **kwargs)
         else:
-            return _access_denied(request, _('Only administrators are allowed here.'))
+            return _access_denied(request, 
+                                  _('Only administrators are allowed here.'))
     return hdlr
 
 #decorator
@@ -200,14 +205,14 @@ def custom_500_handler(request):
     return HttpResponse(msg._container, status=501)
 
 def custom_400_handler(request):
-    msg = simple_message(_('Not found'), 
+    msg = simple_message(_('Not found'),
                           _('The page you requested could not be found'))
     return HttpResponse(msg._container, status=404)
 
 #-----------------------------------------------------------
 
 def user_filters(user):
-    """Returns a dict of filters for Item, Course, etc. querysets,
+    """Returns a dict of filters for Item, ReadingList, etc. querysets,
     based on the given user's permissions."""
     # TODO, figure out a way of EXPLAIN'ing these queries! I have no
     # idea of their complexity.
@@ -215,16 +220,18 @@ def user_filters(user):
         # then only anonymous-access courses are available.
         filters = {'items': Q(course__access='ANON'),
                    'courses': Q(access='ANON'),
-                   'instructors': Q(member__course__access='ANON'),
+                   'instructors': Q(), # TODO: do we really need a filter here?
                    }
     else:
         # logged-in users have access to courses which are of the
         # LOGIN class ('all logged-in users') or in which they
         # have explicit Member-ship.
-        filters = {'items': (Q(course__access__in=('LOGIN','ANON')) | Q(course__member__user=user)),
-                   'courses': (Q(access__in=('LOGIN','ANON')) | Q(member__user=user)),
-                   'instructors': (Q(member__course__access__in=('LOGIN','ANON')) | Q(member__course__member__user=user)),
-                   }
+        filters = {
+            'items': (Q(course__access__in=('LOGIN','ANON')) \
+                          | Q(course__member__user=user)),
+            'courses': (Q(access__in=('LOGIN','ANON')) | Q(member__user=user)),
+            'instructors': Q(), # TODO: do we really need a filter here?
+            }
     return filters
 
 #------------------------------------------------------------
index 4292c4f..fedd597 100644 (file)
@@ -9,6 +9,37 @@ def admin_index(request):
     return g.render('admin/index.xhtml')
 
 
+class CourseForm(ModelForm):
+    class Meta:
+        model = models.Course
+
+    class Index:
+        title = _('Courses')
+        all   = models.Course.objects.order_by('code', 'name').all
+        cols  = ['code', 'name', 'department']
+        links = [0, 1]
+
+    clean_name = strip_and_nonblank('code')
+    clean_name = strip_and_nonblank('name')
+
+admin_courses = generic_handler(CourseForm, decorator=admin_only)
+
+
+class ServiceDeskForm(ModelForm):
+    class Meta:
+        model = models.ServiceDesk
+
+    class Index:
+        title = _('ServiceDesks')
+        all   = models.ServiceDesk.objects.order_by('name').all
+        cols  = ['name']
+        links = [0]
+
+    clean_name = strip_and_nonblank('name')
+    clean_code = strip_and_nonblank('external_id')
+
+admin_desks = generic_handler(ServiceDeskForm, decorator=admin_only)
+
 class TermForm(ModelForm):
     class Meta:
         model = models.Term
@@ -38,49 +69,43 @@ class DeptForm(ModelForm):
 
     class Index:
         title = _('Departments')
-        all   = models.Department.objects.order_by('abbreviation').all
-        cols  = ['abbreviation', 'name']
-        links = [0,1]
+        all   = models.Department.objects.order_by('name').all
+        cols  = ['name', 'service_desk']
+        links = [0]
 
     clean_abbreviation = strip_and_nonblank('abbreviation')
     clean_name = strip_and_nonblank('name')
 
 admin_depts = generic_handler(DeptForm, decorator=admin_only)
 
-###
-# graham - zap this if it messes anything up :-)
-###
+
 class TargetForm(ModelForm):
     class Meta:
-        model = models.Target
+        model = models.Z3950Target
 
     class Index:
         title = _('Targets')
-        all   = models.Target.objects.order_by('name').all
-        cols  = ['name', 'host']
-        links = [0,1]
+        all   = models.Z3950Target.objects.order_by('name').all
+        cols  = ['name', 'host', 'database']
+        links = [0]
 
     clean_name = strip_and_nonblank('name')
     clean_host = strip_and_nonblank('host')
 
 admin_targets = generic_handler(TargetForm, decorator=admin_only)
-###
 
 
-class NewsForm(ModelForm):
+class ConfigForm(ModelForm):
     class Meta:
-        model = models.NewsItem
+        model = models.Config
 
     class Index:
-        title = _('News Items')
-        all   = models.NewsItem.objects.order_by('-id').all
-        cols  = ['id', 'subject', 'published']
-        links = [0, 1]
-
-    clean_subject = strip_and_nonblank('subject')
-    clean_body = strip_and_nonblank('body')
-
-admin_news = generic_handler(NewsForm, decorator=admin_only)
-
+        title = _('Configs')
+        all   = models.Config.objects.order_by('name').all
+        cols  = ['name', 'value']
+        links = [0]
 
+    clean_name = strip_and_nonblank('name')
+    clean_host = strip_and_nonblank('value')
 
+admin_configs = generic_handler(ConfigForm, decorator=admin_only)
index e0bc9a7..232fdad 100644 (file)
@@ -210,8 +210,8 @@ def course_invitation(request):
             return HttpResponseRedirect('.')
         try:
             # note, we only allow the passkey if access='INVIT'.
-            crs = models.Course.objects.filter(access='INVIT').get(passkey=code)
-        except models.Course.DoesNotExist:
+            crs = models.ReadingList.objects.filter(access='INVIT').get(passkey=code)
+        except models.ReadingList.DoesNotExist:
             # todo, do we need a formal logging system? Or a table for
             # invitation failures? They should be captured somehow, I
             # think. Should we temporarily disable accounts after
@@ -229,22 +229,22 @@ def course_invitation(request):
         return HttpResponseRedirect(crs.course_url())
 
 #-----------------------------------------------------------------------------
-# Course-instance handlers
+# ReadingList-instance handlers
 
 @members_only
 def course_detail(request, course_id):
-    course = get_object_or_404(models.Course, pk=course_id)
+    course = get_object_or_404(models.ReadingList, pk=course_id)
     return g.render('course_detail.xhtml', course=course)
 
 @members_only
 def course_search(request, course_id):
-    course = get_object_or_404(models.Course, pk=course_id)
+    course = get_object_or_404(models.ReadingList, pk=course_id)
     return search(request, in_course=course)
 
 @login_required
 def course_join(request, course_id):
     """Self-register into an open-registration course."""
-    course = get_object_or_404(models.Course, pk=course_id)
+    course = get_object_or_404(models.ReadingList, pk=course_id)
     if not course.is_joinable_by(request.user):
         # user should never see this.
         return simple_message(_('You cannot join this course.'), 
index 4e6dc1d..4ab6ad8 100644 (file)
@@ -9,13 +9,13 @@ import os
 #-----------------------------------------------------------------------------
 
 def welcome(request):
-    return g.render('welcome.xhtml')
+    return HttpResponseRedirect('browse/')
 
 # MARK: propose we get rid of this. We already have a 'Courses' browser.
 def open_courses(request):
     page_num = int(request.GET.get('page', 1))
     count = int(request.GET.get('count', 5))
-    paginator = Paginator(models.Course.objects.all(), count) # fixme, what filter?
+    paginator = Paginator(models.ReadingList.objects.all(), count) # fixme, what filter?
     return g.render('open_courses.xhtml', paginator=paginator,
                     page_num=page_num,
                     count=count)
@@ -27,9 +27,9 @@ def instructors(request):
     if action == 'join':
         paginator = Paginator(models.User.active_instructors(), count)
     elif action == 'drop':
-        paginator = Paginator(models.Course.objects.all(), count) # fixme, what filter?
+        paginator = Paginator(models.ReadingList.objects.all(), count) # fixme, what filter?
     else:
-        paginator = Paginator(models.Course.objects.all(), count) # fixme, what filter?
+        paginator = Paginator(models.ReadingList.objects.all(), count) # fixme, what filter?
         
     return g.render('instructors.xhtml', paginator=paginator,
                     page_num=page_num,
@@ -104,7 +104,7 @@ def browse(request, browse_option=''):
     elif browse_option == 'courses':
         # fixme, course filter should not be (active=True) but based on user identity.
         for_courses = user_filters(request.user)['courses']
-        queryset = models.Course.objects.filter(for_courses)
+        queryset = models.ReadingList.objects.filter(for_courses)
         template = 'courses.xhtml'
 
     queryset = queryset and queryset.distinct()
@@ -124,7 +124,7 @@ def instructor_detail(request, instructor_id):
     i am not sure this is the best way to go from instructor
     to course
     '''
-    courses = models.Course.objects.filter(member__user=instructor_id,
+    courses = models.ReadingList.objects.filter(member__user=instructor_id,
                                            member__role='INSTR')
     filters = user_filters(request.user)
     courses = courses.filter(filters['courses'])
@@ -146,7 +146,7 @@ def department_detail(request, department_id):
     page_num = int(request.GET.get('page', 1))
     count = int(request.GET.get('count', 5))
 
-    paginator = Paginator(models.Course.objects.
+    paginator = Paginator(models.ReadingList.objects.
         filter(department__id=department_id).
         order_by('title'), count)
 
index 0533213..1bb08d8 100644 (file)
@@ -217,11 +217,6 @@ def item_add_cat_search(request, course_id, item_id):
 
 #------------------------------------------------------------
 
-#this is used in item_edit.
-metadata_formset_class = modelformset_factory(models.Metadata, 
-                                              fields=['name','value'], 
-                                              extra=3, can_delete=True)
-
 @instructors_only
 def item_edit(request, course_id, item_id):
     course = get_object_or_404(models.Course, pk=course_id)
index c21588a..719f7b4 100644 (file)
@@ -114,7 +114,7 @@ def search(request, in_course=None, with_instructor=None):
         else:
             course_query = get_query(query_string, ['title', 'department__name'])
             # apply the search-filter and the user-filter
-            course_results = models.Course.objects.filter(course_query).filter(user_filter_for_courses)
+            course_results = models.ReadingList.objects.filter(course_query).filter(user_filter_for_courses)
             course_list = course_results.order_by('title')
             course_len = len(course_results)
 
@@ -136,7 +136,7 @@ def search(request, in_course=None, with_instructor=None):
         results_len = len(results_list)
         paginator = Paginator( results_list,
             count)
-        course_results = models.Course.objects.filter(active=True)
+        course_results = models.ReadingList.objects.filter(active=True)
         course_list = course_results.order_by('title')[0:5]
         course_len = len(course_results)
         instructor_results = models.Member.objects.filter(role='INSTR')
@@ -165,7 +165,7 @@ def zsearch(request):
     count = int(request.POST.get('count', 5))
 
     if request.GET.get('page')==None and request.method == 'GET':
-        targets_list = models.Target.objects.filter(active=True).order_by('name')
+        targets_list = models.Z3950Target.objects.filter(active=True).order_by('name')
         targets_len = len(targets_list)
         return g.render('zsearch.xhtml', **locals())
     else:
@@ -178,7 +178,7 @@ def zsearch(request):
         tquery = request.GET.get('query')
         if request.method == 'POST':
             tquery = request.POST['ztitle']
-        search_target= models.Target.objects.get(name=target)
+        search_target= models.Z3950Target.objects.get(name=target)
         conn = zoom.Connection (search_target.host, search_target.port)
         conn.databaseName = search_target.db
         conn.preferredRecordSyntax = search_target.syntax
index 2d7c4aa..1d07a30 100644 (file)
@@ -13,8 +13,11 @@ title = _('Administrative Options')
   <div class="itemadd">
   <ul>
     <li><a href="terms/">Terms</a></li>
+    <li><a href="courses/">Courses</a></li>
     <li><a href="depts/">Departments</a></li>
-    <li><a href="news/">News Items</a></li>
+    <li><a href="desks/">Service Desks</a></li>
+    <li><a href="targets/">Z39.50 Targets</a></li>
+    <li><a href="config/">Configuration settings</a></li>
     <!-- <li><a href="targets/">Z39.50 Targets</a></li> -->
   </ul>
   <!-- <ul> -->
diff --git a/conifer/templates/welcome.xhtml b/conifer/templates/welcome.xhtml
deleted file mode 100644 (file)
index 7d2827b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<?python
-title = _('Welcome!')
-news_items = models.NewsItem.objects.all().order_by('-published','-id')[0:5]
-?>
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:xi="http://www.w3.org/2001/XInclude"
-      xmlns:py="http://genshi.edgewall.org/">
-<xi:include href="master.xhtml"/>
-<head>
-  <title>${title}</title>
-</head>
-<body>
-  <div id="treepanel">
-  <p>Welcome! Please use the links above to browse the reserves, or to join and visit your course sites.</p>
-  <div class="newsitem" py:for="news in news_items">
-    <h2>${news.subject}</h2>
-    <div>${news.generated_body()}</div>
-    <div class="newsdate">posted ${news.published.strftime('%c')}
-    <span py:if="user.has_perm('change_newsitem')">&bull; <a href="admin/news/${news.id}/">edit</a></span></div>
-  </div>
-  <p py:if="user.has_perm('add_newsitem')"><a href="admin/news/0/">Add a news item</a></p>
-  </div>
-</body>
-</html>