Move game_list to mongo

This commit is contained in:
2024-11-17 11:55:29 +01:00
parent d6716ea49b
commit 5f3bb3c1f8
3 changed files with 133 additions and 72 deletions

View File

@@ -87,27 +87,44 @@ async def add(
game: str,
date: str | None = None
):
channel_to_message = await get_game_list_channel_to_message_map()
if interaction.channel is None:
await interaction.response.send_message("Команда не доступна в этом канале (#1)", ephemeral=True)
return
message_id = channel_to_message.get(interaction.channel.id)
if message_id is None:
await interaction.response.send_message("Команда не доступна в этом канале (#3)", ephemeral=True)
return
if not isinstance(interaction.channel, Messageable):
await interaction.response.send_message("Команда не доступна в этом канале (#2)", ephemeral=True)
await interaction.response.send_message(
"Interation not allowed in this channel!", ephemeral=True
)
return
game_list_message = await interaction.channel.fetch_message(message_id)
streamer = await StreamerConfigRepository.find_one(
integration_discord_guild_id=interaction.guild_id,
integration_discord_games_list_channel_id=interaction.channel_id
)
if streamer is None:
await interaction.response.send_message(
"Interation not allowed in this channel!", ephemeral=True
)
return
if streamer.integrations.discord is None or streamer.integrations.discord.games_list is None:
await interaction.response.send_message(
"Need setup!", ephemeral=True
)
return
game_list = await GameList.get(streamer.twitch.id)
if game_list is None:
await interaction.response.send_message(
"Game list not found!", ephemeral=True
)
return
game_list = GameList.parse(game_list_message.content)
game_list.add_game(category, GameItem(name=game, customer=customer, date=date))
game_list_message = await interaction.channel.fetch_message(
streamer.integrations.discord.games_list.message_id
)
await game_list_message.edit(content=str(game_list))
await game_list.save(streamer.twitch.id)
await interaction.response.send_message("Игра добавлена!", ephemeral=True)
@@ -116,18 +133,17 @@ async def game_list_autocomplete(
interaction: discord.Interaction,
current: str,
) -> list[app_commands.Choice[str]]:
if not isinstance(interaction.channel, Messageable):
streamer = await StreamerConfigRepository.find_one(
integration_discord_guild_id=interaction.guild_id,
integration_discord_games_list_channel_id=interaction.channel_id
)
if streamer is None:
return []
channel_to_message = await get_game_list_channel_to_message_map()
message_id = channel_to_message.get(interaction.channel.id)
if message_id is None:
game_list = await GameList.get(streamer.twitch.id)
if game_list is None:
return []
game_list_message = await interaction.channel.fetch_message(message_id)
game_list = GameList.parse(game_list_message.content)
return game_list.get_choices(current)
@@ -135,27 +151,44 @@ async def game_list_autocomplete(
@app_commands.describe(game="Игра")
@app_commands.autocomplete(game=game_list_autocomplete)
async def delete(interaction: discord.Interaction, game: str):
channel_to_message = await get_game_list_channel_to_message_map()
if interaction.channel is None:
await interaction.response.send_message("Команда не доступна в этом канале (#1)", ephemeral=True)
return
message_id = channel_to_message.get(interaction.channel.id)
if message_id is None:
await interaction.response.send_message("Команда не доступна в этом канале (#3)", ephemeral=True)
return
if not isinstance(interaction.channel, Messageable):
await interaction.response.send_message("Команда не доступна в этом канале (#2)", ephemeral=True)
await interaction.response.send_message(
"Interation not allowed in this channel!", ephemeral=True
)
return
game_list_message = await interaction.channel.fetch_message(message_id)
streamer = await StreamerConfigRepository.find_one(
integration_discord_guild_id=interaction.guild_id,
integration_discord_games_list_channel_id=interaction.channel_id
)
if streamer is None:
await interaction.response.send_message(
"Interation not allowed in this channel!", ephemeral=True
)
return
if streamer.integrations.discord is None or streamer.integrations.discord.games_list is None:
await interaction.response.send_message(
"Need setup!", ephemeral=True
)
return
game_list = await GameList.get(streamer.twitch.id)
if game_list is None:
await interaction.response.send_message(
"Game list not found!", ephemeral=True
)
return
game_list = GameList.parse(game_list_message.content)
game_list.delete_game(game)
game_list_message = await interaction.channel.fetch_message(
streamer.integrations.discord.games_list.message_id
)
await game_list_message.edit(content=str(game_list))
await game_list.save(streamer.twitch.id)
await interaction.response.send_message("Игра удалена!", ephemeral=True)

View File

@@ -1,10 +1,11 @@
from typing import Self
from datetime import datetime
import re
from discord import app_commands
from pydantic import BaseModel
from core.mongo import mongo_manager
class GameItem(BaseModel):
name: str
@@ -17,20 +18,6 @@ class GameItem(BaseModel):
else:
return f"* {self.name} ({self.customer})"
@classmethod
def parse(cls, line: str) -> Self:
regex_result_with_date = re.search(r"^\* (.+) \((.+)\) \| (.+)$", line)
if regex_result_with_date is not None:
name, customer, date = regex_result_with_date.groups()
return cls(name=name, customer=customer, date=date)
regex_result_without_date = re.search(r"^\* (.+) \((.+)\)$", line)
if regex_result_without_date is not None:
name, customer = regex_result_without_date.groups()
return cls(name=name, customer=customer, date=None)
raise ValueError(f"Invalid line: {line}")
class Category(BaseModel):
name: str
@@ -38,6 +25,8 @@ class Category(BaseModel):
class GameList:
COLLECTION_NAME = "games_list_data"
CATEGORY_MAP = {
"points": "Заказанные игры (за 12к)",
"paids": "Проплачены 🤑 ",
@@ -48,20 +37,33 @@ class GameList:
self.data = data
@classmethod
def parse(cls, message: str) -> Self:
categories = []
async def get(cls, twitch_id: int) -> Self | None:
async with mongo_manager.connect() as client:
db = client.get_default_database()
collection = db[cls.COLLECTION_NAME]
for line in message.split("\n"):
if line == "".strip():
continue
doc = await collection.find_one({"twitch_id": twitch_id})
if doc is None:
return None
if not line.startswith("*"):
name = line.replace(":", "")
categories.append(Category(name=name, games=[]))
else:
categories[-1].games.append(GameItem.parse(line.strip()))
return cls([
Category(**category)
for category in doc["data"]
])
return cls(data=categories)
async def save(self, twitch_id: int):
async with mongo_manager.connect() as client:
db = client.get_default_database()
collection = db[self.COLLECTION_NAME]
await collection.replace_one(
{"twitch_id": twitch_id},
{
"twitch_id": twitch_id,
"data": [category.model_dump() for category in self.data]
},
upsert=True
)
def add_game(self, category: str, game_item: GameItem):
_category = self.CATEGORY_MAP.get(category)
@@ -79,6 +81,16 @@ class GameList:
if game.name.startswith(game_name):
category.games.remove(game)
def get_choices(self, query: str) -> list[app_commands.Choice[str]]:
choices = []
for category in self.data:
for game in category.games:
if query.lower() in game.name.lower():
choices.append(app_commands.Choice(name=game.name, value=game.name))
return choices[:25]
def __str__(self) -> str:
result = ""
@@ -91,13 +103,3 @@ class GameList:
result += "\n\n"
return result
def get_choices(self, query: str) -> list[app_commands.Choice[str]]:
choices = []
for category in self.data:
for game in category.games:
if query.lower() in game.name.lower():
choices.append(app_commands.Choice(name=game.name, value=game.name))
return choices[:25]

View File

@@ -18,6 +18,32 @@ class StreamerConfigRepository:
return StreamerConfig(**doc)
@classmethod
async def find_one(
cls,
integration_discord_guild_id: int | None = None,
integration_discord_games_list_channel_id: int | None = None,
) -> StreamerConfig | None:
filters = {}
if integration_discord_guild_id is not None:
filters["integrations.discord.guild_id"] = integration_discord_guild_id
if integration_discord_games_list_channel_id is not None:
filters[
"integrations.discord.games_list.channel_id"
] = integration_discord_games_list_channel_id
async with mongo_manager.connect() as client:
db = client.get_default_database()
collection = db[cls.COLLECTION_NAME]
doc = await collection.find_one(filters)
if doc is None:
return None
return StreamerConfig(**doc)
@classmethod
async def all(cls) -> list[StreamerConfig]:
async with mongo_manager.connect() as client: