Exemple #1
0
    def test_create_discussions(self):
        self.setup_sample_course()
        self.setup_alternate_course()

        self.create_discussion(self.sample_course, self.instructor_one)
        self.create_discussion(self.alt_course, self.alt_instructor)

        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))
        self.assertEquals(discussions[0].title, "Sample Course Discussion")

        discussions = get_course_discussions(self.alt_course)
        self.assertEquals(1, len(discussions))
        self.assertEquals(discussions[0].title, "Alternate Course Discussion")
Exemple #2
0
    def test_create_discussions(self):
        self.setup_sample_course()
        self.setup_alternate_course()

        self.create_discussion(self.sample_course, self.instructor_one)
        self.create_discussion(self.alt_course, self.alt_instructor)

        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))
        self.assertEquals(discussions[0].title, "Sample Course Discussion")

        discussions = get_course_discussions(self.alt_course)
        self.assertEquals(1, len(discussions))
        self.assertEquals(discussions[0].title, "Alternate Course Discussion")
Exemple #3
0
 def discussion_count(self, the_course):
     try:
         discussions = get_course_discussions(the_course)
         return len(discussions)
         '# of Discussion Items', '% participating in Discussions',
     except Collaboration.DoesNotExist:
         return 0
Exemple #4
0
    def test_clear_student_only(self):
        url = reverse('course-delete-materials')
        data = {'clear_all': False, 'username': self.superuser.username}

        self.client.login(username=self.superuser.username, password='******')
        self.switch_course(self.client, self.sample_course)

        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 302)
        self.assertTrue('All requested materials were deleted'
                        in response.cookies['messages'].value)

        assets = Asset.objects.filter(course=self.sample_course)
        self.assertEquals(assets.count(), 1)
        self.assertEquals(assets.first(), self.faculty_asset)

        notes = SherdNote.objects.filter(asset__course=self.sample_course)
        self.assertEquals(notes.count(), 1)
        self.assertEquals(notes.first(), self.faculty_note1)

        projects = Project.objects.filter(course=self.sample_course)
        self.assertEquals(projects.count(), 2)
        self.assertTrue(self.faculty_composition in projects.all())
        self.assertTrue(self.assignment in projects.all())

        self.assertEquals(get_course_discussions(self.sample_course),
                          [self.discussion])
        comments = ThreadedComment.objects.filter(parent=self.discussion)
        self.assertEquals(comments.count(), 0)

        self.verify_alt_course_materials()
Exemple #5
0
    def get_context_data(self, **kwargs):
        context = super(CourseDetailView, self).get_context_data(**kwargs)
        course = context.get('object')

        qs = ExternalCollection.objects.filter(course=course)
        collections = qs.filter(uploader=False).order_by('title')
        uploader = qs.filter(uploader=True).first()

        owners = []
        if (course.is_member(self.request.user) and
            (self.request.user.is_staff or
             self.request.user.has_perm('assetmgr.can_upload_for'))):
            owners = UserResource().render_list(self.request, course.members)

        context.update({
            'course': course,
            'classwork_owner': self.request.user,
            'information_title': course_information_title(course),
            'faculty_feed': Project.objects.faculty_compositions(
                course, self.request.user),
            'is_faculty': cached_course_is_faculty(course, self.request.user),
            'discussions': get_course_discussions(course),
            'collections': collections,
            'uploader': uploader,
            'can_upload': False,
            'owners': owners,
        })
        return context
Exemple #6
0
    def test_comments_post(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussion = get_course_discussions(self.sample_course)[0]

        url = reverse('comments-post-comment')
        data = {
            u'comment': [u'posted'],
            u'parent': [discussion.id],  # threadedcomment
            u'name': [],
            u'title': [u''],
            u'url': [u'']
        }

        frm = CommentSecurityForm(target_object=discussion.content_object)
        data.update(frm.generate_security_data())

        self.client.login(username=self.instructor_one.username,
                          password='******')
        self.switch_course(self.client, self.sample_course)
        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 302)

        comment_id = re.search(r'\d+', response.url).group()
        obj = Comment.objects.get(id=comment_id)
        self.assertEquals(obj.comment, 'posted')
        self.assertEquals(obj.content_object, discussion.content_object)
        self.assertEquals(obj.user_name, 'Instructor One')
