示例#1
0
    def save(self, *args, **kwargs):
        created = self.pk is None
        self.content = smart_lower(self.content)

        if created:
            self.author.invalidate_entry_counts()

        super().save(*args, **kwargs)

        # Check if the user has written 10 entries, If so make them available for novice lookup
        if self.author.is_novice and self.author.application_status == "OH" and self.author.entry_count >= 10:
            self.author.application_status = "PN"
            self.author.application_date = timezone.now()
            self.author.save()

            Message.objects.compose(
                get_generic_superuser(),
                self.author,
                gettext(
                    "as you entered your first 10 entries, you have been admitted to"
                    " the novice list. you can see your queue number in your profile page."
                    " if your entry count drops below 10, you will be kicked from the list."
                ),
            )

        # assign topic creator (includes novices)
        if not self.is_draft and not self.topic.created_by:
            self.topic.created_by = self.author
            self.topic.save()

        self.topic.register_wishes(fulfiller_entry=self)
示例#2
0
    def process(self):
        if self.is_ready:
            return

        serializer = ArchiveSerializer()
        entries = self.author.entry_set(
            manager="objects_published").select_related("topic")
        conversations = self.author.conversationarchive_set.all()

        entries_text = serializer.serialize(entries,
                                            fields=("topic__title", "content",
                                                    "date_created",
                                                    "date_edited"))
        conversations_text = (
            "[%s]" % "".join('{"target": "%s", "messages": %s},' %
                             (item.target, item.messages)
                             for item in conversations)[:-1]
        )  # Formatting already-serialized data ([:-1] removes the trailing comma).

        content = '{"entries": %s, "conversations": %s}' % (entries_text,
                                                            conversations_text)
        self.is_ready = True
        self.file.save("backup",
                       ContentFile(content.encode("utf-8")),
                       save=True)

        settings.get_model("Message").objects.compose(
            get_generic_superuser(),
            self.author,
            gettext(
                "your backup is now ready. you may download your backup"
                " file using the link provided in the backup tab of settings."
            ),
        )
示例#3
0
    def register_wishes(self, fulfiller_entry=None):
        """To delete fulfilled wishes and inform wishers."""

        if self.wishes.exists() and self.has_entries:
            invoked_by_entry = fulfiller_entry is not None
            wishes = self.wishes.all().select_related("author")

            for wish in wishes:
                self_fulfillment = invoked_by_entry and fulfiller_entry.author == wish.author

                if not self_fulfillment:
                    message = (gettext(
                        "`%(title)s`, the topic you wished for, had an entry"
                        " entered by `@%(username)s`: (see: #%(entry)d)"
                    ) % {
                        "title": self.title,
                        "username": fulfiller_entry.author.username,
                        "entry": fulfiller_entry.pk,
                    } if invoked_by_entry else gettext(
                        "`%(title)s`, the topic you wished for, is now populated with some entries."
                    ) % {
                        "title": self.title
                    })

                    Message.objects.compose(get_generic_superuser(),
                                            wish.author, message)

            return wishes.delete()
        return None
示例#4
0
    def post(self, request):
        reference = request.POST.get("reference") == "yes"
        target_topic = request.POST.get("target_topic", "").strip()
        from_date = parse_date_or_none(request.POST.get("from_date"))
        to_date = parse_date_or_none(request.POST.get("to_date"))

        try:
            target_topic = Topic.objects.get(title=target_topic)
            generic_superuser = get_generic_superuser()

            topic_list_raw = list(self.get_object_list())
            entries_list = Entry.objects_published.filter(
                topic__in=topic_list_raw)

            if from_date:
                entries_list = entries_list.filter(date_created__gte=from_date)

            if to_date:
                entries_list = entries_list.filter(date_created__lte=to_date)

            entries_count = entries_list.count()
            entries_list.update(
                topic=target_topic)  # Bulk update, does not call save()
            target_topic.register_wishes()

            # Include an informative entry on old topic to indicate the new topic
            if reference:
                bulk_list = [
                    Entry(
                        topic=obj,
                        content=
                        f"({pgettext('editor', 'see')}: {target_topic.title})",
                        author=generic_superuser,
                    ) for obj in topic_list_raw
                ]
                Entry.objects.bulk_create(bulk_list)

            # Admin log
            log_admin(
                f"TopicMove action, count: {entries_count}. sources->{topic_list_raw},"
                f"from->{from_date} to->{to_date}",
                request.user,
                Topic,
                target_topic,
            )

            notifications.success(
                request,
                ngettext("%(count)d entry was transferred",
                         "%(count)d entries were transferred", entries_count) %
                {"count": entries_count},
            )
        except Topic.DoesNotExist:
            notifications.error(request,
                                gettext("Couldn't find the target topic."))
        except Author.DoesNotExist:
            notifications.error(request,
                                gettext("GENERIC_SUPERUSER is missing?"))

        return redirect(self.get_changelist_url())
