Exemple #1
0
    def initialize(self, record_owner_name=None):
        # initialize a few helpful variables here
        self.record_viewer = self.request.user

        self.record_owner = None
        if record_owner_name:
            self.record_owner = get_object_or_404(User,
                                                  username=record_owner_name)

        # Is the current user faculty or a CCNMTL staff member
        self.is_viewer_faculty = cached_course_is_faculty(self.request.course,
                                                          self.record_viewer)

        # Can the record_owner edit the records
        self.viewing_own_records = (self.record_owner == self.record_viewer)
        self.viewing_faculty_records = (
            self.record_owner and
            cached_course_is_faculty(self.request.course, self.record_owner))

        # Does the course allow viewing other user selections?
        # The viewer can always view their own records + faculty records
        # If the viewer is faculty, they can view all records
        self.all_selections_are_visible = \
            all_selections_are_visible(self.request.course)
        self.all_items_are_visible = \
            all_items_are_visible(self.request.course)

        self.visible_authors = []
        if (not self.is_viewer_faculty and
                (not self.all_selections_are_visible or
                 not self.all_items_are_visible)):
            self.visible_authors = [self.record_viewer.id]  # me
            for user in self.request.course.faculty.all():
                self.visible_authors.append(user.id)
Exemple #2
0
    def initialize(self, record_owner_name=None):
        # initialize a few helpful variables here
        self.record_viewer = self.request.user

        self.record_owner = None
        if record_owner_name:
            self.record_owner = get_object_or_404(User,
                                                  username=record_owner_name)

        # Is the current user faculty or a CCNMTL staff member
        self.is_viewer_faculty = cached_course_is_faculty(self.request.course,
                                                          self.record_viewer)

        # Can the record_owner edit the records
        self.viewing_own_records = (self.record_owner == self.record_viewer)
        self.viewing_faculty_records = (
            self.record_owner and
            cached_course_is_faculty(self.request.course, self.record_owner))

        # Does the course allow viewing other user selections?
        # The viewer can always view their own records + faculty records
        # If the viewer is faculty, they can view all records
        self.all_selections_are_visible = \
            all_selections_are_visible(self.request.course)
        self.all_items_are_visible = \
            all_items_are_visible(self.request.course)

        self.visible_authors = []
        if (not self.is_viewer_faculty and
                (not self.all_selections_are_visible or
                 not self.all_items_are_visible)):
            self.visible_authors = [self.record_viewer.id]  # me
            for user in self.request.course.faculty.all():
                self.visible_authors.append(user.id)
Exemple #3
0
    def dispatch(self, *args, **kwargs):
        # initialize a few helpful variables here
        self.record_viewer = self.request.user

        self.record_owner = None
        record_owner_name = kwargs.pop("record_owner_name", None)
        if record_owner_name:
            self.record_owner = get_object_or_404(User, username=record_owner_name)

        # Is the current user faculty or a CCNMTL staff member
        self.is_viewer_faculty = cached_course_is_faculty(self.request.course, self.record_viewer)

        # Can the record_owner edit the records
        self.viewing_own_records = self.record_owner == self.record_viewer
        self.viewing_faculty_records = self.record_owner and cached_course_is_faculty(
            self.request.course, self.record_owner
        )

        # Does the course allow viewing other user selections?
        # The viewer can always view their own records + faculty records
        # If the viewer is faculty, they can view all records
        self.all_selections_are_visible = all_selections_are_visible(self.request.course)

        self.visible_authors = []
        if not self.all_selections_are_visible and not self.is_viewer_faculty:
            self.visible_authors = [self.record_viewer.id]  # me
            for user in self.request.course.faculty.all():
                self.visible_authors.append(user.id)

        return super(RestrictedMaterialsMixin, self).dispatch(*args, **kwargs)
Exemple #4
0
    def dispatch(self, *args, **kwargs):
        # initialize a few helpful variables here
        self.record_viewer = self.request.user

        self.record_owner = None
        record_owner_name = kwargs.pop('record_owner_name', None)
        if record_owner_name:
            self.record_owner = get_object_or_404(User,
                                                  username=record_owner_name)

        # Is the current user faculty or a CCNMTL staff member
        self.is_viewer_faculty = cached_course_is_faculty(
            self.request.course, self.record_viewer)

        # Can the record_owner edit the records
        self.viewing_own_records = (self.record_owner == self.record_viewer)
        self.viewing_faculty_records = (self.record_owner
                                        and cached_course_is_faculty(
                                            self.request.course,
                                            self.record_owner))

        # Does the course allow viewing other user selections?
        # The viewer can always view their own records + faculty records
        # If the viewer is faculty, they can view all records
        self.all_selections_are_visible = \
            all_selections_are_visible(self.request.course)

        self.visible_authors = []
        if not self.all_selections_are_visible and not self.is_viewer_faculty:
            self.visible_authors = [self.record_viewer.id]  # me
            for user in self.request.course.faculty.all():
                self.visible_authors.append(user.id)

        return super(RestrictedMaterialsMixin, self).dispatch(*args, **kwargs)
Exemple #5
0
    def apply_authorization_limits(self, request, object_list):
        course = self.course or request.course

        if (all_selections_are_visible(course) or
                cached_course_is_faculty(course, request.user)):
            return self.get_unrestricted(request, object_list, course)
        else:
            return self.get_restricted(request, object_list, course)
Exemple #6
0
    def apply_authorization_limits(self, request, object_list):
        course = self.course or request.course

        if (all_selections_are_visible(course) or
                cached_course_is_faculty(course, request.user)):
            return self.get_unrestricted(request, object_list, course)
        else:
            return self.get_restricted(request, object_list, course)
Exemple #7
0
 def __init__(self, *args, **kwargs):
     r = super(DashboardSettingsForm, self).__init__(*args, **kwargs)
     self.fields['publish_to_world'].initial = \
         allow_public_compositions(self.instance)
     self.fields['see_eachothers_items'].initial = \
         all_items_are_visible(self.instance)
     self.fields['see_eachothers_selections'].initial = \
         all_selections_are_visible(self.instance)
     self.fields['allow_item_download'].initial = \
         allow_item_download(self.instance)
     self.fields['allow_roster_changes'].initial = \
         allow_roster_changes(self.instance)
     return r
