Example #1
0
def create_or_edit(request, post_type, post=None, mode="create"):
    FormClass = POST_TYPE_MAP.get(post_type) or PostTextForm

    # show blank form on GET
    if request.method != "POST":
        form = FormClass(instance=post)
        return render(request, f"posts/compose/{post_type}.html", {
            "mode": mode,
            "post_type": post_type,
            "form": form,
        })

    # validate form on POST
    form = FormClass(request.POST, request.FILES, instance=post)
    if form.is_valid():
        if not request.me.is_moderator:
            if Post.check_duplicate(user=request.me,
                                    title=form.cleaned_data["title"],
                                    ignore_post_id=post.id if post else None):
                raise ContentDuplicated()

            is_ok = Post.check_rate_limits(request.me)
            if not is_ok:
                raise RateLimitException(
                    title="πŸ™…β€β™‚οΈ Блишком ΠΌΠ½ΠΎΠ³ΠΎ постов",
                    message=
                    "Π’ послСднСС врСмя Π²Ρ‹ создали слишком ΠΌΠ½ΠΎΠ³ΠΎ постов. ΠŸΠΎΡ‚Π΅Ρ€ΠΏΠΈΡ‚Π΅, поТалуйста."
                )

        post = form.save(commit=False)
        if not post.author_id:
            post.author = request.me
        post.type = post_type
        post.html = None  # flush cache
        post.save()

        if mode == "create" or not post.is_visible:
            PostSubscription.subscribe(request.me,
                                       post,
                                       type=PostSubscription.TYPE_ALL_COMMENTS)

        if post.is_visible:
            if post.topic:
                post.topic.update_last_activity()

            SearchIndex.update_post_index(post)
            LinkedPost.create_links_from_text(post, post.text)

        action = request.POST.get("action")
        if action == "publish":
            post.publish()
            LinkedPost.create_links_from_text(post, post.text)

        return redirect("show_post", post.type, post.slug)

    return render(request, f"posts/compose/{post_type}.html", {
        "mode": mode,
        "post_type": post_type,
        "form": form,
    })
Example #2
0
def create_comment(request, post_slug):
    post = get_object_or_404(Post, slug=post_slug)
    if not post.is_commentable and not request.me.is_moderator:
        raise AccessDenied(title="ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΊ этому посту Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹")

    if request.POST.get("reply_to_id"):
        ProperCommentForm = ReplyForm
    elif post.type == Post.TYPE_BATTLE:
        ProperCommentForm = BattleCommentForm
    else:
        ProperCommentForm = CommentForm

    if request.method == "POST":
        form = ProperCommentForm(request.POST)
        if form.is_valid():
            is_ok = Comment.check_rate_limits(request.me)
            if not is_ok:
                raise RateLimitException(
                    title="πŸ™…β€β™‚οΈ Π’Ρ‹ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ слишком часто",
                    message=
                    "ΠŸΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ, Π²Ρ‹ достигли нашСго Π»ΠΈΠΌΠΈΡ‚Π° Π½Π° ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ Π² дСнь. "
                    "ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π½Π°ΠΌ Π² саппорт, ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΠ± этом.")

            comment = form.save(commit=False)
            comment.post = post
            if not comment.author:
                comment.author = request.me

            comment.ipaddress = parse_ip_address(request)
            comment.useragent = parse_useragent(request)
            comment.save()

            # update the shitload of counters :)
            request.me.update_last_activity()
            Comment.update_post_counters(post)
            PostView.increment_unread_comments(comment)
            PostView.register_view(
                request=request,
                user=request.me,
                post=post,
            )
            SearchIndex.update_comment_index(comment)
            LinkedPost.create_links_from_text(post, comment.text)

            return redirect("show_comment", post.slug, comment.id)
        else:
            log.error(f"Comment form error: {form.errors}")
            return render(
                request, "error.html", {
                    "title": "Какая-Ρ‚ΠΎ ошибка ΠΏΡ€ΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ коммСнтария πŸ€·β€β™‚οΈ",
                    "message": f"ΠœΡ‹ ΡƒΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΈ скоро пофиксим. "
                    f"Π’Π°Ρˆ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚ ΠΌΡ‹ сохранили Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ ΠΌΠΎΠ³Π»ΠΈ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΈ Π·Π°ΠΏΠΎΡΡ‚ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅ Ρ€Π°Π·:",
                    "data": form.cleaned_data.get("text")
                })

    raise Http404()
