def form_valid(self, form): versioned = self.versioned_object user = self.request.user if user not in versioned.authors.all( ) and not user.has_perm("tutorialv2.change_validation"): raise PermissionDenied if form.cleaned_data["version"] != self.object.sha_public: raise PermissionDenied unpublish_content(self.object, moderator=self.request.user) if [self.request.user] != list(self.object.authors.all()): # Sends PM if the deleter is not the author # (or is not the only one) of the opinion. msg = render_to_string( "tutorialv2/messages/validation_revoke.md", { "content": versioned, "url": versioned.get_absolute_url(), "admin": user, "message_reject": "\n".join([ "> " + a for a in form.cleaned_data["text"].split("\n") ]), }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("moderation"), ) self.object.save() else: send_message_mp( bot, self.object.validation_private_message, msg, hat=get_hat_from_settings("moderation"), no_notification_for=[self.request.user], ) messages.success(self.request, _("Le contenu a bien été dépublié.")) self.success_url = self.versioned_object.get_absolute_url() return super().form_valid(form)
def form_valid(self, form): versioned = self.versioned_object user = self.request.user if user not in versioned.authors.all( ) and not user.has_perm('tutorialv2.change_validation'): raise PermissionDenied if form.cleaned_data['version'] != self.object.sha_public: raise PermissionDenied unpublish_content(self.object, moderator=self.request.user) if [self.request.user] != list(self.object.authors.all()): # Sends PM if the deleter is not the author # (or is not the only one) of the opinion. msg = render_to_string( 'tutorialv2/messages/validation_revoke.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'admin': user, 'message_reject': '\n'.join([ '> ' + a for a in form.cleaned_data['text'].split('\n') ]) }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) self.object.save(force_slug_update=False) else: send_message_mp(bot, self.object.validation_private_message, msg, hat=get_hat_from_settings('moderation'), no_notification_for=self.request.user) messages.success(self.request, _('Le contenu a bien été dépublié.')) self.success_url = self.versioned_object.get_absolute_url() return super(UnpublishOpinion, self).form_valid(form)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() db_object.sha_picked = form.cleaned_data["version"] db_object.picked_date = datetime.now() db_object.save() # mark to reindex to boost correctly in the search self.public_content_object.es_flagged = True self.public_content_object.save() PickListOperation.objects.create( content=self.object, operation="PICK", staff_user=self.request.user, operation_date=datetime.now(), version=db_object.sha_picked, ) msg = render_to_string( "tutorialv2/messages/validation_opinion.md", { "title": versioned.title, "url": versioned.get_absolute_url(), }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("moderation"), ) self.object.save() else: send_message_mp( bot, self.object.validation_private_message, msg, hat=get_hat_from_settings("moderation"), no_notification_for=[self.request.user], ) messages.success(self.request, _("Le billet a bien été choisi.")) return super().form_valid(form)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() if not db_object.in_public(): raise Http404('This opinion is not published.') elif PickListOperation.objects.filter(content=self.object, is_effective=True).exists() \ and form.cleaned_data['operation'] != 'REMOVE_PUB': raise PermissionDenied( 'There is already an effective operation for this content.') try: PickListOperation.objects.filter(content=self.object).update( is_effective=False, canceler_user=self.request.user) PickListOperation.objects.create( content=self.object, operation=form.cleaned_data['operation'], staff_user=self.request.user, operation_date=datetime.now(), version=db_object.sha_public) if form.cleaned_data['operation'] == 'REMOVE_PUB': unpublish_content(self.object, moderator=self.request.user) # send PM msg = render_to_string( 'tutorialv2/messages/validation_unpublish_opinion.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'moderator': self.request.user, }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, versioned.authors.all(), _('Billet modéré'), versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) except ValueError: logger.exception('Could not %s the opinion %s', form.cleaned_data['operation'], str(self.object)) return HttpResponse(json.dumps({ 'result': 'FAIL', 'reason': str(_('Mauvaise opération')) }), status=400) if not form.cleaned_data['redirect']: return HttpResponse(json.dumps({'result': 'OK'})) else: self.success_url = reverse('opinion:list') messages.success(self.request, _('Le billet a bien été modéré.')) return super().form_valid(form)
def form_valid(self, form): versioned = self.versioned_object if form.cleaned_data['version'] != self.object.sha_public: raise PermissionDenied validation = Validation.objects.filter( content=self.object, version=self.object.sha_public, status='ACCEPT').prefetch_related('content__authors').last() if not validation: raise PermissionDenied unpublish_content(self.object) validation.status = 'PENDING' validation.validator = None # remove previous validator validation.date_validation = None validation.save() self.object.sha_public = None self.object.sha_validation = validation.version self.object.pubdate = None self.object.save() # send PM msg = render_to_string( 'tutorialv2/messages/validation_revoke.md', { 'content': versioned, 'url': versioned.get_absolute_url() + '?version=' + validation.version, 'admin': self.request.user, 'message_reject': '\n'.join( ['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, validation.content.authors.all(), _('Dépublication'), validation.content.title, msg, True, direct=False, hat=get_hat_from_settings('validation'), ) messages.success(self.request, _('Le contenu a bien été dépublié.')) self.success_url = self.versioned_object.get_absolute_url( ) + '?version=' + validation.version return super(RevokeValidation, self).form_valid(form)
def post(self, request, *args, **kwargs): validation = get_object_or_404(Validation, pk=kwargs['pk']) if validation.validator: validation.validator = None validation.date_reserve = None validation.status = 'PENDING' validation.save() messages.info(request, _("Ce contenu n'est plus réservé.")) return redirect(reverse('validation:list')) else: validation.validator = request.user validation.date_reserve = datetime.now() validation.status = 'PENDING_V' validation.save() versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( 'tutorialv2/messages/validation_reserve.md', { 'content': versioned, 'url': versioned.get_absolute_url() + '?version=' + validation.version, }) authors = list(validation.content.authors.all()) if validation.validator in authors: authors.remove(validation.validator) if len(authors) > 0: if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( validation.validator, authors, _('Contenu réservé - {0}').format( validation.content.title), validation.content.title, msg, True, leave=False, direct=False, mark_as_read=True, hat=get_hat_from_settings('validation'), ) validation.content.save(force_slug_update=False) else: send_message_mp( validation.validator, validation.content.validation_private_message, msg) mark_read(validation.content.validation_private_message, validation.validator) messages.info( request, _('Ce contenu a bien été réservé par {0}.').format( request.user.username)) return redirect( reverse('content:view', args=[validation.content.pk, validation.content.slug]) + '?version=' + validation.version)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() db_object.sha_picked = form.cleaned_data['version'] db_object.picked_date = datetime.now() db_object.save() # mark to reindex to boost correctly in the search self.public_content_object.es_flagged = True self.public_content_object.save() PickListOperation.objects.create(content=self.object, operation='PICK', staff_user=self.request.user, operation_date=datetime.now(), version=db_object.sha_picked) msg = render_to_string('tutorialv2/messages/validation_opinion.md', { 'title': versioned.title, 'url': versioned.get_absolute_url(), }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) self.object.save(force_slug_update=False) else: send_message_mp(bot, self.object.validation_private_message, msg, hat=get_hat_from_settings('moderation'), no_notification_for=self.request.user) messages.success(self.request, _('Le billet a bien été choisi.')) return super(PickOpinion, self).form_valid(form)
def form_valid(self, form): db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() if not db_object.sha_picked: raise PermissionDenied( 'Impossible de retirer des billets choisis un billet pas choisi.' ) if db_object.sha_picked != form.cleaned_data['version']: raise PermissionDenied( 'Impossible de retirer des billets choisis un billet pas choisi.' ) db_object.sha_picked = None db_object.save() PickListOperation.objects\ .filter(operation='PICK', is_effective=True, content=self.object)\ .first().cancel(self.request.user) # mark to reindex to boost correctly in the search self.public_content_object.es_flagged = True self.public_content_object.save() msg = render_to_string( 'tutorialv2/messages/validation_invalid_opinion.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'admin': self.request.user, 'message_reject': '\n'.join( ['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) self.object.save(force_slug_update=False) else: send_message_mp(bot, self.object.validation_private_message, msg) messages.success( self.request, _('Le contenu a bien été enlevé de la liste des billets choisis.')) return super(UnpickOpinion, self).form_valid(form)
def activate_account(request): """Activate an account with a token.""" try: token = request.GET['token'] except KeyError: return redirect(reverse('homepage')) token = get_object_or_404(TokenRegister, token=token) usr = token.user # User can't confirm their request if their account is already active if usr.is_active: return render(request, 'member/register/token_already_used.html') # User can't confirm their request if it is too late if datetime.now() > token.date_end: return render(request, 'member/register/token_failed.html', {'token': token}) usr.is_active = True usr.save() # Send welcome message bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'member/messages/account_activated.md', { 'username': usr.username, 'tutorials_url': settings.ZDS_APP['site']['url'] + reverse('publication:list') + '?type=tutorial', 'articles_url': settings.ZDS_APP['site']['url'] + reverse('publication:list') + '?type=article', 'opinions_url': settings.ZDS_APP['site']['url'] + reverse('opinion:list'), 'members_url': settings.ZDS_APP['site']['url'] + reverse('member-list'), 'forums_url': settings.ZDS_APP['site']['url'] + reverse('cats-forums-list'), 'site_name': settings.ZDS_APP['site']['literal_name'] } ) send_mp(bot, [usr], _('Bienvenue sur {}').format(settings.ZDS_APP['site']['literal_name']), _('Le manuel du nouveau membre'), msg, False, True, False, hat=get_hat_from_settings('moderation')) token.delete() # Create an alert for the staff if it's a new provider if usr.email: provider = usr.email.split('@')[-1].lower() if not NewEmailProvider.objects.filter(provider=provider).exists() \ and not User.objects.filter(email__iendswith='@{}'.format(provider)) \ .exclude(pk=usr.pk).exists(): NewEmailProvider.objects.create(user=usr, provider=provider, use=NEW_ACCOUNT) form = LoginForm(initial={'username': usr.username}) return render(request, 'member/register/token_success.html', {'usr': usr, 'form': form})
def form_valid(self, form): old_validation = Validation.objects.filter( content__pk=self.object.pk, status__in=['PENDING', 'PENDING_V']).first() if old_validation: # if an old validation exists, cancel it! old_validator = old_validation.validator old_validation.status = 'CANCEL' old_validation.date_validation = datetime.now() old_validation.save() else: old_validator = None # create a 'validation' object validation = Validation() validation.content = self.object validation.date_proposition = datetime.now() validation.comment_authors = form.cleaned_data['text'] validation.version = form.cleaned_data['version'] if old_validator: validation.validator = old_validator validation.date_reserve = old_validation.date_reserve validation.status = 'PENDING_V' validation.save() # warn the former validator that an update has been made, if any if old_validator: bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'tutorialv2/messages/validation_change.md', { 'content': self.versioned_object, 'validator': validation.validator.username, 'url': self.versioned_object.get_absolute_url() + '?version=' + form.cleaned_data['version'], 'url_history': reverse('content:history', args=[self.object.pk, self.object.slug]) }) send_mp( bot, [old_validator], _('Une nouvelle version a été envoyée en validation.'), self.versioned_object.title, msg, False, hat=get_hat_from_settings('validation'), ) # update the content with the source and the version of the validation self.object.source = form.cleaned_data['source'] self.object.sha_validation = validation.version self.object.save() messages.success(self.request, _("Votre demande de validation a été transmise à l'équipe.")) self.success_url = self.versioned_object.get_absolute_url(version=self.sha) return super(AskValidationForContent, self).form_valid(form)
def form_valid(self, form): old_validation = Validation.objects.filter( content__pk=self.object.pk, status__in=['PENDING', 'PENDING_V']).first() if old_validation: # if an old validation exists, cancel it! old_validator = old_validation.validator old_validation.status = 'CANCEL' old_validation.date_validation = datetime.now() old_validation.save() else: old_validator = None # create a 'validation' object validation = Validation() validation.content = self.object validation.date_proposition = datetime.now() validation.comment_authors = form.cleaned_data['text'] validation.version = form.cleaned_data['version'] if old_validator: validation.validator = old_validator validation.date_reserve = old_validation.date_reserve validation.status = 'PENDING_V' validation.save() # warn the former validator that an update has been made, if any if old_validator: bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'tutorialv2/messages/validation_change.md', { 'content': self.versioned_object, 'validator': validation.validator.username, 'url': self.versioned_object.get_absolute_url() + '?version=' + form.cleaned_data['version'], 'url_history': reverse('content:history', args=[self.object.pk, self.object.slug]) }) send_mp( bot, [old_validator], _('Une nouvelle version a été envoyée en validation.'), self.versioned_object.title, msg, False, hat=get_hat_from_settings('validation'), ) # update the content with the source and the version of the validation self.object.source = form.cleaned_data['source'] self.object.sha_validation = validation.version self.object.save() messages.success(self.request, _("Votre demande de validation a été transmise à l'équipe.")) self.success_url = self.versioned_object.get_absolute_url(version=self.sha) return super(AskValidationForContent, self).form_valid(form)
def activate_account(request): """Activate an account with a token.""" try: token = request.GET["token"] except KeyError: return redirect(reverse("homepage")) token = get_object_or_404(TokenRegister, token=token) usr = token.user # User can't confirm their request if their account is already active if usr.is_active: return render(request, "member/register/token_already_used.html") # User can't confirm their request if it is too late if datetime.now() > token.date_end: return render(request, "member/register/token_failed.html", {"token": token}) usr.is_active = True usr.save() # Send welcome message bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "member/messages/account_activated.md", { "username": usr.username, "site_name": settings.ZDS_APP["site"]["literal_name"], "library_url": settings.ZDS_APP["site"]["url"] + reverse("publication:list"), "opinions_url": settings.ZDS_APP["site"]["url"] + reverse("opinion:list"), "forums_url": settings.ZDS_APP["site"]["url"] + reverse("cats-forums-list"), }, ) send_mp( bot, [usr], _("Bienvenue sur {}").format(settings.ZDS_APP["site"]["literal_name"]), _("Le manuel du nouveau membre"), msg, send_by_mail=False, leave=True, direct=False, hat=get_hat_from_settings("moderation"), ) token.delete() # Create an alert for the staff if it's a new provider if usr.email: provider = usr.email.split("@")[-1].lower() if ( not NewEmailProvider.objects.filter(provider=provider).exists() and not User.objects.filter(email__iendswith=f"@{provider}").exclude(pk=usr.pk).exists() ): NewEmailProvider.objects.create(user=usr, provider=provider, use=NEW_ACCOUNT) form = LoginForm(initial={"username": usr.username}) return render(request, "member/register/token_success.html", {"usr": usr, "form": form})
def form_valid(self, form): user = self.request.user validation = Validation.objects.filter(pk=self.kwargs['pk']).last() if not validation: raise PermissionDenied if validation.validator != user: raise PermissionDenied if validation.status != 'PENDING_V': raise PermissionDenied # reject validation: validation.comment_validator = form.cleaned_data['text'] validation.status = 'REJECT' validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # send PM versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( 'tutorialv2/messages/validation_reject.md', { 'content': versioned, 'url': versioned.get_absolute_url() + '?version=' + validation.version, 'validator': validation.validator, 'message_reject': '\n'.join( ['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, validation.content.authors.all(), _('Rejet de la demande de publication').format(), validation.content.title, msg, True, direct=False, hat=get_hat_from_settings('validation'), ) messages.info(self.request, _('Le contenu a bien été refusé.')) self.success_url = reverse('validation:list') return super(RejectValidation, self).form_valid(form)
def activate_account(request): """Activate an account with a token.""" try: token = request.GET['token'] except KeyError: return redirect(reverse('homepage')) token = get_object_or_404(TokenRegister, token=token) usr = token.user # User can't confirm their request if their account is already active if usr.is_active: return render(request, 'member/register/token_already_used.html') # User can't confirm their request if it is too late if datetime.now() > token.date_end: return render(request, 'member/register/token_failed.html', {'token': token}) usr.is_active = True usr.save() # Send welcome message bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'member/messages/account_activated.md', { 'username': usr.username, 'site_name': settings.ZDS_APP['site']['literal_name'], 'library_url': settings.ZDS_APP['site']['url'] + reverse('publication:list'), 'opinions_url': settings.ZDS_APP['site']['url'] + reverse('opinion:list'), 'forums_url': settings.ZDS_APP['site']['url'] + reverse('cats-forums-list') } ) send_mp(bot, [usr], _('Bienvenue sur {}').format(settings.ZDS_APP['site']['literal_name']), _('Le manuel du nouveau membre'), msg, False, True, False, hat=get_hat_from_settings('moderation')) token.delete() # Create an alert for the staff if it's a new provider if usr.email: provider = usr.email.split('@')[-1].lower() if not NewEmailProvider.objects.filter(provider=provider).exists() \ and not User.objects.filter(email__iendswith='@{}'.format(provider)) \ .exclude(pk=usr.pk).exists(): NewEmailProvider.objects.create(user=usr, provider=provider, use=NEW_ACCOUNT) form = LoginForm(initial={'username': usr.username}) return render(request, 'member/register/token_success.html', {'usr': usr, 'form': form})
def form_valid(self, form): versioned = self.versioned_object if form.cleaned_data['version'] != self.object.sha_public: raise PermissionDenied validation = Validation.objects.filter( content=self.object, version=self.object.sha_public, status='ACCEPT').prefetch_related('content__authors').last() if not validation: raise PermissionDenied unpublish_content(self.object) validation.status = 'PENDING' validation.validator = None # remove previous validator validation.date_validation = None validation.save() self.object.sha_public = None self.object.sha_validation = validation.version self.object.pubdate = None self.object.save() # send PM msg = render_to_string( 'tutorialv2/messages/validation_revoke.md', { 'content': versioned, 'url': versioned.get_absolute_url() + '?version=' + validation.version, 'admin': self.request.user, 'message_reject': '\n'.join(['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, validation.content.authors.all(), _('Dépublication'), validation.content.title, msg, True, direct=False, hat=get_hat_from_settings('validation'), ) messages.success(self.request, _('Le contenu a bien été dépublié.')) self.success_url = self.versioned_object.get_absolute_url() + '?version=' + validation.version return super(RevokeValidation, self).form_valid(form)
def form_valid(self, form): _type = _("de l'article") if self.object.is_tutorial: _type = _("du tutoriel") elif self.object.is_opinion: _type = _("du billet") bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) all_authors_pk = [author.pk for author in self.object.authors.all()] for user in form.cleaned_data["users"]: if user.pk not in all_authors_pk: self.object.authors.add(user) if self.object.validation_private_message: self.object.validation_private_message.add_participant( user) all_authors_pk.append(user.pk) if user != self.request.user: url_index = reverse(self.object.type.lower() + ":find-" + self.object.type.lower(), args=[user.pk]) send_mp( bot, [user], format_lazy("{}{}", _("Ajout à la rédaction "), _type), self.versioned_object.title, render_to_string( "tutorialv2/messages/add_author_pm.md", { "content": self.object, "type": _type, "url": self.object.get_absolute_url(), "index": url_index, "user": user.username, }, ), hat=get_hat_from_settings("validation"), ) UserGallery(gallery=self.object.gallery, user=user, mode=GALLERY_WRITE).save() signals.authors_management.send(sender=self.__class__, content=self.object, performer=self.request.user, author=user, action="add") self.object.save() self.success_url = self.object.get_absolute_url() return super().form_valid(form)
def form_valid(self, form): user = self.request.user validation = Validation.objects.filter(pk=self.kwargs['pk']).last() if not validation: raise PermissionDenied if validation.validator != user: raise PermissionDenied if validation.status != 'PENDING_V': raise PermissionDenied # reject validation: validation.comment_validator = form.cleaned_data['text'] validation.status = 'REJECT' validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # send PM versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( 'tutorialv2/messages/validation_reject.md', { 'content': versioned, 'url': versioned.get_absolute_url() + '?version=' + validation.version, 'validator': validation.validator, 'message_reject': '\n'.join(['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, validation.content.authors.all(), _('Rejet de la demande de publication').format(), validation.content.title, msg, True, direct=False, hat=get_hat_from_settings('validation'), ) messages.info(self.request, _('Le contenu a bien été refusé.')) self.success_url = reverse('validation:list') return super(RejectValidation, self).form_valid(form)
def form_valid(self, form): db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() if not db_object.sha_picked: raise PermissionDenied("Impossible de retirer des billets choisis un billet pas choisi.") if db_object.sha_picked != form.cleaned_data["version"]: raise PermissionDenied("Impossible de retirer des billets choisis un billet pas choisi.") db_object.sha_picked = None db_object.save() PickListOperation.objects.filter(operation="PICK", is_effective=True, content=self.object).first().cancel( self.request.user ) # mark to reindex to boost correctly in the search self.public_content_object.es_flagged = True self.public_content_object.save() msg = render_to_string( "tutorialv2/messages/validation_invalid_opinion.md", { "content": versioned, "url": versioned.get_absolute_url(), "admin": self.request.user, "message_reject": "\n".join(["> " + a for a in form.cleaned_data["text"].split("\n")]), }, ) bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"]) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("moderation"), ) self.object.save() else: send_message_mp(bot, self.object.validation_private_message, msg) messages.success(self.request, _("Le contenu a bien été enlevé de la liste des billets choisis.")) return super().form_valid(form)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() if not db_object.in_public(): raise Http404('This opinion is not published.') elif PickListOperation.objects.filter(content=self.object, is_effective=True).exists() \ and form.cleaned_data['operation'] != 'REMOVE_PUB': raise PermissionDenied('There is already an effective operation for this content.') try: PickListOperation.objects.filter(content=self.object).update(is_effective=False, canceler_user=self.request.user) PickListOperation.objects.create(content=self.object, operation=form.cleaned_data['operation'], staff_user=self.request.user, operation_date=datetime.now(), version=db_object.sha_public) if form.cleaned_data['operation'] == 'REMOVE_PUB': unpublish_content(self.object, moderator=self.request.user) # send PM msg = render_to_string( 'tutorialv2/messages/validation_unpublish_opinion.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'moderator': self.request.user, }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, versioned.authors.all(), _('Billet modéré'), versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) except ValueError: logger.exception('Could not %s the opinion %s', form.cleaned_data['operation'], str(self.object)) return HttpResponse(json.dumps({'result': 'FAIL', 'reason': str(_('Mauvaise opération'))}), status=400) if not form.cleaned_data['redirect']: return HttpResponse(json.dumps({'result': 'OK'})) else: self.success_url = reverse('opinion:list') messages.success(self.request, _('Le billet a bien été modéré.')) return super().form_valid(form)
def post(self, request, *args, **kwargs): validation = get_object_or_404(Validation, pk=kwargs['pk']) if validation.validator: validation.validator = None validation.date_reserve = None validation.status = 'PENDING' validation.save() messages.info(request, _("Ce contenu n'est plus réservé.")) return redirect(reverse('validation:list')) else: validation.validator = request.user validation.date_reserve = datetime.now() validation.status = 'PENDING_V' validation.save() versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( 'tutorialv2/messages/validation_reserve.md', { 'content': versioned, 'url': versioned.get_absolute_url() + '?version=' + validation.version, }) authors = list(validation.content.authors.all()) if validation.validator in authors: authors.remove(validation.validator) if len(authors) > 0: send_mp( validation.validator, authors, _('Contenu réservé - {0}').format(validation.content.title), validation.content.title, msg, True, leave=False, direct=False, mark_as_read=True, hat=get_hat_from_settings('validation'), ) messages.info(request, _('Ce contenu a bien été réservé par {0}.').format(request.user.username)) return redirect( reverse('content:view', args=[validation.content.pk, validation.content.slug]) + '?version=' + validation.version )
def form_valid(self, form): versioned = self.versioned_object user = self.request.user if user not in versioned.authors.all( ) and not user.has_perm('tutorialv2.change_validation'): raise PermissionDenied if form.cleaned_data['version'] != self.object.sha_public: raise PermissionDenied unpublish_content(self.object, moderator=self.request.user) # send PM msg = render_to_string( 'tutorialv2/messages/validation_revoke.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'admin': user, 'message_reject': '\n'.join( ['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, versioned.authors.all(), _('Dépublication'), versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) messages.success(self.request, _('Le contenu a bien été dépublié.')) self.success_url = self.versioned_object.get_absolute_url() return super(UnpublishOpinion, self).form_valid(form)
def form_valid(self, form): db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() if not db_object.sha_picked: raise PermissionDenied('Impossible de retirer des billets choisis un billet pas choisi.') if db_object.sha_picked != form.cleaned_data['version']: raise PermissionDenied('Impossible de retirer des billets choisis un billet pas choisi.') db_object.sha_picked = None db_object.save() PickListOperation.objects\ .filter(operation='PICK', is_effective=True, content=self.object)\ .first().cancel(self.request.user) # mark to reindex to boost correctly in the search self.public_content_object.es_flagged = True self.public_content_object.save() msg = render_to_string( 'tutorialv2/messages/validation_invalid_opinion.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'admin': self.request.user, 'message_reject': '\n'.join(['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, versioned.authors.all(), _('Billet retiré de la liste des billets choisis'), versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) messages.success(self.request, _('Le contenu a bien été enlevé de la liste des billets choisis.')) return super(UnpickOpinion, self).form_valid(form)
def solve_hat_request(request, request_pk): """ Solve a hat request by granting or denying the requested hat according to moderator's decision. """ hat_request = get_object_or_404(HatRequest, pk=request_pk) if 'grant' in request.POST: # hat is granted hat, created = Hat.objects.get_or_create(name__iexact=hat_request.hat, defaults={'name': hat_request.hat}) if created: messages.success(request, _('La casquette « {} » a été créée.').format(hat_request.hat)) hat_request.user.profile.hats.add(hat) messages.success(request, _('La casquette « {0} » a été accordée à {1}.').format( hat_request.hat, hat_request.user.username)) else: messages.success(request, _('La casquette « {0} » a été refusée à {1}.').format( hat_request.hat, hat_request.user.username)) # send a PM to notify member about this decision bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'member/messages/hat_request_decision.md', { 'is_granted': 'grant' in request.POST, 'moderator': request.user, 'hat': hat_request.hat, 'site_name': settings.ZDS_APP['site']['literal_name'], 'comment': request.POST.get('comment', '')[:1000] } ) send_mp(bot, [hat_request.user], _('Casquette « {} »').format(hat_request.hat), '', msg, False, True, False, hat=get_hat_from_settings('hats_management')) hat_request.delete() return redirect('requested-hats')
def form_valid(self, form): versioned = self.versioned_object user = self.request.user if user not in versioned.authors.all() and not user.has_perm('tutorialv2.change_validation'): raise PermissionDenied if form.cleaned_data['version'] != self.object.sha_public: raise PermissionDenied unpublish_content(self.object, moderator=self.request.user) if [self.request.user] != list(self.object.authors.all()): # Sends PM if the deleter is not the author # (or is not the only one) of the opinion. msg = render_to_string( 'tutorialv2/messages/validation_revoke.md', { 'content': versioned, 'url': versioned.get_absolute_url(), 'admin': user, 'message_reject': '\n'.join(['> ' + a for a in form.cleaned_data['text'].split('\n')]) }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, versioned.authors.all(), _('Dépublication'), versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) messages.success(self.request, _('Le contenu a bien été dépublié.')) self.success_url = self.versioned_object.get_absolute_url() return super(UnpublishOpinion, self).form_valid(form)
def notify_member(self, ban, msg): """ Notify the member sanctioned with a MP. :param ban: Sanction. :type ban: Ban object :param msg: message send at the user sanctioned. :type msg: string object :return: nothing :rtype: None """ bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"]) send_mp( bot, [ban.user], ban.type, "", msg, send_by_mail=True, direct=True, hat=get_hat_from_settings("moderation"), )
def notify_member(self, ban, msg): """ Notify the member sanctioned with a MP. :param ban: Sanction. :type ban: Ban object :param msg: message send at the user sanctioned. :type msg: string object :return: nothing :rtype: None """ bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, [ban.user], ban.type, '', msg, True, direct=True, hat=get_hat_from_settings('moderation'), )
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() db_object.sha_picked = form.cleaned_data['version'] db_object.picked_date = datetime.now() db_object.save() # mark to reindex to boost correctly in the search self.public_content_object.es_flagged = True self.public_content_object.save() PickListOperation.objects.create(content=self.object, operation='PICK', staff_user=self.request.user, operation_date=datetime.now(), version=db_object.sha_picked) msg = render_to_string( 'tutorialv2/messages/validation_opinion.md', { 'title': versioned.title, 'url': versioned.get_absolute_url(), }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, versioned.authors.all(), _('Billet approuvé'), versioned.title, msg, True, direct=False, hat=get_hat_from_settings('moderation'), ) messages.success(self.request, _('Le billet a bien été choisi.')) return super(PickOpinion, self).form_valid(form)
def form_valid(self, form): current_user = False users = form.cleaned_data["users"] _type = (_("cet article"), _("de l'article")) if self.object.is_tutorial: _type = (_("ce tutoriel"), _("du tutoriel")) elif self.object.is_opinion: _type = (_("ce billet"), _("du billet")) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) for user in users: if RemoveAuthorFromContent.remove_author(self.object, user): if user.pk == self.request.user.pk: current_user = True else: send_mp( bot, [user], format_lazy("{}{}", _("Retrait de la rédaction "), _type[1]), self.versioned_object.title, render_to_string( "tutorialv2/messages/remove_author_pm.md", { "content": self.object, "user": user.username, }, ), hat=get_hat_from_settings("validation"), ) signals.authors_management.send( sender=self.__class__, content=self.object, performer=self.request.user, author=user, action="remove", ) else: # if user is incorrect or alone messages.error( self.request, _("Vous êtes le seul auteur de {} ou le membre sélectionné " "en a déjà quitté la rédaction.").format(_type[0]), ) return redirect(self.object.get_absolute_url()) self.object.save() authors_list = "" for index, user in enumerate(form.cleaned_data["users"]): if index > 0: if index == len(users) - 1: authors_list += _(" et ") else: authors_list += _(", ") authors_list += user.username if not current_user: # if the removed author is not current user messages.success( self.request, _("Vous avez enlevé {} de la liste des auteurs de {}.").format( authors_list, _type[0])) self.success_url = self.object.get_absolute_url() else: # if current user is leaving the content's redaction, redirect him to a more suitable page messages.success( self.request, _("Vous avez bien quitté la rédaction de {}.").format( _type[0])) self.success_url = reverse(self.object.type.lower() + ":find-" + self.object.type.lower(), args=[self.request.user.username]) return super().form_valid(form)
def delete(self, request, *args, **kwargs): """rewrite delete() function to ensure repository deletion""" self.object = self.get_object() object_type = self.object.type.lower() _type = _("ce tutoriel") if self.object.is_article: _type = _("cet article") elif self.object.is_opinion: _type = _("ce billet") if self.object.authors.count( ) > 1: # if more than one author, just remove author from list RemoveAuthorFromContent.remove_author(self.object, self.request.user) messages.success( self.request, _("Vous avez quitté la rédaction de {}.").format(_type)) else: validation = Validation.objects.filter( content=self.object).order_by("-date_proposition").first() if validation and validation.status == "PENDING_V": # if the validation have a validator, warn him by PM if "text" not in self.request.POST or len( self.request.POST["text"].strip()) < 3: messages.error( self.request, _("Merci de fournir une raison à la suppression.")) return redirect(self.object.get_absolute_url()) else: bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "tutorialv2/messages/validation_cancel_on_delete.md", { "content": self.object, "validator": validation.validator.username, "user": self.request.user, "message": "\n".join([ "> " + line for line in self.request.POST["text"].split("\n") ]), }, ) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, [validation.validator], _("Demande de validation annulée").format(), self.object.title, msg, send_by_mail=False, leave=True, hat=get_hat_from_settings("validation"), automatically_read=validation.validator, ) validation.content.save() else: send_message_mp( bot, validation.content.validation_private_message, msg, hat=get_hat_from_settings("validation"), no_notification_for=[self.request.user], ) if self.object.beta_topic is not None: beta_topic = self.object.beta_topic beta_topic.is_locked = True beta_topic.add_tags(["Supprimé"]) beta_topic.save() post = beta_topic.first_post() post.update_content( _("[[a]]\n" "| Malheureusement, {} qui était en bêta a été supprimé par son auteur.\n\n" ).format(_type) + post.text) post.save() self.object.delete() messages.success(self.request, _("Vous avez bien supprimé {}.").format(_type)) return redirect( reverse(object_type + ":find-" + object_type, args=[request.user.username]))
def settings_promote(request, user_pk): """ Manage groups and activation status of a user. Only superusers are allowed to use this. """ if not request.user.is_superuser: raise PermissionDenied profile = get_object_or_404(Profile, user__pk=user_pk) user = profile.user if request.method == 'POST': form = PromoteMemberForm(request.POST) data = dict(form.data) groups = Group.objects.all() usergroups = user.groups.all() if 'groups' in data: for group in groups: if str(group.id) in data['groups']: if group not in usergroups: user.groups.add(group) messages.success(request, _('{0} appartient maintenant au groupe {1}.') .format(user.username, group.name)) else: if group in usergroups: user.groups.remove(group) messages.warning(request, _('{0} n\'appartient maintenant plus au groupe {1}.') .format(user.username, group.name)) topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user) for topic in topics_followed: if isinstance(topic, Topic) and group in topic.forum.groups.all(): TopicAnswerSubscription.objects.toggle_follow(topic, user) else: for group in usergroups: topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user) for topic in topics_followed: if isinstance(topic, Topic) and group in topic.forum.groups.all(): TopicAnswerSubscription.objects.toggle_follow(topic, user) user.groups.clear() messages.warning(request, _('{0} n\'appartient (plus ?) à aucun groupe.') .format(user.username)) if 'activation' in data and 'on' in data['activation']: user.is_active = True messages.success(request, _('{0} est maintenant activé.') .format(user.username)) else: user.is_active = False messages.warning(request, _('{0} est désactivé.') .format(user.username)) user.save() usergroups = user.groups.all() bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = _('Bonjour {0},\n\n' 'Un administrateur vient de modifier les groupes ' 'auxquels vous appartenez. \n').format(user.username) if len(usergroups) > 0: msg = string_concat(msg, _('Voici la liste des groupes dont vous faites dorénavant partie :\n\n')) for group in usergroups: msg += '* {0}\n'.format(group.name) else: msg = string_concat(msg, _('* Vous ne faites partie d\'aucun groupe')) send_mp( bot, [user], _('Modification des groupes'), '', msg, True, True, hat=get_hat_from_settings('moderation'), ) return redirect(profile.get_absolute_url()) form = PromoteMemberForm(initial={ 'groups': user.groups.all(), 'activation': user.is_active }) return render(request, 'member/settings/promote.html', { 'usr': user, 'profile': profile, 'form': form })
def settings_promote(request, user_pk): """ Manage groups and activation status of a user. Only superusers are allowed to use this. """ if not request.user.is_superuser: raise PermissionDenied profile = get_object_or_404(Profile, user__pk=user_pk) user = profile.user if request.method == "POST": form = PromoteMemberForm(request.POST) data = dict(form.data) groups = Group.objects.all() usergroups = user.groups.all() if "groups" in data: for group in groups: if str(group.id) in data["groups"]: if group not in usergroups: user.groups.add(group) messages.success( request, _("{0} appartient maintenant au groupe {1}."). format(user.username, group.name)) else: if group in usergroups: user.groups.remove(group) messages.warning( request, _("{0} n'appartient maintenant plus au groupe {1}." ).format(user.username, group.name), ) else: user.groups.clear() messages.warning( request, _("{0} n'appartient (plus ?) à aucun groupe.").format( user.username)) if "activation" in data and "on" in data["activation"]: user.is_active = True messages.success( request, _("{0} est maintenant activé.").format(user.username)) else: user.is_active = False messages.warning(request, _("{0} est désactivé.").format(user.username)) user.save() usergroups = user.groups.all() bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = _("Bonjour {0},\n\n" "Un administrateur vient de modifier les groupes " "auxquels vous appartenez. \n").format(user.username) if len(usergroups) > 0: msg = format_lazy( "{}{}", msg, _("Voici la liste des groupes dont vous faites dorénavant partie :\n\n" )) for group in usergroups: msg += f"* {group.name}\n" else: msg = format_lazy("{}{}", msg, _("* Vous ne faites partie d'aucun groupe")) send_mp( bot, [user], _("Modification des groupes"), "", msg, send_by_mail=True, leave=True, hat=get_hat_from_settings("moderation"), ) return redirect(profile.get_absolute_url()) form = PromoteMemberForm(initial={ "groups": user.groups.all(), "activation": user.is_active }) return render(request, "member/admin/promote.html", { "usr": user, "profile": profile, "form": form })
def form_valid(self, form): user = self.request.user validation = Validation.objects\ .filter(pk=self.kwargs['pk'])\ .prefetch_related('content')\ .prefetch_related('content__authors')\ .last() if not validation: raise PermissionDenied if validation.status not in ['PENDING', 'PENDING_V']: raise PermissionDenied # cannot cancel a validation that is already accepted or rejected if user not in validation.content.authors.all() and not user.has_perm('tutorialv2.change_validation'): raise PermissionDenied versioned = validation.content.load_version(sha=validation.version) # reject validation: quote = '\n'.join(['> ' + line for line in form.cleaned_data['text'].split('\n')]) validation.status = 'CANCEL' validation.comment_authors += _('\n\nLa validation a été **annulée** pour la raison suivante :\n\n{}')\ .format(quote) validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # warn the former validator that the all thing have been canceled if validation.validator: bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'tutorialv2/messages/validation_cancel.md', { 'content': versioned, 'validator': validation.validator.username, 'url': versioned.get_absolute_url() + '?version=' + validation.version, 'user': self.request.user, 'message': quote }) send_mp( bot, [validation.validator], _('Demande de validation annulée').format(), versioned.title, msg, False, hat=get_hat_from_settings('validation'), ) messages.info(self.request, _('La validation de ce contenu a bien été annulée.')) self.success_url = reverse('content:view', args=[validation.content.pk, validation.content.slug]) + \ '?version=' + validation.version return super(CancelValidation, self).form_valid(form)
def form_valid(self, form): user = self.request.user validation = (Validation.objects.filter( pk=self.kwargs["pk"]).prefetch_related("content").prefetch_related( "content__authors").last()) if not validation: raise PermissionDenied if validation.status not in ["PENDING", "PENDING_V"]: raise PermissionDenied # cannot cancel a validation that is already accepted or rejected if user not in validation.content.authors.all( ) and not user.has_perm("tutorialv2.change_validation"): raise PermissionDenied versioned = validation.content.load_version(sha=validation.version) # reject validation: quote = "\n".join( ["> " + line for line in form.cleaned_data["text"].split("\n")]) validation.status = "CANCEL" validation.comment_authors = _( "\n\nLa validation a été **annulée** pour la raison suivante :\n\n{}" ).format(quote) validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # warn the former validator that the whole thing has been cancelled if validation.validator: bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "tutorialv2/messages/validation_cancel.md", { "content": versioned, "validator": validation.validator.username, "url": versioned.get_absolute_url() + "?version=" + validation.version, "user": self.request.user, "message": quote, }, ) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, [validation.validator], _("Demande de validation annulée").format(), versioned.title, msg, send_by_mail=False, hat=get_hat_from_settings("validation"), ) validation.content.save() else: send_message_mp(bot, validation.content.validation_private_message, msg) messages.info(self.request, _("La validation de ce contenu a bien été annulée.")) self.success_url = ( reverse("content:view", args=[validation.content.pk, validation.content.slug]) + "?version=" + validation.version) return super(CancelValidation, self).form_valid(form)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object # get initial git path old_git_path = db_object.get_repo_path() # store data for later authors = db_object.authors.all() subcats = db_object.subcategory.all() tags = db_object.tags.all() article = PublishableContent(title=db_object.title, type='ARTICLE', creation_date=datetime.now(), sha_public=db_object.sha_public, public_version=None, licence=db_object.licence, sha_validation=db_object.sha_public, sha_draft=db_object.sha_public, image=db_object.image, source=db_object.source) opinion_url = db_object.get_absolute_url_online() article.save() # add M2M objects for author in authors: article.authors.add(author) for subcat in subcats: article.subcategory.add(subcat) for tag in tags: article.tags.add(tag) article.save() # add information about the conversion to the original opinion db_object.converted_to = article db_object.save() # clone the repo clone_repo(old_git_path, article.get_repo_path()) versionned_article = article.load_version(sha=article.sha_validation) # mandatory to avoid path collision versionned_article.slug = article.slug article.sha_validation = versionned_article.repo_update( versionned_article.title, versionned_article.get_introduction(), versionned_article.get_conclusion()) article.sha_draft = article.sha_validation article.save() # ask for validation validation = Validation() validation.content = article validation.date_proposition = datetime.now() validation.comment_authors = _( 'Promotion du billet « [{0}]({1}) » en article par [{2}]({3}).'. format(article.title, article.get_absolute_url_online(), self.request.user.username, self.request.user.profile.get_absolute_url())) validation.version = article.sha_validation validation.save() # creating the gallery gal = Gallery() gal.title = db_object.gallery.title gal.slug = db_object.gallery.slug gal.pubdate = datetime.now() gal.save() article.gallery = gal # save updates article.save() article.ensure_author_gallery() # send message to user msg = render_to_string('tutorialv2/messages/opinion_promotion.md', { 'content': versioned, 'url': opinion_url, }) bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, article.authors.all(), _('Billet promu en article'), versionned_article.title, msg, True, direct=False, hat=get_hat_from_settings('validation'), ) self.success_url = db_object.get_absolute_url() messages.success( self.request, _('Le billet a bien été promu en article et est en attente de validation.' )) return super(PromoteOpinionToArticle, self).form_valid(form)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object # get initial git path old_git_path = db_object.get_repo_path() # store data for later authors = db_object.authors.all() subcats = db_object.subcategory.all() tags = db_object.tags.all() article = PublishableContent(title=db_object.title, type='ARTICLE', creation_date=datetime.now(), sha_public=db_object.sha_public, public_version=None, licence=db_object.licence, sha_validation=db_object.sha_public, sha_draft=db_object.sha_public, image=db_object.image, source=db_object.source ) opinion_url = db_object.get_absolute_url_online() article.save() # add M2M objects for author in authors: article.authors.add(author) for subcat in subcats: article.subcategory.add(subcat) for tag in tags: article.tags.add(tag) article.save() # add information about the conversion to the original opinion db_object.converted_to = article db_object.save() # clone the repo clone_repo(old_git_path, article.get_repo_path()) versionned_article = article.load_version(sha=article.sha_validation) # mandatory to avoid path collision versionned_article.slug = article.slug article.sha_validation = versionned_article.repo_update(versionned_article.title, versionned_article.get_introduction(), versionned_article.get_conclusion()) article.sha_draft = article.sha_validation article.save() # ask for validation validation = Validation() validation.content = article validation.date_proposition = datetime.now() validation.comment_authors = _('Promotion du billet « [{0}]({1}) » en article par [{2}]({3}).'.format( article.title, article.get_absolute_url_online(), self.request.user.username, self.request.user.profile.get_absolute_url() )) validation.version = article.sha_validation validation.save() # creating the gallery gal = Gallery() gal.title = db_object.gallery.title gal.slug = db_object.gallery.slug gal.pubdate = datetime.now() gal.save() article.gallery = gal # save updates article.save() article.ensure_author_gallery() # send message to user msg = render_to_string( 'tutorialv2/messages/opinion_promotion.md', { 'content': versioned, 'url': opinion_url, }) bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) send_mp( bot, article.authors.all(), _('Billet promu en article'), versionned_article.title, msg, True, direct=False, hat=get_hat_from_settings('validation'), ) self.success_url = db_object.get_absolute_url() messages.success(self.request, _('Le billet a bien été promu en article et est en attente de validation.')) return super(PromoteOpinionToArticle, self).form_valid(form)
def form_valid(self, form): # get database representation and validated version db_object = self.object versioned = self.versioned_object self.success_url = versioned.get_absolute_url_online() if not db_object.in_public(): raise Http404("This opinion is not published.") elif (PickListOperation.objects.filter(content=self.object, is_effective=True).exists() and form.cleaned_data["operation"] != "REMOVE_PUB"): raise PermissionDenied( "There is already an effective operation for this content.") try: PickListOperation.objects.filter(content=self.object).update( is_effective=False, canceler_user=self.request.user) PickListOperation.objects.create( content=self.object, operation=form.cleaned_data["operation"], staff_user=self.request.user, operation_date=datetime.now(), version=db_object.sha_public, ) if form.cleaned_data["operation"] == "REMOVE_PUB": unpublish_content(self.object, moderator=self.request.user) # send PM msg = render_to_string( "tutorialv2/messages/validation_unpublish_opinion.md", { "content": versioned, "url": versioned.get_absolute_url(), "moderator": self.request.user, }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, versioned.authors.all(), self.object.validation_message_title, versioned.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("moderation"), ) self.object.save() else: send_message_mp( bot, self.object.validation_private_message, msg, hat=get_hat_from_settings("moderation"), no_notification_for=[self.request.user], ) except ValueError: logger.exception("Could not %s the opinion %s", form.cleaned_data["operation"], str(self.object)) return HttpResponse(json.dumps({ "result": "FAIL", "reason": str(_("Mauvaise opération")) }), status=400) if not form.cleaned_data["redirect"]: return HttpResponse(json.dumps({"result": "OK"})) else: self.success_url = reverse("opinion:list") messages.success(self.request, _("Le billet a bien été modéré.")) return super().form_valid(form)
def form_valid(self, form): versioned = self.versioned_object if form.cleaned_data["version"] != self.object.sha_public: raise PermissionDenied validation = (Validation.objects.filter( content=self.object, version=self.object.sha_public, status="ACCEPT").prefetch_related("content__authors").last()) if not validation: raise PermissionDenied unpublish_content(self.object) validation.status = "PENDING" validation.validator = None # remove previous validator validation.date_validation = None validation.save() self.object.sha_public = None self.object.sha_validation = validation.version self.object.pubdate = None self.object.save() # send PM msg = render_to_string( "tutorialv2/messages/validation_revoke.md", { "content": versioned, "url": versioned.get_absolute_url() + "?version=" + validation.version, "admin": self.request.user, "message_reject": "\n".join( ["> " + a for a in form.cleaned_data["text"].split("\n")]), }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, validation.content.authors.all(), self.object.validation_message_title, validation.content.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("validation"), ) self.object.save() else: send_message_mp(bot, validation.content.validation_private_message, msg, no_notification_for=[self.request.user]) messages.success(self.request, _("Le contenu a bien été dépublié.")) self.success_url = self.versioned_object.get_absolute_url( ) + "?version=" + validation.version return super(RevokeValidation, self).form_valid(form)
def form_valid(self, form): user = self.request.user validation = Validation.objects.filter(pk=self.kwargs["pk"]).last() if not validation: raise PermissionDenied if validation.validator != user: raise PermissionDenied if validation.status != "PENDING_V": raise PermissionDenied # reject validation: validation.comment_validator = form.cleaned_data["text"] validation.status = "REJECT" validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # send PM versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( "tutorialv2/messages/validation_reject.md", { "content": versioned, "url": versioned.get_absolute_url() + "?version=" + validation.version, "validator": validation.validator, "message_reject": "\n".join( ["> " + a for a in form.cleaned_data["text"].split("\n")]), }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, validation.content.authors.all(), _("Rejet de la demande de publication").format(), validation.content.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("validation"), ) validation.content.save() else: send_message_mp(bot, validation.content.validation_private_message, msg, no_notification_for=[self.request.user]) messages.info(self.request, _("Le contenu a bien été refusé.")) self.success_url = reverse("validation:list") return super(RejectValidation, self).form_valid(form)
def post(self, request, *args, **kwargs): validation = get_object_or_404(Validation, pk=kwargs["pk"]) if validation.validator: validation.validator = None validation.date_reserve = None validation.status = "PENDING" validation.save() messages.info(request, _("Ce contenu n'est plus réservé.")) return redirect(reverse("validation:list")) else: validation.validator = request.user validation.date_reserve = datetime.now() validation.status = "PENDING_V" validation.save() versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( "tutorialv2/messages/validation_reserve.md", { "content": versioned, "url": versioned.get_absolute_url() + "?version=" + validation.version, }, ) authors = list(validation.content.authors.all()) if validation.validator in authors: authors.remove(validation.validator) if len(authors) > 0: if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( validation.validator, authors, _("Contenu réservé - {0}").format( validation.content.title), validation.content.title, msg, send_by_mail=True, leave=False, direct=False, mark_as_read=True, hat=get_hat_from_settings("validation"), ) validation.content.save() else: send_message_mp( validation.validator, validation.content.validation_private_message, msg) mark_read(validation.content.validation_private_message, validation.validator) messages.info( request, _("Ce contenu a bien été réservé par {0}.").format( request.user.username)) return redirect( reverse("content:view", args=[validation.content.pk, validation.content.slug]) + "?version=" + validation.version)
def settings_promote(request, user_pk): """ Manage groups and activation status of a user. Only superusers are allowed to use this. """ if not request.user.is_superuser: raise PermissionDenied profile = get_object_or_404(Profile, user__pk=user_pk) user = profile.user if request.method == 'POST': form = PromoteMemberForm(request.POST) data = dict(form.data) groups = Group.objects.all() usergroups = user.groups.all() if 'groups' in data: for group in groups: if str(group.id) in data['groups']: if group not in usergroups: user.groups.add(group) messages.success(request, _('{0} appartient maintenant au groupe {1}.') .format(user.username, group.name)) else: if group in usergroups: user.groups.remove(group) messages.warning(request, _('{0} n\'appartient maintenant plus au groupe {1}.') .format(user.username, group.name)) topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user) for topic in topics_followed: if isinstance(topic, Topic) and group in topic.forum.groups.all(): TopicAnswerSubscription.objects.toggle_follow(topic, user) else: for group in usergroups: topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user) for topic in topics_followed: if isinstance(topic, Topic) and group in topic.forum.groups.all(): TopicAnswerSubscription.objects.toggle_follow(topic, user) user.groups.clear() messages.warning(request, _('{0} n\'appartient (plus ?) à aucun groupe.') .format(user.username)) if 'activation' in data and 'on' in data['activation']: user.is_active = True messages.success(request, _('{0} est maintenant activé.') .format(user.username)) else: user.is_active = False messages.warning(request, _('{0} est désactivé.') .format(user.username)) user.save() usergroups = user.groups.all() bot = get_object_or_404(User, username=settings.ZDS_APP['member']['bot_account']) msg = _('Bonjour {0},\n\n' 'Un administrateur vient de modifier les groupes ' 'auxquels vous appartenez. \n').format(user.username) if len(usergroups) > 0: msg = string_concat(msg, _('Voici la liste des groupes dont vous faites dorénavant partie :\n\n')) for group in usergroups: msg += '* {0}\n'.format(group.name) else: msg = string_concat(msg, _('* Vous ne faites partie d\'aucun groupe')) send_mp( bot, [user], _('Modification des groupes'), '', msg, True, True, hat=get_hat_from_settings('moderation'), ) return redirect(profile.get_absolute_url()) form = PromoteMemberForm(initial={ 'groups': user.groups.all(), 'activation': user.is_active }) return render(request, 'member/settings/promote.html', { 'usr': user, 'profile': profile, 'form': form })
def form_valid(self, form): user = self.request.user validation = Validation.objects\ .filter(pk=self.kwargs['pk'])\ .prefetch_related('content')\ .prefetch_related('content__authors')\ .last() if not validation: raise PermissionDenied if validation.status not in ['PENDING', 'PENDING_V']: raise PermissionDenied # cannot cancel a validation that is already accepted or rejected if user not in validation.content.authors.all( ) and not user.has_perm('tutorialv2.change_validation'): raise PermissionDenied versioned = validation.content.load_version(sha=validation.version) # reject validation: quote = '\n'.join( ['> ' + line for line in form.cleaned_data['text'].split('\n')]) validation.status = 'CANCEL' validation.comment_authors += _('\n\nLa validation a été **annulée** pour la raison suivante :\n\n{}')\ .format(quote) validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # warn the former validator that the all thing have been canceled if validation.validator: bot = get_object_or_404( User, username=settings.ZDS_APP['member']['bot_account']) msg = render_to_string( 'tutorialv2/messages/validation_cancel.md', { 'content': versioned, 'validator': validation.validator.username, 'url': versioned.get_absolute_url() + '?version=' + validation.version, 'user': self.request.user, 'message': quote }) send_mp( bot, [validation.validator], _('Demande de validation annulée').format(), versioned.title, msg, False, hat=get_hat_from_settings('validation'), ) messages.info(self.request, _('La validation de ce contenu a bien été annulée.')) self.success_url = reverse('content:view', args=[validation.content.pk, validation.content.slug]) + \ '?version=' + validation.version return super(CancelValidation, self).form_valid(form)
def form_valid(self, form): beta_version = self.versioned_object sha_beta = beta_version.current_version # topic of the beta version: topic = self.object.beta_topic if topic: if topic.forum_id != settings.ZDS_APP["forum"]["beta_forum_id"]: # if the topic is moved from the beta forum, then a new one is created instead topic = None _type = self.object.type.lower() if _type == "tutorial": _type = _("tutoriel") elif _type == "opinion": raise PermissionDenied # perform actions: if self.action == "inactive": self.object.sha_beta = None msg_post = render_to_string( "tutorialv2/messages/beta_desactivate.md", { "content": beta_version, "type": _type }) send_post(self.request, topic, self.request.user, msg_post) lock_topic(topic) elif self.action == "set": already_in_beta = self.object.in_beta() all_tags = [] if not already_in_beta or self.object.sha_beta != sha_beta: self.object.sha_beta = sha_beta self.versioned_object.in_beta = True self.versioned_object.sha_beta = sha_beta msg = render_to_string( "tutorialv2/messages/beta_activate_topic.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + self.versioned_object.get_absolute_url_beta(), }, ) if not topic: # if first time putting the content in beta, send a message on the forum and a PM # find tags all_tags = self._get_all_tags() topic = self._create_beta_topic(msg, beta_version, _type, all_tags) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg_pm = render_to_string( "tutorialv2/messages/beta_activate_pm.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + topic.get_absolute_url(), "user": self.request.user, }, ) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, self.object.authors.all(), self.object.validation_message_title, beta_version.title, msg_pm, send_by_mail=False, leave=True, hat=get_hat_from_settings("validation"), ) self.object.save() else: send_message_mp( bot, self.object.validation_private_message, msg, hat=get_hat_from_settings("validation")) # When the anti-spam triggers (because the author of the # message posted themselves within the last 15 minutes), # it is likely that we want to avoid to generate a duplicated # post that couldn't be deleted. We hence avoid to add another # message to the topic. else: all_tags = self._get_all_tags() if not already_in_beta: unlock_topic(topic) msg_post = render_to_string( "tutorialv2/messages/beta_reactivate.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + self.versioned_object.get_absolute_url_beta(), }, ) topic = send_post(self.request, topic, self.request.user, msg_post) elif not topic.antispam(): msg_post = render_to_string( "tutorialv2/messages/beta_update.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + self.versioned_object.get_absolute_url_beta(), }, ) topic = send_post(self.request, topic, self.request.user, msg_post) # make sure that all authors follow the topic: for author in self.object.authors.all(): TopicAnswerSubscription.objects.get_or_create_active( author, topic) mark_read(topic, author) # finally set the tags on the topic if topic: topic.tags.clear() for tag in all_tags: topic.tags.add(tag) topic.save() self.object.save( ) # we should prefer .update but it needs a huge refactoring self.success_url = self.versioned_object.get_absolute_url( version=sha_beta) if self.object.is_beta(sha_beta): self.success_url = self.versioned_object.get_absolute_url_beta() return super(ManageBetaContent, self).form_valid(form)
def form_valid(self, form): old_validation = Validation.objects.filter( content__pk=self.object.pk, status__in=["PENDING", "PENDING_V"]).first() if old_validation: # if an old validation exists, cancel it! old_validator = old_validation.validator old_validation.status = "CANCEL" old_validation.date_validation = datetime.now() old_validation.save() else: old_validator = None # create a 'validation' object validation = Validation() validation.content = self.object validation.date_proposition = datetime.now() validation.comment_authors = form.cleaned_data["text"] validation.version = form.cleaned_data["version"] if old_validator: validation.validator = old_validator validation.date_reserve = old_validation.date_reserve validation.status = "PENDING_V" validation.save() # warn the former validator that an update has been made, if any if old_validator: bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "tutorialv2/messages/validation_change.md", { "content": self.versioned_object, "validator": validation.validator.username, "url": self.versioned_object.get_absolute_url() + "?version=" + form.cleaned_data["version"], "url_history": reverse("content:history", args=[self.object.pk, self.object.slug]), }, ) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, [old_validator], self.object.validation_message_title, self.versioned_object.title, msg, send_by_mail=False, hat=get_hat_from_settings("validation"), ) else: send_message_mp(bot, self.object.validation_private_message, msg) # update the content with the source and the version of the validation self.object.source = self.versioned_object.source self.object.sha_validation = validation.version self.object.save() messages.success( self.request, _("Votre demande de validation a été transmise à l'équipe.")) self.success_url = self.versioned_object.get_absolute_url( version=self.sha) return super(AskValidationForContent, self).form_valid(form)