Skip to content

Commit

Permalink
feat: add TelegramRenderer for notifications (#1255)
Browse files Browse the repository at this point in the history
* Add TelegramRenderer

* Don't wrap into in a code block

* Put PlainRenderer and render_plain back

* Put PlainRenderer and render_plain back (posts.py)
  • Loading branch information
Bobronium authored Sep 9, 2024
1 parent 5be9b62 commit a5d1000
Show file tree
Hide file tree
Showing 17 changed files with 99 additions and 16 deletions.
5 changes: 5 additions & 0 deletions common/markdown/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from common.markdown.club_renderer import ClubRenderer
from common.markdown.email_renderer import EmailRenderer
from common.markdown.plain_renderer import PlainRenderer
from common.markdown.telegram_renderer import TelegramRenderer


def markdown_text(text, renderer=ClubRenderer):
Expand All @@ -16,5 +17,9 @@ def markdown_plain(text):
return markdown_text(text, renderer=PlainRenderer)


def markdown_tg(text):
return markdown_text(text, renderer=TelegramRenderer)


def markdown_email(text):
return markdown_text(text, renderer=EmailRenderer)
55 changes: 55 additions & 0 deletions common/markdown/telegram_renderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import mistune

LIST_BULLET_POINTS = {1: "• ", 2: "◦ ", 3: "▪ "}


def get_bullet_point(level: int) -> str:
return LIST_BULLET_POINTS[(level - 1) % len(LIST_BULLET_POINTS) + 1]


def indent(level: int) -> str:
return " " * (level - 1)


def convert_bulet_to_ordered_list(text, level, start):
current_indent = indent(level)
prefix_to_change = f"{current_indent}{get_bullet_point(level)}"
items = text.split("\n" + prefix_to_change)
items[0] = items[0][len(prefix_to_change):]
return "\n".join(f"{current_indent}{i}. {item}" for i, item in enumerate(items, start or 1))


class TelegramRenderer(mistune.HTMLRenderer):
def image(self, src, alt="", title=None):
if alt:
return f'<a href="{src}">🏞 «{alt}»</a>'
else:
return f'<a href="{src}">🏞🔗</a>'

def strikethrough(self, text):
return f"<s>{text}</s>"

def linebreak(self):
return "\n"

def paragraph(self, text):
return text + "\n\n"

def heading(self, text, level):
return f"<b>{text}</b>\n\n"

def newline(self):
return "\n"

def list(self, text, ordered, level, start=None):
if ordered:
text = convert_bulet_to_ordered_list(text, level, start)
if level > 1:
text = "\n" + text
return text

def list_item(self, text, level):
return f"{indent(level)}{get_bullet_point(level)}{text}\n"

def thematic_break(self):
return '---\n'
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

{% endif %}Re: <b><a href="{{ settings.APP_HOST }}{% url "show_comment" comment.post.slug comment.id %}">{% if comment.post.emoji %}{{ comment.post.emoji }} {% endif %}{% if comment.post.prefix %}{{ comment.post.prefix }} {% endif %}{{ comment.post.title }}</a></b>

(+{{ comment.upvotes }}) <b>{{ comment.author.full_name }}:</b> {% render_plain comment 3000 %}
(+{{ comment.upvotes }}) <b>{{ comment.author.full_name }}:</b> {% render_tg comment 3000 %}

<a href="{{ settings.APP_HOST }}{% url "show_comment" comment.post.slug comment.id %}">{{ comment.created_at | cool_date }}</a>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
{% endif %}{% if comment.title %}
<b>{{ comment.title }}</b>
{% endif %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_plain comment 3000 %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_tg comment 3000 %}

<a href="{{ settings.APP_HOST }}{% url "show_comment" comment.post.slug comment.id %}#comment-{{ comment.id }}">Посмотреть ➜</a>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% if post.emoji %}{{ post.emoji }} {% endif %}<b>{% if post.prefix and post.prefix != post.emoji %}{{ post.prefix }} {% endif %}<a href="{{ settings.APP_HOST }}{% url "show_post" post.type post.slug %}">{{ post.title }}</a> {% if post.room %} [{{ post.room.title }}]{% endif %}</b>

{% load posts %}{% render_plain post 350 %}
{% load posts %}{% render_tg post 350 %}

➜ {{ settings.APP_HOST }}{% url "show_post" post.type post.slug %}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
💬 <b>Кто-то упомянул вас в комментарии под постом «<a href="{{ settings.APP_HOST }}{% url "show_post" comment.post.type comment.post.slug %}#comment-{{ comment.id }}">{{ comment.post.title }}</a>»</b>

{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_plain comment 3000 %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_tg comment 3000 %}

<i>↩ Вы можете ответить просто реплайнув на это сообщение</i>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
{% endif %}{% if comment.title %}
<b>{{ comment.title }}</b>
{% endif %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_plain comment 3000 %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_tg comment 3000 %}

<i>↩ Вы можете ответить просто реплайнув на это сообщение</i>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
💬 <b>Новый реплай к вашему комментарию под постом «<a href="{{ settings.APP_HOST }}{% url "show_post" comment.post.type comment.post.slug %}#comment-{{ comment.id }}">{{ comment.post.title }}</a>»</b>

{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_plain comment 3000 %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_tg comment 3000 %}