Example #3
0
def compose_type(request, post_type):
    if post_type not in dict(Post.TYPES):
        raise Http404()

    FormClass = POST_TYPE_MAP.get(post_type) or PostTextForm

    if request.method == "POST":
        form = FormClass(request.POST, request.FILES)
        if form.is_valid():

            if not request.me.is_moderator:
                if Post.check_duplicate(user=request.me,
                                        title=form.cleaned_data["title"]):
                    raise ContentDuplicated()

                is_ok = Post.check_rate_limits(request.me)
                if not is_ok:
                    raise RateLimitException(
                        title="πŸ™…β€β™‚οΈ Блишком ΠΌΠ½ΠΎΠ³ΠΎ постов",
                        message=
                        "Π’ послСднСС врСмя Π²Ρ‹ создали слишком ΠΌΠ½ΠΎΠ³ΠΎ постов. ΠŸΠΎΡ‚Π΅Ρ€ΠΏΠΈΡ‚Π΅, поТалуйста."
                    )

            post = form.save(commit=False)
            post.author = request.me
            post.type = post_type
            post.save()

            PostSubscription.subscribe(request.me, post)

            if post.is_visible:
                if post.topic:
                    post.topic.update_last_activity()

                SearchIndex.update_post_index(post)
                LinkedPost.create_links_from_text(post, post.text)

            if post.is_visible or request.POST.get("show_preview"):
                return redirect("show_post", post.type, post.slug)
            else:
                return redirect("compose")
    else:
        form = FormClass()

    return render(request, f"posts/compose/{post_type}.html", {
        "mode": "create",
        "form": form
    })
Example #4
0
    def create_for_user(cls, user, recipient, length=6):
        recipient = recipient.lower()
        last_codes_count = Code.objects.filter(
            recipient=recipient,
            created_at__gte=datetime.utcnow() - settings.AUTH_MAX_CODE_TIMEDELTA,
        ).count()
        if last_codes_count > settings.AUTH_MAX_CODE_COUNT:
            raise RateLimitException(title="Π’Ρ‹ запросили слишком ΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄ΠΎΠ²")

        return Code.objects.create(
            recipient=recipient,
            user=user,
            code=random_number(length),
            created_at=datetime.utcnow(),
            expires_at=datetime.utcnow() + settings.AUTH_CODE_EXPIRATION_TIMEDELTA,
        )
Example #5
0
    def register_archive_request(cls, user):
        latest_request = DataRequests.objects\
            .filter(user=user, type=DataRequests.TYPE_ARCHIVE)\
            .order_by("-created_at")\
            .first()

        if latest_request and latest_request.created_at > datetime.utcnow(
        ) - settings.GDPR_ARCHIVE_REQUEST_TIMEDELTA:
            raise RateLimitException(
                title="Π’Ρ‹ ΡƒΠΆΠ΅ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π»ΠΈ Π°Ρ€Ρ…ΠΈΠ² совсСм Π½Π΅Π΄Π°Π²Π½ΠΎ",
                message="ГСнСрация Π°Ρ€Ρ…ΠΈΠ²Π° β€” слоТная Π·Π°Π΄Π°Ρ‡Π°, "
                "ΠΏΠΎΡ‚ΠΎΠΌΡƒ Π½Π°ΠΌ приходится ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒ количСство запросов Π² дСнь. "
                "ΠŸΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚Π΅ Π·Π°Π²Ρ‚Ρ€Π°!")

        return DataRequests.objects.create(
            user=user,
            type=DataRequests.TYPE_ARCHIVE,
        )
Example #6
0
    def check_code(cls, recipient, code):
        recipient = recipient.lower()
        last_code = Code.objects.filter(recipient=recipient).order_by("-created_at").first()
        if not last_code:
            raise InvalidCode()

        if last_code.attempts >= settings.AUTH_MAX_CODE_ATTEMPTS:
            raise RateLimitException(
                title="Π’Ρ‹ Π²Π²Π΅Π»ΠΈ ΠΊΠΎΠ΄ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ нСсколько Ρ€Π°Π·. ΠŸΡ€ΠΈΠ΄Ρ‘Ρ‚ΡΡ Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π·Π°Π½ΠΎΠ²ΠΎ",
                message="ВсС ΠΏΡ€ΠΎΡˆΠ»Ρ‹Π΅ ΠΊΠΎΠ΄Ρ‹ большС Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ Ρ€Π°Π΄ΠΈ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚ ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€Π°"
            )

        if last_code.is_expired() or last_code.code != code:
            last_code.attempts += 1
            last_code.save()
            raise InvalidCode()

        Code.objects.filter(recipient=recipient).delete()
        return last_code.user