Exemple #8
0
 def __init__(self, *args, **kwargs):
     r = super(DashboardSettingsForm, self).__init__(*args, **kwargs)
     self.fields['publish_to_world'].initial = \
         allow_public_compositions(self.instance)
     self.fields['homepage_title'].initial = \
         course_information_title(self.instance)
     self.fields['see_eachothers_items'].initial = \
         all_items_are_visible(self.instance)
     self.fields['see_eachothers_selections'].initial = \
         all_selections_are_visible(self.instance)
     self.fields['allow_item_download'].initial = \
         allow_item_download(self.instance)
     self.fields['allow_roster_changes'].initial = \
         allow_roster_changes(self.instance)
     return r
Exemple #9
0
    def test_post_disabled_selection_visibility(self):
        self.client.login(username=self.instructor_one.username,
                          password='******')
        data = {course_details.ITEM_VISIBILITY_KEY: 0}

        response = self.client.post('/dashboard/settings/', data)
        self.assertEquals(response.status_code, 302)

        # unchanged from defaults
        self.assertEquals(course_information_title(self.sample_course),
                          'From Your Instructor')
        self.assertFalse(allow_public_compositions(self.sample_course))

        # updated
        self.assertFalse(all_items_are_visible(self.sample_course))
        self.assertFalse(all_selections_are_visible(self.sample_course))
Exemple #10
0
    def test_post(self):
        self.assertTrue(
            self.client.login(username=self.instructor_one.username,
                              password='******'))
        data = {
            course_details.COURSE_INFORMATION_TITLE_KEY: "Foo",
            course_details.SELECTION_VISIBILITY_KEY: 0,
            course_details.ITEM_VISIBILITY_KEY: 0,
            course_details.ALLOW_PUBLIC_COMPOSITIONS_KEY: 1
        }

        response = self.client.post('/dashboard/settings/', data)
        self.assertEquals(response.status_code, 302)
        self.assertEquals(course_information_title(self.sample_course), "Foo")
        self.assertTrue(allow_public_compositions(self.sample_course))
        self.assertFalse(all_items_are_visible(self.sample_course))
        self.assertFalse(all_selections_are_visible(self.sample_course))
Exemple #11
0
    def __init__(self, *args, **kwargs):
        r = super(DashboardSettingsForm, self).__init__(*args, **kwargs)
        self.fields['publish_to_world'].initial = \
            allow_public_compositions(self.instance)
        self.fields['homepage_title'].initial = \
            course_information_title(self.instance)
        self.fields['see_eachothers_items'].initial = \
            all_items_are_visible(self.instance)
        self.fields['see_eachothers_selections'].initial = \
            all_selections_are_visible(self.instance)
        self.fields['allow_item_download'].initial = \
            allow_item_download(self.instance)
        lti_context = LTICourseContext.objects.filter(
            group=self.instance.group.id,
            faculty_group=self.instance.faculty_group.id).first()
        self.fields['lti_integration'].initial = \
            (lti_context and lti_context.enable)

        return r
Exemple #12
0
    def __init__(self, request, *args, **kwargs):
        super(ProjectForm, self).__init__(*args, **kwargs)

        lst = [(u.id, get_public_name(u, request))
               for u in request.course.user_set.all()]
        self.fields['participants'].choices = sorted(
            lst, key=lambda participant: participant[1])
        self.fields['participants'].widget.attrs = {
            'id': "id_participants_%s" % self.instance.id
        }

        project = kwargs['instance']
        if project:
            # set initial publish value
            col = project.get_collaboration()
            if col:
                self.initial['publish'] = col.policy_record.policy_name
        else:
            self.instance = None

        choices = self.get_choices(request, project)
        self.fields['publish'].choices = choices

        # response view policy. limit choices if there is no project
        # or the project is a selection assignment
        if (not project or not (
                project.is_composition() or project.is_sequence())):
            choices = [RESPONSE_VIEW_NEVER]
            if all_selections_are_visible(request.course):
                choices.append(RESPONSE_VIEW_SUBMITTED)
                choices.append(RESPONSE_VIEW_ALWAYS)
            self.fields['response_view_policy'].choices = choices

        self.fields['participants'].required = False
        self.fields['body'].required = False
        self.fields['submit'].required = False
        self.fields['publish'].required = False

        # for structured collaboration
        self.fields['title'].widget.attrs['maxlength'] = 80
Exemple #13
0
    def __init__(self, request, *args, **kwargs):
        super(ProjectForm, self).__init__(*args, **kwargs)

        lst = [(u.id, get_public_name(u, request))
               for u in request.course.user_set.all()]
        self.fields['participants'].choices = sorted(
            lst, key=lambda participant: participant[1])
        self.fields['participants'].widget.attrs = {
            'id': "id_participants_%s" % self.instance.id
        }

        project = kwargs['instance']
        if project:
            # set initial publish value
            col = project.get_collaboration()
            if col:
                self.initial['publish'] = col.policy_record.policy_name
        else:
            self.instance = None

        choices = self.get_choices(request, project)
        self.fields['publish'].choices = choices

        # response view policy. limit choices if there is no project
        # or the project is a selection assignment
        if (not project
                or not (project.is_composition() or project.is_sequence())):
            choices = [RESPONSE_VIEW_NEVER]
            if all_selections_are_visible(request.course):
                choices.append(RESPONSE_VIEW_SUBMITTED)
                choices.append(RESPONSE_VIEW_ALWAYS)
            self.fields['response_view_policy'].choices = choices

        self.fields['participants'].required = False
        self.fields['body'].required = False
        self.fields['submit'].required = False
        self.fields['publish'].required = False

        # for structured collaboration
        self.fields['title'].widget.attrs['maxlength'] = 80
