From 35ea45d9c729ec74d2ead870bce837605e737a0c Mon Sep 17 00:00:00 2001 From: mctaylors Date: Sun, 18 May 2025 10:12:35 +0300 Subject: [PATCH 1/3] fix: set encoding for _c.read Signed-off-by: mctaylors --- config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.py b/config.py index 0d97476..c6c1a8b 100644 --- a/config.py +++ b/config.py @@ -4,7 +4,7 @@ from typing import Optional import requests _c = configparser.ConfigParser() -_c.read("config.ini") +_c.read("config.ini", "utf-8") class _General: From f2b6a2ee8f01cf7cda5e3f892863e05e4e464ec8 Mon Sep 17 00:00:00 2001 From: mctaylors Date: Sun, 18 May 2025 10:30:53 +0300 Subject: [PATCH 2/3] chore: make return None statement explicit in format_rating Signed-off-by: mctaylors --- extensions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions.py b/extensions.py index 1ffcc22..edc3571 100644 --- a/extensions.py +++ b/extensions.py @@ -28,3 +28,4 @@ def format_rating(value: str) -> str | None: case "e": # Negative Squared Latin Capital Letter E return "🅴" + return None From b4e406d3515e76ed016cea04aee720310ddc9ca7 Mon Sep 17 00:00:00 2001 From: mctaylors Date: Sun, 18 May 2025 10:54:44 +0300 Subject: [PATCH 3/3] feat: add /info command, pt. 2 Signed-off-by: mctaylors --- commands.py | 58 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/commands.py b/commands.py index 7b27b25..c5ea1c2 100644 --- a/commands.py +++ b/commands.py @@ -1,4 +1,4 @@ -from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup +from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, LinkPreviewOptions from telegram.constants import ParseMode from telegram.ext import ContextTypes @@ -64,26 +64,46 @@ async def info_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No uploader_data = get_json(f"users/{post_data['uploader_id']}") # well, we could check the uploader, but why would we do that? + keyboard = [ + [ + InlineKeyboardButton(f"Open in {app.name}", + url=f"https://{app.hostname}/posts/{post_id}") + ] + ] + reply_markup = InlineKeyboardMarkup(keyboard) + + # noinspection PyListCreation + m = [] + m.append(f"ID: {html_parser.code(post_data['id'])}") + m.append(f"Uploader: {html_parser.hyperlink(uploader_data['name'], + f"http://{app.host}/users/{post_data['uploader_id']}")} " + f"{html_parser.hyperlink("»", f"http://{app.host}/posts?tags=user:{uploader_data['name']}")}") + m.append(f"Date: {post_data['created_at']}") + if post_data['approver_id'] is not None: + approver_data = get_json(f"users/{post_data['approver_id']}") + m.append(f"Approver: {html_parser.hyperlink(approver_data['name'], + f"http://{app.host}/users/{post_data['approver_id']}")} " + f"{html_parser.hyperlink("»", f"http://{app.host}/posts?tags=approver:{approver_data['name']}")}") + m.append(f"Size: {post_data['media_asset']['file_size']} .{post_data['media_asset']['file_ext']} " + f"({post_data['media_asset']['image_width']}x{post_data['media_asset']['image_height']}) " + f"{html_parser.hyperlink("»", f"http://{app.host}/media_assets/{post_data['media_asset']['id']}")}") + m.append(f"Source: {post_data['source'] if post_data['source'] != "" else "🚫"}") + m.append(f"Rating: {format_rating(post_data['rating'])}") + m.append(f"Score: {html_parser.hyperlink(post_data['score'], + f"http://{app.host}/post_votes?search[post_id]={post_data['id']}&variant=compact")} " + f"(+{post_data['up_score']} / -{post_data['down_score']})") + m.append(f"Favorites: {html_parser.hyperlink(post_data['fav_count'], + f"http://{app.host}/posts/{post_data['id']}/favorites")}") + m.append(f"Status: {format_status(post_data)}") + + link_preview_options = LinkPreviewOptions(True) + if not post_data['is_banned']: + link_preview_options = LinkPreviewOptions(url=post_data['large_file_url']) + await context.bot.edit_message_text( - f"{html_parser.bold("Information")}\n" - f"ID: {html_parser.code(post_data['id'])}\n" - f"Uploader: {html_parser.hyperlink(uploader_data['name'], - f"http://{app.host}/users/{post_data['uploader_id']}")} " - f"{html_parser.hyperlink("»", f"http://{app.host}/posts?tags=user:{uploader_data['name']}")}\n" - f"Date: {post_data['created_at']}\n" - f"Size: {post_data['media_asset']['file_size']} .{post_data['media_asset']['file_ext']} " - f"({post_data['media_asset']['image_width']}x{post_data['media_asset']['image_height']}) " - f"{html_parser.hyperlink("»", f"http://{app.host}/media_assets/{post_data['media_asset']['id']}")}\n" - f"Source: {post_data['source']}\n" - f"Rating: {format_rating(post_data['rating'])}\n" - f"Score: {html_parser.hyperlink(post_data['score'], - f"http://{app.host}/post_votes?search[post_id]={post_data['id']}&variant=compact")} " - f"(+{post_data['up_score']} / -{post_data['down_score']})\n" - f"Favorites: {html_parser.hyperlink(post_data['fav_count'], - f"http://{app.host}/posts/{post_data['id']}/favorites")}\n" - f"Status: {format_status(post_data)}", + f"{html_parser.bold("Information")}\n" + "\n".join(m), update.effective_chat.id, message.message_id, - parse_mode=ParseMode.HTML) + parse_mode=ParseMode.HTML, reply_markup=reply_markup, link_preview_options=link_preview_options) except (IndexError, ValueError): await update.message.reply_text( f"{html_parser.bold("Usage")}: {html_parser.code(f"/info <post ID>")}",