def get_context(self, request, assets, notes): # Allow the logged in user to add assets to his composition citable = request.GET.get('citable', '') == 'true' # Include annotation metadata. (makes response much larger) include_annotations = request.GET.get('annotations', '') == 'true' # Initialize the context ures = UserResource() ctx = { 'space_viewer': ures.render_one(request, self.record_viewer), 'is_faculty': self.is_viewer_faculty } if self.record_owner: ctx['space_owner'] = ures.render_one(request, self.record_owner) ctx['active_filters'] = {} for key, val in request.GET.items(): if (key in self.valid_filters or key.startswith('vocabulary-')): ctx['active_filters'][key] = val ctx['editable'] = self.viewing_own_records ctx['citable'] = citable # render the assets ares = AssetResource(include_annotations=include_annotations, extras={ 'editable': self.viewing_own_records, 'citable': citable }) ctx['assets'] = ares.render_list(request, self.record_viewer, assets, notes) return ctx
def all_projects(request): """ An ajax-only request to retrieve a course's projects, assignment responses and selections """ if not request.is_ajax(): raise Http404() if not request.user.is_staff: in_course_or_404(request.user.username, request.course) course = request.course logged_in_user = request.user projects = Project.objects.visible_by_course(request, course) # Assemble the context user_rez = UserResource() course_rez = CourseSummaryResource() data = {'projects': homepage_project_json(request, projects, False), 'space_viewer': user_rez.render_one(request, logged_in_user), 'course': course_rez.render_one(request, course), 'compositions': len(projects) > 0, 'is_faculty': course.is_faculty(logged_in_user)} json_stream = simplejson.dumps(data, indent=2) return HttpResponse(json_stream, mimetype='application/json')
def get_context(self, request, assets, notes): # Allow the logged in user to add assets to his composition citable = request.GET.get('citable', '') == 'true' # Include annotation metadata. (makes response much larger) include_annotations = request.GET.get('annotations', '') == 'true' # Initialize the context ures = UserResource() ctx = { 'space_viewer': ures.render_one(request, self.record_viewer), 'is_faculty': self.is_viewer_faculty } if self.record_owner: ctx['space_owner'] = ures.render_one(request, self.record_owner) ctx['active_filters'] = {} for key, val in request.GET.items(): if (key in self.valid_filters or key.startswith('vocabulary-')): ctx['active_filters'][key] = val ctx['editable'] = self.viewing_own_records ctx['citable'] = citable # render the assets ares = AssetResource(include_annotations=include_annotations, extras={'editable': self.viewing_own_records, 'citable': citable}) ctx['assets'] = ares.render_list(request, self.record_viewer, assets, notes) return ctx
def get(self, request, *args, **kwargs): """Show a threadedcomments discussion of an arbitrary object. discussion_id is the pk of the root comment.""" discussion_id = kwargs.get('discussion_id', None) root_comment = get_object_or_404(ThreadedComment, pk=discussion_id) if not root_comment.content_object.permission_to( 'read', request.course, request.user): return HttpResponseForbidden('You do not have permission \ to view this discussion.') try: my_course = root_comment.content_object.context.content_object except: # legacy: for when contexts weren't being set in new() my_course = request.course root_comment.content_object.context = \ Collaboration.objects.get_for_object(my_course) root_comment.content_object.save() data = {'space_owner': request.user.username} if not request.is_ajax(): data['discussion'] = root_comment return render_to_response('discussions/discussion.html', data, context_instance=RequestContext(request)) else: vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.filter(course=request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data['panels'] = [{ 'panel_state': 'open', 'subpanel_state': 'open', 'panel_state_label': "Discussion", 'template': 'discussion', 'owners': owners, 'vocabulary': vocabulary, 'title': root_comment.title, 'can_edit_title': my_course.is_faculty(request.user), 'root_comment_id': root_comment.id, 'context': threaded_comment_json(request, root_comment) }] # Create a place for asset editing panel = {'panel_state': 'closed', 'panel_state_label': "Item Details", 'template': 'asset_quick_edit', 'update_history': False, 'show_collection': False, 'owners': owners, 'vocabulary': vocabulary, 'context': {'type': 'asset'}} data['panels'].append(panel) return HttpResponse(json.dumps(data), content_type='application/json')
def get(self, request, asset_id=None, annot_id=None): if asset_id: try: asset = Asset.objects.get(pk=asset_id, course=request.course) asset.primary except Asset.DoesNotExist: return asset_switch_course(request, asset_id) except Source.DoesNotExist: ctx = RequestContext(request) return render_to_response('500.html', {}, context_instance=ctx) data = {'asset_id': asset_id, 'annotation_id': annot_id} if not request.is_ajax(): return render_to_response('assetmgr/asset_workspace.html', data, context_instance=RequestContext(request)) ctx = {'type': 'asset'} if asset_id: # @todo - refactor this context out of the mix # ideally, the client would simply request the json # the mixin is expecting a queryset, so this becomes awkward here assets = Asset.objects.filter(pk=asset_id) (assets, notes) = self.visible_assets_and_notes(request, assets) # only return original author's global annotations notes = notes.exclude(~Q(author=request.user), range1__isnull=True) ares = AssetResource() ctx.update(ares.render_one_context(request, asset, notes)) help_setting = UserSetting.get_setting(request.user, "help_item_detail_view", True) ctx['user_settings'] = {'help_item_detail_view': help_setting} vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) update_history = True show_collection = True template = 'asset_workspace' data['panels'] = [{ 'panel_state': 'open', 'panel_state_label': "Annotate Media", 'context': ctx, 'owners': owners, 'vocabulary': vocabulary, 'template': template, 'current_asset': asset_id, 'current_annotation': annot_id, 'update_history': update_history, 'show_collection': show_collection}] return self.render_to_json_response(data)
def get(self, request): user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data = { 'owners': json.dumps(owners), 'return_url': request.GET.get('return_url', '') } return self.render_to_response(data)
def get(self, request, asset_id=None, annot_id=None): if asset_id: try: asset = Asset.objects.get(pk=asset_id, course=request.course) asset.primary except Asset.DoesNotExist: return asset_switch_course(request, asset_id) except Source.DoesNotExist: ctx = RequestContext(request) return render_to_response('500.html', {}, context_instance=ctx) data = {'asset_id': asset_id, 'annotation_id': annot_id} if not request.is_ajax(): return render_to_response('assetmgr/asset_workspace.html', data, context_instance=RequestContext(request)) context = {'type': 'asset'} if asset_id: # @todo - refactor this context out of the mix # ideally, the client would simply request the json # the mixin is expecting a queryset, so this becomes awkward here self.record_owner = request.user assets = Asset.objects.filter(pk=asset_id) (assets, notes) = self.visible_assets_and_notes(request, assets) context['assets'] = { asset.pk: AssetResource().render_one(request, asset, notes) } help_setting = UserSetting.get_setting(request.user, "help_item_detail_view", True) context['user_settings'] = {'help_item_detail_view': help_setting} vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data['panels'] = [{ 'panel_state': 'open', 'panel_state_label': "Annotate Media", 'context': context, 'owners': owners, 'vocabulary': vocabulary, 'template': 'asset_workspace', 'current_asset': asset_id, 'current_annotation': annot_id, 'update_history': True, 'show_collection': True }] return self.render_to_json_response(data)
def get(self, request): user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data = { 'owners': json.dumps(owners), 'return_url': request.GET.get('return_url', ''), 'width': EMBED_WIDTH, 'height': EMBED_HEIGHT } return self.render_to_response(data)
def asset_workspace(request, asset_id=None, annot_id=None): if not request.user.is_staff: in_course_or_404(request.user.username, request.course) if asset_id: try: asset = Asset.objects.get(pk=asset_id, course=request.course) asset.primary except Asset.DoesNotExist: return asset_switch_course(request, asset_id) except Source.DoesNotExist: response = direct_to_template(request, "500.html", {}) response.status_code = 500 return response data = { 'space_owner': request.user.username, 'asset_id': asset_id, 'annotation_id': annot_id } if not request.is_ajax(): return render_to_response('assetmgr/asset_workspace.html', data, context_instance=RequestContext(request)) elif asset_id: # @todo - refactor this context out of the mix # ideally, the client would simply request the json context = detail_asset_json(request, asset) else: context = {'type': 'asset'} vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data['panels'] = [{ 'panel_state': 'open', 'panel_state_label': "Annotate Media", 'context': context, 'owners': owners, 'vocabulary': vocabulary, 'template': 'asset_workspace', 'current_asset': asset_id, 'current_annotation': annot_id, 'update_history': True, 'show_collection': True, }] return HttpResponse(simplejson.dumps(data, indent=2), mimetype='application/json')
def asset_workspace(request, asset_id=None, annot_id=None): if not request.user.is_staff: in_course_or_404(request.user.username, request.course) if asset_id: try: asset = Asset.objects.get(pk=asset_id, course=request.course) asset.primary except Asset.DoesNotExist: return asset_switch_course(request, asset_id) except Source.DoesNotExist: response = direct_to_template(request, "500.html", {}) response.status_code = 500 return response data = {'space_owner': request.user.username, 'asset_id': asset_id, 'annotation_id': annot_id} if not request.is_ajax(): return render_to_response('assetmgr/asset_workspace.html', data, context_instance=RequestContext(request)) elif asset_id: # @todo - refactor this context out of the mix # ideally, the client would simply request the json context = detail_asset_json(request, asset) else: context = {'type': 'asset'} vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data['panels'] = [{'panel_state': 'open', 'panel_state_label': "Annotate Media", 'context': context, 'owners': owners, 'vocabulary': vocabulary, 'template': 'asset_workspace', 'current_asset': asset_id, 'current_annotation': annot_id, 'update_history': True, 'show_collection': True, }] return HttpResponse(simplejson.dumps(data, indent=2), mimetype='application/json')
def test_render_list(self): u = UserFactory(username='******', first_name='Student', last_name='One') self.assertTrue(self.client.login(username=u.username, password="******")) g1 = GroupFactory(name="group1") g2 = GroupFactory(name="group2") CourseFactory(title="Sample Course", faculty_group=g1, group=g2) u.groups.add(g2) UserFactory(username='******', first_name='Instructor', last_name='One').groups.add(g2) UserFactory(username='******').groups.add(g2) UserFactory(username='******').groups.add(g2) UserFactory(username='******', first_name='Student', last_name='Two').groups.add(g2) UserFactory(username='******', first_name="Teacher's", last_name="Assistant").groups.add(g2) sample_course = Course.objects.get(title="Sample Course") members = UserResource().render_list(None, sample_course.members) self.assertEquals(len(members), 6) self.assertEquals(members[0]['public_name'], "test_instructor_two") self.assertEquals(members[1]['public_name'], "test_student_three") self.assertEquals(members[2]['public_name'], "Assistant, Teacher's") self.assertEquals(members[3]['public_name'], "One, Instructor") self.assertEquals(members[4]['public_name'], "One, Student") self.assertEquals(members[5]['public_name'], "Two, Student")
def get(self, request, course_pk=None, asset_id=None, annot_id=None): if asset_id: try: asset = Asset.objects.get(pk=asset_id, course=request.course) asset.primary except Asset.DoesNotExist: return asset_switch_course(request, asset_id) except Source.DoesNotExist: return render(request, '500.html', {}) if not request.is_ajax(): return self.redirect_to_react_views(request.course.id, asset_id, annot_id) ctx = {'asset_id': asset_id, 'annotation_id': annot_id} qs = Vocabulary.objects.filter(course=request.course) vocabulary = VocabularyResource().render_list(request, qs) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) ctx['panels'] = [{ 'panel_state': 'open', 'panel_state_label': "Annotate Media", 'context': { 'type': 'asset', 'is_faculty': self.is_viewer_faculty, 'allow_item_download': self.is_viewer_faculty and course_details.allow_item_download(request.course) }, 'owners': owners, 'vocabulary': vocabulary, 'template': 'asset_workspace', 'current_asset': asset_id, 'current_annotation': annot_id, 'update_history': True, 'show_collection': True }] return self.render_to_json_response(ctx)
def your_projects(request, record_owner_name): """ An ajax-only request to retrieve a specified user's projects, assignment responses and selections """ if not request.is_ajax(): raise Http404() course = request.course in_course_or_404(record_owner_name, course) logged_in_user = request.user is_faculty = course.is_faculty(logged_in_user) record_owner = get_object_or_404(User, username=record_owner_name) viewing_own_work = record_owner == logged_in_user # Record Owner's Visible Work, # sorted by modified date & feedback (if applicable) projects = Project.objects.visible_by_course_and_user(request, course, record_owner) # Show unresponded assignments if viewing self & self is a student assignments = [] if not is_faculty and viewing_own_work: assignments = Project.objects.unresponded_assignments(request, logged_in_user) # Assemble the context user_rez = UserResource() course_rez = CourseSummaryResource() data = { 'assignments': homepage_assignment_json(assignments, is_faculty), 'projects': homepage_project_json(request, projects, viewing_own_work), 'space_viewer': user_rez.render_one(request, logged_in_user), 'space_owner': user_rez.render_one(request, record_owner), 'editable': viewing_own_work, 'course': course_rez.render_one(request, course), 'compositions': len(projects) > 0 or len(assignments) > 0, 'is_faculty': is_faculty} json_stream = simplejson.dumps(data, indent=2) return HttpResponse(json_stream, mimetype='application/json')
def test_render_one(self): self.assertTrue( self.api_client.client.login(username="******", password="******")) student_one = User.objects.get(username='******') member = UserResource().render_one(None, student_one) self.assertEquals(member['public_name'], "Student One")
def get(self, request, asset_id=None, annot_id=None): if asset_id: try: asset = Asset.objects.get(pk=asset_id, course=request.course) asset.primary except Asset.DoesNotExist: return asset_switch_course(request, asset_id) except Source.DoesNotExist: ctx = RequestContext(request) return render_to_response('500.html', {}, context_instance=ctx) ctx = {'asset_id': asset_id, 'annotation_id': annot_id} if not request.is_ajax(): return render_to_response('assetmgr/asset_workspace.html', ctx, context_instance=RequestContext(request)) qs = Vocabulary.objects.filter(course=request.course) vocabulary = VocabularyResource().render_list(request, qs) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) ctx['panels'] = [{ 'panel_state': 'open', 'panel_state_label': "Annotate Media", 'context': { 'type': 'asset', 'is_faculty': self.is_viewer_faculty, 'allow_item_download': self.is_viewer_faculty and allow_item_download(request.course) }, 'owners': owners, 'vocabulary': vocabulary, 'template': 'asset_workspace', 'current_asset': asset_id, 'current_annotation': annot_id, 'update_history': True, 'show_collection': True}] return self.render_to_json_response(ctx)
def test_render_one(self): u = UserFactory(username='******', first_name='Student', last_name='One') self.assertTrue( self.client.login(username=u.username, password="******")) student_one = User.objects.get(username='******') member = UserResource().render_one(None, student_one) self.assertEquals(member['public_name'], "Student One")
def your_projects(request, record_owner_name): """ An ajax-only request to retrieve a specified user's projects, assignment responses and selections """ course = request.course in_course_or_404(record_owner_name, course) logged_in_user = request.user is_faculty = course.is_faculty(logged_in_user) record_owner = get_object_or_404(User, username=record_owner_name) viewing_own_work = record_owner == logged_in_user # Record Owner's Visible Work, # sorted by modified date & feedback (if applicable) projects = Project.objects.visible_by_course_and_user(request, course, record_owner) # Show unresponded assignments if viewing self & self is a student assignments = [] if not is_faculty and viewing_own_work: assignments = Project.objects.unresponded_assignments(request, logged_in_user) # Assemble the context user_rez = UserResource() course_rez = CourseSummaryResource() data = { 'assignments': homepage_assignment_json(assignments, is_faculty), 'projects': homepage_project_json(request, projects, viewing_own_work), 'space_viewer': user_rez.render_one(request, logged_in_user), 'space_owner': user_rez.render_one(request, record_owner), 'editable': viewing_own_work, 'course': course_rez.render_one(request, course), 'compositions': len(projects) > 0 or len(assignments) > 0, 'is_faculty': is_faculty} json_stream = simplejson.dumps(data, indent=2) return HttpResponse(json_stream, mimetype='application/json')
def get(self, request): ures = UserResource() course_res = CourseResource() pres = ProjectResource(editable=self.viewing_own_records, record_viewer=self.record_viewer, is_viewer_faculty=self.is_viewer_faculty) assignments = [] ctx = { 'space_viewer': ures.render_one(request, self.record_viewer), 'editable': self.viewing_own_records, 'course': course_res.render_one(request, request.course), 'is_faculty': self.is_viewer_faculty, 'is_superuser': request.user.is_superuser, } if self.record_owner: ctx['space_owner'] = ures.render_one(request, self.record_owner) if not request.course.is_true_member(self.record_owner): return self.render_to_json_response(ctx) projects = Project.objects.visible_by_course_and_user( request.course, request.user, self.record_owner, self.viewing_faculty_records) # Show unresponded assignments if viewing self & self is a student if not self.is_viewer_faculty and self.viewing_own_records: assignments = list( Project.objects.unresponded_assignments( request.course, request.user)) else: projects = Project.objects.visible_by_course( request.course, request.user) # update counts and paginate ctx['compositions'] = len(projects) > 0 or len(assignments) > 0 ctx.update(self.paginate(pres, assignments, projects)) return self.render_to_json_response(ctx)
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 get(self, request): ures = UserResource() course_rez = CourseResource() pres = ProjectResource(editable=self.viewing_own_records, record_viewer=self.record_viewer, is_viewer_faculty=self.is_viewer_faculty) assignments = [] ctx = { 'space_viewer': ures.render_one(request, self.record_viewer), 'editable': self.viewing_own_records, 'course': course_rez.render_one(request, request.course), 'is_faculty': self.is_viewer_faculty } if (self.record_owner): in_course_or_404(self.record_owner.username, request.course) projects = Project.objects.visible_by_course_and_user( request, request.course, self.record_owner, self.viewing_faculty_records) # Show unresponded assignments if viewing self & self is a student if not self.is_viewer_faculty and self.viewing_own_records: assignments = Project.objects.unresponded_assignments( request, self.record_viewer) ctx['space_owner'] = ures.render_one(request, self.record_owner) ctx['assignments'] = pres.render_assignments(request, assignments) else: projects = Project.objects.visible_by_course( request, request.course) ctx['projects'] = pres.render_projects(request, projects) ctx['compositions'] = len(projects) > 0 or len(assignments) > 0 return self.render_to_json_response(ctx)
def all_projects(request): """ An ajax-only request to retrieve a course's projects, assignment responses and selections """ if not request.user.is_staff: in_course_or_404(request.user.username, request.course) course = request.course logged_in_user = request.user projects = Project.objects.visible_by_course(request, course) # Assemble the context user_rez = UserResource() course_rez = CourseSummaryResource() data = {'projects': homepage_project_json(request, projects, False), 'space_viewer': user_rez.render_one(request, logged_in_user), 'course': course_rez.render_one(request, course), 'compositions': len(projects) > 0, 'is_faculty': course.is_faculty(logged_in_user)} json_stream = simplejson.dumps(data, indent=2) return HttpResponse(json_stream, mimetype='application/json')
def test_render_list(self): self.assertTrue( self.api_client.client.login(username="******", password="******")) sample_course = Course.objects.get(title="Sample Course") members = UserResource().render_list(None, sample_course.members) self.assertEquals(len(members), 6) self.assertEquals(members[0]['public_name'], "test_instructor_two") self.assertEquals(members[1]['public_name'], "test_student_three") self.assertEquals(members[2]['public_name'], "Instructor One") self.assertEquals(members[3]['public_name'], "Student One") self.assertEquals(members[4]['public_name'], "Student Two") self.assertEquals(members[5]['public_name'], "Teacher's Assistant")
def get(self, request, *args, **kwargs): course = get_object_or_404(Course, id=kwargs.pop('course_id', None)) faculty = [user.id for user in course.faculty.all()] faculty_ctx = UserResource().render_list(request, course.faculty.all()) # filter assets & notes by the faculty set assets = Asset.objects.by_course(course) if settings.SURELINK_URL: assets = assets.exclude( source__url__startswith=settings.SURELINK_URL) assets = assets.filter(sherdnote_set__author__id__in=faculty).exclude( source__label='flv_pseudo') notes = SherdNote.objects.get_related_notes( assets, None, faculty, True).exclude_primary_types(['flv_pseudo']) ares = AssetResource(include_annotations=False) asset_ctx = ares.render_list(request, None, None, assets, notes) projects = Project.objects.by_course_and_users(course, faculty) # filter private projects if projects.count() > 0: collabs = Collaboration.objects.get_for_object_list(projects) collabs = collabs.exclude( policy_record__policy_name='PrivateEditorsAreOwners') ids = collabs.values_list('object_pk', flat=True) projects = projects.filter(id__in=ids) info_ctx = CourseInfoResource().render_one(request, course) ctx = { 'course': { 'id': course.id, 'title': course.title, 'faculty': faculty_ctx, 'info': info_ctx }, 'assets': asset_ctx, 'projects': ProjectResource().render_list(request, projects) } return self.render_to_json_response(ctx)
def get_context_data(self, **kwargs): context = super(CourseDetailView, self).get_context_data(**kwargs) course = context.get('object') qs = ExternalCollection.objects.filter(course=self.request.course) collections = qs.filter(uploader=False).order_by('title') uploader = qs.filter(uploader=True).first() owners = [] if (self.request.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), 'owners': owners, 'collections': collections, 'uploader': uploader, 'msg': self.request.GET.get('msg', ''), 'can_upload': course_details.can_upload(self.request.user, self.request.course), }) return context
def get(self, request, *args, **kwargs): course = get_object_or_404(Course, id=kwargs.pop('course_id', None)) faculty = [user.id for user in course.faculty.all()] faculty_ctx = UserResource().render_list(request, course.faculty.all()) # filter assets & notes by the faculty set assets = Asset.objects.by_course(course) assets = assets.filter(sherdnote_set__author__id__in=faculty) notes = SherdNote.objects.get_related_notes(assets, None, faculty) ares = AssetResource(include_annotations=False) asset_ctx = ares.render_list(request, None, assets, notes) projects = Project.objects.by_course_and_users(course, faculty) # filter private projects collabs = Collaboration.objects.get_for_object_list(projects) collabs = collabs.exclude( _policy__policy_name='PrivateEditorsAreOwners') ids = [int(c.object_pk) for c in collabs] projects = projects.filter(id__in=ids) info_ctx = CourseInfoResource().render_one(request, course) ctx = { 'course': { 'id': course.id, 'title': course.title, 'faculty': faculty_ctx, 'info': info_ctx }, 'assets': asset_ctx, 'projects': ProjectResource().render_list(request, projects) } return self.render_to_json_response(ctx)
def discussion_create(request): """Start a discussion of an arbitrary model instance.""" title = request.POST['comment_html'] # Find the object we're discussing. the_content_type = ContentType.objects.get( app_label=request.POST['app_label'], model=request.POST['model']) assert the_content_type is not None the_object = the_content_type.get_object_for_this_type( pk=request.POST['obj_pk']) assert the_object is not None try: obj_sc = Collaboration.get_associated_collab(the_object) except Collaboration.DoesNotExist: obj_sc = Collaboration() # TODO: populate this collab with sensible auth defaults. obj_sc.content_object = the_object obj_sc.save() # sky: I think what I want to do is have the ThreadedComment # point to the_object # and the collaboration will point to the threaded root comment # that way, whereas, if we live in Collaboration-land, # we can get to ThreadedComments # threaded comments can also live in it's own world without 'knowing' # about SC OTOH, threaded comment shouldn't be able # to point to the regular object # until Collaboration says it's OK (i.e. has permissions) # ISSUE: how to migrate? (see models.py) # now create the CHILD collaboration object for the discussion to point at. # This represents the auth for the discussion itself. disc_sc = Collaboration( _parent=obj_sc, title=title, # or we could point it at the root # threadedcomments object. # content_object=None, context=request.collaboration_context, ) disc_sc.policy = request.POST.get('publish', None) if request.POST.get('inherit', None) == 'true': disc_sc.group_id = obj_sc.group_id disc_sc.user_id = obj_sc.user_id disc_sc.save() # finally create the root discussion object, pointing it at the CHILD. new_threaded_comment = ThreadedComment(parent=None, title=title, comment='', user=request.user, content_object=disc_sc) # TODO: find the default site_id new_threaded_comment.site_id = 1 new_threaded_comment.save() disc_sc.content_object = new_threaded_comment disc_sc.save() if not request.is_ajax(): return HttpResponseRedirect("/discussion/%d/" % new_threaded_comment.id) else: vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data = { 'panel_state': 'open', 'panel_state_label': "Instructor Feedback", 'template': 'discussion', 'owners': owners, 'vocabulary': vocabulary, 'context': threaded_comment_json(request, new_threaded_comment) } return HttpResponse(simplejson.dumps(data, indent=2), mimetype='application/json')
def discussion_view(request, discussion_id): """Show a threadedcomments discussion of an arbitrary object. discussion_id is the pk of the root comment.""" root_comment = get_object_or_404(ThreadedComment, pk=discussion_id) if not root_comment.content_object.permission_to('read', request): return HttpResponseForbidden('You do not have permission \ to view this discussion.') try: my_course = root_comment.content_object.context.content_object except: # legacy: for when contexts weren't being set in new() my_course = request.course root_comment.content_object.context = \ Collaboration.get_associated_collab(my_course) root_comment.content_object.save() data = {'space_owner': request.user.username} if not request.is_ajax(): data['discussion'] = root_comment return render_to_response('discussions/discussion.html', data, context_instance=RequestContext(request)) else: vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data['panels'] = [{ 'panel_state': 'open', 'subpanel_state': 'open', 'panel_state_label': "Discussion", 'template': 'discussion', 'owners': owners, 'vocabulary': vocabulary, 'title': root_comment.title, 'can_edit_title': my_course.is_faculty(request.user), 'root_comment_id': root_comment.id, 'context': threaded_comment_json(request, root_comment) }] # Create a place for asset editing panel = { 'panel_state': 'closed', 'panel_state_label': "Item Details", 'template': 'asset_quick_edit', 'update_history': False, 'show_collection': False, 'owners': owners, 'vocabulary': vocabulary, 'context': { 'type': 'asset' } } data['panels'].append(panel) return HttpResponse(simplejson.dumps(data, indent=2), mimetype='application/json')
def project_workspace(request, project_id, feedback=None): """ A multi-panel editable view for the specified project Legacy note: Ideally, this function would be named project_view but StructuredCollaboration requires the view name to be <class>-view to do a reverse lookup Panel 1: Parent Assignment (if applicable) Panel 2: Project Panel 3: Instructor Feedback (if applicable & exists) Keyword arguments: project_id -- the model id """ project = get_object_or_404(Project, pk=project_id) if not project.can_read(request): return HttpResponseForbidden("forbidden") show_feedback = feedback == "feedback" data = { 'space_owner': request.user.username, 'show_feedback': show_feedback } if not request.is_ajax(): data['project'] = project return render_to_response('projects/project.html', data, context_instance=RequestContext(request)) else: panels = [] vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.get_for_object(request.course)) owners = UserResource().render_list(request, request.course.members) is_faculty = request.course.is_faculty(request.user) can_edit = project.can_edit(request) feedback_discussion = project.feedback_discussion() \ if is_faculty or can_edit else None # Project Parent (assignment) if exists parent_assignment = project.assignment() if parent_assignment: resource = ProjectResource( record_viewer=request.user, is_viewer_faculty=is_faculty, editable=parent_assignment.can_edit(request)) assignment_ctx = resource.render_one(request, parent_assignment) panel = { 'is_faculty': is_faculty, 'panel_state': "open" if (project.title == "Untitled" and len(project.body) == 0) else "closed", 'subpanel_state': 'closed', 'context': assignment_ctx, 'owners': owners, 'vocabulary': vocabulary, 'template': 'project' } panels.append(panel) # Requested project, can be either an assignment or composition resource = ProjectResource(record_viewer=request.user, is_viewer_faculty=is_faculty, editable=can_edit) project_context = resource.render_one(request, project) # only editing if it's new project_context['editing'] = \ True if can_edit and len(project.body) < 1 else False project_context['create_instructor_feedback'] = \ is_faculty and parent_assignment and not feedback_discussion panel = { 'is_faculty': is_faculty, 'panel_state': 'closed' if show_feedback else 'open', 'context': project_context, 'template': 'project', 'owners': owners, 'vocabulary': vocabulary } panels.append(panel) # Project Response -- if the requested project is an assignment # This is primarily a student view. The student's response should # pop up automatically when the parent assignment is viewed. if project.is_assignment(request): responses = project.responses_by(request, request.user) if len(responses) > 0: response = responses[0] response_can_edit = response.can_edit(request) resource = ProjectResource(record_viewer=request.user, is_viewer_faculty=is_faculty, editable=response_can_edit) response_context = resource.render_one(request, response) panel = { 'is_faculty': is_faculty, 'panel_state': 'closed', 'context': response_context, 'template': 'project', 'owners': owners, 'vocabulary': vocabulary } panels.append(panel) if not feedback_discussion and response_can_edit: feedback_discussion = response.feedback_discussion() data['panels'] = panels # If feedback exists for the requested project if feedback_discussion: # 3rd pane is the instructor feedback, if it exists panel = { 'panel_state': 'open' if show_feedback else 'closed', 'panel_state_label': "Instructor Feedback", 'template': 'discussion', 'owners': owners, 'vocabulary': vocabulary, 'context': threaded_comment_json(request, feedback_discussion) } panels.append(panel) # Create a place for asset editing panel = { 'panel_state': 'closed', 'panel_state_label': "Item Details", 'template': 'asset_quick_edit', 'update_history': False, 'owners': owners, 'vocabulary': vocabulary, 'context': { 'type': 'asset' } } panels.append(panel) return HttpResponse(json.dumps(data, indent=2), mimetype='application/json')
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 render_assets(request, record_owner, assets): course = request.course logged_in_user = request.user # Is the current user faculty OR staff is_faculty = cached_course_is_faculty(course, logged_in_user) # Can the record_owner edit the records viewing_own_records = (record_owner == logged_in_user) viewing_faculty_records = record_owner and course.is_faculty(record_owner) # Allow the logged in user to add assets to his composition citable = request.GET.get('citable', '') == 'true' # Does the course allow viewing other user selections? owner_selections_are_visible = ( course_details.all_selections_are_visible(course) or viewing_own_records or viewing_faculty_records or is_faculty) # Spew out json for the assets if request.GET.get('annotations', '') == 'true': resource = AssetResource(owner_selections_are_visible, record_owner, { 'editable': viewing_own_records, 'citable': citable }) else: resource = AssetSummaryResource({ 'editable': viewing_own_records, 'citable': citable }) asset_json = resource.render_list(request, assets) active_filters = {} for key, val in request.GET.items(): if (key == 'tag' or key == 'modified' or key.startswith('vocabulary-')): active_filters[key] = val user_resource = UserResource() # #todo -- figure out a cleaner way to do this. Ugli-ness # Collate tag set & vocabulary set for the result set. # Get all visible notes for the returned asset set # These notes may include global annotations for all users, # whereas the rendered set will not active_asset_ids = [a['id'] for a in asset_json] active_notes = [] if record_owner: if owner_selections_are_visible: active_notes = SherdNote.objects.filter( asset__course=course, asset__id__in=active_asset_ids, author__id=record_owner.id) else: if all_selections_are_visible(course) or is_faculty: # Display all tags for the asset set including globals active_notes = SherdNote.objects.filter( asset__course=course, asset__id__in=active_asset_ids) else: whitelist = [f.id for f in course.faculty] whitelist.append(request.user.id) active_notes = SherdNote.objects.filter( asset__course=course, asset__id__in=active_asset_ids, author__id__in=whitelist) tags = [] if len(active_notes) > 0: tags = Tag.objects.usage_for_queryset(active_notes) tags.sort(lambda a, b: cmp(a.name.lower(), b.name.lower())) active_vocabulary = [] note_ids = [n.id for n in active_notes] content_type = ContentType.objects.get_for_model(SherdNote) term_resource = TermResource() for vocab in Vocabulary.objects.get_for_object(request.course): vocabulary = { 'id': vocab.id, 'display_name': vocab.display_name, 'term_set': [] } related = TermRelationship.objects.filter(term__vocabulary=vocab, content_type=content_type, object_id__in=note_ids) terms = [] for rel in related: if rel.term.display_name not in terms: the_term = term_resource.render_one(request, rel.term) vocabulary['term_set'].append(the_term) terms.append(rel.term.display_name) active_vocabulary.append(vocabulary) # Assemble the context data = { 'assets': asset_json, 'active_tags': TagResource().render_list(request, tags), 'active_filters': active_filters, 'active_vocabulary': active_vocabulary, 'space_viewer': user_resource.render_one(request, logged_in_user), 'editable': viewing_own_records, 'citable': citable, 'is_faculty': is_faculty } if record_owner: data['space_owner'] = user_resource.render_one(request, record_owner) json_stream = simplejson.dumps(data, indent=2) return HttpResponse(json_stream, mimetype='application/json')
def get(self, request, *args, **kwargs): project = get_object_or_404(Project, pk=kwargs.get('project_id', None)) data = {'space_owner': request.user.username} if not request.is_ajax(): self.template_name = 'projects/composition.html' data['project'] = project return self.render_to_response(data) else: panels = [] lst = Vocabulary.objects.filter(course=request.course) lst = lst.prefetch_related('term_set') vocabulary = VocabularyResource().render_list(request, lst) owners = UserResource().render_list(request, request.course.members) is_faculty = request.course.is_faculty(request.user) can_edit = project.can_edit(request.course, request.user) # Requested project, can be either an assignment or composition resource = ProjectResource(record_viewer=request.user, is_viewer_faculty=is_faculty, editable=can_edit) project_context = resource.render_one(request, project) # only editing if it's new project_context['editing'] = \ True if can_edit and len(project.body) < 1 else False project_context['create_instructor_feedback'] = False project_revisions_url = reverse( 'project-revisions', args=[request.course.pk, project.id]) panel = { 'is_faculty': is_faculty, 'context': project_context, 'template': 'project', 'owners': owners, 'project_revisions_url': project_revisions_url, 'vocabulary': vocabulary } panels.append(panel) data['panels'] = panels # Create a place for asset editing panel = { 'template': 'asset_quick_edit', 'update_history': False, 'owners': owners, 'vocabulary': vocabulary, 'context': { 'type': 'asset' } } panels.append(panel) return self.render_to_json_response(data)
def get(self, request, *args, **kwargs): project = get_object_or_404(Project, pk=kwargs.get('project_id', None)) assignment = project.assignment() if not assignment or not assignment.is_essay_assignment(): return HttpResponseForbidden('') panels = [] lst = Vocabulary.objects.filter(course=request.course) lst = lst.prefetch_related('term_set') vocabulary = VocabularyResource().render_list(request, lst) owners = UserResource().render_list(request, request.course.members) is_faculty = request.course.is_faculty(request.user) can_edit = project.can_edit(request.course, request.user) feedback_discussion = project.feedback_discussion() \ if is_faculty or can_edit else None parent = project.assignment() # Requested project, can be either an assignment or composition resource = ProjectResource(record_viewer=request.user, is_viewer_faculty=is_faculty, editable=can_edit) project_context = resource.render_one(request, project) # only editing if it's new project_context['editing'] = \ True if can_edit and len(project.body) < 1 else False project_context['create_instructor_feedback'] = \ is_faculty and parent and not feedback_discussion project_revisions_url = reverse('project-revisions', args=[request.course.pk, project.id]) panel = { 'is_faculty': is_faculty, 'show_feedback': feedback_discussion is not None, 'create_feedback_url': reverse('discussion-create', args=[request.course.pk]), 'project_revisions_url': project_revisions_url, 'context': project_context, 'template': 'project_response', 'owners': owners, 'vocabulary': vocabulary } panels.append(panel) # If feedback exists for the requested project if feedback_discussion: # 3rd pane is the instructor feedback, if it exists panel = { 'template': 'project_feedback', 'owners': owners, 'vocabulary': vocabulary, 'context': threaded_comment_json(request, feedback_discussion) } panels.append(panel) # Create a place for asset editing panel = { 'template': 'asset_quick_edit', 'update_history': False, 'owners': owners, 'vocabulary': vocabulary, 'context': { 'type': 'asset' } } panels.append(panel) data = {'space_owner': request.user.username, 'panels': panels} return self.render_to_json_response(data)
def post(self, request, *args, **kwargs): """Start a discussion of an arbitrary model instance.""" title = request.POST['comment_html'] comment = request.POST.get('comment', '') # Find the object we're discussing. model = request.POST['model'] the_content_type = ContentType.objects.get( app_label=request.POST['app_label'], model=model) assert the_content_type is not None the_object = the_content_type.get_object_for_this_type( pk=request.POST['obj_pk']) assert the_object is not None try: obj_sc = Collaboration.objects.get_for_object(the_object) except Collaboration.DoesNotExist: obj_sc = Collaboration() # TODO: populate this collab with sensible auth defaults. obj_sc.content_object = the_object obj_sc.save() # sky: I think what I want to do is have the ThreadedComment # point to the_object # and the collaboration will point to the threaded root comment # that way, whereas, if we live in Collaboration-land, # we can get to ThreadedComments # threaded comments can also live in it's own world without 'knowing' # about SC OTOH, threaded comment shouldn't be able # to point to the regular object # until Collaboration says it's OK (i.e. has permissions) # ISSUE: how to migrate? (see models.py) # now create the CHILD collaboration object for the # discussion to point at. # This represents the auth for the discussion itself. collaboration_context = cached_course_collaboration(request.course) disc_sc = Collaboration( _parent=obj_sc, title=title, context=collaboration_context, ) disc_sc.set_policy(request.POST.get('publish', None)) disc_sc.save() # finally create the root discussion object, pointing it at the CHILD. new_threaded_comment = ThreadedComment(parent=None, title=title, comment=comment, user=request.user, content_object=disc_sc) # TODO: find the default site_id new_threaded_comment.site_id = 1 new_threaded_comment.save() disc_sc.content_object = new_threaded_comment disc_sc.save() DiscussionIndex.update_class_references( new_threaded_comment.comment, new_threaded_comment.user, new_threaded_comment, new_threaded_comment.content_object, new_threaded_comment.user) if not request.is_ajax(): if model == 'project': discussion_url = reverse('project-workspace', args=(request.course.pk, the_object.pk)) else: discussion_url = reverse('discussion-view', args=(request.course.pk, new_threaded_comment.id)) return HttpResponseRedirect(discussion_url) else: vocabulary = VocabularyResource().render_list( request, Vocabulary.objects.filter(course=request.course)) user_resource = UserResource() owners = user_resource.render_list(request, request.course.members) data = { 'panel_state': 'open', 'panel_state_label': "Instructor Feedback", 'template': 'discussion', 'owners': owners, 'vocabulary': vocabulary, 'context': threaded_comment_json(request, new_threaded_comment) } return HttpResponse(json.dumps(data, indent=2), content_type='application/json')