[open-ils-commits] r396 - in servres/trunk/conifer: . syrup syrup/views (gfawcett)

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Apr 26 20:07:12 EDT 2009


Author: gfawcett
Date: 2009-04-26 20:07:11 -0400 (Sun, 26 Apr 2009)
New Revision: 396

Modified:
   servres/trunk/conifer/TODO
   servres/trunk/conifer/syrup/models.py
   servres/trunk/conifer/syrup/views/_common.py
   servres/trunk/conifer/syrup/views/courses.py
   servres/trunk/conifer/syrup/views/general.py
   servres/trunk/conifer/syrup/views/search.py
Log:
Enabled ANON courses. Search and browse results are now limited by user-permissions level.

ANON courses are courses which are open to non-authenticated
users. I'm not sure that this is a good idea yet, but it is useful for
testing.

Browsing will no longer show, for example, courses which the current
user cannot enter. Search will not return items that the current user
cannot view. This is extended to browse-instructors: if the instructor
has no accessible courses, don't bother showing the course.


Modified: servres/trunk/conifer/TODO
===================================================================
--- servres/trunk/conifer/TODO	2009-04-27 00:07:07 UTC (rev 395)
+++ servres/trunk/conifer/TODO	2009-04-27 00:07:11 UTC (rev 396)
@@ -2,14 +2,16 @@
 
 IMPORTANT:
 
+* "create course site" (not "add course")
+
+* save-sequence fails on IE6.
+
 * set up a proper issue-tracker?
 
-* CSS fixes for Internet Explorer. It looks crappy in IE.
+* need more than 10 results on physical-item search results.
 
 * if someone has item checked out, show due date/time on item-about page.
 
-* need more than 10 results on physical-item search results.
-
 * People should be able to register themselves into open courses.
   That is, actually become a member of them.
 
@@ -21,8 +23,6 @@
 
 * Send me email when my sites change?
 
-* "create course site" (not "add course")
-
 MAYBE:
 
 * Generating barcodes in emails, printable screens? (3 of 9 enough?)

Modified: servres/trunk/conifer/syrup/models.py
===================================================================
--- servres/trunk/conifer/syrup/models.py	2009-04-27 00:07:07 UTC (rev 395)
+++ servres/trunk/conifer/syrup/models.py	2009-04-27 00:07:11 UTC (rev 396)
@@ -56,7 +56,7 @@
         """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) \
-            .order_by('-last_name','-first_name')
+            .order_by('-last_name','-first_name').distinct()
     
 for k,v in [(k,v) for k,v in UserExtensionHack.__dict__.items() \
                 if not k.startswith('_')]:

Modified: servres/trunk/conifer/syrup/views/_common.py
===================================================================
--- servres/trunk/conifer/syrup/views/_common.py	2009-04-27 00:07:07 UTC (rev 395)
+++ servres/trunk/conifer/syrup/views/_common.py	2009-04-27 00:07:11 UTC (rev 396)
@@ -164,8 +164,8 @@
         allowed = user.is_superuser
         if not allowed:
             course = models.Course.objects.get(pk=course_id)
-            allowed = ((user.is_anonymous() and course.access=='ANON') or \
-                       (user.is_authenticated() and course.access=='LOGIN'))
+            allowed = course.access=='ANON' or \
+                (user.is_authenticated() and course.access=='LOGIN')
         if not allowed:
             allowed = _fast_user_membership_query(user.id, course_id)
         if allowed:
@@ -216,3 +216,26 @@
     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,
+    based on the given user's permissions."""
+    # TODO, figure out a way of EXPLAIN'ing these queries! I have no
+    # idea of their complexity.
+    if user.is_anonymous():
+        # then only anonymous-access courses are available.
+        filters = {'items': Q(course__access='ANON'),
+                   'courses': Q(access='ANON'),
+                   'instructors': Q(member__course__access='ANON'),
+                   }
+    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)),
+                   }
+    return filters

