def post(self, request, *args, **kwargs): comment_id = kwargs.get('comment_id', None) comment = get_object_or_404(ThreadedComment, pk=comment_id) if not comment.content_object.permission_to('manage', request.course, request.user): return HttpResponseForbidden( 'You do not have permission to edit this discussion.') # update the body of the comment. (confusingly called "comment") comment.comment = request.POST['comment'] if request.POST.get('title', None): comment.title = request.POST['title'] if not comment.parent: disc_sc = comment.content_object disc_sc.title = comment.title disc_sc.save() comment.save() DiscussionIndex.update_class_references(comment.comment, comment.user, comment, comment.content_object, comment.user) ctx = {'context': threaded_comment_json(request, comment)} return self.render_to_json_response(ctx)
def post(self, request): project_type = request.POST.get('project_type', 'composition') body = request.POST.get('body', '') response_policy = request.POST.get('response_view_policy', 'always') due_date = self.format_date(self.request.POST.get('due_date', None)) instructions1 = self.request.POST.get('custom_instructions_1', None) instructions2 = self.request.POST.get('custom_instructions_2', None) summary = self.request.POST.get('summary', None) project = Project.objects.create(author=request.user, course=request.course, title=self.get_title(), project_type=project_type, response_view_policy=response_policy, body=body, due_date=due_date, custom_instructions_1=instructions1, custom_instructions_2=instructions2, summary=summary) project.participants.add(request.user) item_id = request.POST.get('item', None) project.create_or_update_item(item_id) policy = request.POST.get('publish', PUBLISH_DRAFT[0]) collaboration = project.create_or_update_collaboration(policy) DiscussionIndex.update_class_references(project.body, None, None, collaboration, project.author) parent_id = request.POST.get('parent', None) project.set_parent(parent_id) if project_type == PROJECT_TYPE_SEQUENCE_ASSIGNMENT: messages.add_message(request, messages.SUCCESS, self.get_confirmation_message(policy)) if not request.is_ajax(): return HttpResponseRedirect(project.get_absolute_url()) else: is_faculty = request.course.is_faculty(request.user) can_edit = project.can_edit(request.course, request.user) resource = ProjectResource(record_viewer=request.user, is_viewer_faculty=is_faculty, editable=can_edit) project_context = resource.render_one(request, project) project_context['editing'] = True data = { 'panel_state': 'open', 'template': 'project', 'context': project_context } return self.render_to_json_response(data)
def post(self, request, *args, **kwargs): frm = ProjectForm(request, instance=self.project, data=request.POST) if frm.is_valid(): policy = request.POST.get('publish', PUBLISH_DRAFT[0]) if policy == PUBLISH_DRAFT[0]: frm.instance.date_submitted = None else: frm.instance.date_submitted = datetime.now() frm.instance.author = request.user project = frm.save() project.participants.add(request.user) item_id = request.POST.get('item', None) project.create_or_update_item(item_id) # update the collaboration collaboration = project.create_or_update_collaboration(policy) DiscussionIndex.update_class_references(project.body, None, None, collaboration, project.author) parent_id = request.POST.get('parent', None) project.set_parent(parent_id) ctx = { 'status': 'success', 'is_essay_assignment': project.is_essay_assignment(), 'title': project.title, 'context': { 'project': { 'url': project.get_absolute_url() } }, 'revision': { 'id': project.latest_version(), 'public_url': project.public_url(), 'visibility': project.visibility_short(), 'due_date': project.get_due_date() } } else: ctx = {'status': 'error', 'msg': ""} for key, value in frm.errors.items(): if key == '__all__': ctx['msg'] = ctx['msg'] + value[0] + "\n" else: ctx['msg'] = \ '%s "%s" is not valid for the %s field.\n %s\n' % \ (ctx['msg'], frm.data[key], frm.fields[key].label, value[0].lower()) return self.render_to_json_response(ctx)
def post(self, request, *args, **kwargs): frm = ProjectForm(request, instance=self.project, data=request.POST) if frm.is_valid(): policy = request.POST.get('publish', PUBLISH_DRAFT[0]) if policy == PUBLISH_DRAFT[0]: frm.instance.date_submitted = None else: frm.instance.date_submitted = datetime.now() frm.instance.author = request.user project = frm.save() project.participants.add(request.user) item_id = request.POST.get('item', None) project.create_or_update_item(item_id) # update the collaboration collaboration = project.create_or_update_collaboration(policy) DiscussionIndex.update_class_references( project.body, None, None, collaboration, project.author) parent_id = request.POST.get('parent', None) project.set_parent(parent_id) ctx = { 'status': 'success', 'is_assignment': project.is_assignment(), 'title': project.title, 'context': { 'project': { 'url': project.get_absolute_url() } }, 'revision': { 'id': project.latest_version(), 'public_url': project.public_url(), 'visibility': project.visibility_short(), 'due_date': project.get_due_date() } } else: ctx = {'status': 'error', 'msg': ""} for key, value in frm.errors.items(): if key == '__all__': ctx['msg'] = ctx['msg'] + value[0] + "\n" else: ctx['msg'] = \ '%s "%s" is not valid for the %s field.\n %s\n' % \ (ctx['msg'], frm.data[key], frm.fields[key].label, value[0].lower()) return self.render_to_json_response(ctx)
def post(self, request): project_type = request.POST.get('project_type', 'composition') body = request.POST.get('body', '') response_policy = request.POST.get('response_view_policy', 'always') due_date = self.format_date(self.request.POST.get('due_date', None)) instructions1 = self.request.POST.get('custom_instructions_1', None) instructions2 = self.request.POST.get('custom_instructions_2', None) summary = self.request.POST.get('summary', None) project = Project.objects.create( author=request.user, course=request.course, title=self.get_title(), project_type=project_type, response_view_policy=response_policy, body=body, due_date=due_date, custom_instructions_1=instructions1, custom_instructions_2=instructions2, summary=summary) project.participants.add(request.user) item_id = request.POST.get('item', None) project.create_or_update_item(item_id) policy = request.POST.get('publish', PUBLISH_DRAFT[0]) collaboration = project.create_or_update_collaboration(policy) DiscussionIndex.update_class_references( project.body, None, None, collaboration, project.author) parent_id = request.POST.get('parent', None) project.set_parent(parent_id) if project_type == PROJECT_TYPE_SEQUENCE_ASSIGNMENT: messages.add_message(request, messages.SUCCESS, self.get_confirmation_message(policy)) if not request.is_ajax(): return HttpResponseRedirect(project.get_absolute_url()) else: is_faculty = request.course.is_faculty(request.user) can_edit = project.can_edit(request.course, request.user) resource = ProjectResource(record_viewer=request.user, is_viewer_faculty=is_faculty, editable=can_edit) project_context = resource.render_one(request, project) project_context['editing'] = True data = {'panel_state': 'open', 'template': 'project', 'context': project_context} return self.render_to_json_response(data)
def post(self, request): # create a project project = self.create_project() # get the project's collaboration object project_collab = project.get_collaboration() # construct a collaboration for this discussion # the parent will be this project within the course context # all course members can participate in the discussion course_collab = cached_course_collaboration(request.course) disc_collab = Collaboration(_parent=project_collab, title=project.title, context=course_collab) disc_collab.set_policy('CourseProtected') disc_collab.save() # Create a ThreadedComment that will act as the discussion root # It will be tied to the project via the collaboration object # as a generic foreign key new_threaded_comment = ThreadedComment.objects.create( parent=None, title=project.title, comment=project.body, user=request.user, site_id=1, content_object=disc_collab) # Conversely, the discussion collaboration will hold the # discussion root in its generic foreign key # this thread can now be accessed via the "course_discussion" # model attribute disc_collab.content_object = new_threaded_comment disc_collab.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) return HttpResponseRedirect( reverse('project-workspace', args=(request.course.pk, project.pk)))
def test_project(self): asset = AssetFactory.create(course=self.sample_course, primary_source='image') note = SherdNoteFactory( asset=asset, author=self.student_one, tags=',student_one_selection', body='student one selection note', range1=0, range2=1) asset2 = AssetFactory.create(course=self.sample_course, primary_source='image') to_be_deleted = SherdNoteFactory( asset=asset2, author=self.student_one, title='to be deleted') project = ProjectFactory.create( course=self.sample_course, author=self.student_one, policy='CourseProtected') self.add_citation(project, note) self.add_citation(project, to_be_deleted) asset2.delete() collaboration = project.get_collaboration() DiscussionIndex.update_class_references(project.body, None, None, collaboration, project.author) indicies = DiscussionIndex.objects.all() self.assertEquals(indicies.count(), 1) index = indicies.first() self.assertIsNone(index.participant) self.assertIsNone(index.comment) self.assertEquals(index.collaboration, collaboration) self.assertEquals(index.asset, asset) self.assertEquals(index.get_type_label(), 'project') self.assertEquals(index.content_object, asset) self.assertEquals(index.clump_parent(), project) self.assertIsNone(index.get_parent_url()) self.assertEquals(index.body, '')
def create_project(self): request = self.request project_type = request.POST.get('project_type', 'composition') body = request.POST.get('body', '') response_policy = request.POST.get('response_view_policy', 'always') due_date = self.format_date(self.request.POST.get('due_date', None)) instructions1 = self.request.POST.get('custom_instructions_1', None) instructions2 = self.request.POST.get('custom_instructions_2', None) summary = self.request.POST.get('summary', None) project = Project.objects.create(author=request.user, course=request.course, title=self.get_title(), project_type=project_type, response_view_policy=response_policy, body=body, due_date=due_date, custom_instructions_1=instructions1, custom_instructions_2=instructions2, summary=summary) project.participants.add(request.user) item_id = request.POST.get('item', None) project.create_or_update_item(item_id) policy = request.POST.get('publish', PUBLISH_DRAFT[0]) collaboration = project.create_or_update_collaboration(policy) DiscussionIndex.update_class_references(project.body, None, None, collaboration, project.author) parent_id = request.POST.get('parent', None) project.set_parent(parent_id) if project_type == PROJECT_TYPE_SEQUENCE_ASSIGNMENT: messages.add_message(request, messages.SUCCESS, self.get_confirmation_message(policy)) return project
def comment_save(request, comment_id, next_url=None): "save comment, since comments/post only does add, no edit" comment = ThreadedComment.objects.get(pk=comment_id) if comment.content_object.permission_to('manage', request.course, request.user): comment.comment = request.POST['comment'] elif comment.user == request.user: now = datetime.now() comment.comment = '<div class="postupdate">[Post updated at \ <time datetime="%s">%s</time>]</div>%s' % \ (now.isoformat(), now.strftime('%I:%M%p %D').lower(), request.POST['comment']) else: return HttpResponseForbidden('You do not have permission \ to edit this discussion.') if request.POST.get('title', None): comment.title = request.POST['title'] if not comment.parent: disc_sc = comment.content_object disc_sc.title = comment.title disc_sc.save() comment.save() DiscussionIndex.update_class_references(comment.comment, comment.user, comment, comment.content_object, comment.user) if request.META['HTTP_ACCEPT'].startswith("text/html"): return {'comment': comment} else: ctx = {'context': threaded_comment_json(request, comment)} return HttpResponse(json.dumps(ctx), content_type='application/json')
def comment_save(request, comment_id, next_url=None): "save comment, since comments/post only does add, no edit" comment = ThreadedComment.objects.get(pk=comment_id) if comment.content_object.permission_to( 'manage', request.course, request.user): comment.comment = request.POST['comment'] elif comment.user == request.user: now = datetime.now() comment.comment = '<div class="postupdate">[Post updated at \ <time datetime="%s">%s</time>]</div>%s' % \ (now.isoformat(), now.strftime('%I:%M%p %D').lower(), request.POST['comment']) else: return HttpResponseForbidden('You do not have permission \ to edit this discussion.') if request.POST.get('title', None): comment.title = request.POST['title'] if not comment.parent: disc_sc = comment.content_object disc_sc.title = comment.title disc_sc.save() comment.save() DiscussionIndex.update_class_references(comment.comment, comment.user, comment, comment.content_object, comment.user) if request.META['HTTP_ACCEPT'].startswith("text/html"): return {'comment': comment} else: ctx = {'context': threaded_comment_json(request, comment)} return HttpResponse(json.dumps(ctx), content_type='application/json')
def update_references(self): DiscussionIndex.update_class_references(self.project.body, None, None, self.collaboration, self.project.author)
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')
def discussion_create(request): """Start a discussion of an arbitrary model instance.""" title = request.POST['comment_html'] comment = request.POST.get('comment', '') # 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.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. 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.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(): return HttpResponseRedirect("/discussion/%d/" % new_threaded_comment.id) 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')