<i>↩ Вы можете ответить просто реплайнув на это сообщение</i>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
💬 <b>Ваш чувак {{ comment.author.full_name }} оставил коммент к посту «<a href="{{ settings.APP_HOST }}{% url "show_post" comment.post.type comment.post.slug %}#comment-{{ comment.id }}">{{ comment.post.title }}</a>»</b>

{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_plain comment 3000 %}
{% load posts %}<b>{{ comment.author.full_name }}:</b> {% render_tg comment 3000 %}

<i>↩ Вы можете ответить просто реплайнув на это сообщение</i>
2 changes: 1 addition & 1 deletion notifications/telegram/templates/messages/friend_post.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Ваш чувак {{ post.author.full_name }} написал пост 👇

{% if post.emoji %}{{ post.emoji }} {% endif %}<b>{% if post.prefix %}{{ post.prefix }} {% endif %}<a href="{{ settings.APP_HOST }}{% url "show_post" post.type post.slug %}">{{ post.title }}</a> {% if post.room %} [{{ post.room.title }}]{% endif %}</b>
{% load posts %}{% render_plain post 350 %}
{% load posts %}{% render_tg post 350 %}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
💬 <b>{% if not comment.reply_to_id %}Коммент{% else %}Реплай{% endif %} к «<a href="{{ settings.APP_HOST }}{% url "show_post" comment.post.type comment.post.slug %}#comment-{{ comment.id }}">{{ comment.post.title }}</a>»</b> от <a href="{{ settings.APP_HOST }}{% url "profile" comment.author.slug %}">{{ comment.author.slug }}</a>

{% load posts %}{% if comment.title %}<b>{{ comment.title }}</b> {% endif %}{% render_plain comment 300 %}
{% load posts %}{% if comment.title %}<b>{{ comment.title }}</b> {% endif %}{% render_tg comment 300 %}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
🛎 <b>Кто-то позвал модератора в пост «<a href="{{ settings.APP_HOST }}{% url "show_post" comment.post.type comment.post.slug %}#comment-{{ comment.id }}">{{ comment.post.title }}</a>»</b>

{% load posts %}<b>{{ comment.author.slug }}:</b> {% render_plain comment 3000 %}
{% load posts %}<b>{{ comment.author.slug }}:</b> {% render_tg comment 3000 %}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
<b>Аватар:</b> {{ user.avatar }}

<b>Интро:</b>
<pre>{% render_plain intro 2000 %}</pre>
{% render_tg intro 2000 %}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<b>Автор:</b> {{ post.author.slug }} {% if post.author.telegram_data %}(tg: @{{ post.author.telegram_data.username }}){% endif %}
{% if post.url %}<b>Ссылка:</b> {{ post.url }}{% endif %}{% if post.collectible_tag_code %}🚨 <b>Прикреплён коллекционный тег:</b> {{ post.collectible_tag_code }}{% endif %}{% if not post.is_visible_in_feeds %}👀 <b>Пост виден только в комнате! Можно модерить без жести.</b>{% endif %}

{% load posts %}{% render_plain post 350 %}
{% load posts %}{% render_tg post 350 %}

{{ settings.APP_HOST }}{% url "show_post" post.type post.slug %}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{% load posts %}👁 <b>Юзер обновил интро:</b> <a href="{{ settings.APP_HOST }}{% url "profile" user.slug %}">{{ user.slug }}</a>

<pre>{% render_plain intro 1000 %}</pre>
{% render_tg intro 1000 %}
2 changes: 1 addition & 1 deletion notifications/telegram/templates/messages/top.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@

{{ top_comment.author.full_name }} к посту <a href="{{ settings.APP_HOST }}{% url "show_post" top_comment.post.type top_comment.post.slug %}">{{ top_comment.post.title }}</a> (+{{ top_comment.upvotes }})
{% load posts %}
{% render_plain top_comment 300 %}
{% render_tg top_comment 300 %}
27 changes: 25 additions & 2 deletions posts/templatetags/posts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
from django import template
from django.conf import settings
from django.template import loader
from django.template.defaultfilters import truncatechars
from django.template.defaultfilters import truncatechars, truncatechars_html
from django.urls import reverse
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe

from common.embeds import CUSTOM_ICONS, CUSTOM_PARSERS
from common.regexp import FAVICON_RE
from common.markdown.markdown import markdown_text, markdown_plain
from common.markdown.markdown import markdown_text, markdown_plain, markdown_tg
from posts.helpers import extract_any_image
from posts.models.post import Post

Expand Down Expand Up @@ -55,6 +55,29 @@ def render_plain(context, post, truncate=None):
return result


@register.simple_tag()
def render_tg(post_or_comment, truncate=None):
result = mark_safe(markdown_tg(post_or_comment.text))
if truncate:
# HACK: `truncatechars_html` ignores HTML tag length, but Telegram counts it
# ensure the total length (including tags) stays within Telegram's limit
desired_length = truncate
attempt = 0
max_attempts = 30
while len(result) > int(desired_length):
attempt += 1
if attempt > max_attempts:
return result # just to make sure we won't hang in an endless loop
result = truncatechars_html(result, truncate)
truncate -= 100

if "\n" in result:
# ensure visual separation from previous block when rendered multiline comments
result = mark_safe("\n" + result)

return result


@register.simple_tag()
def feed_ordering_url(room, label_code, post_type, ordering_type):
if room:
Expand Down

0 comments on commit a5d1000

Please sign in to comment.