Exemple #14
0
    def apply_limits(self, request, object_list, exclude_global=True):
        if request.user.is_authenticated():
            if exclude_global:
                # only request user's global annotations
                object_list = object_list.exclude(~Q(author=request.user),
                                                  range1__isnull=True)

            # Make sure the requesting user is allowed to see this note
            invisible = []
            courses = {}
            for note in object_list.select_related('asset__course'):
                course = note.asset.course

                # Cache this out per course/user. It's just too slow otherwise
                if not course.id in courses.keys():
                    courses[course.id] = {'whitelist': None}
                    is_faculty = cached_course_is_faculty(course, request.user)
                    if (not course_details.all_selections_are_visible(course)
                            and not is_faculty):
                        courses[course.id]['whitelist'] = list(course.faculty)
                        courses[course.id]['whitelist'].append(request.user)

                if not cached_course_is_member(course, request.user):
                    invisible.append(note.id)
                elif (courses[course.id]['whitelist']
                      and not note.author in courses[course.id]['whitelist']):
                    # apply per course limitations
                    # the user or a faculty member must be the selection author
                    invisible.append(note.id)

            return object_list.exclude(id__in=invisible).order_by('id')
        elif request.public:
            # attribute "public" set on request when requesting a
            # public_to_world essay. all notes are public by default
            return object_list.order_by('id')
        else:
            return []
Exemple #15
0
    def apply_limits(self, request, object_list, exclude_global=True):
        if request.user.is_authenticated():
            if exclude_global:
                # only request user's global annotations
                object_list = object_list.exclude(~Q(author=request.user),
                                                  range1__isnull=True)

            # Make sure the requesting user is allowed to see this note
            invisible = []
            courses = {}
            for note in object_list.select_related('asset__course'):
                course = note.asset.course

                # Cache this out per course/user. It's just too slow otherwise
                if not course.id in courses.keys():
                    courses[course.id] = {'whitelist': None}
                    is_faculty = cached_course_is_faculty(course, request.user)
                    if (not course_details.all_selections_are_visible(course)
                            and not is_faculty):
                        courses[course.id]['whitelist'] = list(course.faculty)
                        courses[course.id]['whitelist'].append(request.user)

                if not cached_course_is_member(course, request.user):
                    invisible.append(note.id)
                elif (courses[course.id]['whitelist'] and
                        not note.author in courses[course.id]['whitelist']):
                    # apply per course limitations
                    # the user or a faculty member must be the selection author
                    invisible.append(note.id)

            return object_list.exclude(id__in=invisible).order_by('id')
        elif request.public:
            # attribute "public" set on request when requesting a
            # public_to_world essay. all notes are public by default
            return object_list.order_by('id')
        else:
            return []
Exemple #16
0
def mediathread_activity_by_course(request):
    """STAFF ONLY reporting of entire application activity """
    if not request.user.is_staff:
        return HttpResponseForbidden("forbidden")

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = \
        'attachment; filename=mediathread_activity_by_course.csv'
    writer = csv.writer(response)
    headers = ['Id', 'Title', 'Instructor', 'Course String',
               'Term', 'Year', 'Section', 'Course Number', 'School',
               'Students', 'Items', 'Selections',
               'Compositions', 'Assignments', 'Discussions',
               'Public To World Compositions',
               'All Selections Visible']
    writer.writerow(headers)

    rows = []
    for c in Course.objects.all().order_by('-id'):
        if (c.faculty_group is None or
            (not (c.faculty_group.name.startswith('t1') or
                  c.faculty_group.name.startswith('t2') or
                  c.faculty_group.name.startswith('t3')))):
            continue

        row = []
        row.append(c.id)
        row.append(c.title)

        if 'instructor' in c.details():
            row.append(c.details()['instructor'].value)
        else:
            row.append('')

        course_string = c.faculty_group.name
        row.append(course_string)

        bits = c.faculty_group.name.split('.')
        row.append(bits[0])  # term
        row.append(bits[1][1:])  # year
        row.append(bits[2])  # section
        row.append(bits[3])  # courseNo
        row.append(bits[4])  # school
        row.append(len(c.students))

        items = Asset.objects.filter(course=c)
        row.append(len(items))

        selections = SherdNote.objects.filter(asset__course=c)
        row.append(len(selections))

        compositions = 0
        assignments = 0

        projects = Project.objects.filter(course=c)
        for p in projects:
            if p.visibility_short() == 'Assignment':
                assignments += 1
            else:
                compositions += 1

        row.append(compositions)
        row.append(assignments)
        try:
            row.append(len(get_course_discussions(c)))
        except Collaboration.DoesNotExist:
            row.append(0)

        row.append(course_details.allow_public_compositions(c))
        row.append(course_details.all_selections_are_visible(c))

        rows.append(row)

    for row in rows:
        try:
            writer.writerow(row)
        except:
            pass

    return response
