forked from test/mau_mau_bot
add __ function to translate complete stack, add dummy decorators to pull locales from db
This commit is contained in:
parent
5ece46527a
commit
cddf13dc5d
4 changed files with 97 additions and 53 deletions
96
bot.py
96
bot.py
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from functools import wraps
|
||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
from telegram import ParseMode, Message, Chat, InlineKeyboardMarkup, \
|
from telegram import ParseMode, Message, Chat, InlineKeyboardMarkup, \
|
||||||
|
@ -40,8 +41,7 @@ from utils import display_name
|
||||||
import card as c
|
import card as c
|
||||||
from errors import (NoGameInChatError, LobbyClosedError, AlreadyJoinedError,
|
from errors import (NoGameInChatError, LobbyClosedError, AlreadyJoinedError,
|
||||||
NotEnoughPlayersError, DeckEmptyError)
|
NotEnoughPlayersError, DeckEmptyError)
|
||||||
from database import db_session, user_locale
|
from utils import _, __
|
||||||
from utils import _
|
|
||||||
|
|
||||||
|
|
||||||
TIMEOUT = 2.5
|
TIMEOUT = 2.5
|
||||||
|
@ -92,6 +92,32 @@ source_text = ("This bot is Free Software and licensed under the AGPL. "
|
||||||
"https://github.com/jh0ker/mau_mau_bot")
|
"https://github.com/jh0ker/mau_mau_bot")
|
||||||
|
|
||||||
|
|
||||||
|
def user_locale(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapped(*pargs, **kwargs):
|
||||||
|
_.push('de_DE') # TODO: Get user locale from Database
|
||||||
|
result = func(*pargs, **kwargs)
|
||||||
|
_.pop()
|
||||||
|
return result
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
|
def game_locales(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapped(*pargs, **kwargs):
|
||||||
|
num_locales = 0
|
||||||
|
for loc in ('en_US', 'de_DE'): # TODO: Get user locales from Database
|
||||||
|
_.push(loc)
|
||||||
|
num_locales += 1
|
||||||
|
|
||||||
|
result = func(*pargs, **kwargs)
|
||||||
|
|
||||||
|
for i in range(num_locales):
|
||||||
|
_.pop()
|
||||||
|
return result
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
@run_async
|
@run_async
|
||||||
def send_async(bot, *args, **kwargs):
|
def send_async(bot, *args, **kwargs):
|
||||||
"""Send a message asynchronously"""
|
"""Send a message asynchronously"""
|
||||||
|
@ -169,8 +195,8 @@ def join_game(bot, update):
|
||||||
|
|
||||||
except DeckEmptyError:
|
except DeckEmptyError:
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("There are not enough cards left in the deck for new "
|
text=_("There are not enough cards left in the deck for "
|
||||||
"players to join."),
|
"new players to join."),
|
||||||
reply_to_message_id=update.message.message_id)
|
reply_to_message_id=update.message.message_id)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -206,11 +232,11 @@ def leave_game(bot, update):
|
||||||
|
|
||||||
except NotEnoughPlayersError:
|
except NotEnoughPlayersError:
|
||||||
gm.end_game(chat, user)
|
gm.end_game(chat, user)
|
||||||
send_async(bot, chat.id, text=_("Game ended!"))
|
send_async(bot, chat.id, text=__("Game ended!"))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("Okay. Next Player: {name}").format(
|
text=__("Okay. Next Player: {name}").format(
|
||||||
name=display_name(game.current_player.user)),
|
name=display_name(game.current_player.user)),
|
||||||
reply_to_message_id=update.message.message_id)
|
reply_to_message_id=update.message.message_id)
|
||||||
|
|
||||||
|
@ -251,7 +277,7 @@ def select_game(bot, update):
|
||||||
timeout=TIMEOUT)
|
timeout=TIMEOUT)
|
||||||
|
|
||||||
|
|
||||||
@user_locale
|
@game_locales
|
||||||
def status_update(bot, update):
|
def status_update(bot, update):
|
||||||
"""Remove player from game if user leaves the group"""
|
"""Remove player from game if user leaves the group"""
|
||||||
chat = update.message.chat
|
chat = update.message.chat
|
||||||
|
@ -268,12 +294,13 @@ def status_update(bot, update):
|
||||||
pass
|
pass
|
||||||
except NotEnoughPlayersError:
|
except NotEnoughPlayersError:
|
||||||
gm.end_game(chat, user)
|
gm.end_game(chat, user)
|
||||||
send_async(bot, chat.id, text=_("Game ended!"))
|
send_async(bot, chat.id, text=__("Game ended!"))
|
||||||
else:
|
else:
|
||||||
send_async(bot, chat.id, text=_("Removing {name} from the game")
|
send_async(bot, chat.id, text=__("Removing {name} from the game")
|
||||||
.format(name=display_name(user)))
|
.format(name=display_name(user)))
|
||||||
|
|
||||||
|
|
||||||
|
@game_locales
|
||||||
@user_locale
|
@user_locale
|
||||||
def start_game(bot, update, args):
|
def start_game(bot, update, args):
|
||||||
"""Handler for the /start command"""
|
"""Handler for the /start command"""
|
||||||
|
@ -310,9 +337,9 @@ def start_game(bot, update, args):
|
||||||
timeout=TIMEOUT)
|
timeout=TIMEOUT)
|
||||||
|
|
||||||
bot.sendMessage(chat.id,
|
bot.sendMessage(chat.id,
|
||||||
text=_("First player: {name}\n"
|
text=__("First player: {name}\n"
|
||||||
"Use /close to stop people from "
|
"Use /close to stop people from "
|
||||||
"joining the game.")
|
"joining the game.")
|
||||||
.format(
|
.format(
|
||||||
name=display_name(game.current_player.user)
|
name=display_name(game.current_player.user)
|
||||||
),
|
),
|
||||||
|
@ -398,6 +425,7 @@ def open_game(bot, update):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@game_locales
|
||||||
@user_locale
|
@user_locale
|
||||||
def skip_player(bot, update):
|
def skip_player(bot, update):
|
||||||
"""Handler for the /skip command"""
|
"""Handler for the /skip command"""
|
||||||
|
@ -433,9 +461,9 @@ def skip_player(bot, update):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("Waiting time to skip this player has "
|
text=__("Waiting time to skip this player has "
|
||||||
"been reduced to {time} seconds.\n"
|
"been reduced to {time} seconds.\n"
|
||||||
"Next player: {name}")
|
"Next player: {name}")
|
||||||
.format(time=skipped_player.waiting_time,
|
.format(time=skipped_player.waiting_time,
|
||||||
name=display_name(next_player.user)))
|
name=display_name(next_player.user)))
|
||||||
game.turn()
|
game.turn()
|
||||||
|
@ -444,17 +472,17 @@ def skip_player(bot, update):
|
||||||
try:
|
try:
|
||||||
gm.leave_game(skipped_player.user, chat)
|
gm.leave_game(skipped_player.user, chat)
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("{name1} was skipped four times in a row "
|
text=__("{name1} was skipped four times in a row "
|
||||||
"and has been removed from the game.\n"
|
"and has been removed from the game.\n"
|
||||||
"Next player: {name2}")
|
"Next player: {name2}")
|
||||||
.format(name1=display_name(skipped_player.user),
|
.format(name1=display_name(skipped_player.user),
|
||||||
name2=display_name(next_player.user)))
|
name2=display_name(next_player.user)))
|
||||||
|
|
||||||
except NotEnoughPlayersError:
|
except NotEnoughPlayersError:
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("{name} was skipped four times in a row "
|
text=__("{name} was skipped four times in a row "
|
||||||
"and has been removed from the game.\n"
|
"and has been removed from the game.\n"
|
||||||
"The game ended.")
|
"The game ended.")
|
||||||
.format(name=display_name(skipped_player.user)))
|
.format(name=display_name(skipped_player.user)))
|
||||||
|
|
||||||
gm.end_game(chat.id, skipped_player.user)
|
gm.end_game(chat.id, skipped_player.user)
|
||||||
|
@ -482,6 +510,7 @@ def news(bot, update):
|
||||||
disable_web_page_preview=True)
|
disable_web_page_preview=True)
|
||||||
|
|
||||||
|
|
||||||
|
@game_locales
|
||||||
@user_locale
|
@user_locale
|
||||||
def reply_to_query(bot, update):
|
def reply_to_query(bot, update):
|
||||||
"""
|
"""
|
||||||
|
@ -543,6 +572,7 @@ def reply_to_query(bot, update):
|
||||||
switch_pm_text=switch, switch_pm_parameter='select')
|
switch_pm_text=switch, switch_pm_parameter='select')
|
||||||
|
|
||||||
|
|
||||||
|
@game_locales
|
||||||
@user_locale
|
@user_locale
|
||||||
def process_result(bot, update):
|
def process_result(bot, update):
|
||||||
"""
|
"""
|
||||||
|
@ -570,7 +600,7 @@ def process_result(bot, update):
|
||||||
return
|
return
|
||||||
elif int(anti_cheat) != last_anti_cheat:
|
elif int(anti_cheat) != last_anti_cheat:
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("Cheat attempt by {name}")
|
text=__("Cheat attempt by {name}")
|
||||||
.format(name=display_name(player.user)))
|
.format(name=display_name(player.user)))
|
||||||
return
|
return
|
||||||
elif result_id == 'call_bluff':
|
elif result_id == 'call_bluff':
|
||||||
|
@ -589,7 +619,7 @@ def process_result(bot, update):
|
||||||
|
|
||||||
if game in gm.chatid_games.get(chat.id, list()):
|
if game in gm.chatid_games.get(chat.id, list()):
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("Next player: {name}")
|
text=__("Next player: {name}")
|
||||||
.format(name=display_name(game.current_player.user)))
|
.format(name=display_name(game.current_player.user)))
|
||||||
|
|
||||||
|
|
||||||
|
@ -600,8 +630,8 @@ def reset_waiting_time(bot, player):
|
||||||
if player.waiting_time < 90:
|
if player.waiting_time < 90:
|
||||||
player.waiting_time = 90
|
player.waiting_time = 90
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("Waiting time for {name} has been reset to 90 "
|
text=__("Waiting time for {name} has been reset to 90 "
|
||||||
"seconds").format(name=display_name(player.user)))
|
"seconds").format(name=display_name(player.user)))
|
||||||
|
|
||||||
|
|
||||||
def do_play_card(bot, player, result_id):
|
def do_play_card(bot, player, result_id):
|
||||||
|
@ -616,15 +646,15 @@ def do_play_card(bot, player, result_id):
|
||||||
send_async(bot, chat.id, text=_("Please choose a color"))
|
send_async(bot, chat.id, text=_("Please choose a color"))
|
||||||
|
|
||||||
if len(player.cards) == 1:
|
if len(player.cards) == 1:
|
||||||
send_async(bot, chat.id, text=_("UNO!"))
|
send_async(bot, chat.id, text="UNO!")
|
||||||
|
|
||||||
if len(player.cards) == 0:
|
if len(player.cards) == 0:
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("{name} won!").format(name=user.first_name))
|
text=__("{name} won!").format(name=user.first_name))
|
||||||
try:
|
try:
|
||||||
gm.leave_game(user, chat)
|
gm.leave_game(user, chat)
|
||||||
except NotEnoughPlayersError:
|
except NotEnoughPlayersError:
|
||||||
send_async(bot, chat.id, text=_("Game ended!"))
|
send_async(bot, chat.id, text=__("Game ended!"))
|
||||||
gm.end_game(chat, user)
|
gm.end_game(chat, user)
|
||||||
|
|
||||||
if botan:
|
if botan:
|
||||||
|
@ -642,7 +672,7 @@ def do_draw(bot, player):
|
||||||
player.draw()
|
player.draw()
|
||||||
except DeckEmptyError:
|
except DeckEmptyError:
|
||||||
send_async(bot, player.game.chat.id,
|
send_async(bot, player.game.chat.id,
|
||||||
text=_("There are no more cards in the deck."))
|
text=__("There are no more cards in the deck."))
|
||||||
|
|
||||||
if (game.last_card.value == c.DRAW_TWO or
|
if (game.last_card.value == c.DRAW_TWO or
|
||||||
game.last_card.special == c.DRAW_FOUR) and \
|
game.last_card.special == c.DRAW_FOUR) and \
|
||||||
|
@ -657,26 +687,26 @@ def do_call_bluff(bot, player):
|
||||||
|
|
||||||
if player.prev.bluffing:
|
if player.prev.bluffing:
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text=_("Bluff called! Giving 4 cards to {name}")
|
text=__("Bluff called! Giving 4 cards to {name}")
|
||||||
.format(name=player.prev.user.first_name))
|
.format(name=player.prev.user.first_name))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
player.prev.draw()
|
player.prev.draw()
|
||||||
except DeckEmptyError:
|
except DeckEmptyError:
|
||||||
send_async(bot, player.game.chat.id,
|
send_async(bot, player.game.chat.id,
|
||||||
text=_("There are no more cards in the deck."))
|
text=__("There are no more cards in the deck."))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
game.draw_counter += 2
|
game.draw_counter += 2
|
||||||
send_async(bot, chat.id,
|
send_async(bot, chat.id,
|
||||||
text="{name1} didn't bluff! Giving 6 cards to {name2}"
|
text=__("{name1} didn't bluff! Giving 6 cards to {name2}")
|
||||||
.format(name1=player.prev.user.first_name,
|
.format(name1=player.prev.user.first_name,
|
||||||
name2=player.user.first_name))
|
name2=player.user.first_name))
|
||||||
try:
|
try:
|
||||||
player.draw()
|
player.draw()
|
||||||
except DeckEmptyError:
|
except DeckEmptyError:
|
||||||
send_async(bot, player.game.chat.id,
|
send_async(bot, player.game.chat.id,
|
||||||
text=_("There are no more cards in the deck."))
|
text=__("There are no more cards in the deck."))
|
||||||
|
|
||||||
game.turn()
|
game.turn()
|
||||||
|
|
||||||
|
|
14
database.py
14
database.py
|
@ -18,21 +18,7 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
from pony.orm import Database, db_session, Optional, Required, Set, PrimaryKey
|
from pony.orm import Database, db_session, Optional, Required, Set, PrimaryKey
|
||||||
|
|
||||||
from utils import _
|
|
||||||
|
|
||||||
# Database singleton
|
# Database singleton
|
||||||
db = Database()
|
db = Database()
|
||||||
|
|
||||||
|
|
||||||
def user_locale(func):
|
|
||||||
@wraps(func)
|
|
||||||
def wrapped(*pargs, **kwargs):
|
|
||||||
_.push('de_DE') # TODO: Get user locale from Database
|
|
||||||
result = func(*pargs, **kwargs)
|
|
||||||
_.pop()
|
|
||||||
return result
|
|
||||||
return wrapped
|
|
||||||
|
|
12
results.py
12
results.py
|
@ -26,7 +26,7 @@ from telegram import InlineQueryResultArticle, InputTextMessageContent, \
|
||||||
InlineQueryResultCachedSticker as Sticker
|
InlineQueryResultCachedSticker as Sticker
|
||||||
|
|
||||||
import card as c
|
import card as c
|
||||||
from utils import display_color, display_name, list_subtract, _
|
from utils import display_color, display_name, list_subtract, _, __
|
||||||
|
|
||||||
|
|
||||||
def add_choose_color(results):
|
def add_choose_color(results):
|
||||||
|
@ -61,7 +61,7 @@ def add_other_cards(playable, player, results, game):
|
||||||
|
|
||||||
def player_list(game):
|
def player_list(game):
|
||||||
"""Generate list of player strings"""
|
"""Generate list of player strings"""
|
||||||
return ["{name} ({number} cards)"
|
return [_("{name} ({number} cards)")
|
||||||
.format(name=player.user.first_name, number=len(player.cards))
|
.format(name=player.user.first_name, number=len(player.cards))
|
||||||
for player in game.players]
|
for player in game.players]
|
||||||
|
|
||||||
|
@ -100,9 +100,9 @@ def add_draw(player, results):
|
||||||
Sticker(
|
Sticker(
|
||||||
"draw", sticker_file_id=c.STICKERS['option_draw'],
|
"draw", sticker_file_id=c.STICKERS['option_draw'],
|
||||||
input_message_content=
|
input_message_content=
|
||||||
InputTextMessageContent(_('Drawing 1 card')
|
InputTextMessageContent(__('Drawing 1 card')
|
||||||
if n == 1 else
|
if n == 1 else
|
||||||
_('Drawing {number} cards')
|
__('Drawing {number} cards')
|
||||||
.format(number=n))
|
.format(number=n))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -125,7 +125,7 @@ def add_pass(results):
|
||||||
results.append(
|
results.append(
|
||||||
Sticker(
|
Sticker(
|
||||||
"pass", sticker_file_id=c.STICKERS['option_pass'],
|
"pass", sticker_file_id=c.STICKERS['option_pass'],
|
||||||
input_message_content=InputTextMessageContent(_('Pass'))
|
input_message_content=InputTextMessageContent(__('Pass'))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ def add_call_bluff(results):
|
||||||
"call_bluff",
|
"call_bluff",
|
||||||
sticker_file_id=c.STICKERS['option_bluff'],
|
sticker_file_id=c.STICKERS['option_bluff'],
|
||||||
input_message_content=
|
input_message_content=
|
||||||
InputTextMessageContent(_("I'm calling your bluff!"))
|
InputTextMessageContent(__("I'm calling your bluff!"))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
28
utils.py
28
utils.py
|
@ -18,6 +18,8 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from flufl.i18n import registry
|
from flufl.i18n import registry
|
||||||
from flufl.i18n import PackageStrategy
|
from flufl.i18n import PackageStrategy
|
||||||
|
|
||||||
|
@ -27,6 +29,32 @@ import locales
|
||||||
strategy = PackageStrategy('unobot', locales)
|
strategy = PackageStrategy('unobot', locales)
|
||||||
application = registry.register(strategy)
|
application = registry.register(strategy)
|
||||||
_ = application._
|
_ = application._
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def __(string):
|
||||||
|
"""Translates text into all locales on the stack"""
|
||||||
|
translations = list()
|
||||||
|
locales = list()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
translation = _(string)
|
||||||
|
|
||||||
|
if translation not in translations:
|
||||||
|
translations.append(translation)
|
||||||
|
|
||||||
|
l = _.code
|
||||||
|
_.pop()
|
||||||
|
|
||||||
|
if l is None:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
locales.append(l)
|
||||||
|
|
||||||
|
for l in reversed(locales):
|
||||||
|
_.push(l)
|
||||||
|
|
||||||
|
return '\n'.join(translations) # TODO
|
||||||
|
|
||||||
|
|
||||||
def list_subtract(list1, list2):
|
def list_subtract(list1, list2):
|
||||||
|
|
Loading…
Reference in a new issue