Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: resetting stats #108

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion blackjack/game/blackjackgame.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
import logging

from datetime import datetime
from enum import Enum

import blackjack.errors as errors
from blackjack.game import Player, Dealer, Deck

Expand All @@ -17,6 +18,7 @@ def __init__(self, gametype=None, game_id=None, lang_id="en"):
self.list_won = []
self.list_tie = []
self.list_lost = []
self.datetime_started = datetime.now()
self.bets_active = True
self._current_player = 0
self.players = []
Expand Down
4 changes: 3 additions & 1 deletion blackjackbot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
stop_command_handler = CommandHandler("stop", game.stop_cmd)
language_command_handler = CommandHandler("language", settings.language_cmd)
stats_command_handler = CommandHandler("stats", util.stats_cmd)
resetstats_command_handler = CommandHandler("resetstats", util.reset_stats_cmd)
comment_command_handler = CommandHandler("comment", util.comment_cmd)
comment_text_command_handler = MessageHandler(Filters.text & ~(Filters.forwarded | Filters.command), util.comment_text)

Expand All @@ -33,12 +34,13 @@
start_callback_handler = CallbackQueryHandler(game.start_callback, pattern=r"^start_[0-9]{7}$")
newgame_callback_handler = CallbackQueryHandler(game.newgame_callback, pattern=r"^newgame$")
language_callback_handler = CallbackQueryHandler(settings.language_callback, pattern=r"^lang_([a-z]{2}(?:-[a-z]{2})?)$")
reset_stats_callback_handler = CallbackQueryHandler(util.reset_stats_callback, pattern=r"^reset_stats_(confirm|cancel)$")

handlers = [banned_user_handler,
start_command_handler, stop_command_handler, join_callback_handler, hit_callback_handler,
stand_callback_handler, start_callback_handler, language_command_handler, stats_command_handler,
newgame_callback_handler, reload_lang_command_handler, language_callback_handler, users_command_handler,
comment_command_handler, comment_text_command_handler, answer_command_handler, ban_command_handler,
unban_command_handler, bans_command_handler]
unban_command_handler, bans_command_handler, resetstats_command_handler, reset_stats_callback_handler]

__all__ = ['handlers', 'error_handler']
9 changes: 4 additions & 5 deletions blackjackbot/commands/game/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,11 @@ def hit_callback(update, context):
player_cards = get_cards_string(player, lang_id)
if player.has_blackjack():
text = (translator("your_cards_are") + "\n\n" + translator("got_blackjack")).format(user_mention, player.cardvalue, player_cards)
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
next_player(update, context)
elif player.cardvalue == 21:
else:
text = (translator("your_cards_are") + "\n\n" + translator("got_21")).format(user_mention, player.cardvalue, player_cards)
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
next_player(update, context)

update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
next_player(update, context)


@needs_active_game
Expand Down
4 changes: 2 additions & 2 deletions blackjackbot/commands/util/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from .functions import remove_inline_keyboard, get_start_keyboard, generate_evaluation_string, html_mention, get_game_keyboard, get_join_keyboard
from .decorators import admin_method, needs_active_game
from .commands import stats_cmd, comment_cmd, comment_text
from .commands import stats_cmd, comment_cmd, comment_text, reset_stats_cmd, reset_stats_callback

__all__ = ['remove_inline_keyboard', 'get_start_keyboard', 'generate_evaluation_string', 'html_mention', 'get_game_keyboard', 'get_join_keyboard',
'stats_cmd', 'comment_cmd', 'comment_text', 'admin_method', 'needs_active_game']
'stats_cmd', 'comment_cmd', 'comment_text', 'admin_method', 'needs_active_game', 'reset_stats_cmd', 'reset_stats_callback']
54 changes: 53 additions & 1 deletion blackjackbot/commands/util/commands.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

from telegram import ForceReply, ParseMode
from telegram import ForceReply, ParseMode, InlineKeyboardButton, InlineKeyboardMarkup

from blackjackbot.commands.admin.functions import notify_admins
from blackjackbot.lang import translate
Expand All @@ -13,6 +13,58 @@ def stats_cmd(update, context):
update.message.reply_text(get_user_stats(update.effective_user.id), parse_mode=ParseMode.HTML)


def reset_stats_cmd(update, context):
"""Asks the user if they want to reset their statistics"""
user_id = update.effective_user.id
chat_id = update.effective_chat.id

_modify_old_reset_message(context)

db = Database()
lang_id = db.get_lang_id(user_id)

keyboard = [[
InlineKeyboardButton(translate("reset_stats_confirm_button"), callback_data='reset_stats_confirm'),
InlineKeyboardButton(translate("reset_stats_cancel_button"), callback_data='reset_stats_cancel'),
]]
reply_markup = InlineKeyboardMarkup(keyboard)