Exemple #17
0
    def get(self, request, *args, **kwargs):
        headers = [
            'Id', 'Created', 'Title', 'Instructor', 'Course String', 'Term',
            'Year', 'Section', 'Course Number', 'School', 'Students',
            '% Active Students', 'Total Items', 'Student Items',
            'Student Selections', 'Compositions', 'Assignments', 'Responses',
            'Discussions', 'Public To World Compositions',
            'All Selections Visible', '# of Active Tags', '% Using Tags',
            '% Items Tagged', '% Selections Tagged',
            '# of Active Vocabulary Terms', '% Using Vocabulary',
            '% Items Classified', '% Selections Classified'
        ]

        rows = []
        # Hard-coding date until we have time to code a proper ui
        qs = Course.objects.filter(created_at__year__gte='2019',
                                   created_at__month__gte='6')
        for the_course in qs.order_by('-id'):
            row = []
            row.append(the_course.id)
            row.append(the_course.created_at.strftime(self.date_fmt))
            row.append(the_course.title)

            if 'instructor' in the_course.details():
                row.append(the_course.details()['instructor'].value)
            else:
                row.append('')

            course_string = the_course.faculty_group.name
            row.append(course_string)

            bits = the_course.faculty_group.name.split('.')
            if len(bits) >= 5:
                row.append(bits[0])  # term
                row.append(bits[1][1:])  # year
                row.append(bits[2])  # section
                row.append(bits[3])  # courseNo
                row.append(bits[4])  # school
            else:
                row.append('')
                row.append('')
                row.append('')
                row.append('')
                row.append('')

            students = self.all_students(the_course)
            row.append(len(students))
            row.append(self.active_students(students))

            items = Asset.objects.filter(course=the_course)
            row.append(len(items))

            # student work only
            student_ids = students.values('id')
            items = Asset.objects.filter(course=the_course,
                                         author__id__in=student_ids)
            row.append(len(items))

            selections = SherdNote.objects.filter(asset__course=the_course,
                                                  author__id__in=student_ids)
            row.append(len(selections))

            compositions, assignments, responses = \
                self.project_count(the_course)
            row.append(compositions)
            row.append(assignments)
            row.append(responses)
            row.append(self.discussion_count(the_course))
            row.append(course_details.allow_public_compositions(the_course))
            row.append(course_details.all_selections_are_visible(the_course))

            # Breakdown tags & vocabulary terms by item & selection
            if len(selections) > 0:
                item_notes = selections.filter(range1=None, range2=None)
                sel_notes = selections.exclude(range1=None, range2=None)

                tags = Tag.objects.usage_for_queryset(selections)
                row.append(len(tags))  # # of Active Tags',

                tagged = selections.filter(tags__isnull=False).values('author')
                tag_users = tagged.distinct().count()
                if len(students) > 0:
                    # % users using tags
                    row.append(float(tag_users) / len(students) * 100)
                else:
                    row.append(0)

                # '% Items Tagged', '% Selections Tagged'
                t = item_notes.filter(tags__isnull=False).exclude(
                    tags__exact='')
                row.append(float(len(t)) / len(selections) * 100)
                t = sel_notes.filter(tags__isnull=False).exclude(
                    tags__exact='')
                row.append(float(len(t)) / len(selections) * 100)

                # Vocabulary
                related = TermRelationship.objects.filter(
                    term__vocabulary__course=the_course,
                    sherdnote__id__in=selections.values_list('id', flat=True))

                # '# of Active Vocabulary Terms'
                q = related.aggregate(Count('term', distinct=True))
                active_terms = q['term__count']
                q = related.aggregate(Count('sherdnote__author',
                                            distinct=True))
                vocab_users = q['sherdnote__author__count']

                row.append(active_terms)
                if len(students) > 0:
                    # % users
                    row.append(float(vocab_users) / len(students) * 100)
                else:
                    row.append(0)

                related_ids = related.values_list('sherdnote__id', flat=True)
                items = len(
                    SherdNote.objects.filter(id__in=related_ids,
                                             range1=None,
                                             range2=None))
                row.append(float(items) / len(selections) * 100)  # % Items
                sel = len(
                    SherdNote.objects.filter(id__in=related_ids).exclude(
                        range1=None, range2=None))
                row.append(float(sel) / len(selections) * 100)  # % Selections

            rows.append(row)

        return self.render_csv_response('mediathread_activity_by_course',
                                        headers, rows)
Exemple #18
0
def mediathread_activity_by_course(request):
    """STAFF ONLY reporting of entire application activity """
    if not request.user.is_staff:
        return HttpResponseForbidden("forbidden")

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = \
        'attachment; filename=mediathread_activity_by_course.csv'
    writer = csv.writer(response)
    headers = [
        'Id', 'Title', 'Instructor', 'Course String', 'Term', 'Year',
        'Section', 'Course Number', 'School', 'Students', '% Active Students',
        'Items', 'Selections', 'Compositions', 'Assignments', 'Discussions',
        'Public To World Compositions', 'All Selections Visible',
        '# of Active Tags', '% Using Tags', '% Items Tagged',
        '% Selections Tagged', '# of Active Vocabulary Terms',
        '% Using Vocabulary', '% Items Classified', '% Selections Classified'
    ]
    writer.writerow(headers)

    rows = []
    for the_course in Course.objects.all().order_by('-id'):
        if (the_course.faculty_group is None
                or (not (the_course.faculty_group.name.startswith('t1')
                         or the_course.faculty_group.name.startswith('t2')
                         or the_course.faculty_group.name.startswith('t3')))):
            continue

        row = []
        row.append(the_course.id)
        row.append(the_course.title)

        if 'instructor' in the_course.details():
            row.append(the_course.details()['instructor'].value)
        else:
            row.append('')

        course_string = the_course.faculty_group.name
        row.append(course_string)

        bits = the_course.faculty_group.name.split('.')
        row.append(bits[0])  # term
        row.append(bits[1][1:])  # year
        row.append(bits[2])  # section
        row.append(bits[3])  # courseNo
        row.append(bits[4])  # school

        students = the_course.group.user_set.all()
        if the_course.faculty_group:
            ids = the_course.faculty_group.user_set.values('id')
            students = students.exclude(id__in=ids)
        row.append(len(students))

        if len(students) > 0:
            active = students.filter(
                Q(projects__isnull=False)
                | Q(sherdnote__isnull=False)).distinct()
            row.append(float(len(active)) / len(students) * 100)
        else:
            row.append(0)

        items = Asset.objects.filter(course=the_course)
        row.append(len(items))

        selections = SherdNote.objects.filter(asset__course=the_course)
        row.append(len(selections))

        compositions = 0
        assignments = 0

        projects = Project.objects.filter(course=the_course)
        for project in projects:
            if project.visibility_short() == 'Assignment':
                assignments += 1
            else:
                compositions += 1

        row.append(compositions)
        row.append(assignments)
        try:
            discussions = get_course_discussions(the_course)
            row.append(len(discussions))
            '# of Discussion Items', '% participating in Discussions',
        except Collaboration.DoesNotExist:
            row.append(0)

        row.append(course_details.allow_public_compositions(the_course))
        row.append(course_details.all_selections_are_visible(the_course))

        # Breakdown tags & vocabulary terms by item & selection
        if len(selections) > 0:
            item_notes = selections.filter(range1=None, range2=None)
            sel_notes = selections.exclude(range1=None, range2=None)

            tags = Tag.objects.usage_for_queryset(selections)
            row.append(len(tags))  # # of Active Tags',
            tag_users = len(
                selections.filter(tags__isnull=False).distinct('author'))
            if len(students) > 0:
                # % users using tags
                row.append(float(tag_users) / len(students) * 100)
            else:
                row.append(0)

            # '% Items Tagged', '% Selections Tagged'
            t = item_notes.filter(tags__isnull=False).exclude(tags__exact='')
            row.append(float(len(t)) / len(selections) * 100)
            t = sel_notes.filter(tags__isnull=False).exclude(tags__exact='')
            row.append(float(len(t)) / len(selections) * 100)

            # Vocabulary
            vocab = Vocabulary.objects.get_for_object(the_course)
            content_type = ContentType.objects.get_for_model(SherdNote)
            related = TermRelationship.objects.filter(
                term__vocabulary__in=vocab,
                content_type=content_type,
                object_id__in=selections.values_list('id'))

            # '# of Active Vocabulary Terms'
            q = related.aggregate(Count('term', distinct=True))
            active_terms = q['term__count']
            vocab_users = len(
                SherdNote.objects.filter(id__in=related.values_list(
                    'object_id')).distinct('author'))

            row.append(active_terms)
            if len(students) > 0:
                row.append(float(vocab_users) / len(students) * 100)  # % users
            else:
                row.append(0)

            related_ids = related.values_list('object_id')
            items = len(
                SherdNote.objects.filter(id__in=related_ids,
                                         range1=None,
                                         range2=None))
            row.append(float(items) / len(selections) * 100)  # % Items
            sel = len(
                SherdNote.objects.filter(id__in=related_ids).exclude(
                    range1=None, range2=None))
            row.append(float(sel) / len(selections) * 100)  # % Selections

        rows.append(row)

    for row in rows:
        try:
            writer.writerow(row)
        except:
            pass

    return response
