Skip to content

Commit

Permalink
Add Game container (#42)
Browse files Browse the repository at this point in the history
Refactor SQL queries

Bump aiosqlite version

Add Facilitator object

Only one game can be at one time

End game statistics

Better name display

Stricter types
  • Loading branch information
antonkomarev authored Aug 25, 2022
1 parent 123f701 commit a3cad52
Show file tree
Hide file tree
Showing 6 changed files with 446 additions and 77 deletions.
72 changes: 62 additions & 10 deletions app/bot.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from aiotg import Bot, Chat, CallbackQuery, BotApiError
from app.utils import init_logging
from app.telegram_user import TelegramUser
from app.game import Game
from app.game_registry import GameRegistry
from app.game_session import GameSession
import asyncio
Expand Down Expand Up @@ -56,20 +58,58 @@ async def on_help_command(chat: Chat, match):
)


@bot.command("(?s)/game\s+(.+)$")
@bot.command("/(game)$")
async def on_game_command(chat: Chat, match):
chat_id = chat.id
facilitator_message_id = str(chat.message["message_id"])
game_name = match.group(1)
facilitator = TelegramUser.from_dict(chat.sender)

if game_name == "game":
game_name = "(no name)"

active_game = await game_registry.find_active_game(chat_id, facilitator)
if active_game is not None:
await chat.send_text(
text="You have active game already. Need to /game_end to start another one."
)
return

game = Game(chat_id, facilitator_message_id, game_name, facilitator)
await create_game(chat, game)


@bot.command("/game_end$")
async def on_game_end_command(chat: Chat, match):
chat_id = chat.id
facilitator = TelegramUser.from_dict(chat.sender)

active_game = await game_registry.find_active_game(chat_id, facilitator)

if active_game is None:
await chat.send_text(
text="You do not have active game. Need to run /game to start game."
)
return

await end_game(chat, active_game)


@bot.command("(?s)/poker\s+(.+)$")
@bot.command("/(poker)$")
async def on_poker_command(chat: Chat, match):
chat_id = chat.id
facilitator_message_id = str(chat.message["message_id"])
topic = match.group(1)
facilitator = chat.sender
facilitator = TelegramUser.from_dict(chat.sender)

if topic == "poker":
topic = "(no topic)"

game_id = 0
game = await game_registry.find_active_game(chat_id, facilitator)

game_session = GameSession(game_id, chat_id, facilitator_message_id, topic, facilitator)
game_session = GameSession(game, chat_id, facilitator_message_id, topic, facilitator)
await create_game_session(chat, game_session)


Expand Down Expand Up @@ -128,7 +168,7 @@ async def on_facilitator_operation_click(chat: Chat, callback_query: CallbackQue
if not game_session:
return await callback_query.answer(text="No such game session")

if callback_query.src["from"]["id"] != game_session.facilitator["id"]:
if callback_query.src["from"]["id"] != game_session.facilitator.id:
return await callback_query.answer(text="Operation `{}` is available only for facilitator".format(operation))

if operation in GameSession.OPERATION_START_ESTIMATION:
Expand Down Expand Up @@ -165,7 +205,7 @@ async def run_operation_end_estimation(chat: Chat, game_session: GameSession):

async def run_re_estimate(chat: Chat, game_session: GameSession):
message = {
"text": game_session.render_message_text(),
"text": game_session.render_system_message_text(),
}

game_session.re_estimate()
Expand All @@ -179,15 +219,27 @@ async def run_re_estimate(chat: Chat, game_session: GameSession):
await create_game_session(chat, game_session)


async def create_game_session(chat: Chat, game_session: GameSession):
response = await chat.send_text(**game_session.render_message())
game_session.system_message_id = response["result"]["message_id"]
await game_registry.create_game_session(game_session)
async def create_game(chat: Chat, game_prototype: Game):
response = await chat.send_text(**game_prototype.render_system_message())
game_prototype.system_message_id = response["result"]["message_id"]
await game_registry.create_game(game_prototype)


async def end_game(chat: Chat, game: Game):
await game_registry.end_game(game)
game_statistics = await game_registry.get_game_statistics(game)
await chat.send_text(**game.render_results_system_message(game_statistics))


async def create_game_session(chat: Chat, game_session_prototype: GameSession):
response = await chat.send_text(**game_session_prototype.render_system_message())
game_session_prototype.system_message_id = response["result"]["message_id"]
await game_registry.create_game_session(game_session_prototype)


async def edit_message(chat: Chat, game_session: GameSession):
try:
await bot.edit_message_text(chat.id, game_session.system_message_id, **game_session.render_message())
await bot.edit_message_text(chat.id, game_session.system_message_id, **game_session.render_system_message())
except BotApiError:
logbook.exception("Error when updating markup")

Expand Down
81 changes: 81 additions & 0 deletions app/game.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from app.telegram_user import TelegramUser


class Game:
STATUS_STARTED = "started"
STATUS_ENDED = "ended"

def __init__(self, chat_id: int, facilitator_message_id: int, name: str, facilitator: TelegramUser):
self.id = None
self.system_message_id = None
self.chat_id = chat_id
self.facilitator_message_id = facilitator_message_id
self.status = self.STATUS_STARTED
self.name = name
self.facilitator = facilitator

def render_system_message(self):
return {
"text": self.render_system_message_text(),
}

def render_results_system_message(self, game_statistics):
return {
"text": self.render_results_system_message_text(game_statistics),
}

def render_system_message_text(self) -> str:
result = ""

result += self.render_name_text()
result += "\n"
result += self.render_facilitator_text()

return result

def render_results_system_message_text(self, game_statistics) -> str:
result = ""

result += self.render_name_text()
result += "\n"
result += self.render_facilitator_text()
result += "\n"
result += "\n"
result += self.render_statistics_text(game_statistics)

return result

def render_facilitator_text(self) -> str:
return "Facilitator: {}".format(self.facilitator.to_string())

def render_name_text(self) -> str:
if self.status == self.STATUS_STARTED:
return "Planning poker started: " + self.name
elif self.status == self.STATUS_ENDED:
return "Planning poker ended: " + self.name
else:
return ""

def render_statistics_text(self, game_statistics) -> str:
result = ""

result += "Estimated topics count: {}".format(game_statistics["estimated_game_sessions_count"])
result += "\n"
result += "Estimations count: {}".format(game_statistics["game_sessions_count"])

return result


def to_dict(self):
return {
"facilitator": self.facilitator.to_dict(),
}

@classmethod
def from_dict(cls, chat_id: int, facilitator_message_id: int, name: str, facilitator: TelegramUser):
return cls(
chat_id,
facilitator_message_id,
name,
facilitator,
)
Loading

0 comments on commit a3cad52

Please sign in to comment.