From 708ffc790365f7ce9681020118b5f3dbc88e2ffc Mon Sep 17 00:00:00 2001 From: KEriks Date: Fri, 27 Aug 2021 00:12:09 +0300 Subject: [PATCH] DB Migration bugfix - OnTheFly --- Dockerfile | 3 ++- dbot/bot_commands.py | 14 ++++++++++---- dbot/db.py | 26 +++++++++++++++++++++----- docker_run.sh | 2 +- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index e94ff0d..aad969f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,5 +11,6 @@ RUN groupadd -g 1000 discordbot \ USER discordbot COPY requirements.txt /app/requirements.txt RUN pip install -r requirements.txt +ENV PYTHONPATH=$PYTHONPATH:/app/dbot #CMD python discord_bot.py -ENTRYPOINT ["/usr/local/bin/python", "/app/discord_bot.py"] +ENTRYPOINT ["/usr/local/bin/python", "/app/dbot/discord_bot.py"] diff --git a/dbot/bot_commands.py b/dbot/bot_commands.py index 3982db6..e4b6cab 100644 --- a/dbot/bot_commands.py +++ b/dbot/bot_commands.py @@ -12,6 +12,11 @@ __all__ = ["bot"] bot = commands.Bot(command_prefix="!") +def _process_member(member): + if not DB.get_member(member.id): + DB.add_member(member.id, str(member)) + + async def control_register(ctx, *args): if " ".join(args) == "From AF With Love!": DB.update_member(ctx.author.id, str(ctx.author), True) @@ -68,8 +73,9 @@ async def on_ready(): @bot.command() -async def empty(ctx, division, minutes: int = 60): - if not ctx.channel.id == 603527159109124096 or not DB.get_member(ctx.message.author.id).get("pm_is_allowed"): +async def empty(ctx, division, minutes: int = 0): + _process_member(ctx.message.author) + if not (ctx.channel.id == 603527159109124096 or DB.get_member(ctx.message.author.id).get("pm_is_allowed")): return await ctx.send("Currently unavailable!") try: div = int(division) @@ -107,8 +113,7 @@ async def division_error(ctx, error): @bot.command() async def control(ctx: commands.Context, command: str, *args): - if not DB.get_member(ctx.author.id): - DB.add_member(ctx.author.id, str(ctx.author)) + _process_member(ctx.message.author) if command == "register": return await control_register(ctx, *args) if command in ["notify", "unnotify"]: @@ -173,3 +178,4 @@ async def control(ctx: commands.Context, command: str, *args): async def control_error(ctx, error): logger.exception(error, exc_info=error) return await ctx.send(MESSAGES["command_failed"]) + diff --git a/dbot/db.py b/dbot/db.py index b82b708..62a7ea1 100644 --- a/dbot/db.py +++ b/dbot/db.py @@ -1,3 +1,4 @@ +import logging from typing import Dict, List, Optional, Union from sqlite_utils import Database @@ -25,13 +26,28 @@ class DiscordDB: db_tables = self._db.table_names() if "member" not in db_tables: self._db.create_table("member", {"name": str, "pm_is_allowed": bool}, pk="id", not_null={"name", "pm_is_allowed"}, defaults={"pm_is_allowed": False}) + else: + self._db.create_table("member_tmp", {"name": str, "pm_is_allowed": bool}, pk="id", not_null={"name", "pm_is_allowed"}, defaults={"pm_is_allowed": False}) + for row in self._db.table("member").rows: + self._db["member_tmp"].insert(row) + logging.info(f"Moving row {row} to tmp member table") + self._db["member"].drop(True) + self._db.create_table("member", {"name": str, "pm_is_allowed": bool}, pk="id", not_null={"name", "pm_is_allowed"}, defaults={"pm_is_allowed": False}) + for row in self._db.table("member_tmp").rows: + self._db["member"].insert(row) + logging.info(f"Moving row {row} from tmp member table") + self._db["member_tmp"].drop(True) + if "player" not in db_tables: self._db.create_table("player", {"name": str}, pk="id", not_null={"name"}) if "notification_channel" in db_tables or "channel" not in db_tables: - self._db.create_table("channel", {"guild_id": int, "channel_id": int, "kind": str}, pk="id", not_null={"guild_id", "channel_id", "kind"}, defaults={"kind": "epic"}) - self._db["channel"].create_index(("guild_id", "channel_id", "kind"), unique=True) + try: + self._db.create_table("channel", {"guild_id": int, "channel_id": int, "kind": str}, pk="id", not_null={"guild_id", "channel_id", "kind"}, defaults={"kind": "epic"}) + self._db["channel"].create_index(("guild_id", "channel_id", "kind"), unique=True) + except: + pass for row in self._db.table("notification_channel").rows: - self._db["channel"].insert(**row) + self._db["channel"].insert(row) if "role_mapping" not in db_tables: self._db.create_table("role_mapping", {"channel_id": int, "division": int, "role_id": int}, pk="id", not_null={"channel_id", "division", "role_id"}) self._db["role_mapping"].add_foreign_key("channel_id", "channel", "id") @@ -87,7 +103,7 @@ class DiscordDB: # Member methods - def get_member(self, member_id) -> Optional[Dict[str, Union[int, str]]]: + def get_member(self, member_id) -> Dict[str, Union[int, str]]: """Get discord member :param member_id: int Discord Member ID @@ -98,7 +114,7 @@ class DiscordDB: try: return self.member.get(member_id) except NotFoundError: - return + return {} def add_member(self, id: int, name: str, pm_is_allowed: bool = False) -> Dict[str, Union[int, str]]: """Add discord member. diff --git a/docker_run.sh b/docker_run.sh index d1c3124..680588c 100755 --- a/docker_run.sh +++ b/docker_run.sh @@ -2,5 +2,5 @@ docker rm -f discord_bot set -e docker build --tag discord_epicbot . -docker run --detach -v $PWD/dbot:/app -v $PWD/debug:/app/debug --env-file=".env" --env PRODUCTION=1 --restart=always --name discord_bot discord_epicbot +docker run --detach -v $PWD/dbot:/app/dbot -v $PWD/debug:/app/debug --env-file=".env" --env PRODUCTION=1 --restart=always --name discord_bot discord_epicbot