🔀 Merge pull request #107 from tehcneko/master

Update python-telegram-bot to 13
This commit is contained in:
Jannes Höke 2022-11-14 14:51:33 +01:00 committed by GitHub
commit cb4d9bd5e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 146 additions and 158 deletions

View file

@ -6,6 +6,8 @@ import card as c
from datetime import datetime
from telegram import Message, Chat
from telegram.ext import CallbackContext
from apscheduler.jobstores.base import JobLookupError
from config import TIME_REMOVAL_AFTER_SKIP, MIN_FAST_TURN_TIME
from errors import DeckEmptyError, NotEnoughPlayersError
@ -191,7 +193,10 @@ def start_player_countdown(bot, game, job_queue):
if game.mode == 'fast':
if game.job:
game.job.schedule_removal()
try:
game.job.schedule_removal()
except JobLookupError:
pass
job = job_queue.run_once(
#lambda x,y: do_skip(bot, player),
@ -205,9 +210,9 @@ def start_player_countdown(bot, game, job_queue):
player.game.job = job
def skip_job(bot, job):
player = job.context.player
def skip_job(context: CallbackContext):
player = context.job.context.player
game = player.game
if game_is_running(game):
job_queue = job.context.job_queue
do_skip(bot, player, job_queue)
job_queue = context.job.context.job_queue
do_skip(context.bot, player, job_queue)

183
bot.py
View file

@ -21,9 +21,9 @@ import logging
from datetime import datetime
from telegram import ParseMode, InlineKeyboardMarkup, \
InlineKeyboardButton
InlineKeyboardButton, Update
from telegram.ext import InlineQueryHandler, ChosenInlineResultHandler, \
CommandHandler, MessageHandler, Filters, CallbackQueryHandler
CommandHandler, MessageHandler, Filters, CallbackQueryHandler, CallbackContext
from telegram.ext.dispatcher import run_async
import card as c
@ -49,9 +49,10 @@ logging.basicConfig(
level=logging.INFO
)
logger = logging.getLogger(__name__)
logging.getLogger('apscheduler').setLevel(logging.WARNING)
@user_locale
def notify_me(bot, update):
def notify_me(update: Update, context: CallbackContext):
"""Handler for /notify_me command, pm people for next game"""
chat_id = update.message.chat_id
if update.message.chat.type == 'private':
@ -67,12 +68,12 @@ def notify_me(bot, update):
@user_locale
def new_game(bot, update):
def new_game(update: Update, context: CallbackContext):
"""Handler for the /new command"""
chat_id = update.message.chat_id
if update.message.chat.type == 'private':
help_handler(bot, update)
help_handler(update, context)
else:
@ -89,88 +90,88 @@ def new_game(bot, update):
game.starter = update.message.from_user
game.owner.append(update.message.from_user.id)
game.mode = DEFAULT_GAMEMODE
send_async(bot, chat_id,
send_async(context.bot, chat_id,
text=_("Created a new game! Join the game with /join "
"and start the game with /start"))
@user_locale
def kill_game(bot, update):
def kill_game(update: Update, context: CallbackContext):
"""Handler for the /kill command"""
chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)
if update.message.chat.type == 'private':
help_handler(bot, update)
help_handler(update, context)
return
if not games:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There is no running game in this chat."))
return
game = games[-1]
if user_is_creator_or_admin(user, game, bot, chat):
if user_is_creator_or_admin(user, game, context.bot, chat):
try:
gm.end_game(chat, user)
send_async(bot, chat.id, text=__("Game ended!", multi=game.translate))
send_async(context.bot, chat.id, text=__("Game ended!", multi=game.translate))
except NoGameInChatError:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("The game is not started yet. "
"Join the game with /join and start the game with /start"),
reply_to_message_id=update.message.message_id)
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
@user_locale
def join_game(bot, update):
def join_game(update: Update, context: CallbackContext):
"""Handler for the /join command"""
chat = update.message.chat
if update.message.chat.type == 'private':
help_handler(bot, update)
help_handler(update, context)
return
try:
gm.join_game(update.message.from_user, chat)
except LobbyClosedError:
send_async(bot, chat.id, text=_("The lobby is closed"))
send_async(context.bot, chat.id, text=_("The lobby is closed"))
except NoGameInChatError:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("No game is running at the moment. "
"Create a new game with /new"),
reply_to_message_id=update.message.message_id)
except AlreadyJoinedError:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("You already joined the game. Start the game "
"with /start"),
reply_to_message_id=update.message.message_id)
except DeckEmptyError:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There are not enough cards left in the deck for "
"new players to join."),
reply_to_message_id=update.message.message_id)
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Joined the game"),
reply_to_message_id=update.message.message_id)
@user_locale
def leave_game(bot, update):
def leave_game(update: Update, context: CallbackContext):
"""Handler for the /leave command"""
chat = update.message.chat
user = update.message.from_user
@ -178,7 +179,7 @@ def leave_game(bot, update):
player = gm.player_for_user_in_chat(user, chat)
if player is None:
send_async(bot, chat.id, text=_("You are not playing in a game in "
send_async(context.bot, chat.id, text=_("You are not playing in a game in "
"this group."),
reply_to_message_id=update.message.message_id)
return
@ -190,23 +191,23 @@ def leave_game(bot, update):
gm.leave_game(user, chat)
except NoGameInChatError:
send_async(bot, chat.id, text=_("You are not playing in a game in "
send_async(context.bot, chat.id, text=_("You are not playing in a game in "
"this group."),
reply_to_message_id=update.message.message_id)
except NotEnoughPlayersError:
gm.end_game(chat, user)
send_async(bot, chat.id, text=__("Game ended!", multi=game.translate))
send_async(context.bot, chat.id, text=__("Game ended!", multi=game.translate))
else:
if game.started:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=__("Okay. Next Player: {name}",
multi=game.translate).format(
name=display_name(game.current_player.user)),
reply_to_message_id=update.message.message_id)
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=__("{name} left the game before it started.",
multi=game.translate).format(
name=display_name(user)),
@ -214,11 +215,11 @@ def leave_game(bot, update):
@user_locale
def kick_player(bot, update):
def kick_player(update: Update, context: CallbackContext):
"""Handler for the /kick command"""
if update.message.chat.type == 'private':
help_handler(bot, update)
help_handler(update, context)
return
chat = update.message.chat
@ -228,20 +229,20 @@ def kick_player(bot, update):
game = gm.chatid_games[chat.id][-1]
except (KeyError, IndexError):
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("No game is running at the moment. "
"Create a new game with /new"),
reply_to_message_id=update.message.message_id)
return
if not game.started:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("The game is not started yet. "
"Join the game with /join and start the game with /start"),
reply_to_message_id=update.message.message_id)
return
if user_is_creator_or_admin(user, game, bot, chat):
if user_is_creator_or_admin(user, game, context.bot, chat):
if update.message.reply_to_message:
kicked = update.message.reply_to_message.from_user
@ -250,40 +251,40 @@ def kick_player(bot, update):
gm.leave_game(kicked, chat)
except NoGameInChatError:
send_async(bot, chat.id, text=_("Player {name} is not found in the current game.".format(name=display_name(kicked))),
send_async(context.bot, chat.id, text=_("Player {name} is not found in the current game.".format(name=display_name(kicked))),
reply_to_message_id=update.message.message_id)
return
except NotEnoughPlayersError:
gm.end_game(chat, user)
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("{0} was kicked by {1}".format(display_name(kicked), display_name(user))))
send_async(bot, chat.id, text=__("Game ended!", multi=game.translate))
send_async(context.bot, chat.id, text=__("Game ended!", multi=game.translate))
return
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("{0} was kicked by {1}".format(display_name(kicked), display_name(user))))
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Please reply to the person you want to kick and type /kick again."),
reply_to_message_id=update.message.message_id)
return
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=__("Okay. Next Player: {name}",
multi=game.translate).format(
name=display_name(game.current_player.user)),
reply_to_message_id=update.message.message_id)
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
def select_game(bot, update):
def select_game(update: Update, context: CallbackContext):
"""Handler for callback queries to select the current game"""
chat_id = int(update.callback_query.data)
@ -299,16 +300,15 @@ def select_game(bot, update):
text=_("Game not found."))
return
@run_async
def selected(bot):
def selected():
back = [[InlineKeyboardButton(text=_("Back to last group"),
switch_inline_query='')]]
bot.answerCallbackQuery(update.callback_query.id,
context.bot.answerCallbackQuery(update.callback_query.id,
text=_("Please switch to the group you selected!"),
show_alert=False,
timeout=TIMEOUT)
bot.editMessageText(chat_id=update.callback_query.message.chat_id,
context.bot.editMessageText(chat_id=update.callback_query.message.chat_id,
message_id=update.callback_query.message.message_id,
text=_("Selected group: {group}\n"
"<b>Make sure that you switch to the correct "
@ -318,11 +318,11 @@ def select_game(bot, update):
parse_mode=ParseMode.HTML,
timeout=TIMEOUT)
selected(bot)
dispatcher.run_async(selected)
@game_locales
def status_update(bot, update):
def status_update(update: Update, context: CallbackContext):
"""Remove player from game if user leaves the group"""
chat = update.message.chat
@ -337,17 +337,17 @@ def status_update(bot, update):
pass
except NotEnoughPlayersError:
gm.end_game(chat, user)
send_async(bot, chat.id, text=__("Game ended!",
send_async(context.bot, chat.id, text=__("Game ended!",
multi=game.translate))
else:
send_async(bot, chat.id, text=__("Removing {name} from the game",
send_async(context.bot, chat.id, text=__("Removing {name} from the game",
multi=game.translate)
.format(name=display_name(user)))
@game_locales
@user_locale
def start_game(bot, update, args, job_queue):
def start_game(update: Update, context: CallbackContext):
"""Handler for the /start command"""
if update.message.chat.type != 'private':
@ -356,16 +356,16 @@ def start_game(bot, update, args, job_queue):
try:
game = gm.chatid_games[chat.id][-1]
except (KeyError, IndexError):
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There is no game running in this chat. Create "
"a new one with /new"))
return
if game.started:
send_async(bot, chat.id, text=_("The game has already started"))
send_async(context.bot, chat.id, text=_("The game has already started"))
elif len(game.players) < MIN_PLAYERS:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=__("At least {minplayers} players must /join the game "
"before you can start it").format(minplayers=MIN_PLAYERS))
@ -383,23 +383,22 @@ def start_game(bot, update, args, job_queue):
multi=game.translate)
.format(name=display_name(game.current_player.user)))
@run_async
def send_first():
"""Send the first card and player"""
bot.sendSticker(chat.id,
context.bot.sendSticker(chat.id,
sticker=c.STICKERS[str(game.last_card)],
timeout=TIMEOUT)
bot.sendMessage(chat.id,
context.bot.sendMessage(chat.id,
text=first_message,
reply_markup=InlineKeyboardMarkup(choice),
timeout=TIMEOUT)
send_first()
start_player_countdown(bot, game, job_queue)
dispatcher.run_async(send_first)
start_player_countdown(context.bot, game, context.job_queue)
elif len(args) and args[0] == 'select':
elif len(context.args) and context.args[0] == 'select':
players = gm.userid_players[update.message.from_user.id]
groups = list()
@ -414,23 +413,23 @@ def start_game(bot, update, args, job_queue):
callback_data=str(player.game.chat.id))]
)
send_async(bot, update.message.chat_id,
send_async(context.bot, update.message.chat_id,
text=_('Please select the group you want to play in.'),
reply_markup=InlineKeyboardMarkup(groups))
else:
help_handler(bot, update)
help_handler(update, context)
@user_locale
def close_game(bot, update):
def close_game(update: Update, context: CallbackContext):
"""Handler for the /close command"""
chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)
if not games:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There is no running game in this chat."))
return
@ -438,12 +437,12 @@ def close_game(bot, update):
if user.id in game.owner:
game.open = False
send_async(bot, chat.id, text=_("Closed the lobby. "
send_async(context.bot, chat.id, text=_("Closed the lobby. "
"No more players can join this game."))
return
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
@ -451,14 +450,14 @@ def close_game(bot, update):
@user_locale
def open_game(bot, update):
def open_game(update: Update, context: CallbackContext):
"""Handler for the /open command"""
chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)
if not games:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There is no running game in this chat."))
return
@ -466,11 +465,11 @@ def open_game(bot, update):
if user.id in game.owner:
game.open = True
send_async(bot, chat.id, text=_("Opened the lobby. "
send_async(context.bot, chat.id, text=_("Opened the lobby. "
"New players may /join the game."))
return
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
@ -478,14 +477,14 @@ def open_game(bot, update):
@user_locale
def enable_translations(bot, update):
def enable_translations(update: Update, context: CallbackContext):
"""Handler for the /enable_translations command"""
chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)
if not games:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There is no running game in this chat."))
return
@ -493,12 +492,12 @@ def enable_translations(bot, update):
if user.id in game.owner:
game.translate = True
send_async(bot, chat.id, text=_("Enabled multi-translations. "
send_async(context.bot, chat.id, text=_("Enabled multi-translations. "
"Disable with /disable_translations"))
return
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
@ -506,14 +505,14 @@ def enable_translations(bot, update):
@user_locale
def disable_translations(bot, update):
def disable_translations(update: Update, context: CallbackContext):
"""Handler for the /disable_translations command"""
chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)
if not games:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("There is no running game in this chat."))
return
@ -521,13 +520,13 @@ def disable_translations(bot, update):
if user.id in game.owner:
game.translate = False
send_async(bot, chat.id, text=_("Disabled multi-translations. "
send_async(context.bot, chat.id, text=_("Disabled multi-translations. "
"Enable them again with "
"/enable_translations"))
return
else:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
@ -536,14 +535,14 @@ def disable_translations(bot, update):
@game_locales
@user_locale
def skip_player(bot, update):
def skip_player(update: Update, context: CallbackContext):
"""Handler for the /skip command"""
chat = update.message.chat
user = update.message.from_user
player = gm.player_for_user_in_chat(user, chat)
if not player:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("You are not playing in a game in this chat."))
return
@ -558,19 +557,19 @@ def skip_player(bot, update):
# You can skip yourself even if you have time left (you'll still draw)
if delta < skipped_player.waiting_time and player != skipped_player:
n = skipped_player.waiting_time - delta
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Please wait {time} second",
"Please wait {time} seconds",
n)
.format(time=n),
reply_to_message_id=update.message.message_id)
else:
do_skip(bot, player)
do_skip(context.bot, player)
@game_locales
@user_locale
def reply_to_query(bot, update):
def reply_to_query(update: Update, context: CallbackContext):
"""
Handler for inline queries.
Builds the result list for inline queries and answers to the client.
@ -638,13 +637,13 @@ def reply_to_query(bot, update):
if players and game and len(players) > 1:
switch = _('Current game: {game}').format(game=game.chat.title)
answer_async(bot, update.inline_query.id, results, cache_time=0,
answer_async(context.bot, update.inline_query.id, results, cache_time=0,
switch_pm_text=switch, switch_pm_parameter='select')
@game_locales
@user_locale
def process_result(bot, update, job_queue):
def process_result(update: Update, context: CallbackContext):
"""
Handler for chosen inline results.
Checks the players actions and acts accordingly.
@ -671,38 +670,38 @@ def process_result(bot, update, job_queue):
mode = result_id[5:]
game.set_mode(mode)
logger.info("Gamemode changed to {mode}".format(mode = mode))
send_async(bot, chat.id, text=__("Gamemode changed to {mode}".format(mode = mode)))
send_async(context.bot, chat.id, text=__("Gamemode changed to {mode}".format(mode = mode)))
return
elif len(result_id) == 36: # UUID result
return
elif int(anti_cheat) != last_anti_cheat:
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=__("Cheat attempt by {name}", multi=game.translate)
.format(name=display_name(player.user)))
return
elif result_id == 'call_bluff':
reset_waiting_time(bot, player)
do_call_bluff(bot, player)
reset_waiting_time(context.bot, player)
do_call_bluff(context.bot, player)
elif result_id == 'draw':
reset_waiting_time(bot, player)
do_draw(bot, player)
reset_waiting_time(context.bot, player)
do_draw(context.bot, player)
elif result_id == 'pass':
game.turn()
elif result_id in c.COLORS:
game.choose_color(result_id)
else:
reset_waiting_time(bot, player)
do_play_card(bot, player, result_id)
reset_waiting_time(context.bot, player)
do_play_card(context.bot, player, result_id)
if game_is_running(game):
nextplayer_message = (
__("Next player: {name}", multi=game.translate)
.format(name=display_name(game.current_player.user)))
choice = [[InlineKeyboardButton(text=_("Make your choice!"), switch_inline_query_current_chat='')]]
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=nextplayer_message,
reply_markup=InlineKeyboardMarkup(choice))
start_player_countdown(bot, game, job_queue)
start_player_countdown(context.bot, game, context.job_queue)
def reset_waiting_time(bot, player):

