Example #1
0
def create_badge_for_comment(request, comment_id):
    comment = get_object_or_404(Comment, id=comment_id)
    if comment.is_deleted:
        raise BadRequest(
            title="😵 Комментарий удалён",
            message="Нельзя выдавать награды за удалённые комменты")
    if comment.author.deleted_at:
        raise BadRequest(title="😵 Пользователь удалился",
                         message="Нельзя выдавать награды удалённым юзерам")
    if comment.author == request.me:
        raise BadRequest(title="😵 Это же ты",
                         message="Нельзя выдавать награды самому себе")
    if request.method != "POST":
        if request.me.membership_days_left(
        ) < settings.MIN_DAYS_TO_GIVE_BADGES:
            return render(request, "badges/messages/insufficient_funds.html")

        return render(request, "badges/create.html", {
            "comment": comment,
            "badges": Badge.visible_objects().all(),
        })

    badge_code = request.POST.get("badge_code")
    badge = Badge.objects.filter(code=badge_code).first()
    if not badge or not badge.is_visible:
        raise BadRequest(title="🙅‍♀️ Бейджик недоступен",
                         message="Данную награду пока нельзя выдавать")

    note = (request.POST.get("note") or "")[:1000]
    user_badge = UserBadge.create_user_badge(
        badge=badge,
        from_user=request.me,
        to_user=comment.author,
        comment=comment,
        note=note,
    )

    # bump post on home page by updating its last_activity_at
    Post.objects.filter(id=comment.post_id).update(
        last_activity_at=datetime.utcnow())

    # show insufficient funds warning if < 3 months
    show_funds_warning = request.me.membership_days_left() - \
        user_badge.badge.price_days < settings.MIN_DAYS_TO_GIVE_BADGES * 3

    return render(request, "badges/messages/success.html", {
        "user_badge": user_badge,
        "show_funds_warning": show_funds_warning,
    })
Example #2
0
    def create_user_badge(cls, badge, from_user, to_user, post=None, comment=None, note=None):
        if from_user == to_user:
            raise BadRequest(
                title="🛑 Нельзя дарить награды самому себе",
                message="Это что такое-то вообще!"
            )

        if badge.price_days >= from_user.membership_days_left():
            raise InsufficientFunds(
                title="💸 Недостаточно средств :(",
                message=f"Вы не можете подарить юзеру эту награду, "
                        f"так как у вас осталось {math.floor(from_user.membership_days_left())} дней членства, "
                        f"а награда стоит {badge.price_days}. "
                        f"Продлите членство в настройках своего профиля."
            )

        with transaction.atomic():
            # save user badge into the database
            try:
                user_badge = UserBadge.objects.create(
                    badge=badge,
                    from_user=from_user,
                    to_user=to_user,
                    post=post,
                    comment=comment,
                    note=note,
                )
            except IntegrityError:
                raise ContentDuplicated(
                    title="🛑 Вы уже дарили награду за этот пост или комментарий",
                    message="Повторно награды дарить нельзя. Но вы можете подарить другую награду."
                )

            # deduct days balance from profile
            User.objects\
                .filter(id=from_user.id)\
                .update(
                    membership_expires_at=F("membership_expires_at") - timedelta(days=badge.price_days)
                )

            # add badge to post/comment metadata (for caching purposes)
            comment_or_post = comment or post
            metadata = comment_or_post.metadata or {}
            badges = metadata.get("badges") or {}
            if badge.code not in badges:
                # add new badge
                badges[badge.code] = {
                    "title": badge.title,
                    "description": badge.description,
                    "count": 1,
                }
            else:
                # if badge exists, increment badge count
                badges[badge.code]["count"] += 1

            # update metadata only (do not use .save(), it saves all fields and can cause side-effects)
            metadata["badges"] = badges
            type(comment_or_post).objects.filter(id=comment_or_post.id).update(metadata=metadata)

        return user_badge
Example #3
0
def request_delete_account(request, user_slug):
    if request.method != "POST":
        return redirect("edit_account", user_slug, permanent=False)

    user = get_object_or_404(User, slug=user_slug)
    if user.id != request.me.id and not request.me.is_god:
        raise Http404()

    confirmation_string = request.POST.get("confirm")
    if confirmation_string != settings.GDPR_DELETE_CONFIRMATION:
        raise BadRequest(
            title="Неправильная строка подтверждения",
            message=
            f"Вы должны в точности написать \"{settings.GDPR_DELETE_CONFIRMATION}\" "
            f"чтобы запустить процедуру удаления аккаунта")

    DataRequests.register_forget_request(user)

    code = Code.create_for_user(user=user,
                                recipient=user.email,
                                length=settings.GDPR_DELETE_CODE_LENGTH)
    async_task(send_delete_account_request_email, user=user, code=code)

    return render(request, "users/messages/delete_account_requested.html",
                  {"user": user})
Example #4
0
def gift_membership_days(days,
                         from_user,
                         to_user,
                         deduct_from_original_user=True):
    if days <= 0:
        raise BadRequest(message="Количество дней должно быть больше 0")

    amount = timedelta(days=days)

    if deduct_from_original_user and from_user.membership_expires_at - amount <= datetime.utcnow(
    ):
        raise InsufficientFunds()

    with transaction.atomic():
        if to_user.membership_expires_at <= datetime.utcnow():
            to_user.membership_expires_at = datetime.utcnow()
        to_user.membership_expires_at += amount
        to_user.membership_platform_type = User.MEMBERSHIP_PLATFORM_DIRECT
        to_user.save()

        if deduct_from_original_user:
            from_user.membership_expires_at -= amount
            from_user.save()

    return to_user.membership_expires_at
Example #5
0
def create_badge_for_post(request, post_slug):
    post = get_object_or_404(Post, slug=post_slug)
    if post.deleted_at:
        raise BadRequest(title="😵 Пост удалён",
                         message="Нельзя давать награды за удалённые посты")

    if request.method != "POST":
        if request.me.membership_days_left(
        ) < settings.MIN_DAYS_TO_GIVE_BADGES:
            return render(request, "badges/messages/insufficient_funds.html")

        return render(request, "badges/create.html", {
            "post": post,
            "badges": Badge.visible_objects().all(),
        })

    badge_code = request.POST.get("badge_code")
    badge = Badge.objects.filter(code=badge_code).first()
    if not badge or not badge.is_visible:
        raise BadRequest(title="🙅‍♀️ Бейджик недоступен",
                         message="Данную награду пока нельзя выдавать")

    note = (request.POST.get("note") or "")[:1000]
    user_badge = UserBadge.create_user_badge(
        badge=badge,
        from_user=request.me,
        to_user=post.author,
        post=post,
        note=note,
    )

    # bump post on home page by updating its last_activity_at
    Post.objects.filter(id=post.id).update(last_activity_at=datetime.utcnow())

    # show insufficient funds warning if < 3 months
    show_funds_warning = request.me.membership_days_left() - \
        user_badge.badge.price_days < settings.MIN_DAYS_TO_GIVE_BADGES * 3

    return render(request, "badges/messages/success.html", {
        "user_badge": user_badge,
        "show_funds_warning": show_funds_warning,
    })
Example #6
0
    def save(self, *args, **kwargs):
        if self.reply_to and self.reply_to.reply_to and self.reply_to.reply_to.reply_to_id:
            raise BadRequest(message="3 уровня комментариев это максимум")

        self.updated_at = datetime.utcnow()
        return super().save(*args, **kwargs)