コード例 #1
0
ファイル: posts.py プロジェクト: thelebster/vas3k.club
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,
    })
コード例 #2
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
    })
コード例 #3
0
def render_post(request, post, context=None):
    # render "raw" newsletters
    if post.type == Post.TYPE_WEEKLY_DIGEST:
        return HttpResponse(post.html)

    # select votes and comments
    if request.me:
        comments = Comment.objects_for_user(request.me).filter(post=post).all()
        is_bookmark = PostBookmark.objects.filter(post=post,
                                                  user=request.me).exists()
        is_voted = PostVote.objects.filter(post=post, user=request.me).exists()
        upvoted_at = int(
            PostVote.objects.filter(
                post=post, user=request.me).first().created_at.timestamp() *
            1000) if is_voted else None
        subscription = PostSubscription.get(request.me, post)
    else:
        comments = Comment.visible_objects(show_deleted=True).filter(
            post=post).all()
        is_voted = False
        is_bookmark = False
        upvoted_at = None
        subscription = None

    # order comments
    comment_order = request.GET.get("comment_order") or "-upvotes"
    if comment_order in POSSIBLE_COMMENT_ORDERS:
        comments = comments.order_by(
            comment_order,
            "created_at")  # additionally sort by time to preserve an order

    # hide deleted comments for battle (visual junk)
    if post.type == Post.TYPE_BATTLE:
        comments = comments.filter(is_deleted=False)

    comment_form = CommentForm(initial={'text': post.comment_template}
                               ) if post.comment_template else CommentForm()
    context = {
        **(context or {}),
        "post": post,
        "comments": comments,
        "comment_form": comment_form,
        "comment_order": comment_order,
        "reply_form": ReplyForm(),
        "is_bookmark": is_bookmark,
        "is_voted": is_voted,
        "upvoted_at": upvoted_at,
        "subscription": subscription,
    }

    # TODO: make a proper mapping here in future
    if post.type == Post.TYPE_BATTLE:
        context["comment_form"] = BattleCommentForm()

    try:
        return render(request, f"posts/show/{post.type}.html", context)
    except TemplateDoesNotExist:
        return render(request, "posts/show/post.html", context)
コード例 #4
0
def async_create_or_update_comment(comment):
    notified_user_ids = set()

    # notify post subscribers
    post_subscribers = PostSubscription.post_subscribers(comment.post)
    for post_subscriber in post_subscribers:
        if post_subscriber.user.telegram_id and comment.author != post_subscriber.user:
            template = "comment_to_post.html" if post_subscriber.user == comment.post.author else "comment_to_post_announce.html"
            send_telegram_message(
                chat=Chat(id=post_subscriber.user.telegram_id),
                text=render_html_message(template, comment=comment),
            )
            notified_user_ids.add(post_subscriber.user.id)

    # on reply — notify thread author (do not notify yourself)
    if comment.reply_to:
        thread_author = comment.reply_to.author
        if thread_author.telegram_id and comment.author != thread_author and thread_author.id not in notified_user_ids:
            send_telegram_message(
                chat=Chat(id=thread_author.telegram_id),
                text=render_html_message("comment_to_thread.html",
                                         comment=comment),
            )
            notified_user_ids.add(thread_author.id)

    # post top level comments to online channel
    if not comment.reply_to:
        send_telegram_message(
            chat=CLUB_ONLINE,
            text=render_html_message("comment_to_post_announce.html",
                                     comment=comment),
        )

    # parse @nicknames and notify their users
    for username in USERNAME_RE.findall(comment.text):
        if username == settings.MODERATOR_USERNAME:
            send_telegram_message(
                chat=ADMIN_CHAT,
                text=render_html_message("moderator_mention.html",
                                         comment=comment),
            )
            continue

        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user.id not in notified_user_ids:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
            )
            notified_user_ids.add(user.id)
コード例 #5
0
ファイル: posts.py プロジェクト: thelebster/vas3k.club
def toggle_post_subscription(request, post_slug):
    if request.method != "POST":
        raise Http404()

    post = get_object_or_404(Post, slug=post_slug)

    subscription, is_created = PostSubscription.subscribe(
        user=request.me,
        post=post,
        type=PostSubscription.TYPE_TOP_LEVEL_ONLY,
    )

    if not is_created:
        subscription.delete()

    return {"status": "created" if is_created else "deleted"}
コード例 #6
0
def async_create_or_update_comment(comment):
    notified_user_ids = set()

    # notify post subscribers
    post_subscribers = PostSubscription.post_subscribers(comment.post)
    for post_subscriber in post_subscribers:
        if post_subscriber.user.telegram_id and comment.author != post_subscriber.user:
            # respect subscription type (i.e. all comments vs top level only)
            if post_subscriber.type == PostSubscription.TYPE_ALL_COMMENTS \
                    or (post_subscriber.type == PostSubscription.TYPE_TOP_LEVEL_ONLY and not comment.reply_to_id):
                send_telegram_message(
                    chat=Chat(id=post_subscriber.user.telegram_id),
                    text=render_html_message("comment_to_post.html",
                                             comment=comment),
                )
                notified_user_ids.add(post_subscriber.user.id)

    # notify thread author on reply (note: do not notify yourself)
    if comment.reply_to:
        thread_author = comment.reply_to.author
        if thread_author.telegram_id and comment.author != thread_author and thread_author.id not in notified_user_ids:
            send_telegram_message(
                chat=Chat(id=thread_author.telegram_id),
                text=render_html_message("comment_to_thread.html",
                                         comment=comment),
            )
            notified_user_ids.add(thread_author.id)

    # post top level comments to online channel
    if not comment.reply_to and comment.post.is_visible and comment.post.is_visible_in_feeds:
        send_telegram_message(
            chat=CLUB_ONLINE,
            text=render_html_message("comment_to_post.html", comment=comment),
        )

    # notify friends about your comments (not replies)
    if not comment.reply_to:
        friends = Friend.friends_for_user(comment.author)
        for friend in friends:
            if friend.user_from.telegram_id \
                    and friend.is_subscribed_to_comments \
                    and friend.user_from.id not in notified_user_ids:
                send_telegram_message(
                    chat=Chat(id=friend.user_from.telegram_id),
                    text=render_html_message("friend_comment.html",
                                             comment=comment),
                )
                notified_user_ids.add(friend.user_from.id)

    # parse @nicknames and notify their users
    for username in USERNAME_RE.findall(comment.text):
        if username == settings.MODERATOR_USERNAME:
            send_telegram_message(
                chat=ADMIN_CHAT,
                text=render_html_message("moderator_mention.html",
                                         comment=comment),
            )
            continue

        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user.id not in notified_user_ids:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
            )
            notified_user_ids.add(user.id)