Skip to content

Commit

Permalink
fix: reply command (#148)
Browse files Browse the repository at this point in the history
* fix: reply empty command

* docs: update changelog with reply fix

* fix: fix reply command

* chore : restore comment

* test: add test case for reply

* fix: remove invalid configuration include_trailing_comma

* chore: update CHANGELOG

* chore: black formatting

---------

Co-authored-by: Ernesto Casablanca <[email protected]>
  • Loading branch information
Picred and TendTo authored Feb 14, 2024
1 parent 3fd91e6 commit f31bf02
Show file tree
Hide file tree
Showing 45 changed files with 68 additions and 17 deletions.
6 changes: 5 additions & 1 deletion .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/spotted/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Modules used in this bot"""

from telegram.ext import Application

from spotted.data import Config, init_db
Expand Down
1 change: 1 addition & 0 deletions src/spotted/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Main module"""

import argparse
from typing import TYPE_CHECKING

Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Modules that work with the data section"""

from telegram.ext import Application

from .config import Config
Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Read the bot configuration from the settings.yaml and the autoreplies.yaml files"""

import logging
import os
import re
Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/data_reader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Read data from files"""

import os
from importlib import resources

Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/db_manager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Handles the management of databases"""

import logging
import os
import sqlite3
Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/pending_post.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Pending post management"""

from dataclasses import dataclass
from datetime import datetime, timezone

Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/post_data.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Data management for the bot"""

from .db_manager import DbManager


Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/published_post.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Published post management"""

from dataclasses import dataclass
from datetime import datetime

Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/report.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Reports management"""

from dataclasses import dataclass
from datetime import datetime

Expand Down
1 change: 1 addition & 0 deletions src/spotted/data/user.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Users management"""

from dataclasses import dataclass
from datetime import datetime
from random import choice
Expand Down
1 change: 1 addition & 0 deletions src/spotted/debug/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""Modules used during debug"""

from .log_manager import error_handler, log_message, logger
1 change: 1 addition & 0 deletions src/spotted/debug/log_manager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Handles the logging of events"""

import html
import logging
import traceback
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Modules that handle the events the bot recognizes and reacts to"""

from datetime import time
from warnings import filterwarnings

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/anonym_comment.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Anonym Comment on a post in the comment group"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/approve.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Approve actions the admin can take on a pending post."""

import logging

from telegram import Update
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/autoreply.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/autoreply command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/ban.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/ban command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/cancel.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/cancel command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/clean_pending.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/clean_pending command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/constants.py
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/db_backup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/db_backup command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/follow_comment.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Detect Comment on a post in the comment group"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/forwarded_post.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Message forwarded by the telegram channel"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/help.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/help command"""

from telegram import Update
from telegram.constants import ParseMode
from telegram.ext import CallbackContext
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/job_handlers.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/purge.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/purge command"""

from time import sleep

from telegram import Update
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/reload.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/reload command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand Down
11 changes: 6 additions & 5 deletions src/spotted/handlers/reply.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/reply command"""

from telegram import Update
from telegram.ext import CallbackContext

Expand All @@ -15,25 +16,25 @@ 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"
"Per mandare un messaggio ad un utente, rispondere al suo post o report con /reply "
"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(
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/report_spot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""report callback"""

from telegram import Update
from telegram.error import Forbidden
from telegram.ext import (
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/report_user.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/report command"""

from telegram import Update
from telegram.ext import (
CallbackContext,
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/rules.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/rules command"""

from telegram import Update
from telegram.constants import ParseMode
from telegram.ext import CallbackContext
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/sban.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/sban command"""

from telegram import Update
from telegram.error import Forbidden
from telegram.ext import CallbackContext
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/settings command"""

import logging

from telegram import Update
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/spot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/spot command"""

from random import choice

from telegram import Update
Expand Down
1 change: 1 addition & 0 deletions src/spotted/handlers/start.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""/start command"""

from telegram import Update
from telegram.constants import ParseMode
from telegram.ext import CallbackContext
Expand Down
1 change: 1 addition & 0 deletions src/spotted/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
1 change: 1 addition & 0 deletions src/spotted/utils/conversation_util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Common functions needed in conversation handlers"""

from typing import Callable

from telegram import Update
Expand Down
1 change: 1 addition & 0 deletions src/spotted/utils/info_util.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions src/spotted/utils/keyboard_util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Creates the inlinekeyboard sent by the bot in its messages.
Callback_data format: <callback_family>_<callback_name>,[arg]"""

from itertools import islice, zip_longest

from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup
Expand Down
9 changes: 3 additions & 6 deletions tests/integration/telegram_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 13 additions & 2 deletions tests/integration/test_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down

0 comments on commit f31bf02

Please sign in to comment.