Exemple #7
0
    def test_comment_save(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussion = get_course_discussions(self.sample_course)[0]

        data = {
            u'comment': [u'update'],
            u'name': [u''],
            u'parent': [u''],
            u'title': [u''],
            u'url': [u''],
            u'object_pk': [discussion.id],
            u'content_type': [u'structuredcollaboration.collaboration'],
        }

        url = reverse('comment-save', args=[discussion.id])
        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 302)  # login required

        self.client.login(username=self.instructor_one.username,
                          password='******')
        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 405)  # course required

        self.switch_course(self.client, self.sample_course)
        response = self.client.post(url, data, HTTP_ACCEPT='text/html')
        self.assertEquals(response.status_code, 200)

        discussion.refresh_from_db()
        self.assertEquals(discussion.comment, 'update')
Exemple #8
0
    def test_comments_post(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussion = get_course_discussions(self.sample_course)[0]

        url = reverse('comments-post-comment')
        data = {
            u'comment': [u'posted'],
            u'parent': [discussion.id],  # threadedcomment
            u'name': [],
            u'title': [u''],
            u'url': [u'']
        }

        frm = CommentSecurityForm(target_object=discussion.content_object)
        data.update(frm.generate_security_data())

        self.client.login(username=self.instructor_one.username,
                          password='******')
        self.switch_course(self.client, self.sample_course)
        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 302)

        comment_id = re.search(r'\d+', response.url).group()
        obj = Comment.objects.get(id=comment_id)
        self.assertEquals(obj.comment, 'posted')
        self.assertEquals(obj.content_object, discussion.content_object)
        self.assertEquals(obj.user_name, 'Instructor One')
    def test_private_student_faculty(self):
        policy = PrivateStudentAndFaculty()

        course = self.sample_course

        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        collaboration = Collaboration.objects.get_for_object(discussions[0])

        user = self.student_one
        self.assertFalse(policy.read(collaboration, course, user))
        self.assertFalse(policy.edit(collaboration, course, user))
        self.assertFalse(policy.manage(collaboration, course, user))
        self.assertFalse(policy.delete(collaboration, course, user))

        user = self.instructor_one
        self.assertTrue(policy.read(collaboration, course, user))
        self.assertTrue(policy.edit(collaboration, course, user))
        self.assertTrue(policy.manage(collaboration, course, user))
        self.assertTrue(policy.delete(collaboration, course, user))

        user = self.student_two
        self.assertFalse(policy.read(collaboration, course, user))
        self.assertFalse(policy.edit(collaboration, course, user))
        self.assertFalse(policy.manage(collaboration, course, user))
        self.assertFalse(policy.delete(collaboration, course, user))
Exemple #10
0
 def discussion_count(self, the_course):
     try:
         discussions = get_course_discussions(the_course)
         return len(discussions)
         '# of Discussion Items', '% participating in Discussions',
     except Collaboration.DoesNotExist:
         return 0
Exemple #11
0
    def form_valid(self, form):
        # delete the requested materials
        notes = SherdNote.objects.filter(asset__course=self.request.course)
        assets = Asset.objects.filter(course=self.request.course)
        projects = Project.objects.filter(course=self.request.course)

        if not form.cleaned_data['clear_all']:
            # exclude assets, projects & notes authored by faculty
            faculty = self.request.course.faculty_group.user_set.all()
            assets = assets.exclude(author__in=faculty)
            projects = projects.exclude(author__in=faculty)
            notes = notes.exclude(author__in=faculty)

        notes.delete()
        assets.delete()
        projects.delete()

        # Clear all discussions. The root comment will be preserved.
        discussions = get_course_discussions(self.request.course)
        parents = [d.id for d in discussions]
        comments = ThreadedComment.objects.filter(parent_id__in=parents)
        comments.delete()

        # @todo - kill all unreferenced tags

        messages.add_message(self.request, messages.INFO,
                             'All requested materials were deleted')

        return super(CourseDeleteMaterialsView, self).form_valid(form)
