diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index ac3e4511..c4a7fc0e 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -13,7 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The database backup periodically sent to the admin can now be encrypted with a key (see `crypto_key` in the _settings.yaml_ file) - Added utility script `f_crypto` to encrypt/decrypt files with a key or generate a new key -### Changes +### Fixed + +- The **/reply** command supports the bot tag after the slash and correctly parses the text to send to the user + +### Changed - Added readme overview page in the docs - Added Privacy Policy in the docs. It is referenced in the bot **/start** command diff --git a/pyproject.toml b/pyproject.toml index cf50b30c..e3f0b4a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,7 +97,6 @@ testpaths = ["tests"] [tool.black] target-version = ['py38', 'py39', 'py310', 'py311'] line-length = 120 -include_trailing_comma = false include = '(src|tests)\/.*\.py' # Isort configuration (import sorter) diff --git a/src/spotted/__init__.py b/src/spotted/__init__.py index eed0bd85..3e809c9e 100644 --- a/src/spotted/__init__.py +++ b/src/spotted/__init__.py @@ -1,4 +1,5 @@ """Modules used in this bot""" + from telegram.ext import Application from spotted.data import Config, init_db diff --git a/src/spotted/__main__.py b/src/spotted/__main__.py index 4a68eb0c..c401a2df 100644 --- a/src/spotted/__main__.py +++ b/src/spotted/__main__.py @@ -1,4 +1,5 @@ """Main module""" + import argparse from typing import TYPE_CHECKING diff --git a/src/spotted/data/__init__.py b/src/spotted/data/__init__.py index cf2f8e5f..9aeab3bf 100644 --- a/src/spotted/data/__init__.py +++ b/src/spotted/data/__init__.py @@ -1,4 +1,5 @@ """Modules that work with the data section""" + from telegram.ext import Application from .config import Config diff --git a/src/spotted/data/config.py b/src/spotted/data/config.py index 211273eb..84dea568 100644 --- a/src/spotted/data/config.py +++ b/src/spotted/data/config.py @@ -1,4 +1,5 @@ """Read the bot configuration from the settings.yaml and the autoreplies.yaml files""" + import logging import os import re diff --git a/src/spotted/data/data_reader.py b/src/spotted/data/data_reader.py index 5004a582..2836f030 100644 --- a/src/spotted/data/data_reader.py +++ b/src/spotted/data/data_reader.py @@ -1,4 +1,5 @@ """Read data from files""" + import os from importlib import resources diff --git a/src/spotted/data/db_manager.py b/src/spotted/data/db_manager.py index 191d9744..585a9c43 100644 --- a/src/spotted/data/db_manager.py +++ b/src/spotted/data/db_manager.py @@ -1,4 +1,5 @@ """Handles the management of databases""" + import logging import os import sqlite3 diff --git a/src/spotted/data/pending_post.py b/src/spotted/data/pending_post.py index 2407a6c6..41fe016e 100644 --- a/src/spotted/data/pending_post.py +++ b/src/spotted/data/pending_post.py @@ -1,4 +1,5 @@ """Pending post management""" + from dataclasses import dataclass from datetime import datetime, timezone diff --git a/src/spotted/data/post_data.py b/src/spotted/data/post_data.py index b278e656..3f39fca1 100644 --- a/src/spotted/data/post_data.py +++ b/src/spotted/data/post_data.py @@ -1,4 +1,5 @@ """Data management for the bot""" + from .db_manager import DbManager diff --git a/src/spotted/data/published_post.py b/src/spotted/data/published_post.py index ea7b519a..d1caa0d9 100644 --- a/src/spotted/data/published_post.py +++ b/src/spotted/data/published_post.py @@ -1,4 +1,5 @@ """Published post management""" + from dataclasses import dataclass from datetime import datetime diff --git a/src/spotted/data/report.py b/src/spotted/data/report.py index fe01f640..eb44af23 100644 --- a/src/spotted/data/report.py +++ b/src/spotted/data/report.py @@ -1,4 +1,5 @@ """Reports management""" + from dataclasses import dataclass from datetime import datetime diff --git a/src/spotted/data/user.py b/src/spotted/data/user.py index bec34d08..2a472e21 100644 --- a/src/spotted/data/user.py +++ b/src/spotted/data/user.py @@ -1,4 +1,5 @@ """Users management""" + from dataclasses import dataclass from datetime import datetime from random import choice diff --git a/src/spotted/debug/__init__.py b/src/spotted/debug/__init__.py index adcd1607..42a6a7f2 100644 --- a/src/spotted/debug/__init__.py +++ b/src/spotted/debug/__init__.py @@ -1,2 +1,3 @@ """Modules used during debug""" + from .log_manager import error_handler, log_message, logger diff --git a/src/spotted/debug/log_manager.py b/src/spotted/debug/log_manager.py index 387183d3..9d353596 100644 --- a/src/spotted/debug/log_manager.py +++ b/src/spotted/debug/log_manager.py @@ -1,4 +1,5 @@ """Handles the logging of events""" + import html import logging import traceback diff --git a/src/spotted/handlers/__init__.py b/src/spotted/handlers/__init__.py index 72e89c64..550fb760 100644 --- a/src/spotted/handlers/__init__.py +++ b/src/spotted/handlers/__init__.py @@ -1,4 +1,5 @@ """Modules that handle the events the bot recognizes and reacts to""" + from datetime import time from warnings import filterwarnings diff --git a/src/spotted/handlers/anonym_comment.py b/src/spotted/handlers/anonym_comment.py index b30186e5..328b3ae8 100644 --- a/src/spotted/handlers/anonym_comment.py +++ b/src/spotted/handlers/anonym_comment.py @@ -1,4 +1,5 @@ """Anonym Comment on a post in the comment group""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/approve.py b/src/spotted/handlers/approve.py index 1031ba2f..99a153cd 100644 --- a/src/spotted/handlers/approve.py +++ b/src/spotted/handlers/approve.py @@ -1,4 +1,5 @@ """Approve actions the admin can take on a pending post.""" + import logging from telegram import Update diff --git a/src/spotted/handlers/autoreply.py b/src/spotted/handlers/autoreply.py index 102b2e73..b8d041ec 100644 --- a/src/spotted/handlers/autoreply.py +++ b/src/spotted/handlers/autoreply.py @@ -1,4 +1,5 @@ """/autoreply command""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/ban.py b/src/spotted/handlers/ban.py index 8501699d..85276efc 100644 --- a/src/spotted/handlers/ban.py +++ b/src/spotted/handlers/ban.py @@ -1,4 +1,5 @@ """/ban command""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/cancel.py b/src/spotted/handlers/cancel.py index 1ed35ad5..cb182f1d 100644 --- a/src/spotted/handlers/cancel.py +++ b/src/spotted/handlers/cancel.py @@ -1,4 +1,5 @@ """/cancel command""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/clean_pending.py b/src/spotted/handlers/clean_pending.py index 776c8dfc..10f56dd4 100644 --- a/src/spotted/handlers/clean_pending.py +++ b/src/spotted/handlers/clean_pending.py @@ -1,4 +1,5 @@ """/clean_pending command""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/constants.py b/src/spotted/handlers/constants.py index f84d7fe3..ca2df786 100644 --- a/src/spotted/handlers/constants.py +++ b/src/spotted/handlers/constants.py @@ -1,4 +1,5 @@ """Constants used by the bot handlers""" + from enum import Enum, auto, unique CHAT_PRIVATE_ERROR = "Non puoi usare quest comando ora\nMandami un messaggio in privato" diff --git a/src/spotted/handlers/db_backup.py b/src/spotted/handlers/db_backup.py index c21dd187..a60455d8 100644 --- a/src/spotted/handlers/db_backup.py +++ b/src/spotted/handlers/db_backup.py @@ -1,4 +1,5 @@ """/db_backup command""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/follow_comment.py b/src/spotted/handlers/follow_comment.py index 15108963..8bfdc69a 100644 --- a/src/spotted/handlers/follow_comment.py +++ b/src/spotted/handlers/follow_comment.py @@ -1,4 +1,5 @@ """Detect Comment on a post in the comment group""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/forwarded_post.py b/src/spotted/handlers/forwarded_post.py index 4d635efb..7adee6b5 100644 --- a/src/spotted/handlers/forwarded_post.py +++ b/src/spotted/handlers/forwarded_post.py @@ -1,4 +1,5 @@ """Message forwarded by the telegram channel""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/help.py b/src/spotted/handlers/help.py index 9a52db6e..16686e54 100644 --- a/src/spotted/handlers/help.py +++ b/src/spotted/handlers/help.py @@ -1,4 +1,5 @@ """/help command""" + from telegram import Update from telegram.constants import ParseMode from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/job_handlers.py b/src/spotted/handlers/job_handlers.py index c1fb2cb7..24f7ac24 100644 --- a/src/spotted/handlers/job_handlers.py +++ b/src/spotted/handlers/job_handlers.py @@ -1,4 +1,5 @@ """Scheduled jobs of the bot""" + from base64 import b64decode from binascii import Error as BinasciiError from datetime import datetime, timedelta, timezone diff --git a/src/spotted/handlers/purge.py b/src/spotted/handlers/purge.py index 61aa482e..3a6b6dcc 100644 --- a/src/spotted/handlers/purge.py +++ b/src/spotted/handlers/purge.py @@ -1,4 +1,5 @@ """/purge command""" + from time import sleep from telegram import Update diff --git a/src/spotted/handlers/reload.py b/src/spotted/handlers/reload.py index 5cc67c8b..9d907ee4 100644 --- a/src/spotted/handlers/reload.py +++ b/src/spotted/handlers/reload.py @@ -1,4 +1,5 @@ """/reload command""" + from telegram import Update from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/reply.py b/src/spotted/handlers/reply.py index d061533e..b027b2d3 100644 --- a/src/spotted/handlers/reply.py +++ b/src/spotted/handlers/reply.py @@ -1,4 +1,5 @@ """/reply command""" + from telegram import Update from telegram.ext import CallbackContext @@ -15,8 +16,7 @@ async def reply_cmd(update: Update, context: CallbackContext): context: context passed by the handler """ info = EventInfo.from_message(update, context) - - if len(info.text) <= 7: # the reply is empty + if len(info.args) == 0: # the reply is empty await info.bot.send_message( chat_id=info.chat_id, text="La reply è vuota\n" @@ -24,16 +24,17 @@ async def reply_cmd(update: Update, context: CallbackContext): "seguito da ciò che gli si vuole dire", ) return - + ### build the reply text from the args + reply_text = " ".join(info.args) g_message_id = update.message.reply_to_message.message_id if (pending_post := PendingPost.from_group(admin_group_id=info.chat_id, g_message_id=g_message_id)) is not None: await info.bot.send_message( chat_id=pending_post.user_id, - text="COMUNICAZIONE DEGLI ADMIN SUL TUO ULTIMO POST:\n" + info.text[7:].strip(), + text=f"COMUNICAZIONE DEGLI ADMIN SUL TUO ULTIMO POST:\n{reply_text}", ) elif (report := Report.from_group(admin_group_id=info.chat_id, g_message_id=g_message_id)) is not None: await info.bot.send_message( - chat_id=report.user_id, text="COMUNICAZIONE DEGLI ADMIN SUL TUO ULTIMO REPORT:\n" + info.text[7:].strip() + chat_id=report.user_id, text=f"COMUNICAZIONE DEGLI ADMIN SUL TUO ULTIMO REPORT:\n{reply_text}" ) else: # the reply does not refer to a pending post or a report await info.bot.send_message( diff --git a/src/spotted/handlers/report_spot.py b/src/spotted/handlers/report_spot.py index d876af51..614042f6 100644 --- a/src/spotted/handlers/report_spot.py +++ b/src/spotted/handlers/report_spot.py @@ -1,4 +1,5 @@ """report callback""" + from telegram import Update from telegram.error import Forbidden from telegram.ext import ( diff --git a/src/spotted/handlers/report_user.py b/src/spotted/handlers/report_user.py index 0986e524..3111a035 100644 --- a/src/spotted/handlers/report_user.py +++ b/src/spotted/handlers/report_user.py @@ -1,4 +1,5 @@ """/report command""" + from telegram import Update from telegram.ext import ( CallbackContext, diff --git a/src/spotted/handlers/rules.py b/src/spotted/handlers/rules.py index 675c30d6..d45be585 100644 --- a/src/spotted/handlers/rules.py +++ b/src/spotted/handlers/rules.py @@ -1,4 +1,5 @@ """/rules command""" + from telegram import Update from telegram.constants import ParseMode from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/sban.py b/src/spotted/handlers/sban.py index 8bbd377f..bd9067b4 100644 --- a/src/spotted/handlers/sban.py +++ b/src/spotted/handlers/sban.py @@ -1,4 +1,5 @@ """/sban command""" + from telegram import Update from telegram.error import Forbidden from telegram.ext import CallbackContext diff --git a/src/spotted/handlers/settings.py b/src/spotted/handlers/settings.py index 2e799bb8..67e38589 100644 --- a/src/spotted/handlers/settings.py +++ b/src/spotted/handlers/settings.py @@ -1,4 +1,5 @@ """/settings command""" + import logging from telegram import Update diff --git a/src/spotted/handlers/spot.py b/src/spotted/handlers/spot.py index c48ecd19..d76924d3 100644 --- a/src/spotted/handlers/spot.py +++ b/src/spotted/handlers/spot.py @@ -1,4 +1,5 @@ """/spot command""" + from random import choice from telegram import Update diff --git a/src/spotted/handlers/start.py b/src/spotted/handlers/start.py index 709d9c29..64229f00 100644 --- a/src/spotted/handlers/start.py +++ b/src/spotted/handlers/start.py @@ -1,4 +1,5 @@ """/start command""" + from telegram import Update from telegram.constants import ParseMode from telegram.ext import CallbackContext diff --git a/src/spotted/utils/__init__.py b/src/spotted/utils/__init__.py index b290a483..1ee19e23 100644 --- a/src/spotted/utils/__init__.py +++ b/src/spotted/utils/__init__.py @@ -1,4 +1,5 @@ """Modules that provide various util""" + from .conversation_util import conv_cancel, conv_fail from .info_util import EventInfo from .keyboard_util import ( diff --git a/src/spotted/utils/conversation_util.py b/src/spotted/utils/conversation_util.py index 9537d64b..5e91d100 100644 --- a/src/spotted/utils/conversation_util.py +++ b/src/spotted/utils/conversation_util.py @@ -1,4 +1,5 @@ """Common functions needed in conversation handlers""" + from typing import Callable from telegram import Update diff --git a/src/spotted/utils/info_util.py b/src/spotted/utils/info_util.py index adf49bd5..672c669e 100644 --- a/src/spotted/utils/info_util.py +++ b/src/spotted/utils/info_util.py @@ -1,4 +1,5 @@ """Common info needed in both command and callback handlers""" + from telegram import Bot, CallbackQuery, Chat, InlineKeyboardMarkup, Message, Update from telegram.error import BadRequest from telegram.ext import CallbackContext diff --git a/src/spotted/utils/keyboard_util.py b/src/spotted/utils/keyboard_util.py index 63569d1e..189f94e6 100644 --- a/src/spotted/utils/keyboard_util.py +++ b/src/spotted/utils/keyboard_util.py @@ -1,5 +1,6 @@ """Creates the inlinekeyboard sent by the bot in its messages. Callback_data format: _,[arg]""" + from itertools import islice, zip_longest from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup diff --git a/tests/integration/telegram_simulator.py b/tests/integration/telegram_simulator.py index 3035f31b..43fcb32c 100644 --- a/tests/integration/telegram_simulator.py +++ b/tests/integration/telegram_simulator.py @@ -112,8 +112,7 @@ async def send_command( user: "User" = None, chat: "Chat" = None, reply_to_message: "Message | int | None" = None, - ) -> "Message": - ... + ) -> "Message": ... async def send_command( self, @@ -147,12 +146,10 @@ async def send_message( entities: "list[MessageEntity] | None" = None, reply_to_message: "Message | int | None" = None, message_thread_id: "int | None" = None, - ) -> "Message": - ... + ) -> "Message": ... @overload - async def send_message(self, message: "Message") -> "Message": - ... + async def send_message(self, message: "Message") -> "Message": ... async def send_message( self, diff --git a/tests/integration/test_bot.py b/tests/integration/test_bot.py index 18b0488c..c7dae5d7 100644 --- a/tests/integration/test_bot.py +++ b/tests/integration/test_bot.py @@ -285,9 +285,20 @@ async def test_reply_post_cmd(self, telegram: TelegramSimulator, admin_group: Ch """Tests the /reply command. The bot sends a message to the user on behalf of the admin """ - await telegram.send_message("/reply TEST", chat=admin_group, reply_to_message=pending_post) + await telegram.send_message("/reply TEST Test2", chat=admin_group, reply_to_message=pending_post) assert telegram.messages[-2].text.startswith("COMUNICAZIONE DEGLI ADMIN SUL TUO ULTIMO POST:\n") - assert telegram.messages[-2].text.endswith("TEST") + assert telegram.messages[-2].text.endswith("TEST Test2") + assert telegram.last_message.text == "L'utente ha ricevuto il messaggio" + + async def test_reply_bot_tag_post_cmd( + self, telegram: TelegramSimulator, admin_group: Chat, pending_post: Message + ): + """Tests the /reply command with the bot tag. + The bot sends a message to the user on behalf of the admin + """ + await telegram.send_message("/reply@bot_tag TEST1 Test2", chat=admin_group, reply_to_message=pending_post) + assert telegram.messages[-2].text.startswith("COMUNICAZIONE DEGLI ADMIN SUL TUO ULTIMO POST:\n") + assert telegram.messages[-2].text.endswith("TEST1 Test2") assert telegram.last_message.text == "L'utente ha ricevuto il messaggio" async def test_autoreply_list_cmd(self, telegram: TelegramSimulator, admin_group: Chat, pending_post: Message): diff --git a/tests/unit/test_db.py b/tests/unit/test_db.py index 7aad4ec8..fde96885 100644 --- a/tests/unit/test_db.py +++ b/tests/unit/test_db.py @@ -16,8 +16,8 @@ def db_results(create_test_db: DbManager) -> dict: Yields: Iterator[dict]: dictionary containing the results for the test queries """ - create_test_db.row_factory = ( - lambda cursor, row: list(row) if cursor.description[0][0] != "number" else {"number": row[0]} + create_test_db.row_factory = lambda cursor, row: ( + list(row) if cursor.description[0][0] != "number" else {"number": row[0]} ) create_test_db.query_from_file("config/db/db_test.sql")