Exemplo n.º 1
0
def async_create_or_update_post(post, is_created):
    if not post.is_approved_by_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_post.html", post=post),
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton(
                        "👍 Одобрить", callback_data=f"approve_post:{post.id}"),
                    telegram.InlineKeyboardButton(
                        "😕 Так себе", callback_data=f"forgive_post:{post.id}"),
                ],
                 [
                     telegram.InlineKeyboardButton(
                         "❌ В черновики",
                         callback_data=f"delete_post:{post.id}"),
                 ]]))

    # post to online channel
    send_telegram_message(
        chat=CLUB_ONLINE,
        text=render_html_message("channel_post_announce.html", post=post),
        parse_mode=telegram.ParseMode.HTML,
        disable_preview=True,
    )
Exemplo n.º 2
0
def notify_user_profile_rejected(user: User, reason: RejectReason):
    try:
        text = render_html_message(f"rejected/{reason.value}.html", user=user)
    except TemplateDoesNotExist:
        text = render_html_message(f"rejected/intro.html", user=user)

    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=text,
        )
Exemplo n.º 3
0
def notify_post_author_rejected(post):
    if post.author.telegram_id:
        send_telegram_message(
            chat=Chat(id=post.author.telegram_id),
            text=render_html_message("post_rejected.html", post=post),
            parse_mode=telegram.ParseMode.HTML,
        )
Exemplo n.º 4
0
def announce_in_club_chat(post):
    send_telegram_message(
        chat=CLUB_CHAT,
        text=render_html_message("channel_post_announce.html", post=post),
        parse_mode=telegram.ParseMode.HTML,
        disable_preview=True,
    )
Exemplo n.º 5
0
def announce_post(request, post_slug):
    post = get_object_or_404(Post, slug=post_slug)

    initial = {
        "text": render_html_message("channel_post_announce.html", post=post),
        "image": extract_some_image(post),
    }

    if request.method == "POST":
        form = PostAnnounceForm(request.POST, initial=initial)
        if form.is_valid():
            announce_in_club_channel(
                post=post,
                announce_text=form.cleaned_data["text"],
                image=form.cleaned_data["image"] if form.cleaned_data["with_image"] else None
            )
            return render(request, "message.html", {
                "title": "Запощено ✅"
            })
    else:
        form = PostAnnounceForm(initial=initial)

    return render(request, "admin/simple_form.html", {
        "title": "Анонсировать пост на канале",
        "post": post,
        "form": form
    })
Exemplo n.º 6
0
def async_create_or_update_achievement(user_achievement: UserAchievement):
    user = user_achievement.user
    achievement = user_achievement.achievement

    # messages
    if user.is_club_member and user.telegram_id:
        if achievement.image:
            send_telegram_image(
                chat=Chat(id=user.telegram_id),
                image_url=achievement.image,
                text=render_html_message("achievement.html",
                                         user=user,
                                         achievement=achievement),
            )

    # emails
    if not user.is_email_unsubscribed:
        email_template = loader.get_template("emails/achievement.html")
        send_club_email(
            recipient=user.email,
            subject=f"🎖 Вас наградили бейджиком «{achievement.name}»",
            html=email_template.render({
                "user": user,
                "achievement": achievement
            }),
            tags=["achievement"])
Exemplo n.º 7
0
def async_create_or_update_comment(comment, is_created):
    # notify admins
    send_telegram_message(
        chat=ADMIN_CHAT,
        text=render_html_message("moderator_comment.html", comment=comment),
        parse_mode=telegram.ParseMode.HTML,
    )

    # notify post author
    post_author = comment.post.author
    if post_author.telegram_id and comment.author != post_author:
        send_telegram_message(
            chat=Chat(id=comment.post.author.telegram_id),
            text=render_html_message("comment_to_post.html", comment=comment),
            parse_mode=telegram.ParseMode.HTML,
        )

    # on reply — notify thread author (do not notify yourself)
    thread_author = None
    if comment.reply_to:
        thread_author = comment.reply_to.author
        if comment.reply_to_id and thread_author.telegram_id and comment.author != thread_author:
            send_telegram_message(
                chat=Chat(id=comment.reply_to.author.telegram_id),
                text=render_html_message("comment_to_thread.html",
                                         comment=comment),
                parse_mode=telegram.ParseMode.HTML,
            )

    # post first level comments to club chat
    # if not comment.reply_to:
    #     send_telegram_message(
    #         chat=CLUB_CHAT,
    #         text=render_html_message("comment_to_post_announce.html", comment=comment),
    #         parse_mode=telegram.ParseMode.HTML,
    #     )

    # parse @nicknames and notify their users
    for username in USERNAME_RE.findall(comment.text):
        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user != post_author and user != thread_author:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
                parse_mode=telegram.ParseMode.HTML,
            )