Exemple #19
0
    def get(self, request, *args, **kwargs):
        headers = ['Id', 'Title', 'Instructor', 'Course String',
                   'Term', 'Year', 'Section', 'Course Number', 'School',
                   'Students', '% Active Students',
                   'Items', 'Selections',
                   'Compositions', 'Assignments', 'Discussions',
                   'Public To World Compositions', 'All Selections Visible',
                   '# of Active Tags', '% Using Tags',
                   '% Items Tagged', '% Selections Tagged',
                   '# of Active Vocabulary Terms', '% Using Vocabulary',
                   '% Items Classified', '% Selections Classified']

        rows = []
        for the_course in Course.objects.all().order_by('-id'):
            if not self.include_course(the_course):
                continue

            row = []
            row.append(the_course.id)
            row.append(the_course.title)

            if 'instructor' in the_course.details():
                row.append(the_course.details()['instructor'].value)
            else:
                row.append('')

            course_string = the_course.faculty_group.name
            row.append(course_string)

            bits = the_course.faculty_group.name.split('.')
            row.append(bits[0])  # term
            row.append(bits[1][1:])  # year
            row.append(bits[2])  # section
            row.append(bits[3])  # courseNo
            row.append(bits[4])  # school

            students = self.all_students(the_course)
            row.append(len(students))
            row.append(self.active_students(students))

            items = Asset.objects.filter(course=the_course)
            row.append(len(items))

            selections = SherdNote.objects.filter(asset__course=the_course)
            row.append(len(selections))

            compositions, assignments = self.project_count(the_course)
            row.append(compositions)
            row.append(assignments)
            row.append(self.discussion_count(the_course))
            row.append(course_details.allow_public_compositions(the_course))
            row.append(course_details.all_selections_are_visible(the_course))

            # Breakdown tags & vocabulary terms by item & selection
            if len(selections) > 0:
                item_notes = selections.filter(range1=None, range2=None)
                sel_notes = selections.exclude(range1=None, range2=None)

                tags = Tag.objects.usage_for_queryset(selections)
                row.append(len(tags))  # # of Active Tags',

                tagged = selections.filter(tags__isnull=False).values('author')
                tag_users = tagged.distinct().count()
                if len(students) > 0:
                    # % users using tags
                    row.append(float(tag_users) / len(students) * 100)
                else:
                    row.append(0)

                # '% Items Tagged', '% Selections Tagged'
                t = item_notes.filter(tags__isnull=False).exclude(
                    tags__exact='')
                row.append(float(len(t)) / len(selections) * 100)
                t = sel_notes.filter(tags__isnull=False).exclude(
                    tags__exact='')
                row.append(float(len(t)) / len(selections) * 100)

                # Vocabulary
                vocab = Vocabulary.objects.get_for_object(the_course)
                content_type = ContentType.objects.get_for_model(SherdNote)
                related = TermRelationship.objects.filter(
                    term__vocabulary__in=vocab,
                    content_type=content_type,
                    object_id__in=selections.values_list('id'))

                # '# of Active Vocabulary Terms'
                q = related.aggregate(Count('term', distinct=True))
                active_terms = q['term__count']
                termed = SherdNote.objects.filter(
                    id__in=related.values_list('object_id')).values('author')
                vocab_users = termed.distinct().count()

                row.append(active_terms)
                if len(students) > 0:
                    # % users
                    row.append(float(vocab_users) / len(students) * 100)
                else:
                    row.append(0)

                related_ids = related.values_list('object_id')
                items = len(SherdNote.objects.filter(id__in=related_ids,
                                                     range1=None, range2=None))
                row.append(float(items) / len(selections) * 100)  # % Items
                sel = len(SherdNote.objects.filter(id__in=related_ids).exclude(
                    range1=None, range2=None))
                row.append(float(sel) / len(selections) * 100)  # % Selections

            rows.append(row)

        return self.render_csv_response(
            'mediathread_activity_by_course', headers, rows)