示例#5
0
    def accept_application(self):
        # Alter the user status
        user = self.novice
        user.application_status = Author.APPROVED
        user.is_novice = False
        user.save()

        # Log admin info
        admin_info_msg = _(
            "Authorship of the user '%(username)s' was approved.") % {
                "username": user.username
            }
        log_admin(admin_info_msg, self.request.user, Author, user)

        # Send information messages to the user
        user_info_msg = _(
            "dear %(username)s, congratulations! your application"
            " of authorship has been approved. you can utilize your"
            " authorship by logging in.") % {
                "username": user.username
            }
        Message.objects.compose(get_generic_superuser(), user, user_info_msg)
        user.email_user(_("your authorship has been approved"), user_info_msg,
                        settings.FROM_EMAIL)

        notifications.success(self.request, admin_info_msg)
        return True
示例#6
0
    def decline_application(self):
        # Alter the user status & delete entries
        user = self.novice
        Entry.objects_published.filter(
            author=user).delete()  # does not trigger model's delete()
        user.application_status = Author.ON_HOLD
        user.application_date = None
        user.save()

        # Log admin info
        admin_info_msg = _(
            "Authorship of the user '%(username)s' was rejected.") % {
                "username": user.username
            }
        log_admin(admin_info_msg, self.request.user, Author, user)

        # Send information messages to the user
        user_info_msg = _(
            "dear %(username)s, your application of authorship has been"
            " rejected and all of your entries has been deleted. if you"
            " fill up 10 entries, you will be admitted to novice list again."
        ) % {
            "username": user.username
        }
        Message.objects.compose(get_generic_superuser(), user, user_info_msg)
        user.email_user(_("your authorship has been rejected"), user_info_msg,
                        settings.FROM_EMAIL)

        notifications.success(self.request, admin_info_msg)
        return True
示例#7
0
    def post(self, request):
        time_choices = {
            "D1": timedelta(days=1),
            "W1": timedelta(days=7),
            "W2": timedelta(days=14),
            "M1": timedelta(days=30),
            "M3": timedelta(days=90),
            "PM": None,
        }

        choice = request.POST.get("suspension_time")

        if choice in time_choices.keys():
            if choice == "PM":
                suspended_until = parse_date_or_none("01.01.2038")
            else:
                suspended_until = timezone.now() + time_choices[choice]

            # Evaluate it immediately because it needs to be iterated and we need to call len()
            user_list_raw = list(self.get_object_list())

            # Get and parse information for suspension
            action_information = request.POST.get("information", gettext("No information was given."))

            message_for_user = gettext(
                "your account has been suspended. administration message: %(message)s\n\n"
                "in your profile page, you can see the remaining time until your account gets reactivated."
            ) % {"message": action_information}
            message_for_log = f"Suspended until {suspended_until}, information: {action_information}"

            log_list = []  # Reserve list that hold instances for bulk creation
            generic_superuser = get_generic_superuser()

            # Set new suspended_until and append instances to reserved lists
            for user in user_list_raw:
                user.suspended_until = suspended_until
                log_list.append(logentry_instance(message_for_log, request.user, Author, user))
                Message.objects.compose(generic_superuser, user, message_for_user)

            # Bulk creation/updates
            Author.objects.bulk_update(user_list_raw, ["suspended_until"])  # Update Author, does not call save()
            logentry_bulk_create(log_list)  # Log user suspension for admin history

            count = len(user_list_raw)
            notifications.success(
                request,
                ngettext("%(count)d author was suspended.", "%(count)d authors were suspended.", count)
                % {"count": count},
            )
        else:
            notifications.error(request, gettext("The selected duration was invalid."))

        return redirect(self.get_changelist_url())
示例#8
0
    def post(self, request):
        response = redirect(self.get_changelist_url())
        factors = (request.POST.get("multiplier",
                                    ""), request.POST.get("quantity", ""))

        if not all(map(str.isdigit, factors)):
            notifications.error(request,
                                gettext("The selected duration was invalid."))
            return response

        ban_hours = math.prod(map(int, factors))
        suspended_until = timezone.now() + timedelta(hours=ban_hours)

        # Evaluate it immediately because it needs to be iterated and we need to call len()
        user_list_raw = list(self.get_object_list())

        action_information = request.POST.get(
            "information", gettext("No information was given."))
        message_for_user = gettext(
            "your account has been suspended. administration message: %(message)s\n\n"
            "in your profile page, you can see the remaining time until your account gets reactivated."
        ) % {
            "message": action_information
        }
        message_for_log = f"Suspended until {suspended_until}, information: {action_information}"

        log_list = []  # Reserve list that hold instances for bulk creation
        generic_superuser = get_generic_superuser()

        # Set new suspended_until and append instances to reserved lists
        for user in user_list_raw:
            user.suspended_until = suspended_until
            log_list.append(
                logentry_instance(message_for_log, request.user, Author, user))
            Message.objects.compose(generic_superuser, user, message_for_user)

        # Bulk creation/updates
        Author.objects.bulk_update(
            user_list_raw,
            ["suspended_until"])  # Update Author, does not call save()
        logentry_bulk_create(log_list)  # Log user suspension for admin history

        count = len(user_list_raw)
        notifications.success(
            request,
            ngettext("%(count)d author was suspended.",
                     "%(count)d authors were suspended.", count) %
            {"count": count},
        )
        return response