sent_message = update.message.reply_text(translate("reset_stats_confirm", lang_id), reply_markup=reply_markup)
reset_message = {"message_id": sent_message.message_id, "chat_id": chat_id}
context.user_data["reset_messages"] = reset_message


def _modify_old_reset_message(context):
"""Removes the last saved reset confirmation messages from the chat history"""
reset_message = context.user_data.get("reset_message", None)
if reset_message is None:
return

try:
context.bot.edit_message_reply_markup(chat_id=reset_message.get("chat_id"), message_id=reset_message.get("message_id"))
except:
pass

context.user_data["reset_messages"] = None


def reset_stats_callback(update, context):
"""Handler for confirmation of statistics reset"""
query = update.callback_query
query.answer()

user_id = update.effective_user.id
db = Database()
lang_id = db.get_lang_id(user_id)

if query.data == "reset_stats_confirm":
db.reset_stats(user_id=user_id)
query.edit_message_text(translate("reset_stats_executed", lang_id))

elif query.data == "reset_stats_cancel":
query.edit_message_text(translate("reset_stats_cancelled", lang_id))


def comment_cmd(update, context):
"""MessageHandler callback for the /comment command"""
if context.user_data.get("state", UserState.IDLE) != UserState.IDLE:
Expand Down
18 changes: 18 additions & 0 deletions blackjackbot/gamestore.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import logging
from datetime import datetime, timedelta
from random import randint

from .errors.noactivegameexception import NoActiveGameException
Expand Down Expand Up @@ -82,3 +83,20 @@ def _game_stopped_callback(self, game):
self.remove_game(self._game_dict[game.id])

self.logger.debug("Current games: {}".format(len(self._chat_dict)))

def cleanup_stale_games(self):
stale_timeout_min = 10
now = datetime.now()
remove_chat_ids = []

for game_id, chat_id in self._game_dict.items():
game = self.get_game(chat_id)

game_older_than_10_mins = game.datetime_started < (now - timedelta(minutes=stale_timeout_min))
if game_older_than_10_mins:
logging.info("Killing game with id {} because it's stale for > {} mins".format(game.id, stale_timeout_min))
# TODO notify chat
remove_chat_ids.append(chat_id)

for chat_id in remove_chat_ids:
self.remove_game(chat_id)
8 changes: 7 additions & 1 deletion blackjackbot/lang/strings/translations_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,11 @@
"admin_reply": "⚠ You need to reply to the user's comment!",
"reply_from_maintainer": "The maintainer of this bot sent you a reply:\n\n{}",
"statistic_template": "Here are your statistics 📊:\n\n<b>Played Games:</b> {}\n<b>Won Games:</b> {}\n<b>Last Played:</b> {} UTC\n\n{}\n\n<b>Winning rate:</b> {:.2%}",
"dealer_name": "Dealer"
"dealer_name": "Dealer",
"reset_stats_confirm": "Do you really want to reset your statistics?",
"reset_stats_confirm_button": "Reset",
"reset_stats_cancel_button": "Cancel",
"reset_stats_executed": "Alright, I reset your statistics!",
"reset_stats_cancelled": "Okay, I did not reset your statistics!",
"no_stats": "You haven't played yet, there are no statistics for you."
}
13 changes: 12 additions & 1 deletion bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import logging.handlers
import pathlib

from telegram.ext import Updater
from telegram.ext import Updater, JobQueue

import config
from blackjackbot import handlers, error_handler
from blackjackbot.gamestore import GameStore

logdir_path = pathlib.Path(__file__).parent.joinpath("logs").absolute()
logfile_path = logdir_path.joinpath("bot.log")
Expand All @@ -32,6 +33,16 @@

updater.dispatcher.add_error_handler(error_handler)


# Set up jobs
def stale_game_cleaner(context):
gs = GameStore()
gs.cleanup_stale_games()


updater.job_queue.run_repeating(callback=stale_game_cleaner, interval=300, first=300)


if config.USE_WEBHOOK:
updater.start_webhook(listen=config.WEBHOOK_IP, port=config.WEBHOOK_PORT, url_path=config.BOT_TOKEN, cert=config.CERTPATH, webhook_url=config.WEBHOOK_URL)
updater.bot.set_webhook(config.WEBHOOK_URL)
Expand Down
2 changes: 1 addition & 1 deletion database/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def get_user_stats(user_id):

if played_games == 0:
# prevent division by zero errors
played_games = 1
return translate("no_stats")

last_played_formatted = datetime.utcfromtimestamp(last_played).strftime('%d.%m.%y %H:%M')
win_percentage = round(float(won_games) / float(played_games), 4)
Expand Down