Exemple #20
0
def render_assets(request, record_owner, assets):
    course = request.course
    logged_in_user = request.user

    # Is the current user faculty OR staff
    is_faculty = cached_course_is_faculty(course, logged_in_user)

    # Can the record_owner edit the records
    viewing_own_records = (record_owner == logged_in_user)
    viewing_faculty_records = record_owner and course.is_faculty(record_owner)

    # Allow the logged in user to add assets to his composition
    citable = request.GET.get('citable', '') == 'true'

    # Does the course allow viewing other user selections?
    owner_selections_are_visible = (
        course_details.all_selections_are_visible(course) or
        viewing_own_records or viewing_faculty_records or is_faculty)

    # Spew out json for the assets
    if request.GET.get('annotations', '') == 'true':
        resource = AssetResource(owner_selections_are_visible,
                                 record_owner,
                                 {'editable': viewing_own_records,
                                  'citable': citable})
    else:
        resource = AssetSummaryResource({'editable': viewing_own_records,
                                         'citable': citable})

    asset_json = resource.render_list(request, assets)

    active_filters = {}
    for k, val in request.GET.items():
        if (k == 'tag' or k == 'modified' or k.startswith('vocabulary-')):
            active_filters[k] = val

    user_resource = UserResource()

    # #todo -- figure out a cleaner way to do this. Ugli-ness
    # Collate tag set & vocabulary set for the result set.
    # Get all visible notes for the returned asset set
    # These notes may include global annotations for all users,
    # whereas the rendered set will not
    active_asset_ids = [a['id'] for a in asset_json]
    active_notes = []
    if record_owner:
        if owner_selections_are_visible:
            active_notes = SherdNote.objects.filter(
                asset__course=course, asset__id__in=active_asset_ids,
                author__id=record_owner.id)
    else:
        if all_selections_are_visible(course) or is_faculty:
            # Display all tags for the asset set including globals
            active_notes = SherdNote.objects.filter(
                asset__course=course, asset__id__in=active_asset_ids)
        else:
            whitelist = [f.id for f in course.faculty]
            whitelist.append(request.user.id)
            active_notes = SherdNote.objects.filter(
                asset__course=course,
                asset__id__in=active_asset_ids,
                author__id__in=whitelist)

    tags = []
    if len(active_notes) > 0:
        tags = Tag.objects.usage_for_queryset(active_notes)
        tags.sort(lambda a, b: cmp(a.name.lower(), b.name.lower()))

    active_vocabulary = []
    note_ids = [n.id for n in active_notes]
    content_type = ContentType.objects.get_for_model(SherdNote)
    term_resource = TermResource()
    for v in Vocabulary.objects.get_for_object(request.course):
        vocabulary = {
            'id': v.id,
            'display_name': v.display_name,
            'term_set': []
        }
        related = TermRelationship.objects.filter(term__vocabulary=v,
                                                  content_type=content_type,
                                                  object_id__in=note_ids)

        terms = []
        for r in related:
            if r.term.display_name not in terms:
                the_term = term_resource.render_one(request, r.term)
                vocabulary['term_set'].append(the_term)
                terms.append(r.term.display_name)

        active_vocabulary.append(vocabulary)

    # Assemble the context
    data = {'assets': asset_json,
            'active_tags': TagResource().render_list(request, tags),
            'active_filters': active_filters,
            'active_vocabulary': active_vocabulary,
            'space_viewer': user_resource.render_one(request, logged_in_user),
            'editable': viewing_own_records,
            'citable': citable,
            'is_faculty': is_faculty}

    if record_owner:
        data['space_owner'] = user_resource.render_one(request, record_owner)

    json_stream = simplejson.dumps(data, indent=2)
    return HttpResponse(json_stream, mimetype='application/json')
Exemple #21
0
def mediathread_activity_by_course(request):
    """STAFF ONLY reporting of entire application activity """
    if not request.user.is_staff:
        return HttpResponseForbidden("forbidden")

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = \
        'attachment; filename=mediathread_activity_by_course.csv'
    writer = csv.writer(response)
    headers = ['Id', 'Title', 'Instructor', 'Course String',
               'Term', 'Year', 'Section', 'Course Number', 'School',
               'Students', '% Active Students',
               'Items', 'Selections',
               'Compositions', 'Assignments', 'Discussions',
               'Public To World Compositions', 'All Selections Visible',
               '# of Active Tags', '% Using Tags',
               '% Items Tagged', '% Selections Tagged',
               '# of Active Vocabulary Terms', '% Using Vocabulary',
               '% Items Classified', '% Selections Classified']
    writer.writerow(headers)

    rows = []
    for the_course in Course.objects.all().order_by('-id'):
        if (the_course.faculty_group is None or
            (not (the_course.faculty_group.name.startswith('t1') or
                  the_course.faculty_group.name.startswith('t2') or
                  the_course.faculty_group.name.startswith('t3')))):
            continue

        row = []
        row.append(the_course.id)
        row.append(the_course.title)

        if 'instructor' in the_course.details():
            row.append(the_course.details()['instructor'].value)
        else:
            row.append('')

        course_string = the_course.faculty_group.name
        row.append(course_string)

        bits = the_course.faculty_group.name.split('.')
        row.append(bits[0])  # term
        row.append(bits[1][1:])  # year
        row.append(bits[2])  # section
        row.append(bits[3])  # courseNo
        row.append(bits[4])  # school

        students = the_course.group.user_set.all()
        if the_course.faculty_group:
            ids = the_course.faculty_group.user_set.values('id')
            students = students.exclude(id__in=ids)
        row.append(len(students))

        if len(students) > 0:
            active = students.filter(Q(projects__isnull=False) |
                                     Q(sherdnote__isnull=False)).distinct()
            row.append(float(len(active)) / len(students) * 100)
        else:
            row.append(0)

        items = Asset.objects.filter(course=the_course)
        row.append(len(items))

        selections = SherdNote.objects.filter(asset__course=the_course)
        row.append(len(selections))

        compositions = 0
        assignments = 0

        projects = Project.objects.filter(course=the_course)
        for project in projects:
            if project.visibility_short() == 'Assignment':
                assignments += 1
            else:
                compositions += 1

        row.append(compositions)
        row.append(assignments)
        try:
            discussions = get_course_discussions(the_course)
            row.append(len(discussions))
            '# of Discussion Items', '% participating in Discussions',
        except Collaboration.DoesNotExist:
            row.append(0)

        row.append(course_details.allow_public_compositions(the_course))
        row.append(course_details.all_selections_are_visible(the_course))

        # Breakdown tags & vocabulary terms by item & selection
        if len(selections) > 0:
            item_notes = selections.filter(range1=None, range2=None)
            sel_notes = selections.exclude(range1=None, range2=None)

            tags = Tag.objects.usage_for_queryset(selections)
            row.append(len(tags))  # # of Active Tags',
            tag_users = len(
                selections.filter(tags__isnull=False).distinct('author'))
            if len(students) > 0:
                # % users using tags
                row.append(float(tag_users) / len(students) * 100)
            else:
                row.append(0)

            # '% Items Tagged', '% Selections Tagged'
            t = item_notes.filter(tags__isnull=False).exclude(tags__exact='')
            row.append(float(len(t)) / len(selections) * 100)
            t = sel_notes.filter(tags__isnull=False).exclude(tags__exact='')
            row.append(float(len(t)) / len(selections) * 100)

            # Vocabulary
            vocab = Vocabulary.objects.get_for_object(the_course)
            content_type = ContentType.objects.get_for_model(SherdNote)
            related = TermRelationship.objects.filter(
                term__vocabulary__in=vocab,
                content_type=content_type,
                object_id__in=selections.values_list('id'))

            # '# of Active Vocabulary Terms'
            q = related.aggregate(Count('term', distinct=True))
            active_terms = q['term__count']
            vocab_users = len(SherdNote.objects.filter(
                id__in=related.values_list('object_id')).distinct(
                'author'))

            row.append(active_terms)
            if len(students) > 0:
                row.append(float(vocab_users) / len(students) * 100)  # % users
            else:
                row.append(0)

            related_ids = related.values_list('object_id')
            items = len(SherdNote.objects.filter(id__in=related_ids,
                                                 range1=None, range2=None))
            row.append(float(items) / len(selections) * 100)  # % Items
            sel = len(SherdNote.objects.filter(id__in=related_ids).exclude(
                range1=None, range2=None))
            row.append(float(sel) / len(selections) * 100)  # % Selections

        rows.append(row)

    for row in rows:
        try:
            writer.writerow(row)
        except:
            pass

    return response