View file

@ -101,7 +101,7 @@ def __(singular, plural=None, n=1, multi=False):
def user_locale(func):
@wraps(func)
@db_session
def wrapped(bot, update, *pargs, **kwargs):
def wrapped(update, context, *pargs, **kwargs):
user = _user_chat_from_update(update)[0]
with db_session:
@ -112,7 +112,7 @@ def user_locale(func):
else:
_.push('en_US')
result = func(bot, update, *pargs, **kwargs)
result = func(update, context, *pargs, **kwargs)
_.pop()
return result
return wrapped
@ -121,7 +121,7 @@ def user_locale(func):
def game_locales(func):
@wraps(func)
@db_session
def wrapped(bot, update, *pargs, **kwargs):
def wrapped(update, context, *pargs, **kwargs):
user, chat = _user_chat_from_update(update)
player = gm.player_for_user_in_chat(user, chat)
locales = list()
@ -141,7 +141,7 @@ def game_locales(func):
_.push(loc)
locales.append(loc)
result = func(bot, update, *pargs, **kwargs)
result = func(update, context, *pargs, **kwargs)
while _.code:
_.pop()
@ -151,21 +151,10 @@ def game_locales(func):
def _user_chat_from_update(update):
user = update.effective_user
chat = update.effective_chat
try:
user = update.message.from_user
chat = update.message.chat
except (NameError, AttributeError):
try:
user = update.inline_query.from_user
chat = gm.userid_current[user.id].game.chat
except KeyError:
chat = None
except (NameError, AttributeError):
try:
user = update.chosen_inline_result.from_user
chat = gm.userid_current[user.id].game.chat
except (NameError, AttributeError, KeyError):
chat = None
if chat is None and user is not None and user.id in gm.userid_current:
chat = gm.userid_current.get(user.id).game.chat
return user, chat