Exemple #12
0
    def test_comment_save(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussion = get_course_discussions(self.sample_course)[0]

        data = {
            u'comment': [u'update'],
            u'name': [u''],
            u'parent': [u''],
            u'title': [u''],
            u'url': [u''],
            u'object_pk': [discussion.id],
            u'content_type': [u'structuredcollaboration.collaboration'],
        }

        url = reverse('comment-save', args=[discussion.id])
        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 302)  # login required

        self.client.login(username=self.instructor_one.username,
                          password='******')
        response = self.client.post(url, data)
        self.assertEquals(response.status_code, 405)  # course required

        self.switch_course(self.client, self.sample_course)
        response = self.client.post(url, data, HTTP_ACCEPT='text/html')
        self.assertEquals(response.status_code, 200)

        discussion.refresh_from_db()
        self.assertEquals(discussion.comment, 'update')
Exemple #13
0
def mediathread_activity_by_school(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_school.csv'
    writer = csv.writer(response)
    headers = [
        'School', 'Items', 'Selections', 'Compositions', 'Assignments',
        'Discussions'
    ]
    writer.writerow(headers)

    rows = {}
    for the_course in Course.objects.all().order_by('-id'):
        if 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

        bits = the_course.faculty_group.name.split('.')
        school = bits[4]

        if school not in rows:
            row = [school, 0, 0, 0, 0, 0]
            rows[school] = row

        items = Asset.objects.filter(course=the_course)
        rows[school][1] += len(items)

        selections = SherdNote.objects.filter(asset__course=the_course)
        rows[school][2] += 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

        rows[school][3] += compositions
        rows[school][4] += assignments
        try:
            rows[school][5] += len(get_course_discussions(the_course))
        except Collaboration.DoesNotExist:
            pass  # no discussions exist, that's ok

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

    return response
Exemple #14
0
    def test_view_discussions(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))

        request = RequestFactory().get('/discussion/delete/', {})
        request.user = self.instructor_one
        request.course = self.sample_course
        request.collaboration_context, created = \
            Collaboration.objects.get_or_create(
                content_type=ContentType.objects.get_for_model(Course),
                object_pk=str(self.sample_course.pk))

        discussions = get_course_discussions(self.sample_course)
        response = discussion_view(request, discussions[0].id)
        self.assertEquals(response.status_code, 200)