Exemple #22
0
    def get(self, request, *args, **kwargs):
        headers = ['Id', 'Created', 'Title', 'Instructor', 'Course String',
                   'Term', 'Year', 'Section', 'Course Number', 'School',
                   'Students', '% Active Students',
                   'Total Items', 'Student Items', 'Student Selections',
                   'Compositions', 'Assignments', 'Responses', 'Discussions',
                   'Public To World Compositions', 'All Selections Visible',
                   '# of Active Tags', '% Using Tags',
                   '% Items Tagged', '% Selections Tagged',
                   '# of Active Vocabulary Terms', '% Using Vocabulary',
                   '% Items Classified', '% Selections Classified']

        rows = []
        # Hard-coding date until we have time to code a proper ui
        qs = Course.objects.filter(created_at__year__gte='2018')
        for the_course in qs.order_by('-id'):
            row = []
            row.append(the_course.id)
            row.append(the_course.created_at.strftime(self.date_fmt))
            row.append(the_course.title)

            if 'instructor' in the_course.details():
                row.append(the_course.details()['instructor'].value)
            else:
                row.append('')

            course_string = the_course.faculty_group.name
            row.append(course_string)

            bits = the_course.faculty_group.name.split('.')
            if len(bits) >= 5:
                row.append(bits[0])  # term
                row.append(bits[1][1:])  # year
                row.append(bits[2])  # section
                row.append(bits[3])  # courseNo
                row.append(bits[4])  # school
            else:
                row.append('')
                row.append('')
                row.append('')
                row.append('')
                row.append('')

            students = self.all_students(the_course)
            row.append(len(students))
            row.append(self.active_students(students))

            items = Asset.objects.filter(course=the_course)
            row.append(len(items))

            # student work only
            student_ids = students.values('id')
            items = Asset.objects.filter(
                course=the_course, author__id__in=student_ids)
            row.append(len(items))

            selections = SherdNote.objects.filter(
                asset__course=the_course, author__id__in=student_ids)
            row.append(len(selections))

            compositions, assignments, responses = \
                self.project_count(the_course)
            row.append(compositions)
            row.append(assignments)
            row.append(responses)
            row.append(self.discussion_count(the_course))
            row.append(course_details.allow_public_compositions(the_course))
            row.append(course_details.all_selections_are_visible(the_course))

            # Breakdown tags & vocabulary terms by item & selection
            if len(selections) > 0:
                item_notes = selections.filter(range1=None, range2=None)
                sel_notes = selections.exclude(range1=None, range2=None)

                tags = Tag.objects.usage_for_queryset(selections)
                row.append(len(tags))  # # of Active Tags',

                tagged = selections.filter(tags__isnull=False).values('author')
                tag_users = tagged.distinct().count()
                if len(students) > 0:
                    # % users using tags
                    row.append(float(tag_users) / len(students) * 100)
                else:
                    row.append(0)

                # '% Items Tagged', '% Selections Tagged'
                t = item_notes.filter(tags__isnull=False).exclude(
                    tags__exact='')
                row.append(float(len(t)) / len(selections) * 100)
                t = sel_notes.filter(tags__isnull=False).exclude(
                    tags__exact='')
                row.append(float(len(t)) / len(selections) * 100)

                # Vocabulary
                related = TermRelationship.objects.filter(
                    term__vocabulary__course=the_course,
                    sherdnote__id__in=selections.values_list('id', flat=True))

                # '# of Active Vocabulary Terms'
                q = related.aggregate(Count('term', distinct=True))
                active_terms = q['term__count']
                q = related.aggregate(
                    Count('sherdnote__author', distinct=True))
                vocab_users = q['sherdnote__author__count']

                row.append(active_terms)
                if len(students) > 0:
                    # % users
                    row.append(float(vocab_users) / len(students) * 100)
                else:
                    row.append(0)

                related_ids = related.values_list('sherdnote__id', flat=True)
                items = len(SherdNote.objects.filter(id__in=related_ids,
                                                     range1=None, range2=None))
                row.append(float(items) / len(selections) * 100)  # % Items
                sel = len(SherdNote.objects.filter(id__in=related_ids).exclude(
                    range1=None, range2=None))
                row.append(float(sel) / len(selections) * 100)  # % Selections

            rows.append(row)

        return self.render_csv_response(
            'mediathread_activity_by_course', headers, rows)
