Compare commits

...
53 Commits
Author SHA1 Message Date
renovate-bot 9e905fb4b2 Update python Docker tag to v3.13.6 2025-08-10 04:00:46 +00:00
imcompiling db2657a5b3 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.8.3' (#105) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 59s
Reviewed-on: #105
Reviewed-by: imcompiling <[email protected]>
2025-07-28 09:03:36 -04:00
renovate-bot ff2c233381 Update ghcr.io/astral-sh/uv Docker tag to v0.8.3 2025-07-27 04:00:33 +00:00
imcompiling ab9176b10d Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.8.0' (#104) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 1m8s
Reviewed-on: #104
Reviewed-by: imcompiling <[email protected]>
2025-07-21 09:15:11 -04:00
renovate-bot 7c77603711 Update ghcr.io/astral-sh/uv Docker tag to v0.8.0 2025-07-20 04:00:40 +00:00
imcompiling 5cc41b8e8c Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.7.20' (#103) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 59s
Reviewed-on: #103
Reviewed-by: imcompiling <[email protected]>
2025-07-15 09:03:32 -04:00
renovate-bot d470ca3a8f Update ghcr.io/astral-sh/uv Docker tag to v0.7.20 2025-07-13 04:00:39 +00:00
imcompiling f2d55f435d Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.7.12' (#102) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 57s
Reviewed-on: #102
Reviewed-by: imcompiling <[email protected]>
2025-06-09 09:09:31 -04:00
renovate-bot ea63c5ea88 Update ghcr.io/astral-sh/uv Docker tag to v0.7.12 2025-06-08 04:01:08 +00:00
imcompiling b01616f744 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.7.9' (#101) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 57s
Reviewed-on: #101
Reviewed-by: imcompiling <[email protected]>
2025-06-02 09:28:57 -04:00
renovate-bot 811ec5c7ee Update ghcr.io/astral-sh/uv Docker tag to v0.7.9 2025-06-01 04:01:08 +00:00
imcompiling 1950bcdc16 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.7.8' (#100) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 1m5s
Reviewed-on: #100
Reviewed-by: imcompiling <[email protected]>
2025-05-28 08:29:50 -04:00
renovate-bot 972ecef2be Update ghcr.io/astral-sh/uv Docker tag to v0.7.8 2025-05-25 04:01:09 +00:00
imcompiling 540efc8819 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.7.5' (#99) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 1m2s
Reviewed-on: #99
Reviewed-by: imcompiling <[email protected]>
2025-05-21 11:20:30 -04:00
renovate-bot 7d02608a14 Update ghcr.io/astral-sh/uv Docker tag to v0.7.5 2025-05-18 04:01:11 +00:00
imcompiling 7861e498c5 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.7.3' (#98) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 57s
Reviewed-on: #98
Reviewed-by: imcompiling <[email protected]>
2025-05-12 09:53:13 -04:00
renovate-bot dd28de3cac Update ghcr.io/astral-sh/uv Docker tag to v0.7.3 2025-05-11 04:01:21 +00:00
imcompiling cf872c071b Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.6.17' (#97) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 56s
Reviewed-on: #97
Reviewed-by: imcompiling <[email protected]>
2025-04-28 12:13:06 -04:00
renovate-bot 6c6b5cac25 Update ghcr.io/astral-sh/uv Docker tag to v0.6.17 2025-04-27 04:01:07 +00:00
imcompiling 50ce8fbfa3 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.6.14' (#95) from renovate/ghcr.io-astral-sh-uv-0.x into main
Reviewed-on: #95
2025-04-13 10:32:24 -04:00
renovate-bot d0ef8e723f Update ghcr.io/astral-sh/uv Docker tag to v0.6.14 2025-04-13 14:13:11 +00:00
imcompiling c434154d84 Merge branch '90-00-in-score'
build_latest / build (push) Successful in 32s
build_release / build (push) Successful in 17s
2025-04-11 09:10:28 -04:00
imcompiling bc038c8d74 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.6.12' (#94) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 57s
Reviewed-on: #94
Reviewed-by: imcompiling <[email protected]>
2025-04-06 11:58:45 -04:00
renovate-bot 7528552280 Update ghcr.io/astral-sh/uv Docker tag to v0.6.12 2025-04-06 04:01:34 +00:00
imcompiling b71669630a Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.6.10' (#93) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Successful in 54s
Reviewed-on: #93
Reviewed-by: imcompiling <[email protected]>
2025-03-30 12:47:06 -04:00
renovate-bot 52eb92d527 Update ghcr.io/astral-sh/uv Docker tag to v0.6.10 2025-03-30 04:01:32 +00:00
imcompiling 46bce400af Merge pull request 'Update actions/checkout action to v4' (#92) from renovate/actions-checkout-4.x into main
build_latest / build (push) Successful in 47s
build_release / build (push) Successful in 19s
Reviewed-on: #92
Reviewed-by: imcompiling <[email protected]>
2025-03-23 23:38:13 -04:00
imcompiling b681d7a923 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.6.9' (#91) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_latest / build (push) Has been cancelled
Reviewed-on: #91
Reviewed-by: imcompiling <[email protected]>
2025-03-23 23:37:49 -04:00
renovate-bot ec086448ea Update actions/checkout action to v4 2025-03-23 04:01:09 +00:00
renovate-bot 476b0e89ef Update ghcr.io/astral-sh/uv Docker tag to v0.6.9 2025-03-23 04:01:04 +00:00
imcompiling c1b327ca05 Change regex to strip a 10th place 0 only.
build_develop / build (push) Successful in 36s
2025-03-21 13:56:28 -04:00
imcompiling fa39949b1a Merge branch 'main' of https://gitea.cheezers.org/imcompiling/agon
build_latest / build (push) Successful in 37s
2025-03-21 10:45:04 -04:00
imcompiling f1290af45b Remove a double respond. 2025-03-21 10:44:57 -04:00
imcompiling 10954ef117 Merge branch '82-group-message-after-deletion'
build_latest / build (push) Successful in 36s
build_release / build (push) Successful in 18s
2025-03-20 11:04:26 -04:00
imcompiling 0540f7a9eb Add thread as an option everywhere a textchannel is used.
build_develop / build (push) Successful in 35s
2025-03-20 11:04:00 -04:00
imcompiling a4aab09360 Use or instead of two isinstance calls. 2025-03-20 10:56:59 -04:00
imcompiling af7518c1a2 Delete old group message when changing output channel.
build_develop / build (push) Successful in 29s
2025-03-20 10:55:48 -04:00
imcompiling 5be029fb57 Catch when the message has been deleted without entry deletion in my database. 2025-03-20 10:42:24 -04:00
imcompiling d82999b141 Check for channel being None. Allow groups to be posted in threads. 2025-03-20 09:50:31 -04:00
imcompiling 1ffb7fa9a7 Correct database ignore.
build_develop / build (push) Successful in 18s
build_latest / build (push) Successful in 18s
build_release / build (push) Successful in 19s
2025-03-19 09:51:38 -04:00
imcompiling 2566bee0ce Use home dir.
build_develop / build (push) Successful in 36s
2025-03-19 09:37:32 -04:00
imcompiling 3d113a06d4 Update workflows.
build_develop / build (push) Successful in 35s
2025-03-19 09:35:21 -04:00
imcompiling 2e3b8c86da Add more to dockerignore. 2025-03-19 09:30:44 -04:00
imcompiling 058e3aefa1 Update how agon is run. 2025-03-19 09:28:30 -04:00
imcompiling 7a4ba3a5af Update all imports with new file structure. 2025-03-19 09:22:29 -04:00
imcompiling 2f5f25ea75 Remove unneede file. 2025-03-19 09:17:43 -04:00
imcompiling fd476ce512 Move files from utilities to top level of module. 2025-03-19 09:17:07 -04:00
imcompiling 9588cdc8a0 Rename main.py to app.py, add init and main dunder files. 2025-03-19 09:11:02 -04:00
imcompiling 17769022bc Move all files into agon module. 2025-03-19 09:07:39 -04:00
imcompiling a46dc0388c Delete sql file. it is unneeded now. 2025-03-19 09:07:14 -04:00
imcompiling 553f79425f Delete database/pyproject.toml
build_develop / build (push) Successful in 36s
2025-03-19 08:49:17 -04:00
imcompiling 72cd6e9fd1 Merge pull request 'Update ghcr.io/astral-sh/uv Docker tag to v0.6.6' (#87) from renovate/ghcr.io-astral-sh-uv-0.x into main
build_develop / build (push) Successful in 56s
Reviewed-on: #87
Reviewed-by: imcompiling <[email protected]>
2025-03-16 11:09:44 -04:00
renovate-bot f63984e25a Update ghcr.io/astral-sh/uv Docker tag to v0.6.6 2025-03-16 04:01:28 +00:00
40 changed files with 157 additions and 210 deletions
+3
View File
@@ -1,2 +1,5 @@
.* .*
Dockerfile Dockerfile
LICENSE
README.md
renovate.json
+9 -3
View File
@@ -2,7 +2,11 @@ name: build_develop
on: on:
push: push:
branches: [main] branches:
- "*"
- "!main"
paths-ignore:
- "README.md"
jobs: jobs:
build: build:
@@ -20,7 +24,9 @@ jobs:
registry: gitea.cheezers.org registry: gitea.cheezers.org
username: imcompiling username: imcompiling
password: ${{ secrets.PASSWORD }} password: ${{ secrets.PASSWORD }}
- name: set env
run: echo "GIT_BRANCH=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_ENV
- name: Build Docker Image - name: Build Docker Image
run: docker build -t gitea.cheezers.org/imcompiling/agon:develop . run: docker build -t gitea.cheezers.org/imcompiling/agon:${{env.GIT_BRANCH}} .
- name: Push Docker Image - name: Push Docker Image
run: docker push gitea.cheezers.org/imcompiling/agon:develop run: docker push gitea.cheezers.org/imcompiling/agon:${{env.GIT_BRANCH}}
+28
View File
@@ -0,0 +1,28 @@
name: build_latest
on:
push:
branches: [main]
paths-ignore:
- "README.md"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Docker
uses: https://github.com/papodaca/install-docker-action@v1
- name: Log into container registry
uses: docker/login-action@v3
with:
registry: gitea.cheezers.org
username: imcompiling
password: ${{ secrets.PASSWORD }}
- name: Build Docker Image
run: docker build -t gitea.cheezers.org/imcompiling/agon:latest .
- name: Push Docker Image
run: docker push gitea.cheezers.org/imcompiling/agon:latest
+1 -3
View File
@@ -23,8 +23,6 @@ jobs:
- name: Set env - name: Set env
run: echo "GIT_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV run: echo "GIT_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Build Docker Images - name: Build Docker Images
run: docker build -t gitea.cheezers.org/imcompiling/agon:latest -t gitea.cheezers.org/imcompiling/agon:${{env.GIT_TAG}} . run: docker build -t gitea.cheezers.org/imcompiling/agon:${{env.GIT_TAG}} .
- name: Push Latest Image
run: docker push gitea.cheezers.org/imcompiling/agon:latest
- name: Push Tagged Image - name: Push Tagged Image
run: docker push gitea.cheezers.org/imcompiling/agon:${{env.GIT_TAG}} run: docker push gitea.cheezers.org/imcompiling/agon:${{env.GIT_TAG}}
+1 -1
View File
@@ -135,4 +135,4 @@ deleted_backups/
highscores_data/ highscores_data/
TODO.txt TODO.txt
sql_tester.py sql_tester.py
database.db /database
+2 -2
View File
@@ -8,8 +8,8 @@
"name": "Python: Module", "name": "Python: Module",
"type": "debugpy", "type": "debugpy",
"request": "launch", "request": "launch",
"module": "main", "module": "agon",
"justMyCode": true "justMyCode": true
} }
] ]
} }
+5 -5
View File
@@ -1,15 +1,15 @@
FROM python:3.12.3-slim FROM python:3.13.6-slim
# install uv # install uv
COPY --from=ghcr.io/astral-sh/uv:0.6.5 /uv /uvx /bin/ COPY --from=ghcr.io/astral-sh/uv:0.8.3 /uv /uvx /bin/
RUN apt-get update && apt-get -y upgrade && apt-get -y install sqlite3 RUN apt-get update && apt-get -y upgrade && apt-get -y install sqlite3
# Copy project to image # Copy project to image
ADD . /agon ADD . /home
# Sync the project into a new environment, using the frozen lockfile # Sync the project into a new environment, using the frozen lockfile
WORKDIR /agon WORKDIR /home
RUN uv sync --frozen --no-dev RUN uv sync --frozen --no-dev
CMD ["uv", "run", "./main.py"] CMD ["uv", "run", "--frozen", "--no-dev", "-m", "agon"]
+1
View File
@@ -0,0 +1 @@
"""Empty init file for off_cooldown_bot module."""
+14
View File
@@ -0,0 +1,14 @@
"""Starts the app for agon."""
import logging
from .app import run
nextcord_logger = logging.getLogger("nextcord")
nextcord_logger.setLevel(logging.DEBUG)
nextcord_handler = logging.FileHandler(filename="nextcord.log", encoding="utf-8", mode="w")
nextcord_handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s"))
nextcord_logger.addHandler(nextcord_handler)
if __name__ == "__main__":
run()
+6 -17
View File
@@ -1,23 +1,16 @@
"""Main file for Agon bot.""" """Main file for Agon bot."""
import logging import pathlib
import os
import sys import sys
import nextcord import nextcord
from nextcord.ext import commands from nextcord.ext import commands
from utilities import config from . import config
from utilities.logger import agon_logger from .logger import agon_logger
nextcord_logger = logging.getLogger("nextcord")
nextcord_logger.setLevel(logging.DEBUG)
nextcord_handler = logging.FileHandler(filename="nextcord.log", encoding="utf-8", mode="w")
nextcord_handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s"))
nextcord_logger.addHandler(nextcord_handler)
def main() -> None: def run() -> None:
"""Main function for bot.""" """Main function for bot."""
min_python_version = (3, 12) min_python_version = (3, 12)
if sys.version_info < min_python_version: if sys.version_info < min_python_version:
@@ -34,8 +27,8 @@ def main() -> None:
) )
# Get the modules of all cogs whose directory structure is ./cogs/<module_name> # Get the modules of all cogs whose directory structure is ./cogs/<module_name>
for folder in os.listdir("cogs"): for folder in pathlib.Path("./agon/cogs").iterdir():
bot.load_extension(f"cogs.{folder}") bot.load_extension(f"agon.cogs.{folder.name}")
@bot.listen() @bot.listen()
async def on_ready() -> None: async def on_ready() -> None:
@@ -47,7 +40,3 @@ def main() -> None:
# Run Discord bot # Run Discord bot
bot.run(config.DISCORD_TOKEN) bot.run(config.DISCORD_TOKEN)
if __name__ == "__main__":
main()
@@ -2,15 +2,15 @@
from nextcord.ext import commands from nextcord.ext import commands
from cogs.commands.create import CreateCog from agon.cogs.commands.create import CreateCog
from cogs.commands.delete import DeleteCog from agon.cogs.commands.delete import DeleteCog
from cogs.commands.get import GetCog from agon.cogs.commands.get import GetCog
from cogs.commands.help import HelpCog from agon.cogs.commands.help import HelpCog
from cogs.commands.refresh import RefreshCog from agon.cogs.commands.refresh import RefreshCog
from cogs.commands.set import SetCog from agon.cogs.commands.set import SetCog
from cogs.commands.submission import SubmissionCog from agon.cogs.commands.submission import SubmissionCog
from cogs.commands.update import UpdateCog from agon.cogs.commands.update import UpdateCog
from cogs.commands.view import ViewCog from agon.cogs.commands.view import ViewCog
# This function will be called when this extension is loaded. # This function will be called when this extension is loaded.
@@ -6,9 +6,9 @@ from sqlalchemy import exc, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup from agon.database.models import Category, CategoryGroup
from utilities.utils import MAX_LINE_LENGTH, autofill_groups, send_highscore_message from agon.utils import MAX_LINE_LENGTH, autofill_groups, send_highscore_message
class CreateCog(commands.Cog, name="Create Cog"): class CreateCog(commands.Cog, name="Create Cog"):
@@ -99,7 +99,7 @@ class CreateCog(commands.Cog, name="Create Cog"):
min_value=1, min_value=1,
max_value=30, max_value=30,
), ),
channel: nextcord.TextChannel | None = nextcord.SlashOption( channel: nextcord.TextChannel | nextcord.Thread | None = nextcord.SlashOption(
description="Channel to post Group in. If left empty, defaults to current channel.", description="Channel to post Group in. If left empty, defaults to current channel.",
required=False, required=False,
default=None, default=None,
@@ -6,9 +6,9 @@ from sqlalchemy import distinct, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup, Score from agon.database.models import Category, CategoryGroup, Score
from utilities.utils import ( from agon.utils import (
autofill_categories, autofill_categories,
autofill_groups, autofill_groups,
autofill_users_in_group_category, autofill_users_in_group_category,
@@ -37,7 +37,7 @@ class DeleteCog(commands.Cog, name="Delete Cog"):
async def channel_messages( async def channel_messages(
self, self,
interaction: nextcord.Interaction, interaction: nextcord.Interaction,
channel: nextcord.TextChannel | None = nextcord.SlashOption( channel: nextcord.TextChannel | nextcord.Thread | None = nextcord.SlashOption(
description="Channel to clear of messages.", description="Channel to clear of messages.",
required=False, required=False,
default=None, default=None,
@@ -54,7 +54,7 @@ class DeleteCog(commands.Cog, name="Delete Cog"):
Is a SlashOption. Limited to text channels. Defaults to None. Is a SlashOption. Limited to text channels. Defaults to None.
""" """
if not channel: if not channel:
if isinstance(interaction.channel, nextcord.TextChannel): if isinstance(interaction.channel, nextcord.TextChannel | nextcord.Thread):
channel = interaction.channel channel = interaction.channel
else: else:
# This should never happen. # This should never happen.
@@ -4,9 +4,9 @@ import nextcord
from nextcord.ext import commands from nextcord.ext import commands
from sqlmodel import Session, col, select from sqlmodel import Session, col, select
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup from agon.database.models import Category, CategoryGroup
from utilities.utils import autofill_categories, autofill_groups from agon.utils import autofill_categories, autofill_groups
class GetCog(commands.Cog, name="Get command."): class GetCog(commands.Cog, name="Get command."):
@@ -6,9 +6,9 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import CategoryGroup from agon.database.models import CategoryGroup
from utilities.utils import autofill_groups, send_highscore_message from agon.utils import autofill_groups, send_highscore_message
class RefreshCog(commands.Cog, name="Refresh Cog"): class RefreshCog(commands.Cog, name="Refresh Cog"):
@@ -6,10 +6,10 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup, Guild from agon.database.models import Category, CategoryGroup, Guild
from utilities.logger import agon_logger from agon.logger import agon_logger
from utilities.utils import MAX_LINE_LENGTH, autofill_categories, autofill_groups, send_highscore_message from agon.utils import MAX_LINE_LENGTH, autofill_categories, autofill_groups, send_highscore_message
class SetCog(commands.Cog, name="Set command."): class SetCog(commands.Cog, name="Set command."):
@@ -251,6 +251,10 @@ class SetCog(commands.Cog, name="Set command."):
channel (nextcord.abc.GuildChannel, optional): Channel to register. channel (nextcord.abc.GuildChannel, optional): Channel to register.
Is a SlashOption. Limited to text channels, Defaults to None. Is a SlashOption. Limited to text channels, Defaults to None.
""" """
if interaction.guild is None or interaction.channel is None:
agon_logger.warning("Set command was called with an interaction that had no guild or channel.")
return
channel_id = interaction.channel.id if not channel else channel.id channel_id = interaction.channel.id if not channel else channel.id
with Session(engine) as session: with Session(engine) as session:
@@ -262,11 +266,14 @@ class SetCog(commands.Cog, name="Set command."):
if (group := session.scalar(stmt)) is None: if (group := session.scalar(stmt)) is None:
await interaction.response.send_message("Group or Category was not found.", ephemeral=True) await interaction.response.send_message("Group or Category was not found.", ephemeral=True)
return return
old_channel_id = group.channel_id
group.channel_id = channel_id group.channel_id = channel_id
session.commit() session.commit()
# TODO(imcompiling): delete the message and call send_highscore_message to send a new one. Bug needs fixed
# first. old_channel = interaction.guild.get_channel(old_channel_id)
# 082 if old_channel and isinstance(old_channel, nextcord.TextChannel | nextcord.Thread) and group.message_id:
await old_channel.get_partial_message(group.message_id).delete()
await interaction.send(f"Registered <#{channel_id}>.", ephemeral=True) await interaction.send(f"Registered <#{channel_id}>.", ephemeral=True)
@group.subcommand( @group.subcommand(
@@ -8,11 +8,11 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from cogs.submission.verification_view import VerificationView from agon.cogs.submission.verification_view import VerificationView
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup, Guild, Submission from agon.database.models import Category, CategoryGroup, Guild, Submission
from main import agon_logger from agon.logger import agon_logger
from utilities.utils import autofill_categories, autofill_groups, submit_score from agon.utils import autofill_categories, autofill_groups, submit_score
class SubmissionCog(commands.Cog): class SubmissionCog(commands.Cog):
@@ -80,9 +80,7 @@ class SubmissionCog(commands.Cog):
if ( if (
verified_score := await self.verify_score(interaction, score, is_time_record=category.is_time_record) verified_score := await self.verify_score(interaction, score, is_time_record=category.is_time_record)
) is None: ) is None:
# This response message will be filled out better once command is split up to # Verify score handles responding. Might change when submit is split up.
# know which type it expects...
await interaction.response.send_message("Format was incorrect.", ephemeral=True)
return return
# Create submission verification request or submit score if verification not needed. # Create submission verification request or submit score if verification not needed.
@@ -103,7 +101,7 @@ class SubmissionCog(commands.Cog):
await interaction.response.send_message(error_response, ephemeral=True) await interaction.response.send_message(error_response, ephemeral=True)
return return
if not isinstance(channel, nextcord.TextChannel): if not isinstance(channel, nextcord.TextChannel | nextcord.Thread):
await interaction.response.send_message("An error happened with submission.") await interaction.response.send_message("An error happened with submission.")
agon_logger.error( agon_logger.error(
"Channel id %s in guild %s is does not correspond to a TextChannel.", channel.id, channel.guild.id "Channel id %s in guild %s is does not correspond to a TextChannel.", channel.id, channel.guild.id
@@ -210,9 +208,9 @@ class SubmissionCog(commands.Cog):
elif re.search("^[0-9](\\.[0-9])?$", score): elif re.search("^[0-9](\\.[0-9])?$", score):
# need to add 0 in seconds and leading colon and 0 # need to add 0 in seconds and leading colon and 0
score = "0:0" + score score = "0:0" + score
elif re.search("^[0]?[0-9]:[0-9]{2}(\\.[0-9])?$", score): elif re.search("^[0][0-9]:[0-9]{2}(\\.[0-9])?$", score):
# if there is a minute 10ths place 0, remove # if there is a minute 10ths place 0, remove
score = score.lstrip("0") score = score[1:]
return score return score
@@ -6,9 +6,9 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Guild from agon.database.models import Guild
from utilities.utils import autofill_users_in_guild from agon.utils import autofill_users_in_guild
from .views.update_username_verify import UpdateUsernameVerifyView from .views.update_username_verify import UpdateUsernameVerifyView
@@ -7,9 +7,9 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup, Score from agon.database.models import Category, CategoryGroup, Score
from utilities.utils import MAX_LINE_LENGTH, autofill_categories, autofill_groups, format_score_string from agon.utils import MAX_LINE_LENGTH, autofill_categories, autofill_groups, format_score_string
class ViewCog(commands.Cog, name="View Command"): class ViewCog(commands.Cog, name="View Command"):
@@ -4,9 +4,9 @@ import nextcord
from sqlalchemy import delete, select from sqlalchemy import delete, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup from agon.database.models import Category, CategoryGroup
from utilities.utils import send_highscore_message from agon.utils import send_highscore_message
class DeleteConfirmView(nextcord.ui.Modal): class DeleteConfirmView(nextcord.ui.Modal):
@@ -43,7 +43,7 @@ class DeleteConfirmView(nextcord.ui.Modal):
session.delete(group) session.delete(group)
# delete the message related to group # delete the message related to group
channel = interaction.guild.get_channel(group.channel_id) channel = interaction.guild.get_channel(group.channel_id)
if not isinstance(channel, nextcord.TextChannel): if not isinstance(channel, nextcord.TextChannel | nextcord.Thread):
return return
message: nextcord.Message = await channel.fetch_message(group.message_id) message: nextcord.Message = await channel.fetch_message(group.message_id)
await message.delete() await message.delete()
@@ -5,9 +5,9 @@ from sqlalchemy import distinct, exc, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup, Score from agon.database.models import Category, CategoryGroup, Score
from utilities.utils import send_highscore_message from agon.utils import send_highscore_message
class UpdateUsernameVerifyView(nextcord.ui.View): class UpdateUsernameVerifyView(nextcord.ui.View):
@@ -6,8 +6,8 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Guild from agon.database.models import Guild
class GuildListener(commands.Cog, name="Guild Listener"): class GuildListener(commands.Cog, name="Guild Listener"):
@@ -5,8 +5,8 @@ from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Guild from agon.database.models import Guild
class GuildData(commands.Cog, name="Guild Data"): class GuildData(commands.Cog, name="Guild Data"):
@@ -5,9 +5,9 @@ from sqlalchemy import delete, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Submission from agon.database.models import Submission
from utilities.utils import submit_score from agon.utils import submit_score
class VerificationView(nextcord.ui.View): class VerificationView(nextcord.ui.View):
+4 -3
View File
@@ -1,8 +1,9 @@
"""Simple file to set up the sqlmodel connection to database.""" """Simple file to set up the sqlmodel connection to database."""
from sqlmodel import SQLModel, create_engine from sqlmodel import SQLModel, create_engine
from utilities import config
from utilities.logger import agon_logger from agon import config
from agon.logger import agon_logger
from . import models # noqa: F401 - Need this import for creating the models. from . import models # noqa: F401 - Need this import for creating the models.
@@ -10,7 +11,7 @@ if config.ENVIRONMENT == "prod":
url = f"mysql+pymysql://{config.SQL_USER}:{config.SQL_PASS}@{config.SQL_HOST}/{config.SQL_DB}" url = f"mysql+pymysql://{config.SQL_USER}:{config.SQL_PASS}@{config.SQL_HOST}/{config.SQL_DB}"
agon_logger.info("Connected to prod database.") agon_logger.info("Connected to prod database.")
else: else:
url = "sqlite:///database.db" url = "sqlite:///database/database.db"
agon_logger.info("Connected to local dev database.") agon_logger.info("Connected to local dev database.")
engine = create_engine(url) engine = create_engine(url)
+16 -10
View File
@@ -8,9 +8,9 @@ from sqlalchemy import distinct, select
from sqlalchemy.orm import Session, aliased from sqlalchemy.orm import Session, aliased
from sqlmodel import col from sqlmodel import col
from database.db import engine from agon.database.db import engine
from database.models import Category, CategoryGroup, Guild, Score from agon.database.models import Category, CategoryGroup, Guild, Score
from main import agon_logger from agon.logger import agon_logger
MAX_LINE_LENGTH = 142 MAX_LINE_LENGTH = 142
@@ -342,11 +342,13 @@ async def send_highscore_message(session: Session, guild: nextcord.Guild, group:
group (CategoryGroup): group to post to the message. group (CategoryGroup): group to post to the message.
""" """
highscore_string = format_highscore_message(session, group) highscore_string = format_highscore_message(session, group)
channel = guild.get_channel(group.channel_id) if (channel := guild.get_channel(group.channel_id)) is None:
agon_logger.error("Channel id %s in guild %s does not exist.", group.channel_id, guild.id)
return
if not isinstance(channel, nextcord.TextChannel): if not isinstance(channel, nextcord.TextChannel | nextcord.Thread):
agon_logger.error( agon_logger.error(
"Channel id %s in guild %s is does not correspond to a TextChannel.", channel.id, channel.guild.id "Channel id %s in guild %s is does not correspond to a TextChannel or Thread.", channel.id, channel.guild.id
) )
return return
@@ -356,10 +358,14 @@ async def send_highscore_message(session: Session, guild: nextcord.Guild, group:
group.message_id = message.id group.message_id = message.id
session.commit() session.commit()
else: else:
# TODO(imcompiling): check what happens when message is deleted. try:
# https://gitea.cheezers.org/imcompiling/agon/issues/83 message: nextcord.Message = await channel.fetch_message(group.message_id)
message: nextcord.Message = await channel.fetch_message(group.message_id) await message.edit(content=highscore_string)
await message.edit(content=highscore_string) except nextcord.NotFound:
# Message was deleted on discord's side.
message: nextcord.Message = await channel.send(highscore_string)
group.message_id = message.id
session.commit()
return return
-40
View File
@@ -1,40 +0,0 @@
import os
from dotenv import load_dotenv
from sqlmodel import Session, SQLModel, create_engine, select
from models import CategoryGroup, Guild
load_dotenv()
SQL_DB = os.getenv("SQL_DB", "")
SQL_HOST = os.getenv("SQL_HOST", "")
SQL_PASS = os.getenv("SQL_PASS", "")
SQL_USER = os.getenv("SQL_USER", "")
url = "sqlite:///database.db"
# url = f"mysql+pymysql://{SQL_USER}:{SQL_PASS}@{SQL_HOST}/{SQL_DB}"
engine = create_engine(url)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
guild = Guild(id=1, name="test guild")
session.add(guild)
group1 = CategoryGroup(name="group1", channel_id=1, guild_id=1, message_id=1)
group2 = CategoryGroup(name="group2", channel_id=2, guild_id=1, message_id=2)
session.add(group1)
session.add(group2)
session.commit()
# anotherone = Guild(id=2, name="test guild 2", submission_channel=1, verification_channel=2)
# session.add(anotherone)
# group1 = CategoryGroup(name="group1", channel_id=1, guild_id=2, message_id=1)
# group2 = CategoryGroup(name="group2", channel_id=2, guild_id=2, message_id=2)
# session.add(group1)
# session.add(group2)
# session.commit()
stmt = select(Guild).where(Guild.name == "Dakiny")
guild = session.scalar(stmt)
print(guild.category_groups)
-7
View File
@@ -1,7 +0,0 @@
[tool.ruff]
# Extend the `pyproject.toml` file in the parent directory...
extend = "../pyproject.toml"
[tool.ruff.lint]
# ignore implicit-namespace-package in this directory.
ignore = ["INP001"]
-56
View File
@@ -1,56 +0,0 @@
CREATE DATABASE highscores;
use highscores;
CREATE TABLE Guilds(
GuildId bigint unsigned not null unique,
GuildName varchar(95) not null,
SubmissionChannel bigint unsigned, -- deprecated, is not used anymore.
VerificationChannel bigint unsigned,
Active boolean DEFAULT true,
PRIMARY KEY (GuildId)
);
CREATE TABLE CategoryGroups(
GroupId int unsigned not null unique AUTO_INCREMENT,
GroupName varchar(50) not null,
ChannelId bigint unsigned,
GuildId bigint unsigned not null,
MessageId bigint unsigned,
PadLength smallint not null DEFAULT 26,
UsernameLength smallint DEFAULT 12,
CONSTRAINT UniqueGuildCategoryGroup UNIQUE (GuildId, GroupName),
FOREIGN KEY (GuildId) REFERENCES Guilds(GuildId) ON DELETE CASCADE,
PRIMARY KEY (GroupId)
);
CREATE TABLE Categories(
CategoryId int unsigned not null unique AUTO_INCREMENT,
CategoryName varchar(30) not null,
GroupId int unsigned not null,
Size smallint not null DEFAULT 3,
IsAscending boolean not null DEFAULT true,
IsTimeRecord boolean not null DEFAULT false,
IsValidated boolean not null DEFAULT true,
CONSTRAINT UniqueCategoryInGroup UNIQUE (GroupId, CategoryName),
FOREIGN KEY (GroupId) REFERENCES CategoryGroups(GroupId) ON DELETE CASCADE,
PRIMARY Key (CategoryId)
);
CREATE TABLE Scores(
UserName varchar(30) not null,
Score float not null, -- Maybe should have time and int scores?? timestamp type?
CategoryId int unsigned not null,
FOREIGN KEY (CategoryId) REFERENCES Categories(CategoryId) ON DELETE CASCADE,
PRIMARY KEY (CategoryId, UserName)
);
CREATE TABLE Submissions(
CategoryId int unsigned not null,
GroupId int unsigned not null,
GuildId bigint unsigned not null,
MessageId bigint unsigned not null,
Score varchar(30) not null, -- Score is stored as a string until converted during submission
UserId bigint unsigned not null,
UserName varchar(30) not null,
PRIMARY KEY (CategoryId, UserName) -- one submission a category per user.
);
-1
View File
@@ -1 +0,0 @@
"""Package of utility functions and environment configuration variables."""