Exemple #15
0
def mediathread_activity_by_school(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_school.csv'
    writer = csv.writer(response)
    headers = ['School', 'Items', 'Selections',
               'Compositions', 'Assignments', 'Discussions']
    writer.writerow(headers)

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

        bits = c.faculty_group.name.split('.')
        school = bits[4]

        if not school in rows:
            row = [school, 0, 0, 0, 0, 0]
            rows[school] = row

        items = Asset.objects.filter(course=c)
        rows[school][1] += len(items)

        selections = SherdNote.objects.filter(asset__course=c)
        rows[school][2] += 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

        rows[school][3] += compositions
        rows[school][4] += assignments
        try:
            rows[school][5] += len(get_course_discussions(c))
        except Collaboration.DoesNotExist:
            pass  # no discussions exist, that's ok

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

    return response
Exemple #16
0
    def verify_alt_course_materials(self):
        # alt course assets, notes & projects are intact
        assets = Asset.objects.filter(course=self.alt_course)
        self.assertEquals(self.alt_asset, assets.first())
        notes = SherdNote.objects.filter(asset__course=self.alt_course)
        self.assertEquals(self.alt_note, notes.first())
        projects = Project.objects.filter(course=self.alt_course)
        self.assertEquals(self.alt_composition, projects.first())

        self.assertEquals(get_course_discussions(self.alt_course),
                          [self.alt_discussion])
        comments = ThreadedComment.objects.filter(parent=self.alt_discussion)
        self.assertEquals(self.alt_comment, comments.first())
Exemple #17
0
def deprecated_course_detail_view(request, course_pk):
    try:
        course = get_object_or_404(Course, pk=course_pk)
        request.course = course
        request.session[SESSION_KEY] = course
    except Course.DoesNotExist:
        return HttpResponseRedirect('/accounts/login/')

    logged_in_user = request.user
    classwork_owner = request.user  # Viewing your own work by default
    if 'username' in request.GET:
        user_name = request.GET['username']
        in_course_or_404(user_name, request.course)
        classwork_owner = get_object_or_404(User, username=user_name)

    qs = ExternalCollection.objects.filter(course=request.course)
    collections = qs.filter(uploader=False).order_by('title')
    uploader = qs.filter(uploader=True).first()

    owners = []
    if (request.course.is_member(logged_in_user)
            and (logged_in_user.is_staff
                 or logged_in_user.has_perm('assetmgr.can_upload_for'))):
        owners = UserResource().render_list(request, request.course.members)

    context = {
        'classwork_owner':
        classwork_owner,
        'information_title':
        course_information_title(course),
        'faculty_feed':
        Project.objects.faculty_compositions(course, logged_in_user),
        'is_faculty':
        cached_course_is_faculty(course, logged_in_user),
        'discussions':
        get_course_discussions(course),
        'msg':
        request.GET.get('msg', ''),
        'view':
        request.GET.get('view', ''),
        'collections':
        collections,
        'uploader':
        uploader,
        'can_upload':
        course_details.can_upload(request.user, request.course),
        'owners':
        owners
    }

    return context
Exemple #18
0
    def test_delete_discussions(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))

        discussion = discussions[0]
        discussion_id = discussions[0].id
        ctype = ContentType.objects.get(model='threadedcomment',
                                        app_label='threadedcomments')
        coll = Collaboration.objects.get(content_type=ctype,
                                         object_pk=discussion_id)
        self.assertEquals(coll.content_object, discussion)

        url = reverse('discussion-delete', args=[discussion_id])

        # anonymous
        response = self.client.post(url, {})
        self.assertEquals(response.status_code, 302)

        # non-faculty
        self.client.login(username=self.student_one.username, password='******')
        response = self.client.post(url, {})
        self.assertEquals(response.status_code, 403)

        # faculty
        self.client.login(username=self.instructor_one.username,
                          password='******')
        self.switch_course(self.client, self.sample_course)
        response = self.client.post(url, {})
        self.assertEquals(response.status_code, 302)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(0, len(discussions))

        with self.assertRaises(Collaboration.DoesNotExist):
            Collaboration.objects.get(content_type=ctype,
                                      object_pk=discussion_id)
Exemple #19
0
    def test_delete_discussions(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))

        discussion = discussions[0]
        discussion_id = discussions[0].id
        ctype = ContentType.objects.get(model='threadedcomment',
                                        app_label='threadedcomments')
        coll = Collaboration.objects.get(content_type=ctype,
                                         object_pk=str(discussion_id))
        self.assertEquals(coll.content_object, discussion)

        url = reverse('discussion-delete', args=[discussion_id])

        # anonymous
        response = self.client.post(url, {})
        self.assertEquals(response.status_code, 302)

        # non-faculty
        self.client.login(username=self.student_one.username, password='******')
        response = self.client.post(url, {})
        self.assertEquals(response.status_code, 403)

        # faculty
        self.client.login(username=self.instructor_one.username,
                          password='******')
        self.switch_course(self.client, self.sample_course)
        response = self.client.post(url, {})
        self.assertEquals(response.status_code, 302)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(0, len(discussions))

        with self.assertRaises(Collaboration.DoesNotExist):
            Collaboration.objects.get(content_type=ctype,
                                      object_pk=str(discussion_id))
