1"""
2Internationalize your bot
3
4Step 1: extract texts
5 # pybabel extract --input-dirs=. -o locales/mybot.pot
6
7 Some useful options:
8 - Extract texts with pluralization support
9 # -k __:1,2
10 - Add comments for translators, you can use another tag if you want (TR)
11 # --add-comments=NOTE
12 - Disable comments with string location in code
13 # --no-location
14 - Set project name
15 # --project=MySuperBot
16 - Set version
17 # --version=2.2
18
19Step 2: create *.po files. E.g. create en, ru, uk locales.
20 # pybabel init -i locales/mybot.pot -d locales -D mybot -l en
21 # pybabel init -i locales/mybot.pot -d locales -D mybot -l ru
22 # pybabel init -i locales/mybot.pot -d locales -D mybot -l uk
23
24Step 3: translate texts located in locales/{language}/LC_MESSAGES/mybot.po
25 To open .po file you can use basic text editor or any PO editor, e.g. https://poedit.net/
26
27Step 4: compile translations
28 # pybabel compile -d locales -D mybot
29
30Step 5: When you change the code of your bot you need to update po & mo files.
31 Step 5.1: regenerate pot file:
32 command from step 1
33 Step 5.2: update po files
34 # pybabel update -d locales -D mybot -i locales/mybot.pot
35 Step 5.3: update your translations
36 location and tools you know from step 3
37 Step 5.4: compile mo files
38 command from step 4
39"""
40
41from pathlib import Path
42
43from aiogram import Bot, Dispatcher, executor, types
44from aiogram.contrib.middlewares.i18n import I18nMiddleware
45
46TOKEN = 'BOT_TOKEN_HERE'
47I18N_DOMAIN = 'mybot'
48
49BASE_DIR = Path(__file__).parent
50LOCALES_DIR = BASE_DIR / 'locales'
51
52bot = Bot(TOKEN, parse_mode=types.ParseMode.HTML)
53dp = Dispatcher(bot)
54
55# Setup i18n middleware
56i18n = I18nMiddleware(I18N_DOMAIN, LOCALES_DIR)
57dp.middleware.setup(i18n)
58
59# Alias for gettext method
60_ = i18n.gettext
61
62
63@dp.message_handler(commands='start')
64async def cmd_start(message: types.Message):
65 # Simply use `_('message')` instead of `'message'` and never use f-strings for translatable texts.
66 await message.reply(_('Hello, <b>{user}</b>!').format(user=message.from_user.full_name))
67
68
69@dp.message_handler(commands='lang')
70async def cmd_lang(message: types.Message, locale):
71 # For setting custom lang you have to modify i18n middleware
72 await message.reply(_('Your current language: <i>{language}</i>').format(language=locale))
73
74# If you care about pluralization, here's small handler
75# And also, there's and example of comments for translators. Most translation tools support them.
76
77# Alias for gettext method, parser will understand double underscore as plural (aka ngettext)
78__ = i18n.gettext
79
80
81# some likes manager
82LIKES_STORAGE = {'count': 0}
83
84
85def get_likes() -> int:
86 return LIKES_STORAGE['count']
87
88
89def increase_likes() -> int:
90 LIKES_STORAGE['count'] += 1
91 return get_likes()
92
93
94@dp.message_handler(commands='like')
95async def cmd_like(message: types.Message, locale):
96 likes = increase_likes()
97
98 # NOTE: This is comment for a translator
99 await message.reply(__('Aiogram has {number} like!', 'Aiogram has {number} likes!', likes).format(number=likes))
100
101
102if __name__ == '__main__':
103 executor.start_polling(dp, skip_updates=True)