View file

@ -1,2 +1,2 @@
python-telegram-bot==8.1.1
python-telegram-bot==13.11
pony

View file

@ -18,8 +18,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from telegram import ReplyKeyboardMarkup
from telegram.ext import CommandHandler, RegexHandler
from telegram import ReplyKeyboardMarkup, Update
from telegram.ext import CommandHandler, Filters, MessageHandler, CallbackContext
from utils import send_async
from user_setting import UserSetting
@ -29,11 +29,11 @@ from internationalization import _, user_locale
@user_locale
def show_settings(bot, update):
def show_settings(update: Update, context: CallbackContext):
chat = update.message.chat
if update.message.chat.type != 'private':
send_async(bot, chat.id,
send_async(context.bot, chat.id,
text=_("Please edit your settings in a private chat with "
"the bot."))
return
@ -49,27 +49,27 @@ def show_settings(bot, update):
stats = '' + ' ' + _("Delete all statistics")
kb = [[stats], ['🌍' + ' ' + _("Language")]]
send_async(bot, chat.id, text='🔧' + ' ' + _("Settings"),
send_async(context.bot, chat.id, text='🔧' + ' ' + _("Settings"),
reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True))
@user_locale
def kb_select(bot, update, groups):
def kb_select(update: Update, context: CallbackContext):
chat = update.message.chat
user = update.message.from_user
option = groups[0]
option = context.match[1]
if option == '📊':
us = UserSetting.get(id=user.id)
us.stats = True
send_async(bot, chat.id, text=_("Enabled statistics!"))
send_async(context.bot, chat.id, text=_("Enabled statistics!"))
elif option == '🌍':
kb = [[locale + ' - ' + descr]
for locale, descr
in sorted(available_locales.items())]
send_async(bot, chat.id, text=_("Select locale"),
send_async(context.bot, chat.id, text=_("Select locale"),
reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True))
@ -79,28 +79,27 @@ def kb_select(bot, update, groups):
us.first_places = 0
us.games_played = 0
us.cards_played = 0
send_async(bot, chat.id, text=_("Deleted and disabled statistics!"))
send_async(context.bot, chat.id, text=_("Deleted and disabled statistics!"))
@user_locale
def locale_select(bot, update, groups):
def locale_select(update: Update, context: CallbackContext):
chat = update.message.chat
user = update.message.from_user
option = groups[0]
option = context.match[1]
if option in available_locales:
us = UserSetting.get(id=user.id)
us.lang = option
_.push(option)
send_async(bot, chat.id, text=_("Set locale!"))
send_async(context.bot, chat.id, text=_("Set locale!"))
_.pop()
def register():
dispatcher.add_handler(CommandHandler('settings', show_settings))
dispatcher.add_handler(RegexHandler('^([' + '📊' +
'🌍' +
'' + ']) .+$',
kb_select, pass_groups=True))
dispatcher.add_handler(RegexHandler(r'^(\w\w_\w\w) - .*',
locale_select, pass_groups=True))
dispatcher.add_handler(MessageHandler(Filters.regex('^([' + '📊' +
'🌍' +
'' + ']) .+$'),
kb_select))
dispatcher.add_handler(MessageHandler(Filters.regex(r'^(\w\w_\w\w) - .*'),
locale_select))

View file

@ -30,5 +30,5 @@ db.bind('sqlite', os.getenv('UNO_DB', 'uno.sqlite3'), create_db=True)
db.generate_mapping(create_tables=True)
gm = GameManager()
updater = Updater(token=TOKEN, workers=WORKERS)
updater = Updater(token=TOKEN, workers=WORKERS, use_context=True)
dispatcher = updater.dispatcher

View file

@ -17,8 +17,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from telegram import ParseMode
from telegram.ext import CommandHandler
from telegram import ParseMode, Update
from telegram.ext import CommandHandler, CallbackContext
from user_setting import UserSetting
from utils import send_async
@ -26,7 +26,7 @@ from shared_vars import dispatcher
from internationalization import _, user_locale
@user_locale
def help_handler(bot, update):
def help_handler(update: Update, context: CallbackContext):
"""Handler for the /help command"""
help_text = _("Follow these steps:\n\n"
"1. Add this bot to a group\n"
@ -64,11 +64,11 @@ def help_handler(bot, update):
"<a href=\"https://telegram.me/unobotupdates\">update channel</a>"
" and buy an UNO card game.")
send_async(bot, update.message.chat_id, text=help_text,
send_async(context.bot, update.message.chat_id, text=help_text,
parse_mode=ParseMode.HTML, disable_web_page_preview=True)
@user_locale
def modes(bot, update):
def modes(update: Update, context: CallbackContext):
"""Handler for the /help command"""
modes_explanation = _("This UNO bot has four game modes: Classic, Sanic, Wild and Text.\n\n"
" 🎻 The Classic mode uses the conventional UNO deck and there is no auto skip.\n"
@ -77,11 +77,11 @@ def modes(bot, update):
" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it uses the text.\n\n"
"To change the game mode, the GAME CREATOR has to type the bot nickname and a space, "
"just like when playing a card, and all gamemode options should appear.")
send_async(bot, update.message.chat_id, text=modes_explanation,
send_async(context.bot, update.message.chat_id, text=modes_explanation,
parse_mode=ParseMode.HTML, disable_web_page_preview=True)
@user_locale
def source(bot, update):
def source(update: Update, context: CallbackContext):
"""Handler for the /help command"""
source_text = _("This bot is Free Software and licensed under the AGPL. "
"The code is available here: \n"
@ -94,25 +94,25 @@ def source(bot, update):
"Originals available on http://game-icons.net\n"
"Icons edited by ɳick")
send_async(bot, update.message.chat_id, text=source_text + '\n' +
send_async(context.bot, update.message.chat_id, text=source_text + '\n' +
attributions,
parse_mode=ParseMode.HTML, disable_web_page_preview=True)
@user_locale
def news(bot, update):
def news(update: Update, context: CallbackContext):
"""Handler for the /news command"""
send_async(bot, update.message.chat_id,
send_async(context.bot, update.message.chat_id,
text=_("All news here: https://telegram.me/unobotupdates"),
disable_web_page_preview=True)
@user_locale
def stats(bot, update):
def stats(update: Update, context: CallbackContext):
user = update.message.from_user
us = UserSetting.get(id=user.id)
if not us or not us.stats:
send_async(bot, update.message.chat_id,
send_async(context.bot, update.message.chat_id,
text=_("You did not enable statistics. Use /settings in "
"a private chat with the bot to enable them."))
else:
@ -140,7 +140,7 @@ def stats(bot, update):
n).format(number=n)
)
send_async(bot, update.message.chat_id,
send_async(context.bot, update.message.chat_id,
text='\n'.join(stats_text))

View file

@ -20,11 +20,9 @@
import logging
from telegram.ext.dispatcher import run_async
from internationalization import _, __
from mwt import MWT
from shared_vars import gm
from shared_vars import gm, dispatcher
logger = logging.getLogger(__name__)
@ -82,26 +80,24 @@ def error(bot, update, error):
logger.exception(error)
@run_async
def send_async(bot, *args, **kwargs):
"""Send a message asynchronously"""
if 'timeout' not in kwargs:
kwargs['timeout'] = TIMEOUT
try:
bot.sendMessage(*args, **kwargs)
dispatcher.run_async(bot.sendMessage, *args, **kwargs)
except Exception as e:
error(None, None, e)
@run_async
def answer_async(bot, *args, **kwargs):
"""Answer an inline query asynchronously"""
if 'timeout' not in kwargs:
kwargs['timeout'] = TIMEOUT
try:
bot.answerInlineQuery(*args, **kwargs)
dispatcher.run_async(bot.answerInlineQuery, *args, **kwargs)
except Exception as e:
error(None, None, e)