Exemple #20
0
def triple_homepage(request):
    if not request.course:
        return HttpResponseRedirect('/accounts/login/')

    logged_in_user = request.user
    classwork_owner = request.user  # Viewing your own work by default
    if 'username' in request.GET:
        user_name = request.GET['username']
        in_course_or_404(user_name, request.course)
        classwork_owner = get_object_or_404(User, username=user_name)

    course = request.course

    collections = ExternalCollection.objects.filter(
        course=request.course, uploader=False).order_by('title')
    uploader = ExternalCollection.objects.filter(course=request.course,
                                                 uploader=True).first()

    owners = []
    if (in_course(logged_in_user.username, request.course) and
        (logged_in_user.is_staff or
         logged_in_user.has_perm('assetmgr.can_upload_for'))):
        owners = UserResource().render_list(request, request.course.members)

    context = {
        'classwork_owner': classwork_owner,
        "information_title": course_information_title(course),
        'faculty_feed': Project.objects.faculty_compositions(course,
                                                             logged_in_user),
        'is_faculty': course.is_faculty(logged_in_user),
        'discussions': get_course_discussions(course),
        'msg': request.GET.get('msg', ''),
        'view': request.GET.get('view', ''),
        'collections': collections,
        'uploader': uploader,
        'can_upload': course_details.can_upload(request.user, request.course),
        'owners': owners
    }

    if getattr(settings, 'DJANGOSHERD_FLICKR_APIKEY', None):
        # MUST only contain string values for now!!
        # (see templates/assetmgr/bookmarklet.js to see why or fix)
        context['bookmarklet_vars'] = {
            'flickr_apikey': settings.DJANGOSHERD_FLICKR_APIKEY
        }

    return context
Exemple #21
0
    def form_valid(self, form):
        # delete the requested materials
        notes = SherdNote.objects.filter(asset__course=self.request.course)
        assets = Asset.objects.filter(course=self.request.course)
        projects = Project.objects.filter(course=self.request.course)

        if not form.cleaned_data['clear_all']:
            # exclude assets, projects & notes authored by faculty
            faculty = self.request.course.faculty_group.user_set.all()
            assets = assets.exclude(author__in=faculty)
            projects = projects.exclude(author__in=faculty)
            notes = notes.exclude(author__in=faculty)

        # delete all the media on CUNIX first
        (url, secret) = self.get_delete_endpoint()
        if url:
            for a in assets:
                if a.upload_references() == 1:
                    self.delete_uploaded_media(url, secret, a)

        notes.delete()
        assets.delete()
        projects.delete()

        # Clear all discussions. The root comment will be preserved.
        discussions = get_course_discussions(self.request.course)
        parents = [d.id for d in discussions]
        comments = ThreadedComment.objects.filter(parent_id__in=parents)
        comments.delete()

        # @todo - kill all unreferenced tags

        if 'delete-course' in form.data:
            messages.add_message(
                self.request, messages.INFO,
                u'{} and requested materials were deleted'.format(
                    self.request.course.title))
            self.request.course.delete()
            self.success_url = '/?unset_course'
        else:
            self.success_url = reverse('course-delete-materials',
                                       args=[self.request.course.pk])
            messages.add_message(self.request, messages.INFO,
                                 'All requested materials were deleted')

        return super(CourseDeleteMaterialsView, self).form_valid(form)
