diff --git a/classes/callbacks.py b/classes/callbacks.py new file mode 100644 index 0000000..b05b3d3 --- /dev/null +++ b/classes/callbacks.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass + +from pyrogram.types import CallbackQuery + + +@dataclass +class CallbackLanguage: + language: str + + @classmethod + def from_callback(cls, callback: CallbackQuery): + action, language = str(callback.data).split(":") + if action.lower() != "language": + raise ValueError("Callback provided is not a language callback") + return cls(language) diff --git a/classes/pyrouser.py b/classes/pyrouser.py index 62a327a..527d72a 100644 --- a/classes/pyrouser.py +++ b/classes/pyrouser.py @@ -1,3 +1,4 @@ +import logging from dataclasses import dataclass from typing import Union @@ -5,6 +6,8 @@ from bson import ObjectId from modules.database import col_users +logger = logging.getLogger(__name__) + @dataclass class PyroUser: @@ -16,10 +19,24 @@ class PyroUser: id: int locale: Union[str, None] - async def update_locale(self, locale: str) -> None: + @classmethod + async def find(cls, id: int, locale: Union[str, None] = None): + db_entry = await col_users.find_one({"id": id}) + + if db_entry is None: + inserted = await col_users.insert_one({"id": id, "locale": locale}) + db_entry = await col_users.find_one({"_id": inserted.inserted_id}) + + if db_entry is None: + raise RuntimeError("Could not find inserted user entry.") + + return cls(**db_entry) + + async def update_locale(self, locale: Union[str, None]) -> None: """Change user's locale stored in the database ### Args: - * locale (`str`): New locale to be set + * locale (`Union[str, None]`): New locale to be set """ + logger.debug("%s's locale has been set to %s", self.id, locale) await col_users.update_one({"_id": self._id}, {"$set": {"locale": locale}}) diff --git a/config_example.json b/config_example.json index 058bb17..2fc6588 100644 --- a/config_example.json +++ b/config_example.json @@ -22,6 +22,13 @@ "disabled_plugins": [], "commands": { "start": { + "scopes": [ + { + "name": "BotCommandScopeDefault" + } + ] + }, + "remove_commands": { "scopes": [ { "name": "BotCommandScopeChat", diff --git a/locale/en.json b/locale/en.json index 3ddacc1..e410b34 100644 --- a/locale/en.json +++ b/locale/en.json @@ -1,5 +1,23 @@ { + "metadata": { + "flag": "πŸ‡¬πŸ‡§", + "name": "English", + "codes": [ + "en", + "en-US", + "en-GB" + ] + }, "commands": { - "start": "Start using the bot" + "start": "Start using the bot", + "language": "Change bot's language", + "remove_commands": "Unregister all commands" + }, + "messages": { + "start": "Welcome! I'm your bot!", + "locale_choice": "Alright. Please choose the language using keyboard below." + }, + "callback": { + "locale_set": "Your language now is: {locale}" } } \ No newline at end of file diff --git a/locale/uk.json b/locale/uk.json index 145bcb8..462e807 100644 --- a/locale/uk.json +++ b/locale/uk.json @@ -1,5 +1,22 @@ { + "metadata": { + "flag": "πŸ‡ΊπŸ‡¦", + "name": "Π£ΠΊΡ€Π°Ρ—Π½ΡΡŒΠΊΠ°", + "codes": [ + "uk", + "uk-UA" + ] + }, "commands": { - "start": "ΠŸΠΎΡ‡Π°Ρ‚ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚ΡƒΠ²Π°Ρ‚ΠΈΡΡŒ Π±ΠΎΡ‚ΠΎΠΌ" + "start": "ΠŸΠΎΡ‡Π°Ρ‚ΠΈ ΠΊΠΎΡ€ΠΈΡΡ‚ΡƒΠ²Π°Ρ‚ΠΈΡΡŒ Π±ΠΎΡ‚ΠΎΠΌ", + "language": "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ ΠΌΠΎΠ²Ρƒ Π±ΠΎΡ‚Π°", + "remove_commands": "Π’ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ всі ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ" + }, + "messages": { + "start": "ΠŸΡ€ΠΈΠ²Ρ–Ρ‚! Π― Ρ‚Π²Ρ–ΠΉ Π±ΠΎΡ‚!", + "locale_choice": "Π“Π°Ρ€Π°Π·Π΄. Π‘ΡƒΠ΄ΡŒ ласка, ΠΎΠ±Π΅Ρ€Ρ–Ρ‚ΡŒ ΠΌΠΎΠ²Ρƒ Π·Π° допомогою ΠΊΠ»Π°Π²Ρ–Π°Ρ‚ΡƒΡ€ΠΈ Π½ΠΈΠΆΡ‡Π΅." + }, + "callback": { + "locale_set": "ВстановлСно ΠΌΠΎΠ²Ρƒ: {locale}" } } \ No newline at end of file diff --git a/plugins/callbacks/callback.py b/plugins/callbacks/callback.py index 9233d97..56c73f6 100644 --- a/plugins/callbacks/callback.py +++ b/plugins/callbacks/callback.py @@ -1,10 +1,11 @@ from pyrogram import filters -from pyrogram.client import Client from pyrogram.types import CallbackQuery from classes.pyroclient import PyroClient -@Client.on_callback_query(filters.regex("nothing")) # type: ignore -async def callback_nothing(app: PyroClient, clb: CallbackQuery): - await clb.answer(text="Nothing here...") +@PyroClient.on_callback_query(filters.regex("nothing")) # type: ignore +async def callback_nothing(app: PyroClient, callback: CallbackQuery): + await callback.answer( + text=app._("nothing", "callbacks", locale=callback.from_user.language_code) + ) diff --git a/plugins/commands/command.py b/plugins/commands/command.py index 97a136f..c9bf0b4 100644 --- a/plugins/commands/command.py +++ b/plugins/commands/command.py @@ -1,12 +1,13 @@ from pyrogram import filters -from pyrogram.client import Client from pyrogram.types import Message from classes.pyroclient import PyroClient -@Client.on_message( +@PyroClient.on_message( ~filters.scheduled & filters.private & filters.command(["start"], prefixes=["/"]) # type: ignore ) -async def command_start(app: PyroClient, msg: Message): - await msg.reply_text("Welcome! I'm your bot!") +async def command_start(app: PyroClient, message: Message): + await message.reply_text( + app._("start", "messages", locale=message.from_user.language_code) + ) diff --git a/plugins/commands/remove_commands.py b/plugins/commands/remove_commands.py index 939dab5..008b8a0 100644 --- a/plugins/commands/remove_commands.py +++ b/plugins/commands/remove_commands.py @@ -1,13 +1,12 @@ from pyrogram import filters -from pyrogram.client import Client from pyrogram.types import Message from classes.pyroclient import PyroClient -@Client.on_message( +@PyroClient.on_message( ~filters.scheduled & filters.private & filters.command(["remove_commands"], prefixes=["/"]) # type: ignore ) -async def command_remove_commands(app: PyroClient, msg: Message): - await msg.reply_text("Okay.") +async def command_remove_commands(app: PyroClient, message: Message): + await message.reply_text("Okay.") await app.remove_commands(command_sets=await app.collect_commands()) diff --git a/plugins/handlers/handler.py b/plugins/handlers/handler.py index 9eb8622..f1ccfb4 100644 --- a/plugins/handlers/handler.py +++ b/plugins/handlers/handler.py @@ -1,10 +1,9 @@ from pyrogram import filters -from pyrogram.client import Client from pyrogram.types import Message from classes.pyroclient import PyroClient -@Client.on_message(filters.text & filters.private) # type: ignore +@PyroClient.on_message(filters.text & filters.private) # type: ignore async def handler_echo(app: PyroClient, message: Message): await message.reply(message.text[::-1]) diff --git a/plugins/inline.py b/plugins/inline.py index 1daa5a8..d5d74e4 100644 --- a/plugins/inline.py +++ b/plugins/inline.py @@ -1,4 +1,3 @@ -from pyrogram.client import Client from pyrogram.types import ( InlineQuery, InlineQueryResultArticle, @@ -8,7 +7,7 @@ from pyrogram.types import ( from classes.pyroclient import PyroClient -@Client.on_inline_query() # type: ignore +@PyroClient.on_inline_query() # type: ignore async def inline(app: PyroClient, inline_query: InlineQuery): await inline_query.answer( results=[ diff --git a/plugins/language.py b/plugins/language.py index 5c0fbd5..3c02d02 100644 --- a/plugins/language.py +++ b/plugins/language.py @@ -1,16 +1,20 @@ from pykeyboard import InlineButton, InlineKeyboard from pyrogram import filters -from pyrogram.client import Client from pyrogram.types import CallbackQuery, Message +from classes.callbacks import CallbackLanguage from classes.pyroclient import PyroClient +from classes.pyrouser import PyroUser -@Client.on_message( +@PyroClient.on_message( ~filters.scheduled & filters.private & filters.command(["language"], prefixes=["/"]) # type: ignore ) async def command_language(app: PyroClient, message: Message): - user = await app.find_user(message.from_user) + user = await PyroUser.find( + message.from_user.id, locale=message.from_user.language_code + ) + keyboard = InlineKeyboard(row_width=2) buttons = [] @@ -27,16 +31,18 @@ async def command_language(app: PyroClient, message: Message): ) -@Client.on_callback_query(filters.regex(r"language:[\s\S]*")) # type: ignore +@PyroClient.on_callback_query(filters.regex(r"language:[\s\S]*")) # type: ignore async def callback_language(app: PyroClient, callback: CallbackQuery): - user = await app.find_user(callback.from_user) - language = str(callback.data).split(":")[1] + user = await PyroUser.find( + callback.from_user.id, locale=callback.from_user.language_code + ) + parsed = CallbackLanguage.from_callback(callback) - await user.update_locale(language) + await user.update_locale(parsed.language) await callback.answer( - app._("locale_set", "callbacks", locale=language).format( - locale=app._("name", "metadata", locale=language) + app._("locale_set", "callbacks", locale=parsed.language).format( + locale=app._("name", "metadata", locale=parsed.language) ), show_alert=True, )