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 edit_post(request, post_slug): post = get_object_or_404(Post, slug=post_slug) if post.author != request.me and not request.me.is_moderator: raise AccessDenied() PostFormClass = POST_TYPE_MAP.get(post.type) or PostTextForm if request.method == "POST": form = PostFormClass(request.POST, request.FILES, instance=post) if form.is_valid(): post = form.save(commit=False) if not post.author: post.author = request.me post.html = None # flush cache post.save() SearchIndex.update_post_index(post) LinkedPost.create_links_from_text(post, post.text) if post.is_visible: return redirect("show_post", post.type, post.slug) else: return redirect("compose") else: form = PostFormClass(instance=post) return render(request, f"posts/compose/{post.type}.html", { "mode": "edit", "form": form })
def do_post_admin_actions(request, post, data): if not request.me.is_moderator: raise AccessDenied() do_common_admin_and_curator_actions(request, post, data) # Close comments if data["close_comments"]: post.is_commentable = False post.save() # Transfer ownership to the given username if data["transfer_ownership"]: user = User.objects.filter( slug=data["transfer_ownership"].strip()).first() if user: post.author = user post.save() if data["refresh_linked"]: LinkedPost.create_links_from_text(post, post.text) post_comments = Comment.visible_objects().filter(post=post, is_deleted=False) for comment in post_comments: LinkedPost.create_links_from_text(comment.post, comment.text) return redirect("show_post", post.type, post.slug)
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()
def comment_to_post(update: Update, context: CallbackContext) -> None: user = get_club_user(update) if not user: return None post = get_club_post(update) if not post or post.type in [Post.TYPE_BATTLE, Post.TYPE_WEEKLY_DIGEST]: return None is_ok = Comment.check_rate_limits(user) if not is_ok: update.message.reply_text( f"🙅♂️ Извините, вы комментировали слишком часто и достигли дневного лимита" ) return None text = update.message.text or update.message.caption if not text: update.message.reply_text( f"😣 Сорян, я пока умею только в текстовые реплаи" ) return None if len(text) < MIN_COMMENT_LEN: update.message.reply_text( f"😋 Твой коммент слишком короткий. Не буду постить его в Клуб, пускай остается в чате" ) return None reply = Comment.objects.create( author=user, post=post, text=text, useragent="TelegramBot (like TwitterBot)", metadata={ "telegram": update.to_dict() } ) LinkedPost.create_links_from_text(post, text) new_comment_url = settings.APP_HOST + reverse("show_comment", kwargs={ "post_slug": reply.post.slug, "comment_id": reply.id }) update.message.reply_text( f"➜ <a href=\"{new_comment_url}\">Отвечено</a> 👍", parse_mode=ParseMode.HTML, disable_web_page_preview=True )
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 handle(self, *args, **options): LinkedPost.objects.all().delete() posts = Post.visible_objects().exclude( type__in=[Post.TYPE_INTRO, Post.TYPE_WEEKLY_DIGEST]) for post in posts: print(f"Parsing post: {post.slug}") LinkedPost.create_links_from_text(post, post.text) del posts comments = Comment.visible_objects() for comment in comments: print(f"Parsing comment: {comment.id}") LinkedPost.create_links_from_text(comment.post, comment.text) print("Done 🥙")