Exemple #22
0
    def form_valid(self, form):
        # delete the requested materials
        notes = SherdNote.objects.filter(asset__course=self.request.course)
        assets = Asset.objects.filter(course=self.request.course)
        projects = Project.objects.filter(course=self.request.course)

        if not form.cleaned_data['clear_all']:
            # exclude assets, projects & notes authored by faculty
            faculty = self.request.course.faculty_group.user_set.all()
            assets = assets.exclude(author__in=faculty)
            projects = projects.exclude(author__in=faculty)
            notes = notes.exclude(author__in=faculty)

        # delete all the media on CUNIX first
        (url, secret) = self.get_delete_endpoint()
        if url:
            for a in assets:
                if a.upload_references() == 1:
                    self.delete_uploaded_media(url, secret, a)

        notes.delete()
        assets.delete()
        projects.delete()

        # Clear all discussions. The root comment will be preserved.
        discussions = get_course_discussions(self.request.course)
        parents = [d.id for d in discussions]
        comments = ThreadedComment.objects.filter(parent_id__in=parents)
        comments.delete()

        # @todo - kill all unreferenced tags

        if 'delete-course' in form.data:
            messages.add_message(
                self.request, messages.INFO,
                u'{} and requested materials were deleted'.format(
                    self.request.course.title))
            self.request.course.delete()
            self.success_url = '/?unset_course'
        else:
            self.success_url = reverse('course-delete-materials')
            messages.add_message(self.request, messages.INFO,
                                 'All requested materials were deleted')

        return super(CourseDeleteMaterialsView, self).form_valid(form)
Exemple #23
0
    def test_view_discussions(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))

        request = RequestFactory().get('/discussion/', {})
        request.user = self.instructor_one
        request.course = self.sample_course
        request.collaboration_context, created = \
            Collaboration.objects.get_or_create(
                content_type=ContentType.objects.get_for_model(Course),
                object_pk=self.sample_course.pk)

        view = DiscussionView()
        view.request = request
        response = view.get(request, discussion_id=discussions[0].id)
        self.assertEquals(response.status_code, 200)
    def handle(self, *app_labels, **options):
        # kill assets & projects & comments not owned by sandbox_instructor
        sandbox = get_guest_sandbox()
        instructor = User.objects.get(username='******')

        assets = Asset.objects.filter(course=sandbox)
        assets = assets.exclude(author=instructor)
        assets.delete()

        notes = SherdNote.objects.filter(asset__course=sandbox)
        notes = notes.exclude(author=instructor)
        notes.delete()

        projects = Project.objects.filter(course=sandbox)
        projects = projects.exclude(author=instructor)
        projects.delete()

        discussions = get_course_discussions(sandbox)
        parents = [d.id for d in discussions]
        comments = ThreadedComment.objects.filter(parent_id__in=parents)
        comments.delete()
Exemple #25
0
def course_detail_view(request):
    if not request.course:
        return HttpResponseRedirect('/accounts/login/')

    logged_in_user = request.user
    classwork_owner = request.user  # Viewing your own work by default
    if 'username' in request.GET:
        user_name = request.GET['username']
        in_course_or_404(user_name, request.course)
        classwork_owner = get_object_or_404(User, username=user_name)

    course = request.course

    qs = ExternalCollection.objects.filter(course=request.course)
    collections = qs.filter(uploader=False).order_by('title')
    uploader = qs.filter(uploader=True).first()

    owners = []
    if (request.course.is_member(logged_in_user) and
        (logged_in_user.is_staff or
         logged_in_user.has_perm('assetmgr.can_upload_for'))):
        owners = UserResource().render_list(request, request.course.members)

    context = {
        'classwork_owner': classwork_owner,
        'information_title': course_information_title(course),
        'faculty_feed': Project.objects.faculty_compositions(course,
                                                             logged_in_user),
        'is_faculty': cached_course_is_faculty(course, logged_in_user),
        'discussions': get_course_discussions(course),
        'msg': request.GET.get('msg', ''),
        'view': request.GET.get('view', ''),
        'collections': collections,
        'uploader': uploader,
        'can_upload': course_details.can_upload(request.user, request.course),
        'owners': owners
    }

    return context