Exemplo n.º 8
0
def announce_in_club_chats(post):
    if post.topic and post.topic.chat_id:
        # announce to the topic chat
        send_telegram_message(
            chat=Chat(id=post.topic.chat_id),
            text=render_html_message("channel_post_announce.html", post=post),
            parse_mode=telegram.ParseMode.HTML,
            disable_preview=True,
        )
    else:
        # announce to public chat
        send_telegram_message(
            chat=CLUB_CHAT,
            text=render_html_message("channel_post_announce.html", post=post),
            parse_mode=telegram.ParseMode.HTML,
            disable_preview=True,
        )
Exemplo n.º 9
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):
        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)
Exemplo n.º 10
0
def async_create_or_update_post(post, is_created):
    if not post.is_approved_by_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_new_post_review.html",
                                     post=post),
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton(
                        "👍 Одобрить", callback_data=f"approve_post:{post.id}"),
                    telegram.InlineKeyboardButton(
                        "😕 Так себе", callback_data=f"forgive_post:{post.id}"),
                ],
                 [
                     telegram.InlineKeyboardButton(
                         "❌ В черновики",
                         callback_data=f"delete_post:{post.id}"),
                 ]]))

    # post to online channel
    send_telegram_message(
        chat=CLUB_ONLINE,
        text=render_html_message("channel_post_announce.html", post=post),
        parse_mode=telegram.ParseMode.HTML,
        disable_preview=True,
    )

    # parse @nicknames and notify mentioned users (only if post is visible)
    if post.is_visible and (is_created or "is_visible" in post.changed_fields):
        notified_user_ids = set()
        for username in USERNAME_RE.findall(post.text):
            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("post_mention.html", post=post),
                )
                notified_user_ids.add(user.id)
Exemplo n.º 11
0
def async_create_or_update_comment(comment, is_created):
    # notify post author
    post_author = comment.post.author
    if post_author.telegram_id and comment.author != post_author:
        send_telegram_message(
            chat=Chat(id=comment.post.author.telegram_id),
            text=render_html_message("comment_to_post.html", comment=comment),
        )

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

    # 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):
        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user != post_author and user != thread_author:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
            )
Exemplo n.º 12
0
def notify_profile_needs_review(user, intro):
    user_profile_url = settings.APP_HOST + reverse("profile", kwargs={"user_slug": user.slug})
    send_telegram_message(
        chat=ADMIN_CHAT,
        text=render_html_message("moderator_new_member_review.html", user=user, intro=intro),
        reply_markup=telegram.InlineKeyboardMarkup([
            [
                telegram.InlineKeyboardButton("👍 Впустить", callback_data=f"approve_user:{user.id}"),
                telegram.InlineKeyboardButton("❌️ Отказать", callback_data=f"reject_user:{user.id}"),
            ],
            [
                telegram.InlineKeyboardButton("😏 Посмотреть", url=user_profile_url),
            ]
        ])
    )
Exemplo n.º 13
0
    def handle(self, *args, **options):
        new_posts = Post.visible_objects()\
            .filter(
                is_approved_by_moderator=True,
                published_at__gte=datetime.utcnow() - timedelta(hours=24),
            )\
            .exclude(type=Post.TYPE_INTRO)\
            .order_by("-upvotes")[:6]

        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("good_morning.html", posts=new_posts, greetings=random.choice(DUMB_GREETINGS)),
        )

        self.stdout.write("Done 🥙")
Exemplo n.º 14
0
def async_create_or_update_post(post, is_created):
    if not post.is_approved_by_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_post.html", post=post),
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton(
                        "👍 Одобрить", callback_data=f"approve_post:{post.id}"),
                    telegram.InlineKeyboardButton(
                        "😕 Так себе", callback_data=f"forgive_post:{post.id}"),
                ],
                 [
                     telegram.InlineKeyboardButton(
                         "❌ В черновики",
                         callback_data=f"delete_post:{post.id}"),
                 ]]))
Exemplo n.º 15
0
def announce_in_club_channel(post, announce_text=None, image=None):
    if not announce_text:
        announce_text = render_html_message("channel_post_announce.html",
                                            post=post)

    if image:
        send_telegram_image(
            chat=CLUB_CHANNEL,
            image_url=image,
            text=announce_text,
        )
    else:
        send_telegram_message(
            chat=CLUB_CHANNEL,
            text=announce_text,
            disable_preview=False,
            parse_mode=telegram.ParseMode.HTML,
        )
