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, })
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 })
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)
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)
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"}
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)