Exemple #26
0
    def test_view_discussions_ajax(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))

        request = RequestFactory().get('/discussion/', {},
                                       HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        request.user = self.instructor_one
        request.course = self.sample_course
        request.collaboration_context, created = \
            Collaboration.objects.get_or_create(
                content_type=ContentType.objects.get_for_model(Course),
                object_pk=str(self.sample_course.pk))

        view = DiscussionView()
        view.request = request
        response = view.get(request, discussion_id=discussions[0].id)
        self.assertEquals(response.status_code, 200)

        the_json = loads(response.content)
        self.assertEquals(the_json['space_owner'],
                          self.instructor_one.username)
Exemple #27
0
    def test_view_discussions_ajax(self):
        self.setup_sample_course()
        self.create_discussion(self.sample_course, self.instructor_one)
        discussions = get_course_discussions(self.sample_course)
        self.assertEquals(1, len(discussions))

        request = RequestFactory().get('/discussion/', {},
                                       HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        request.user = self.instructor_one
        request.course = self.sample_course
        request.collaboration_context, created = \
            Collaboration.objects.get_or_create(
                content_type=ContentType.objects.get_for_model(Course),
                object_pk=self.sample_course.pk)

        view = DiscussionView()
        view.request = request
        response = view.get(request, discussion_id=discussions[0].id)
        self.assertEquals(response.status_code, 200)

        the_json = loads(response.content)
        self.assertEquals(the_json['space_owner'],
                          self.instructor_one.username)
Exemple #28
0
    def get_context_data(self, **kwargs):
        context = super(CourseDetailView, self).get_context_data(**kwargs)
        course = context.get('object')

        qs = ExternalCollection.objects.filter(course=course)
        collections = qs.filter(uploader=False).order_by('title')
        uploader = qs.filter(uploader=True).first()

        owners = []
        if (course.is_member(self.request.user) and
            (self.request.user.is_staff
             or self.request.user.has_perm('assetmgr.can_upload_for'))):
            owners = UserResource().render_list(self.request, course.members)

        context.update({
            'course':
            course,
            'classwork_owner':
            self.request.user,
            'information_title':
            course_information_title(course),
            'faculty_feed':
            Project.objects.faculty_compositions(course, self.request.user),
            'is_faculty':
            cached_course_is_faculty(course, self.request.user),
            'discussions':
            get_course_discussions(course),
            'collections':
            collections,
            'uploader':
            uploader,
            'can_upload':
            False,
            'owners':
            owners,
        })
        return context
Exemple #29
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 #30
0
def triple_homepage(request):
    if not request.course:
        return HttpResponseRedirect('/accounts/login/')

    logged_in_user = request.user
    classwork_owner = request.user  # Viewing your own work by default
    if 'username' in request.GET:
        user_name = request.GET['username']
        in_course_or_404(user_name, request.course)
        classwork_owner = get_object_or_404(User, username=user_name)

    c = request.course

    archives = []
    upload_archive = None
    for a in c.asset_set.archives().order_by('title'):
        archive = a.sources['archive']
        thumb = a.sources.get('thumb', None)
        description = a.metadata().get('description', '')
        uploader = a.metadata().get('upload', 0)

        archive_context = {
            "id": a.id,
            "title": a.title,
            "thumb": (None if not thumb else {"id": thumb.id,
                                              "url": thumb.url}),
            "archive": {"id": archive.id, "url": archive.url},
            "metadata": (description[0]
                         if hasattr(description, 'append') else description)
        }

        if (uploader[0] if hasattr(uploader, 'append') else uploader):
            upload_archive = archive_context
        else:
            archives.append(archive_context)

    archives.sort(key=operator.itemgetter('title'))

    show_tour = should_show_tour(request, c, logged_in_user)

    owners = []
    if (in_course(logged_in_user.username, request.course) and
        (logged_in_user.is_staff or
         logged_in_user.has_perm('assetmgr.can_upload_for'))):
        owners = UserResource().render_list(request, request.course.members)

    discussions = get_course_discussions(c)

    context = {
        'classwork_owner': classwork_owner,
        'help_homepage_instructor_column': False,
        'help_homepage_classwork_column': False,
        'faculty_feed': get_prof_feed(c, request),
        'is_faculty': c.is_faculty(logged_in_user),
        'discussions': discussions,
        'msg': request.GET.get('msg', ''),
        'view': request.GET.get('view', ''),
        'archives': archives,
        'upload_archive': upload_archive,
        'can_upload': course_details.can_upload(request.user, request.course),
        'show_tour': show_tour,
        'owners': owners
    }

    if getattr(settings, 'DJANGOSHERD_FLICKR_APIKEY', None):
        # MUST only contain string values for now!!
        # (see templates/assetmgr/bookmarklet.js to see why or fix)
        context['bookmarklet_vars'] = {
            'flickr_apikey': settings.DJANGOSHERD_FLICKR_APIKEY
        }

    return context
Exemple #31
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 #32
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 #33
0
def triple_homepage(request):
    if not request.course:
        return HttpResponseRedirect('/accounts/login/')

    logged_in_user = request.user
    classwork_owner = request.user  # Viewing your own work by default
    if 'username' in request.GET:
        user_name = request.GET['username']
        in_course_or_404(user_name, request.course)
        classwork_owner = get_object_or_404(User, username=user_name)

    course = request.course

    archives = []
    upload_archive = None
    for item in course.asset_set.archives().order_by('title'):
        archive = item.sources['archive']
        thumb = item.sources.get('thumb', None)
        description = item.metadata().get('description', '')
        uploader = item.metadata().get('upload', 0)

        archive_context = {
            "id": item.id,
            "title": item.title,
            "thumb": (None if not thumb else {"id": thumb.id,
                                              "url": thumb.url}),
            "archive": {"id": archive.id, "url": archive.url},
            "metadata": (description[0]
                         if hasattr(description, 'append') else description)
        }

        if (uploader[0] if hasattr(uploader, 'append') else uploader):
            upload_archive = archive_context
        else:
            archives.append(archive_context)

    archives.sort(key=operator.itemgetter('title'))

    owners = []
    if (in_course(logged_in_user.username, request.course) and
        (logged_in_user.is_staff or
         logged_in_user.has_perm('assetmgr.can_upload_for'))):
        owners = UserResource().render_list(request, request.course.members)

    context = {
        'classwork_owner': classwork_owner,
        'help_homepage_instructor_column': False,
        'help_homepage_classwork_column': False,
        'faculty_feed': get_prof_feed(course, request),
        'is_faculty': course.is_faculty(logged_in_user),
        'discussions': get_course_discussions(course),
        'msg': request.GET.get('msg', ''),
        'view': request.GET.get('view', ''),
        'archives': archives,
        'upload_archive': upload_archive,
        'can_upload': course_details.can_upload(request.user, request.course),
        'show_tour': should_show_tour(request, course, logged_in_user),
        'owners': owners
    }

    if getattr(settings, 'DJANGOSHERD_FLICKR_APIKEY', None):
        # MUST only contain string values for now!!
        # (see templates/assetmgr/bookmarklet.js to see why or fix)
        context['bookmarklet_vars'] = {
            'flickr_apikey': settings.DJANGOSHERD_FLICKR_APIKEY
        }

    return context
Exemple #34
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
Exemple #35
0
 def get_context_data(self, **kwargs):
     ctx = super().get_context_data(**kwargs)
     ctx['status'] = self.request.GET.get('status', 'all')
     ctx['title'] = self.request.GET.get('title', '')
     ctx['discussions'] = get_course_discussions(self.request.course)
     return ctx