Exemplo n.º 16
0
def create_or_update_post(sender, instance, created, **kwargs):
    if instance.type == Post.TYPE_INTRO and instance.is_visible and "text" in instance.changed_fields:
        # send intro updates to moderators
        async_task(
            send_telegram_message,
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_updated_intro.html",
                                     user=instance.author,
                                     intro=instance),
        )
        return None

    if not created and "is_visible" not in instance.changed_fields:
        return None  # we're not interested in updates, only if they change visibility

    if instance.type in {Post.TYPE_WEEKLY_DIGEST}:
        return None  # skip emails

    if not instance.is_visible:
        return None  # skip drafts too

    async_task(async_create_or_update_post, instance, created)
Exemplo n.º 17
0
def notify_profile_needs_review(user, intro):
    admin_profile_url = settings.APP_HOST + reverse(
        "admin_profile", kwargs={"user_slug": user.slug})

    send_telegram_message(
        chat=ADMIN_CHAT,
        text=render_html_message("moderator_new_member_review.html",
                                 user=user,
                                 intro=intro),
        reply_markup=telegram.InlineKeyboardMarkup(
            [[
                telegram.InlineKeyboardButton(
                    "👍 Впустить", callback_data=f"approve_user:{user.id}")
            ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Плохое интро",
                     callback_data=f"reject_user_intro:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Недостаточно данных",
                     callback_data=f"reject_user_data:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Агрессия",
                     callback_data=f"reject_user_aggression:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Слишком общее",
                     callback_data=f"reject_user_general:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton("✏️ Написать юзеру",
                                               url=admin_profile_url),
             ]]))
Exemplo n.º 18
0
    def handle(self, *args, **options):
        # render digest using a special html endpoint
        digest_url = "https://vas3k.club" + reverse("render_weekly_digest")
        self.stdout.write(f"Generating digest: {digest_url}")

        digest_html_response = requests.get(digest_url)
        if digest_html_response.status_code > 400:
            log.error("Weekly digest error: bad status code", extra={"html": digest_html_response.text})
            return

        digest_html = digest_html_response.text

        # save digest as a post
        issue = (datetime.utcnow() - settings.LAUNCH_DATE).days // 7
        year, week, _ = (datetime.utcnow() - timedelta(days=7)).isocalendar()
        post, _ = Post.objects.update_or_create(
            slug=f"{year}_{week}",
            type=Post.TYPE_WEEKLY_DIGEST,
            defaults=dict(
                author=User.objects.filter(slug="vas3k").first(),
                title=f"Клубный журнал. Итоги недели. Выпуск #{issue}",
                html=digest_html,
                text=digest_html,
                is_pinned_until=datetime.utcnow() + timedelta(days=1),
                is_visible=True,
                is_public=False,
            )
        )

        SearchIndex.update_post_index(post)

        # sending emails
        subscribed_users = User.objects\
            .filter(
                is_email_verified=True,
                membership_expires_at__gte=datetime.utcnow() - timedelta(days=14)
            )\
            .exclude(email_digest_type=User.EMAIL_DIGEST_TYPE_NOPE)\
            .exclude(is_profile_rejected=True)\
            .exclude(is_email_unsubscribed=True)

        for user in subscribed_users:
            self.stdout.write(f"Sending to {user.email}...")

            if not options.get("production") and user.email != "*****@*****.**":
                self.stdout.write("Test mode. Use --production to send the digest to all users")
                continue

            try:
                user_digest_html = str(digest_html)
                user_digest_html = user_digest_html\
                    .replace("%username%", user.slug)\
                    .replace("%user_id%", str(user.id))\
                    .replace("%secret_code%", user.secret_hash)

                send_club_email(
                    recipient=user.email,
                    subject=f"🤘 Клубный журнал. Итоги недели. Выпуск #{issue}",
                    html=user_digest_html,
                    tags=["weekly_digest", f"weekly_digest_{issue}"]
                )
            except Exception as ex:
                self.stdout.write(f"Sending to {user.email} failed: {ex}")
                log.exception(f"Error while sending an email to {user.email}")
                continue

        if options.get("production"):
            # flush digest intro for next time
            GodSettings.objects.update(digest_intro=None)

        send_telegram_message(
            chat=CLUB_CHANNEL,
            text=render_html_message("weekly_digest_announce.html", post=post),
            disable_preview=False,
            parse_mode=telegram.ParseMode.HTML,
        )

        self.stdout.write("Done 🥙")