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")
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
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()
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
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_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')
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))
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)
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
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)
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
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())
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
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)
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))
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
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)
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)
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()
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
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)
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)
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
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
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
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
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
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
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
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