Modified: servres/trunk/conifer/syrup/views/courses.py
===================================================================
--- servres/trunk/conifer/syrup/views/courses.py	2009-04-27 00:07:07 UTC (rev 395)
+++ servres/trunk/conifer/syrup/views/courses.py	2009-04-27 00:07:11 UTC (rev 396)
@@ -91,6 +91,7 @@
     # the ones in 'models'.
     choices = [
         # note: I'm leaving ANON out for now, until we discuss it further.
+        (u'ANON', _(u'Anyone on the planet may access this site.')),
         (u'CLOSE', _(u'No students: this site is closed.')),
         (u'STUDT', _(u'Students in my course -- I will provide section numbers')),
         (u'INVIT', _(u'Students in my course -- I will share an Invitation Code with them')),

Modified: servres/trunk/conifer/syrup/views/general.py
===================================================================
--- servres/trunk/conifer/syrup/views/general.py	2009-04-27 00:07:07 UTC (rev 395)
+++ servres/trunk/conifer/syrup/views/general.py	2009-04-27 00:07:11 UTC (rev 396)
@@ -85,16 +85,19 @@
         template = 'browse_index.xhtml'
     elif browse_option == 'instructors':
         queryset = models.User.active_instructors()
+        queryset = queryset.filter(user_filters(request.user)['instructors'])
         template = 'instructors.xhtml'
     elif browse_option == 'departments':
         queryset = models.Department.objects.filter(active=True)
         template = 'departments.xhtml'
     elif browse_option == 'courses':
         # fixme, course filter should not be (active=True) but based on user identity.
-        queryset = models.Course.objects.all()
+        for_courses = user_filters(request.user)['courses']
+        queryset = models.Course.objects.filter(for_courses)
         template = 'courses.xhtml'
 
-    paginator = queryset and Paginator(queryset, count) or None # index has no queryset.
+    queryset = queryset and queryset.distinct()
+    paginator = Paginator(queryset, count)
     return g.render(template, paginator=paginator,
                     page_num=page_num,
                     count=count)
@@ -112,6 +115,8 @@
     '''
     courses = models.Course.objects.filter(member__user=instructor_id,
                                            member__role='INSTR')
+    filters = user_filters(request.user)
+    courses = courses.filter(filters['courses'])
     paginator = Paginator(courses.order_by('title'), count)
 
     '''

Modified: servres/trunk/conifer/syrup/views/search.py
===================================================================
--- servres/trunk/conifer/syrup/views/search.py	2009-04-27 00:07:07 UTC (rev 395)
+++ servres/trunk/conifer/syrup/views/search.py	2009-04-27 00:07:11 UTC (rev 396)
@@ -63,11 +63,14 @@
         # we start with an empty results_list, as a default
         results_list = models.Item.objects.filter(pk=-1)
 
+        # Next, we filter based on user permissions.
+        flt = user_filters(request.user)
+        user_filter_for_items, user_filter_for_courses = flt['items'], flt['courses'] 
+        # Note, we haven't user-filtered anything yet; we've just set
+        # up the filters.
+
         # numeric search: If the query-string is a single number, then
-        # we do an item-ID search, or a barcode search.  fixme:
-        # item-ID is not a good short-id, since the physical item may
-        # be represented in multiple Item records. We need a
-        # short-number for barcodes.
+        # we do a short-number search, or a barcode search.
 
         if re.match(r'\d+', query_string):
             # Search by short ID.
@@ -85,7 +88,13 @@
             results_list = models.Item.objects.filter(item_query)
 
         if in_course:
+            # For an in-course search, we know the user has
+            # permissions to view the course; no need for
+            # user_filter_for_items.
             results_list = results_list.filter(course=in_course)
+        else:
+            results_list = results_list.filter(user_filter_for_items)
+
         results_list = results_list.order_by('title')
         results_len = len(results_list)
         paginator = Paginator(results_list, count)
@@ -96,22 +105,21 @@
             course_list = []; course_len = 0
         else:
             course_query = get_query(query_string, ['title', 'department__name'])
-            print 'course_query'
-            print course_query
-            course_results = models.Course.objects.filter(course_query).all()
-            # course_list = models.Course.objects.filter(course_query).filter(active=True).order_by('title')[0:5]
-            course_list = course_results.order_by('title')[0:5]
-            #there might be a better way of doing this, though instr and course tables should not be expensive to query
-            #len directly on course_list will reflect limit
+            # apply the search-filter and the user-filter
+            course_results = models.Course.objects.filter(course_query).filter(user_filter_for_courses)
+            course_list = course_results.order_by('title')
             course_len = len(course_results)
 
         #instructor search
-        instr_query = get_query(query_string, ['user__last_name'])
-        instructor_results = models.Member.objects.filter(instr_query).filter(role='INSTR')
         if in_course:
-            instructor_results = instructor_results.filter(course=in_course)
-        instructor_list = instructor_results.order_by('user__last_name')[0:5]
-        instr_len = len(instructor_results)
+            instructor_list = []; instr_len = 0
+        else:
+            instr_query = get_query(query_string, ['user__last_name'])
+            instructor_results = models.Member.objects.filter(instr_query).filter(role='INSTR')
+            if in_course:
+                instructor_results = instructor_results.filter(course=in_course)
+            instructor_list = instructor_results.order_by('user__last_name')[0:5]
+            instr_len = len(instructor_results)
     elif in_course:
         # we are in a course, but have no query? Return to the course-home page.
         return HttpResponseRedirect('../')



More information about the open-ils-commits mailing list