Exemple #23
0
def render_assets(request, record_owner, assets):
    course = request.course
    logged_in_user = request.user

    # Is the current user faculty OR staff
    is_faculty = cached_course_is_faculty(course, logged_in_user)

    # Can the record_owner edit the records
    viewing_own_records = (record_owner == logged_in_user)
    viewing_faculty_records = record_owner and course.is_faculty(record_owner)

    # Allow the logged in user to add assets to his composition
    citable = request.GET.get('citable', '') == 'true'

    # Does the course allow viewing other user selections?
    owner_selections_are_visible = (
        course_details.all_selections_are_visible(course)
        or viewing_own_records or viewing_faculty_records or is_faculty)

    # Spew out json for the assets
    if request.GET.get('annotations', '') == 'true':
        resource = AssetResource(owner_selections_are_visible, record_owner, {
            'editable': viewing_own_records,
            'citable': citable
        })
    else:
        resource = AssetSummaryResource({
            'editable': viewing_own_records,
            'citable': citable
        })

    asset_json = resource.render_list(request, assets)

    active_filters = {}
    for key, val in request.GET.items():
        if (key == 'tag' or key == 'modified'
                or key.startswith('vocabulary-')):
            active_filters[key] = val

    user_resource = UserResource()

    # #todo -- figure out a cleaner way to do this. Ugli-ness
    # Collate tag set & vocabulary set for the result set.
    # Get all visible notes for the returned asset set
    # These notes may include global annotations for all users,
    # whereas the rendered set will not
    active_asset_ids = [a['id'] for a in asset_json]
    active_notes = []
    if record_owner:
        if owner_selections_are_visible:
            active_notes = SherdNote.objects.filter(
                asset__course=course,
                asset__id__in=active_asset_ids,
                author__id=record_owner.id)
    else:
        if all_selections_are_visible(course) or is_faculty:
            # Display all tags for the asset set including globals
            active_notes = SherdNote.objects.filter(
                asset__course=course, asset__id__in=active_asset_ids)
        else:
            whitelist = [f.id for f in course.faculty]
            whitelist.append(request.user.id)
            active_notes = SherdNote.objects.filter(
                asset__course=course,
                asset__id__in=active_asset_ids,
                author__id__in=whitelist)

    tags = []
    if len(active_notes) > 0:
        tags = Tag.objects.usage_for_queryset(active_notes)
        tags.sort(lambda a, b: cmp(a.name.lower(), b.name.lower()))

    active_vocabulary = []
    note_ids = [n.id for n in active_notes]
    content_type = ContentType.objects.get_for_model(SherdNote)
    term_resource = TermResource()
    for vocab in Vocabulary.objects.get_for_object(request.course):
        vocabulary = {
            'id': vocab.id,
            'display_name': vocab.display_name,
            'term_set': []
        }
        related = TermRelationship.objects.filter(term__vocabulary=vocab,
                                                  content_type=content_type,
                                                  object_id__in=note_ids)

        terms = []
        for rel in related:
            if rel.term.display_name not in terms:
                the_term = term_resource.render_one(request, rel.term)
                vocabulary['term_set'].append(the_term)
                terms.append(rel.term.display_name)

        active_vocabulary.append(vocabulary)

    # Assemble the context
    data = {
        'assets': asset_json,
        'active_tags': TagResource().render_list(request, tags),
        'active_filters': active_filters,
        'active_vocabulary': active_vocabulary,
        'space_viewer': user_resource.render_one(request, logged_in_user),
        'editable': viewing_own_records,
        'citable': citable,
        'is_faculty': is_faculty
    }

    if record_owner:
        data['space_owner'] = user_resource.render_one(request, record_owner)

    json_stream = simplejson.dumps(data, indent=2)
    return HttpResponse(json_stream, mimetype='application/json')
 def test_all_selections_are_visible(self):
     # default
     self.assertTrue(all_selections_are_visible(self.sample_course))
 def test_all_selections_are_visible(self):
     # default
     self.assertTrue(all_selections_are_visible(self.sample_course))
Exemple #26
0
def mediathread_activity_by_course(request):
    """STAFF ONLY reporting of entire application activity """
    if not request.user.is_staff:
        return HttpResponseForbidden("forbidden")

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = \
        'attachment; filename=mediathread_activity_by_course.csv'
    writer = csv.writer(response)
    headers = [
        'Id', 'Title', 'Instructor', 'Course String', 'Term', 'Year',
        'Section', 'Course Number', 'School', 'Students', 'Items',
        'Selections', 'Compositions', 'Assignments', 'Discussions',
        'Public To World Compositions', 'All Selections Visible'
    ]
    writer.writerow(headers)

    rows = []
    for the_course in Course.objects.all().order_by('-id'):
        if (the_course.faculty_group is None
                or (not (the_course.faculty_group.name.startswith('t1')
                         or the_course.faculty_group.name.startswith('t2')
                         or the_course.faculty_group.name.startswith('t3')))):
            continue

        row = []
        row.append(the_course.id)
        row.append(the_course.title)

        if 'instructor' in the_course.details():
            row.append(the_course.details()['instructor'].value)
        else:
            row.append('')

        course_string = the_course.faculty_group.name
        row.append(course_string)

        bits = the_course.faculty_group.name.split('.')
        row.append(bits[0])  # term
        row.append(bits[1][1:])  # year
        row.append(bits[2])  # section
        row.append(bits[3])  # courseNo
        row.append(bits[4])  # school
        row.append(len(the_course.students))

        items = Asset.objects.filter(course=the_course)
        row.append(len(items))

        selections = SherdNote.objects.filter(asset__course=the_course)
        row.append(len(selections))

        compositions = 0
        assignments = 0

        projects = Project.objects.filter(course=the_course)
        for project in projects:
            if project.visibility_short() == 'Assignment':
                assignments += 1
            else:
                compositions += 1

        row.append(compositions)
        row.append(assignments)
        try:
            row.append(len(get_course_discussions(the_course)))
        except Collaboration.DoesNotExist:
            row.append(0)

        row.append(course_details.allow_public_compositions(the_course))
        row.append(course_details.all_selections_are_visible(the_course))

        rows.append(row)

    for row in rows:
        try:
            writer.writerow(row)
        except:
            pass

    return response