diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..39a0136 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ + +LANGUAGES := en zh_CN zh_TW fr_FR ja_JP ko_KR + +gentranslations: + xgettext -d beanbot -o locale/beanbot.pot **/*.py + for lang in $(LANGUAGES); do \ + mkdir -p locale/$$lang/LC_MESSAGES; \ + if [ -f locale/$$lang/LC_MESSAGES/beanbot.po ]; then \ + msgmerge --update locale/$$lang/LC_MESSAGES/beanbot.po locale/beanbot.pot; \ + else \ + msginit -i locale/beanbot.pot -o locale/$$lang/LC_MESSAGES/beanbot.po -l $$lang; \ + fi; \ + done + +compiletranslations: + for lang in $(LANGUAGES); do \ + msgfmt -o locale/$$lang/LC_MESSAGES/beanbot.mo locale/$$lang/LC_MESSAGES/beanbot.po; \ + done diff --git a/bots/mmbot.py b/bots/mmbot.py index 53c569b..ef98114 100644 --- a/bots/mmbot.py +++ b/bots/mmbot.py @@ -1,5 +1,6 @@ import click from datetime import datetime, timedelta +from gettext import gettext as _ from mmpy_bot import Bot, Settings from mmpy_bot import Plugin, listen_to, listen_webhook from mmpy_bot.plugins.base import PluginManager @@ -78,8 +79,8 @@ async def render(self, message: Message): "attachments": [ { "actions": [ - self.gen_action("submit", "提交", tx_content), - self.gen_action("cancel", "取消", tx_content), + self.gen_action("submit", _("Submit"), tx_content), + self.gen_action("cancel", _("Cancel"), tx_content), ] } ] @@ -107,9 +108,8 @@ async def submit_listener(self, event: WebHookEvent): "data": {"post": {"id": post_id}}, }), reaction) - # 需要改 listen_to 实现中对 reg 的替换代码,以支持单独命令输入 @listen_to("bill", direct_only=True, allowed_users=[OWNER_NAME]) - @click.command(help="查询账户变动") + @click.command(help=_("Query account changes")) @click.option("-l", "--level", default=2, type=int) @click.argument("date", nargs=-1, type=str) def bill(self, message: Message, level: int, date: str): @@ -126,7 +126,7 @@ def bill(self, message: Message, level: int, date: str): self.driver.reply_to(message, f"**{resp_table.title}**\n\n{result}") @listen_to("expense", direct_only=True, allowed_users=[OWNER_NAME]) - @click.command(help="查询支出") + @click.command(help=_("Query expenses")) @click.option("-l", "--level", default=2, type=int) @click.argument("args", nargs=-1, type=str) def expense(self, message: Message, level: int, args: str): diff --git a/bots/telegram_bot.py b/bots/telegram_bot.py index 9bfe09e..df2326d 100644 --- a/bots/telegram_bot.py +++ b/bots/telegram_bot.py @@ -1,8 +1,9 @@ # coding: utf-8 import time -import telegram +from gettext import gettext as _ import logging from datetime import timedelta, datetime +import telegram from telegram import Update from telegram.ext import ( Application, filters, @@ -103,8 +104,8 @@ async def expense(update, context): _button_list = [ - telegram.InlineKeyboardButton("提交", callback_data="提交"), - telegram.InlineKeyboardButton("取消", callback_data="取消"), + telegram.InlineKeyboardButton(_("Submit"), callback_data="submit"), + telegram.InlineKeyboardButton(_("Cancel"), callback_data="cancel"), ] _pending_txs_reply_markup = telegram.InlineKeyboardMarkup([_button_list]) @@ -133,12 +134,12 @@ async def callback(update, context): query = update.callback_query await query.answer() - if choice == "提交": - result_msg = "已提交 ✅" + if choice == "submit": + result_msg = _("Submitted ✅") bean_manager.commit_trx(trx) logging.info("Commit transaction: %s\n", trx) else: - result_msg = "已取消 ❌" + result_msg = _("Cancelled ❌") logging.info("Cancel transaction") if result_msg: diff --git a/conf.py b/conf.py index 520610e..a02f9eb 100644 --- a/conf.py +++ b/conf.py @@ -1,4 +1,6 @@ +import os import yaml +import gettext _ImmutableError = TypeError("This dictionary is immutable") @@ -35,7 +37,7 @@ def __init__(self, config_path): def __bool__(self): return bool(self._config) - def get(self, key, default): + def get(self, key, default=None): return self._config.get(key, default) def __getattr__(self, key): @@ -60,3 +62,9 @@ def from_dict(cls, dictionary): def load_config(config_path): global config config = Config(config_path) + + +def set_locale(): + if config.get("language") is not None: + os.environ['LANGUAGE'] = config.get("language") + gettext.translation("beanbot", config.get("language"), fallback=True).install() diff --git a/config.yaml.example b/config.yaml.example index bca1d2d..51c853b 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -1,3 +1,5 @@ +language: zh_CN # If set, it can override the default locale from environment variables + beancount: filename: main.bean # The entrypoint for all transactions, and generated transaction will also append to this file currency: CNY diff --git a/locale/beanbot.pot b/locale/beanbot.pot new file mode 100644 index 0000000..acbbf8c --- /dev/null +++ b/locale/beanbot.pot @@ -0,0 +1,42 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 21:08+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "" diff --git a/locale/en/LC_MESSAGES/beanbot.mo b/locale/en/LC_MESSAGES/beanbot.mo new file mode 100644 index 0000000..3ab1d27 Binary files /dev/null and b/locale/en/LC_MESSAGES/beanbot.mo differ diff --git a/locale/en/LC_MESSAGES/beanbot.po b/locale/en/LC_MESSAGES/beanbot.po new file mode 100644 index 0000000..f731976 --- /dev/null +++ b/locale/en/LC_MESSAGES/beanbot.po @@ -0,0 +1,42 @@ +# English translations for PACKAGE package. +# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David Dai , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 20:40+0800\n" +"PO-Revision-Date: 2024-08-22 20:40+0800\n" +"Last-Translator: David Dai \n" +"Language-Team: English\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "Submit" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "Cancel" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "Query account changes" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "Query expenses" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "Submitted ✅" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "Cancelled ❌" diff --git a/locale/fr_FR/LC_MESSAGES/beanbot.mo b/locale/fr_FR/LC_MESSAGES/beanbot.mo new file mode 100644 index 0000000..0e29761 Binary files /dev/null and b/locale/fr_FR/LC_MESSAGES/beanbot.mo differ diff --git a/locale/fr_FR/LC_MESSAGES/beanbot.po b/locale/fr_FR/LC_MESSAGES/beanbot.po new file mode 100644 index 0000000..a2a1a3f --- /dev/null +++ b/locale/fr_FR/LC_MESSAGES/beanbot.po @@ -0,0 +1,43 @@ +# French translations for PACKAGE package +# Traductions françaises du paquet PACKAGE. +# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David Dai , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 21:07+0800\n" +"PO-Revision-Date: 2024-08-22 21:07+0800\n" +"Last-Translator: David Dai \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "Soumettre" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "Annuler" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "Interroger les changements de compte" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "Interroger les dépenses" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "Soumis ✅" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "Annulé ❌" diff --git a/locale/ja_JP/LC_MESSAGES/beanbot.mo b/locale/ja_JP/LC_MESSAGES/beanbot.mo new file mode 100644 index 0000000..bdd20a5 Binary files /dev/null and b/locale/ja_JP/LC_MESSAGES/beanbot.mo differ diff --git a/locale/ja_JP/LC_MESSAGES/beanbot.po b/locale/ja_JP/LC_MESSAGES/beanbot.po new file mode 100644 index 0000000..1e80a5a --- /dev/null +++ b/locale/ja_JP/LC_MESSAGES/beanbot.po @@ -0,0 +1,43 @@ +# Japanese translations for PACKAGE package +# PACKAGE �ѥå��������Ф������. +# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David Dai , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 21:07+0800\n" +"PO-Revision-Date: 2024-08-22 21:07+0800\n" +"Last-Translator: David Dai \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "送信" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "キャンセル" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "口座変更の照会" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "経費の照会" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "送信済み ✅" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "キャンセル済み ❌" diff --git a/locale/ko_KR/LC_MESSAGES/beanbot.mo b/locale/ko_KR/LC_MESSAGES/beanbot.mo new file mode 100644 index 0000000..f90e3be Binary files /dev/null and b/locale/ko_KR/LC_MESSAGES/beanbot.mo differ diff --git a/locale/ko_KR/LC_MESSAGES/beanbot.po b/locale/ko_KR/LC_MESSAGES/beanbot.po new file mode 100644 index 0000000..b2c18bb --- /dev/null +++ b/locale/ko_KR/LC_MESSAGES/beanbot.po @@ -0,0 +1,43 @@ +# Korean translations for PACKAGE package +# PACKAGE ��Ű���� ���� �ѱ��� ������. +# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David Dai , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 21:08+0800\n" +"PO-Revision-Date: 2024-08-22 21:08+0800\n" +"Last-Translator: David Dai \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "제출" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "취소" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "계정 변경 조회" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "지출 조회" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "제출됨 ✅" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "취소됨 ❌" diff --git a/locale/zh_CN/LC_MESSAGES/beanbot.mo b/locale/zh_CN/LC_MESSAGES/beanbot.mo new file mode 100644 index 0000000..f633f83 Binary files /dev/null and b/locale/zh_CN/LC_MESSAGES/beanbot.mo differ diff --git a/locale/zh_CN/LC_MESSAGES/beanbot.po b/locale/zh_CN/LC_MESSAGES/beanbot.po new file mode 100644 index 0000000..cd20e37 --- /dev/null +++ b/locale/zh_CN/LC_MESSAGES/beanbot.po @@ -0,0 +1,42 @@ +# Chinese translations for PACKAGE package +# PACKAGE 软件包的简体中文翻译. +# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David Dai , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 20:40+0800\n" +"PO-Revision-Date: 2024-08-22 20:40+0800\n" +"Last-Translator: David Dai \n" +"Language-Team: Chinese (simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "提交" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "取消" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "查询账户变更" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "查询支出" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "已提交 ✅" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "已取消 ❌" diff --git a/locale/zh_TW/LC_MESSAGES/beanbot.mo b/locale/zh_TW/LC_MESSAGES/beanbot.mo new file mode 100644 index 0000000..35c3ee0 Binary files /dev/null and b/locale/zh_TW/LC_MESSAGES/beanbot.mo differ diff --git a/locale/zh_TW/LC_MESSAGES/beanbot.po b/locale/zh_TW/LC_MESSAGES/beanbot.po new file mode 100644 index 0000000..5a3a084 --- /dev/null +++ b/locale/zh_TW/LC_MESSAGES/beanbot.po @@ -0,0 +1,42 @@ +# Chinese translations for PACKAGE package +# PACKAGE 套件的正體中文翻譯. +# Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David Dai , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-22 20:40+0800\n" +"PO-Revision-Date: 2024-08-22 20:40+0800\n" +"Last-Translator: David Dai \n" +"Language-Team: Chinese (traditional) \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: bots/mmbot.py:82 bots/telegram_bot.py:107 +msgid "Submit" +msgstr "提交" + +#: bots/mmbot.py:83 bots/telegram_bot.py:108 +msgid "Cancel" +msgstr "取消" + +#: bots/mmbot.py:112 +msgid "Query account changes" +msgstr "查詢賬戶變更" + +#: bots/mmbot.py:129 +msgid "Query expenses" +msgstr "查詢支出" + +#: bots/telegram_bot.py:138 +msgid "Submitted ✅" +msgstr "已提交 ✅" + +#: bots/telegram_bot.py:142 +msgid "Cancelled ❌" +msgstr "已取消 ❌" diff --git a/main.py b/main.py index 7d5fd83..fc14771 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,17 @@ import argparse +import gettext +import pathlib import conf import logging from bean_utils.bean import init_bean_manager +def _init_locale(): + locale_dir = pathlib.Path(__file__).parent / 'locale' + gettext.bindtextdomain('beanbot', locale_dir) + gettext.textdomain('beanbot') + + if __name__ == "__main__": # Init logging logging.basicConfig(level=logging.INFO) @@ -21,6 +29,9 @@ args = parser.parse_args() if args.command is not None: conf.load_config(args.c) + # Init i18n + conf.set_locale() + _init_locale() init_bean_manager() if args.command == "telegram":