def get_public_object(self): try: if 'pk' in self.kwargs: pk = int(self.kwargs['pk']) elif 'pk' in self.request.GET: pk = int(self.request.GET['pk']) elif 'pk' in self.request.POST: pk = int(self.request.POST['pk']) else: raise Http404("Impossible de trouver le paramètre 'pk'.") except ValueError as badvalue: raise Http404( "La valeur du paramètre pk '{}' n'est pas un entier valide.". format(badvalue)) queryset = PublishedContent.objects\ .filter(content_pk=pk)\ .prefetch_related('content')\ .prefetch_related('content__authors')\ .prefetch_related('content__subcategory')\ .prefetch_related('content__tags')\ .prefetch_related('content__public_version')\ .select_related('content__last_note') if self.current_content_type: queryset = queryset.filter(content_type=self.current_content_type) if 'slug' in self.kwargs: queryset = queryset.filter(content_public_slug=self.kwargs['slug']) obj = queryset.order_by('publication_date').last( ) # 'last' version must be the most recent to be published if obj is None: raise Http404('Aucun contenu ne possède ce slug.') # Redirection ? if obj.must_redirect: if obj.content.public_version and self.redirection_is_needed: raise MustRedirect(self.get_redirect_url(obj)) elif obj.content.public_version and not self.redirection_is_needed: obj = obj.content.public_version else: # should only happen if the content is unpublished raise Http404( "La redirection est activée mais le contenu n'est pas public." ) self.is_author = self.request.user in obj.authors.all() self.is_staff = self.request.user.has_perm( 'tutorialv2.change_publishablecontent') self.current_content_type = obj.content_type if obj and obj.content.last_note: mark_read(obj.content, self.request.user) return obj
def get_public_object(self): try: if 'pk' in self.kwargs: pk = int(self.kwargs['pk']) elif 'pk' in self.request.GET: pk = int(self.request.GET['pk']) elif 'pk' in self.request.POST: pk = int(self.request.POST['pk']) else: raise Http404("Impossible de trouver le paramètre 'pk'.") except ValueError as badvalue: raise Http404("La valeur du paramètre pk '{}' n'est pas un entier valide.".format(badvalue)) queryset = PublishedContent.objects\ .filter(content_pk=pk)\ .prefetch_related('content')\ .prefetch_related('content__authors')\ .prefetch_related('content__subcategory')\ .prefetch_related('content__tags')\ .prefetch_related('content__public_version')\ .select_related('content__last_note') if self.current_content_type: queryset = queryset.filter(content_type=self.current_content_type) if 'slug' in self.kwargs: queryset = queryset.filter(content_public_slug=self.kwargs['slug']) obj = queryset.order_by('publication_date').last() # 'last' version must be the most recent to be published if obj is None: raise Http404('Aucun contenu ne possède ce slug.') # Redirection ? if obj.must_redirect: if obj.content.public_version and self.redirection_is_needed: raise MustRedirect(self.get_redirect_url(obj)) elif obj.content.public_version and not self.redirection_is_needed: obj = obj.content.public_version else: # should only happen if the content is unpublished raise Http404("La redirection est activée mais le contenu n'est pas public.") self.is_author = self.request.user in obj.authors.all() self.is_staff = self.request.user.has_perm('tutorialv2.change_publishablecontent') self.current_content_type = obj.content_type if obj and obj.content.last_note: mark_read(obj.content, self.request.user) return obj
def form_valid(self, form): if self.check_as and self.object.antispam(self.request.user): raise PermissionDenied if 'preview' in self.request.POST: # previewing return self.form_invalid(form) is_new = False if self.reaction: # it's an edition self.reaction.update = datetime.now() self.reaction.editor = self.request.user 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 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).all() for alert in alerts: SolveNoteAlert.solve(alert, self.reaction, self.request.user) self.reaction.update_content(form.cleaned_data["text"]) 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() mark_read(self.object) self.success_url = self.reaction.get_absolute_url() return super(SendNoteFormView, self).form_valid(form)
def get_context_data(self, **kwargs): """Show the given tutorial if exists.""" context = super(DisplayOnlineContent, self).get_context_data(**kwargs) if context['is_staff']: if self.current_content_type == 'OPINION': context['alerts'] = self.object.alerts_on_this_content.all() context['formRevokeValidation'] = RevokeValidationForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) context['formUnpublication'] = UnpublicationForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) context['formWarnTypo'] = WarnTypoForm(self.versioned_object, self.versioned_object) queryset_reactions = 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__pk=self.object.pk) \ .order_by('pubdate') # pagination of articles and opinions context['previous_content'] = None context['next_content'] = None if self.current_content_type in ('ARTICLE', 'OPINION'): queryset_pagination = PublishedContent.objects.filter( content_type=self.current_content_type, must_redirect=False) if self.current_content_type == 'OPINION': # filter opinions only from the same author queryset_pagination = queryset_pagination.filter( authors__in=self.object.authors.all()) context['previous_content'] = queryset_pagination \ .filter(publication_date__lt=self.public_content_object.publication_date) \ .order_by('publication_date').first() context['next_content'] = queryset_pagination \ .filter(publication_date__gt=self.public_content_object.publication_date) \ .order_by('publication_date').first() if self.versioned_object.type == 'OPINION': context['formPickOpinion'] = PickOpinionForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) context['formUnpickOpinion'] = UnpickOpinionForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) context['formConvertOpinion'] = PromoteOpinionToArticleForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) # pagination of comments make_pagination(context, self.request, queryset_reactions, settings.ZDS_APP['content']['notes_per_page'], context_list_name='reactions', with_previous_item=True) # is JS activated ? context['is_js'] = True if not self.object.js_support: context['is_js'] = False # optimize requests: votes = CommentVote.objects.filter( user_id=self.request.user.id, comment__in=queryset_reactions).all() context['user_like'] = [ vote.comment_id for vote in votes if vote.positive ] context['user_dislike'] = [ vote.comment_id for vote in votes if not vote.positive ] if self.request.user.has_perm('tutorialv2.change_contentreaction'): context['user_can_modify'] = [ reaction.pk for reaction in queryset_reactions ] else: context['user_can_modify'] = [ reaction.pk for reaction in queryset_reactions if reaction.author == self.request.user ] context['is_antispam'] = self.object.antispam() context['pm_link'] = self.object.get_absolute_contact_url( _('À propos de')) context[ 'subscriber_count'] = ContentReactionAnswerSubscription.objects.get_subscriptions( self.object).count() # We need reading time expressed in minutes try: context['reading_time'] = int( self.versioned_object.get_tree_level() * self.object.public_version.char_count / settings.ZDS_APP['content']['characters_per_minute']) except ZeroDivisionError as e: logger.warning( 'could not compute reading time: setting characters_per_minute is set to zero (error=%s)', e) if self.request.user.is_authenticated(): for reaction in context['reactions']: signals.content_read.send(sender=reaction.__class__, instance=reaction, user=self.request.user) signals.content_read.send(sender=self.object.__class__, instance=self.object, user=self.request.user, target=PublishableContent) if last_participation_is_old(self.object, self.request.user): mark_read(self.object, self.request.user) return context
def get_context_data(self, **kwargs): """Show the given tutorial if exists.""" context = super(DisplayOnlineContent, self).get_context_data(**kwargs) if context['is_staff']: context['formRevokeValidation'] = RevokeValidationForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) context['formWarnTypo'] = WarnTypoForm(self.versioned_object, self.versioned_object) queryset_reactions = ContentReaction.objects\ .select_related('author')\ .select_related('author__profile')\ .select_related('editor')\ .prefetch_related('alerts')\ .prefetch_related('alerts__author')\ .filter(related_content__pk=self.object.pk)\ .order_by("pubdate") # pagination of articles context['paginate_articles'] = False if self.object.type == 'ARTICLE': # fetch all articles in order to find the previous and the next one all_articles = \ [a for a in PublishedContent.objects .filter(content_type="ARTICLE", must_redirect=False) .order_by('publication_date') .all()] articles_count = len(all_articles) try: position = all_articles.index(self.public_content_object) except ValueError: pass # for an unknown reason, the article is not in the list. This should not happen else: context['paginate_articles'] = True context['previous_article'] = None context['next_article'] = None if position > 0: context['previous_article'] = all_articles[position - 1] if position < articles_count - 1: context['next_article'] = all_articles[position + 1] # pagination of comments make_pagination(context, self.request, queryset_reactions, settings.ZDS_APP['content']['notes_per_page'], context_list_name='reactions', with_previous_item=True) # is JS activated ? context["is_js"] = True if not self.object.js_support: context["is_js"] = False # optimize requests: context["user_dislike"] = CommentDislike.objects\ .select_related('note')\ .filter(user__pk=self.request.user.pk, comments__in=context['reactions'])\ .values_list('comments__pk', flat=True) context["user_like"] = CommentLike.objects\ .select_related('note')\ .filter(user__pk=self.request.user.pk, comments__in=context['reactions'])\ .values_list('comments__pk', flat=True) if self.request.user.has_perm('tutorialv2.change_contentreaction'): context["user_can_modify"] = [ reaction.pk for reaction in context['reactions'] ] else: queryset_reactions_user = ContentReaction.objects\ .filter(author__pk=self.request.user.pk, related_content__pk=self.object.pk)\ .values_list('id', flat=True) context["user_can_modify"] = queryset_reactions_user context['isantispam'] = self.object.antispam() # handle reactions: if last_participation_is_old(self.object, self.request.user): mark_read(self.object) return context
def get_context_data(self, **kwargs): """Show the given tutorial if exists.""" context = super(DisplayOnlineContent, self).get_context_data(**kwargs) if context["is_staff"]: if self.current_content_type == "OPINION": context["alerts"] = self.object.alerts_on_this_content.all() context["formRevokeValidation"] = RevokeValidationForm( self.versioned_object, initial={"version": self.versioned_object.sha_public}) context["formUnpublication"] = UnpublicationForm( self.versioned_object, initial={"version": self.versioned_object.sha_public}) context["formWarnTypo"] = WarnTypoForm(self.versioned_object, self.versioned_object) queryset_reactions = ( 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__pk=self.object.pk).order_by("pubdate")) # pagination of articles and opinions context["previous_content"] = None context["next_content"] = None if self.current_content_type in ("ARTICLE", "OPINION"): queryset_pagination = PublishedContent.objects.filter( content_type=self.current_content_type, must_redirect=False) context["previous_content"] = (queryset_pagination.filter( publication_date__lt=self.public_content_object. publication_date).order_by("-publication_date").first()) context["next_content"] = (queryset_pagination.filter( publication_date__gt=self.public_content_object. publication_date).order_by("publication_date").first()) if self.versioned_object.type == "OPINION": context["formPickOpinion"] = PickOpinionForm( self.versioned_object, initial={"version": self.versioned_object.sha_public}) context["formUnpickOpinion"] = UnpickOpinionForm( self.versioned_object, initial={"version": self.versioned_object.sha_public}) context["formConvertOpinion"] = PromoteOpinionToArticleForm( self.versioned_object, initial={"version": self.versioned_object.sha_public}) else: context["content_suggestions"] = ContentSuggestion.objects.filter( publication=self.object) excluded_for_search = [ str(x.suggestion.pk) for x in context["content_suggestions"] ] excluded_for_search.append(str(self.object.pk)) context["formAddSuggestion"] = SearchSuggestionForm( content=self.object, initial={"excluded_pk": ",".join(excluded_for_search)}) context["form_edit_tags"] = EditContentTagsForm( self.versioned_object, self.object) # pagination of comments make_pagination( context, self.request, queryset_reactions, settings.ZDS_APP["content"]["notes_per_page"], context_list_name="reactions", with_previous_item=True, ) # is JS activated ? context["is_js"] = True if not self.object.js_support: context["is_js"] = False # optimize requests: votes = CommentVote.objects.filter( user_id=self.request.user.id, comment__in=queryset_reactions).all() context["user_like"] = [ vote.comment_id for vote in votes if vote.positive ] context["user_dislike"] = [ vote.comment_id for vote in votes if not vote.positive ] if self.request.user.has_perm("tutorialv2.change_contentreaction"): context["user_can_modify"] = [ reaction.pk for reaction in queryset_reactions ] else: context["user_can_modify"] = [ reaction.pk for reaction in queryset_reactions if reaction.author == self.request.user ] context["is_antispam"] = self.object.antispam() context["pm_link"] = self.object.get_absolute_contact_url( _("À propos de")) context[ "subscriber_count"] = ContentReactionAnswerSubscription.objects.get_subscriptions( self.object).count() # We need reading time expressed in minutes try: char_count = self.object.public_version.char_count if char_count: context["reading_time"] = int( self.versioned_object.get_tree_level() * char_count / settings.ZDS_APP["content"]["characters_per_minute"]) except ZeroDivisionError as e: logger.warning( "could not compute reading time: setting characters_per_minute is set to zero (error=%s)", e) if self.request.user.is_authenticated: for reaction in context["reactions"]: signals.content_read.send(sender=reaction.__class__, instance=reaction, user=self.request.user) signals.content_read.send(sender=self.object.__class__, instance=self.object, user=self.request.user, target=PublishableContent) if last_participation_is_old(self.object, self.request.user): mark_read(self.object, self.request.user) context["contributions"] = ContentContribution.objects.filter( content=self.object).order_by("contribution_role__position") context[ "content_suggestions_random"] = ContentSuggestion.objects.filter( publication=self.object).order_by( "?")[:settings.ZDS_APP["content"]["suggestions_per_page"]] return context
def get_context_data(self, **kwargs): """Show the given tutorial if exists.""" context = super(DisplayOnlineContent, self).get_context_data(**kwargs) if context['is_staff']: context['formRevokeValidation'] = RevokeValidationForm( self.versioned_object, initial={'version': self.versioned_object.sha_public}) context['formWarnTypo'] = WarnTypoForm(self.versioned_object, self.versioned_object) queryset_reactions = ContentReaction.objects\ .select_related('author')\ .select_related('author__profile')\ .select_related('editor')\ .prefetch_related('alerts')\ .prefetch_related('alerts__author')\ .filter(related_content__pk=self.object.pk)\ .order_by("pubdate") # pagination of articles context['paginate_articles'] = False if self.object.type == 'ARTICLE': # fetch all articles in order to find the previous and the next one all_articles = \ [a for a in PublishedContent.objects .filter(content_type="ARTICLE", must_redirect=False) .order_by('publication_date') .all()] articles_count = len(all_articles) try: position = all_articles.index(self.public_content_object) except ValueError: pass # for an unknown reason, the article is not in the list. This should not happen else: context['paginate_articles'] = True context['previous_article'] = None context['next_article'] = None if position > 0: context['previous_article'] = all_articles[position - 1] if position < articles_count - 1: context['next_article'] = all_articles[position + 1] # pagination of comments make_pagination(context, self.request, queryset_reactions, settings.ZDS_APP['content']['notes_per_page'], context_list_name='reactions', with_previous_item=True) # is JS activated ? context["is_js"] = True if not self.object.js_support: context["is_js"] = False # optimize requests: votes = CommentVote.objects.filter(user_id=self.request.user.id, comment__in=queryset_reactions).all() context["user_like"] = [vote.comment_id for vote in votes if vote.positive] context["user_dislike"] = [vote.comment_id for vote in votes if not vote.positive] if self.request.user.has_perm('tutorialv2.change_contentreaction'): context["user_can_modify"] = [reaction.pk for reaction in queryset_reactions] else: context["user_can_modify"] = [reaction.pk for reaction in queryset_reactions if reaction.author == self.request.user] context['isantispam'] = self.object.antispam() context['pm_link'] = self.object.get_absolute_contact_url(_(u'À propos de')) context['subscriber_count'] = ContentReactionAnswerSubscription.objects.get_subscriptions(self.object).count() if self.request.user.is_authenticated(): for reaction in context['reactions']: signals.content_read.send(sender=reaction.__class__, instance=reaction, user=self.request.user) signals.content_read.send( sender=self.object.__class__, instance=self.object, user=self.request.user, target=PublishableContent) if last_participation_is_old(self.object, self.request.user): mark_read(self.object, self.request.user) return context