def test_last_participation_is_old(self): article = PublishedContentFactory(author_list=[self.user_author], type="ARTICLE") new_user = ProfileFactory().user reac = ContentReaction(author=self.user_author, position=1, related_content=article) reac.update_content("I will find you.") reac.save() article.last_note = reac article.save() self.assertFalse(last_participation_is_old(article, new_user)) ContentRead(user=self.user_author, note=reac, content=article).save() reac = ContentReaction(author=new_user, position=2, related_content=article) reac.update_content("I will find you.") reac.save() article.last_note = reac article.save() ContentRead(user=new_user, note=reac, content=article).save() self.assertFalse(last_participation_is_old(article, new_user)) self.assertTrue(last_participation_is_old(article, self.user_author))
def test_last_participation_is_old(self): article = PublishedContentFactory(author_list=[self.user_author], type='ARTICLE') new_user = ProfileFactory().user reac = ContentReaction(author=self.user_author, position=1, related_content=article) reac.update_content('I will find you.') reac.save() article.last_note = reac article.save() self.assertFalse(last_participation_is_old(article, new_user)) ContentRead(user=self.user_author, note=reac, content=article).save() reac = ContentReaction(author=new_user, position=2, related_content=article) reac.update_content('I will find you.') reac.save() article.last_note = reac article.save() ContentRead(user=new_user, note=reac, content=article).save() self.assertFalse(last_participation_is_old(article, new_user)) self.assertTrue(last_participation_is_old(article, self.user_author))
class SendNoteFormView(LoggedWithReadWriteHability, SingleOnlineContentFormViewMixin): denied_if_lock = True form_class = NoteForm check_as = True reaction = None template_name = 'tutorialv2/comment/new.html' quoted_reaction_text = '' new_note = False def get_form_kwargs(self): kwargs = super(SendNoteFormView, self).get_form_kwargs() kwargs['content'] = self.object kwargs['reaction'] = None # handle the case when another user have post something in between if 'last_note' in self.request.POST and self.request.POST[ 'last_note'].strip() != '': try: last_note = int(self.request.POST['last_note']) except ValueError: pass else: if self.object.last_note and last_note != self.object.last_note.pk: self.new_note = True kwargs['last_note'] = self.object.last_note.pk return kwargs def get_initial(self): initial = super(SendNoteFormView, self).get_initial() if self.quoted_reaction_text: initial['text'] = self.quoted_reaction_text return initial def get_context_data(self, **kwargs): context = super(SendNoteFormView, self).get_context_data(**kwargs) # handle the case were there is a new message in the discussion if self.new_note: context['newnote'] = True # last few messages context['notes'] = ContentReaction.objects\ .select_related('author') \ .select_related('author__profile') \ .select_related('hat') \ .select_related('editor') \ .prefetch_related('alerts_on_this_comment') \ .prefetch_related('alerts_on_this_comment__author') \ .filter(related_content=self.object) \ .order_by('-pubdate')[:settings.ZDS_APP['content']['notes_per_page']] return context def get(self, request, *args, **kwargs): # handle quoting case if 'cite' in self.request.GET: try: cited_pk = int(self.request.GET['cite']) except ValueError: raise Http404('L\'argument `cite` doit être un entier.') reaction = ContentReaction.objects.filter(pk=cited_pk).first() if reaction: if not reaction.is_visible: raise PermissionDenied text = '\n'.join('> ' + line for line in reaction.text.split('\n')) text += '\nSource: [{}]({})'.format( reaction.author.username, reaction.get_absolute_url()) if self.request.is_ajax(): return StreamingHttpResponse( json_handler.dumps({'text': text}, ensure_ascii=False)) else: self.quoted_reaction_text = text try: return super(SendNoteFormView, self).get(request, *args, **kwargs) except MustRedirect: # if someone changed the pk argument, and reached a 'must redirect' public object raise Http404( "Aucun contenu public trouvé avec l'identifiant {}".format( str(self.request.GET.get('pk', 0)))) def post(self, request, *args, **kwargs): if 'preview' in request.POST and request.is_ajax(): content = render_to_response('misc/preview.part.html', {'text': request.POST['text']}) return StreamingHttpResponse(content) else: return super(SendNoteFormView, self).post(request, *args, **kwargs) def form_valid(self, form): if self.check_as and self.object.antispam(self.request.user): raise PermissionDenied if 'preview' in self.request.POST: return self.form_invalid(form) is_new = False if self.reaction: # it's an edition edit = CommentEdit() edit.comment = self.reaction edit.editor = self.request.user edit.original_text = self.reaction.text edit.save() self.reaction.update = datetime.now() self.reaction.editor = self.request.user self.reaction.hat = get_hat_from_request(self.request, self.reaction.author) else: self.reaction = ContentReaction() self.reaction.pubdate = datetime.now() self.reaction.author = self.request.user self.reaction.position = self.object.get_note_count() + 1 self.reaction.related_content = self.object self.reaction.hat = get_hat_from_request(self.request) is_new = True # also treat alerts if editor is a moderator if self.request.user != self.reaction.author and not is_new: alerts = Alert.objects.filter(comment__pk=self.reaction.pk, solved=False) for alert in alerts: alert.solve(self.request.user, _('Le message a été modéré.')) self.reaction.update_content( form.cleaned_data['text'], on_error=lambda m: messages.error( self.request, _('Erreur du serveur Markdown: {}').format('\n- '.join(m)))) self.reaction.ip_address = get_client_ip(self.request) self.reaction.save() if is_new: # we first need to save the reaction self.object.last_note = self.reaction self.object.save(update_date=False, force_slug_update=False) self.success_url = self.reaction.get_absolute_url() return super(SendNoteFormView, self).form_valid(form)
class SendNoteFormView(LoggedWithReadWriteHability, SingleOnlineContentFormViewMixin): denied_if_lock = True form_class = NoteForm check_as = True reaction = None template_name = "tutorialv2/comment/new.html" quoted_reaction_text = "" new_note = False def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["content"] = self.object kwargs["reaction"] = None # handle the case when another user have post something in between if "last_note" in self.request.POST and self.request.POST[ "last_note"].strip() != "": try: last_note = int(self.request.POST["last_note"]) except ValueError: pass else: if self.object.last_note and last_note != self.object.last_note.pk: self.new_note = True kwargs["last_note"] = self.object.last_note.pk return kwargs def get_initial(self): initial = super().get_initial() if self.quoted_reaction_text: initial["text"] = self.quoted_reaction_text return initial def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # handle the case were there is a new message in the discussion if self.new_note: context["newnote"] = True # last few messages context["notes"] = ( ContentReaction.objects.select_related("author").select_related( "author__profile").select_related("hat").select_related( "editor").prefetch_related("alerts_on_this_comment"). prefetch_related("alerts_on_this_comment__author").filter( related_content=self.object).order_by("-pubdate") [:settings.ZDS_APP["content"]["notes_per_page"]]) return context def get(self, request, *args, **kwargs): # handle quoting case if "cite" in self.request.GET: try: cited_pk = int(self.request.GET["cite"]) except ValueError: raise Http404("L'argument `cite` doit être un entier.") reaction = ContentReaction.objects.filter(pk=cited_pk).first() if reaction: if not reaction.is_visible: raise PermissionDenied text = "\n".join("> " + line for line in reaction.text.split("\n")) text += f"\nSource: [{reaction.author.username}]({reaction.get_absolute_url()})" if self.request.is_ajax(): return StreamingHttpResponse( json_handler.dumps({"text": text}, ensure_ascii=False)) else: self.quoted_reaction_text = text try: return super().get(request, *args, **kwargs) except MustRedirect: # if someone changed the pk argument, and reached a 'must redirect' public object raise Http404( "Aucun contenu public trouvé avec l'identifiant {}".format( str(self.request.GET.get("pk", 0)))) def post(self, request, *args, **kwargs): if "preview" in request.POST and request.is_ajax(): content = render(request, "misc/preview.part.html", {"text": request.POST["text"]}) return StreamingHttpResponse(content) else: return super().post(request, *args, **kwargs) def form_valid(self, form): if self.check_as and self.object.antispam(self.request.user): raise PermissionDenied if "preview" in self.request.POST: return self.form_invalid(form) is_new = False if self.reaction: # it's an edition edit = CommentEdit() edit.comment = self.reaction edit.editor = self.request.user edit.original_text = self.reaction.text edit.save() self.reaction.update = datetime.now() self.reaction.editor = self.request.user self.reaction.hat = get_hat_from_request(self.request, self.reaction.author) else: self.reaction = ContentReaction() self.reaction.pubdate = datetime.now() self.reaction.author = self.request.user self.reaction.position = self.object.get_note_count() + 1 self.reaction.related_content = self.object self.reaction.hat = get_hat_from_request(self.request) is_new = True # also treat alerts if editor is a moderator if self.request.user != self.reaction.author and not is_new: alerts = Alert.objects.filter(comment__pk=self.reaction.pk, solved=False) for alert in alerts: alert.solve(self.request.user, _("Le message a été modéré.")) self.reaction.update_content( form.cleaned_data["text"], on_error=lambda m: messages.error( self.request, _("Erreur du serveur Markdown: {}").format("\n- ".join(m))), ) self.reaction.ip_address = get_client_ip(self.request) self.reaction.save() if is_new: # we first need to save the reaction self.object.last_note = self.reaction self.object.save(update_date=False) self.success_url = self.reaction.get_absolute_url() return super().form_valid(form)