Skip to content

Commit 0bf4d50

Browse files
committed
feat(strings): add Italian language support for bot messages
- Introduced a new module for user-facing Italian strings, enhancing the bot's personality with Matrix and Python themes. - Updated various command handlers to utilize the new strings for improved localization, including moderation, welcome, and settings commands. - Refactored message responses to ensure consistency and clarity in user interactions.
1 parent bc2127c commit 0bf4d50

7 files changed

Lines changed: 220 additions & 124 deletions

File tree

src/python_italy_bot/handlers/announce.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
66
from telegram.ext import CommandHandler, ContextTypes
77

8+
from .. import strings
89
from ..config import Settings
910
from ..services.captcha import BUTTON_URL_PATTERN
1011
from ..services.moderation import ModerationService
@@ -60,40 +61,37 @@ async def _handle_announce(
6061
return
6162

6263
if chat.type != "private":
63-
await message.reply_text("Questo comando funziona solo in chat privata.")
64+
await message.reply_text(strings.ONLY_IN_PRIVATE)
6465
return
6566

6667
if settings.bot_owner_id is None:
67-
await message.reply_text("BOT_OWNER_ID non configurato.")
68+
await message.reply_text(strings.ANNOUNCE_NO_OWNER_CONFIGURED)
6869
return
6970

7071
if user.id != settings.bot_owner_id:
71-
await message.reply_text("Solo il proprietario del bot può usare questo comando.")
72+
await message.reply_text(strings.ANNOUNCE_OWNER_ONLY)
7273
return
7374

7475
raw_text = message.text or ""
7576
announcement = raw_text.partition(" ")[2].strip()
7677

7778
if not announcement:
78-
await message.reply_text(
79-
"Uso: /announce <messaggio>\n\n"
80-
"Supporta HTML e bottoni: [Testo](buttonurl://url)"
81-
)
79+
await message.reply_text(strings.ANNOUNCE_USAGE)
8280
return
8381

8482
clean_text, keyboard = _parse_button_urls(announcement)
8583

8684
if not clean_text:
87-
await message.reply_text("Il messaggio non può essere vuoto.")
85+
await message.reply_text(strings.ANNOUNCE_EMPTY_MESSAGE)
8886
return
8987

9088
chat_ids = await moderation_service.get_all_chats()
9189

9290
if not chat_ids:
93-
await message.reply_text("Nessun gruppo registrato.")
91+
await message.reply_text(strings.ANNOUNCE_NO_GROUPS)
9492
return
9593

96-
await message.reply_text(f"Invio annuncio a {len(chat_ids)} gruppi...")
94+
await message.reply_text(strings.ANNOUNCE_SENDING.format(count=len(chat_ids)))
9795

9896
success = 0
9997
failed = 0
@@ -111,7 +109,7 @@ async def _handle_announce(
111109
failed += 1
112110
logger.warning("Failed to send announcement to %s: %s", chat_id, e)
113111

114-
await message.reply_text(f"Annuncio inviato: {success} ok, {failed} falliti.")
112+
await message.reply_text(strings.announce_result(success, failed))
115113

116114

117115
def create_announce_handlers(

src/python_italy_bot/handlers/id.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from telegram import Update
44
from telegram.ext import CommandHandler, ContextTypes
55

6+
from .. import strings
7+
68

79
def create_id_handlers() -> list:
810
"""Create the /id command handler."""
@@ -18,4 +20,6 @@ async def _handle_id(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None
1820
if chat is None or user is None or message is None:
1921
return
2022

21-
await message.reply_text(f"ID chat: {chat.id}\nID utente: {user.id}")
23+
await message.reply_text(
24+
strings.ID_RESPONSE.format(chat_id=chat.id, user_id=user.id)
25+
)

src/python_italy_bot/handlers/moderation.py

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from telegram.constants import ChatMemberStatus
88
from telegram.ext import CommandHandler, ContextTypes, MessageHandler, filters
99

10+
from .. import strings
1011
from ..services.moderation import ModerationService
1112

1213
logger = logging.getLogger(__name__)
@@ -55,17 +56,15 @@ async def _handle_force_group_registration(
5556

5657
chat = update.effective_chat
5758
if chat is None or chat.type == "private":
58-
await message.reply_text("Questo comando funziona solo nei gruppi.")
59+
await message.reply_text(strings.ONLY_IN_GROUPS)
5960
return
6061

6162
if not await _is_admin(context, chat.id, message.from_user.id):
62-
await message.reply_text(
63-
"Solo gli amministratori possono usare questo comando."
64-
)
63+
await message.reply_text(strings.ONLY_ADMINS)
6564
return
6665

6766
await moderation_service.register_chat(chat.id)
68-
await message.reply_text(f"Gruppo registrato. Chat ID: {chat.id}")
67+
await message.reply_text(strings.GROUP_REGISTERED.format(chat_id=chat.id))
6968

7069

7170
async def _handle_ban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -80,9 +79,7 @@ async def _handle_ban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> Non
8079
return
8180

8281
if not await _is_admin(context, chat.id, message.from_user.id):
83-
await message.reply_text(
84-
"Solo gli amministratori possono usare questo comando."
85-
)
82+
await message.reply_text(strings.ONLY_ADMINS)
8683
return
8784

8885
args = message.text.split(maxsplit=2)[1:] if message.text else []
@@ -98,9 +95,7 @@ async def _handle_ban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> Non
9895
user_id = await _resolve_user_id(context, chat.id, target)
9996

10097
if user_id is None:
101-
await message.reply_text(
102-
"Uso: /ban user_id [motivo], o rispondi al messaggio con /ban [motivo]."
103-
)
98+
await message.reply_text(strings.BAN_USAGE)
10499
return
105100

106101
chat_ids = await moderation_service.add_global_ban(
@@ -117,11 +112,7 @@ async def _handle_ban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> Non
117112
logger.debug("Ban in chat %s failed: %s", cid, e)
118113
fail_count += 1
119114

120-
msg = f"Utente bannato globalmente in {success_count} gruppi."
121-
if fail_count > 0:
122-
msg += f" ({fail_count} falliti)"
123-
msg += f"\nMotivo: {reason or 'Nessuno'}"
124-
await message.reply_text(msg)
115+
await message.reply_text(strings.ban_success(success_count, fail_count, reason))
125116

126117

127118
async def _handle_unban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -136,9 +127,7 @@ async def _handle_unban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> N
136127
return
137128

138129
if not await _is_admin(context, chat.id, message.from_user.id):
139-
await message.reply_text(
140-
"Solo gli amministratori possono usare questo comando."
141-
)
130+
await message.reply_text(strings.ONLY_ADMINS)
142131
return
143132

144133
args = message.text.split(maxsplit=1)[1:] if message.text else []
@@ -149,9 +138,7 @@ async def _handle_unban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> N
149138
user_id = await _resolve_user_id(context, chat.id, args[0])
150139

151140
if user_id is None:
152-
await message.reply_text(
153-
"Uso: /unban user_id, o rispondi al messaggio con /unban"
154-
)
141+
await message.reply_text(strings.UNBAN_USAGE)
155142
return
156143

157144
chat_ids = await moderation_service.remove_global_ban(user_id)
@@ -166,10 +153,7 @@ async def _handle_unban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> N
166153
logger.debug("Unban in chat %s failed: %s", cid, e)
167154
fail_count += 1
168155

169-
msg = f"Utente sbannato globalmente da {success_count} gruppi."
170-
if fail_count > 0:
171-
msg += f" ({fail_count} falliti)"
172-
await message.reply_text(msg)
156+
await message.reply_text(strings.unban_success(success_count, fail_count))
173157

174158

175159
async def _handle_mute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -184,9 +168,7 @@ async def _handle_mute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
184168
return
185169

186170
if not await _is_admin(context, chat.id, message.from_user.id):
187-
await message.reply_text(
188-
"Solo gli amministratori possono usare questo comando."
189-
)
171+
await message.reply_text(strings.ONLY_ADMINS)
190172
return
191173

192174
args = message.text.split(maxsplit=3)[1:] if message.text else []
@@ -212,11 +194,9 @@ async def _handle_mute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
212194
user_id = await _resolve_user_id(context, chat.id, target)
213195

214196
if user_id is None:
215-
await message.reply_text(
216-
"Uso: /mute @username [minuti] [motivo], o rispondi al messaggio"
217-
)
197+
await message.reply_text(strings.MUTE_USAGE)
218198
if user_id is None:
219-
await message.reply_text("Utente non trovato.")
199+
await message.reply_text(strings.USER_NOT_FOUND)
220200
return
221201

222202
until = None
@@ -239,15 +219,10 @@ async def _handle_mute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
239219
reason=reason,
240220
until=until,
241221
)
242-
msg = "Utente mutato"
243-
if duration:
244-
msg += f" per {duration} minuti"
245-
if reason:
246-
msg += f". Motivo: {reason}"
247-
await message.reply_text(msg)
222+
await message.reply_text(strings.mute_success(duration, reason))
248223
except Exception as e:
249224
logger.warning("Mute failed: %s", e)
250-
await message.reply_text("Impossibile mutare l'utente.")
225+
await message.reply_text(strings.MUTE_FAILED)
251226

252227

253228
async def _handle_unmute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -262,9 +237,7 @@ async def _handle_unmute(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
262237
return
263238

264239
if not await _is_admin(context, chat.id, message.from_user.id):
265-
await message.reply_text(
266-
"Solo gli amministratori possono usare questo comando."
267-
)
240+
await message.reply_text(strings.ONLY_ADMINS)
268241
return
269242

270243
args = message.text.split(maxsplit=1)[1:] if message.text else []
@@ -275,11 +248,9 @@ async def _handle_unmute(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
275248
user_id = await _resolve_user_id(context, chat.id, args[0])
276249

277250
if user_id is None:
278-
await message.reply_text(
279-
"Uso: /unmute @username, /unmute user_id, o rispondi al messaggio"
280-
)
251+
await message.reply_text(strings.UNMUTE_USAGE)
281252
if user_id is None:
282-
await message.reply_text("Utente non trovato.")
253+
await message.reply_text(strings.USER_NOT_FOUND)
283254
return
284255

285256
from telegram import ChatPermissions
@@ -303,10 +274,10 @@ async def _handle_unmute(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
303274
try:
304275
await context.bot.restrict_chat_member(chat.id, user_id, full_perms)
305276
await moderation_service.remove_mute(user_id, chat.id)
306-
await message.reply_text("Utente smutato.")
277+
await message.reply_text(strings.UNMUTE_SUCCESS)
307278
except Exception as e:
308279
logger.warning("Unmute failed: %s", e)
309-
await message.reply_text("Impossibile smutare l'utente.")
280+
await message.reply_text(strings.UNMUTE_FAILED)
310281

311282

312283
async def _handle_report(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -333,9 +304,7 @@ async def _handle_report(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
333304
message_id = message.reply_to_message.message_id
334305

335306
if reported_user_id is None or reported_user is None:
336-
await message.reply_text(
337-
"Rispondi al messaggio da segnalare con /report [motivo]"
338-
)
307+
await message.reply_text(strings.REPORT_USAGE)
339308
return
340309

341310
await moderation_service.add_report(
@@ -355,9 +324,7 @@ async def _handle_report(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
355324
reason=reason,
356325
)
357326

358-
await message.reply_text(
359-
"Segnalazione inviata. Gli amministratori la esamineranno."
360-
)
327+
await message.reply_text(strings.REPORT_SUCCESS)
361328
logger.info(
362329
"Report: %s reported %s in chat %s",
363330
message.from_user.id,
@@ -389,9 +356,7 @@ async def _handle_admin_mention(
389356
reason=reason,
390357
)
391358

392-
await message.reply_text(
393-
"Richiesta inviata. Gli amministratori interverranno."
394-
)
359+
await message.reply_text(strings.ADMIN_REQUEST_SUCCESS)
395360
logger.info(
396361
"Admin request: %s in chat %s",
397362
message.from_user.id,

src/python_italy_bot/handlers/settings.py

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from telegram.constants import ChatMemberStatus
77
from telegram.ext import CommandHandler, ContextTypes
88

9+
from .. import strings
910
from ..services.captcha import CaptchaService
1011

1112
logger = logging.getLogger(__name__)
@@ -55,33 +56,24 @@ async def _handle_setwelcome(
5556

5657
chat = update.effective_chat
5758
if chat is None or chat.type == "private":
58-
await message.reply_text("Questo comando funziona solo nei gruppi.")
59+
await message.reply_text(strings.ONLY_IN_GROUPS)
5960
return
6061

6162
if not await _is_admin(context, chat.id, message.from_user.id):
62-
await message.reply_text(
63-
"Solo gli amministratori possono usare questo comando."
64-
)
63+
await message.reply_text(strings.ONLY_ADMINS)
6564
return
6665

6766
if message.text is None:
6867
return
6968

7069
parts = message.text.split(maxsplit=1)
7170
if len(parts) < 2:
72-
await message.reply_text(
73-
"Uso: /setwelcome <messaggio>\n\n"
74-
"Placeholder disponibili:\n"
75-
" {username} - @username o nome completo\n"
76-
" {chatname} - nome del gruppo\n\n"
77-
"Sintassi bottoni:\n"
78-
" [Testo](buttonurl://URL)"
79-
)
71+
await message.reply_text(strings.SETWELCOME_USAGE)
8072
return
8173

8274
welcome_message = parts[1]
8375
await captcha_service.set_welcome_message(chat.id, welcome_message)
84-
await message.reply_text("Messaggio di benvenuto impostato!")
76+
await message.reply_text(strings.SETWELCOME_SUCCESS)
8577
logger.info(
8678
"Welcome message set for chat %s by admin %s",
8779
chat.id,
@@ -100,17 +92,15 @@ async def _handle_resetwelcome(
10092

10193
chat = update.effective_chat
10294
if chat is None or chat.type == "private":
103-
await message.reply_text("Questo comando funziona solo nei gruppi.")
95+
await message.reply_text(strings.ONLY_IN_GROUPS)
10496
return
10597

10698
if not await _is_admin(context, chat.id, message.from_user.id):
107-
await message.reply_text(
108-
"Solo gli amministratori possono usare questo comando."
109-
)
99+
await message.reply_text(strings.ONLY_ADMINS)
110100
return
111101

112102
await captcha_service.set_welcome_message(chat.id, None)
113-
await message.reply_text("Messaggio di benvenuto ripristinato al default.")
103+
await message.reply_text(strings.RESETWELCOME_SUCCESS)
114104
logger.info(
115105
"Welcome message reset for chat %s by admin %s",
116106
chat.id,
@@ -129,23 +119,21 @@ async def _handle_getwelcome(
129119

130120
chat = update.effective_chat
131121
if chat is None or chat.type == "private":
132-
await message.reply_text("Questo comando funziona solo nei gruppi.")
122+
await message.reply_text(strings.ONLY_IN_GROUPS)
133123
return
134124

135125
if not await _is_admin(context, chat.id, message.from_user.id):
136-
await message.reply_text(
137-
"Solo gli amministratori possono usare questo comando."
138-
)
126+
await message.reply_text(strings.ONLY_ADMINS)
139127
return
140128

141129
custom_message = await captcha_service.get_welcome_message(chat.id)
142130
if custom_message:
143131
await message.reply_text(
144-
f"Messaggio di benvenuto attuale:\n\n{custom_message}"
132+
strings.GETWELCOME_CUSTOM.format(message=custom_message)
145133
)
146134
else:
147135
bot_username = (await context.bot.get_me()).username or "bot"
148136
default = captcha_service.get_default_welcome_template(bot_username)
149137
await message.reply_text(
150-
f"Nessun messaggio personalizzato. Default:\n\n{default}"
138+
strings.GETWELCOME_DEFAULT.format(message=default)
151139
)

0 commit comments

Comments
 (0)