Skip to content

Commit e659704

Browse files
committed
Use a database for league settings
1 parent 6a2b720 commit e659704

File tree

10 files changed

+453
-207
lines changed

10 files changed

+453
-207
lines changed

.pylintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ disable=
66
too-few-public-methods,
77
too-many-arguments,
88
no-value-for-parameter,
9-
consider-using-f-string
9+
consider-using-f-string,
10+
too-many-locals
1011

1112
[FORMAT]
1213
max-line-length=119

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ WORKDIR /app
55
COPY gumo ./gumo
66
COPY requirements.txt .
77

8+
RUN apk add git
9+
810
RUN pip install --upgrade pip
911
RUN pip install -r requirements.txt
1012

docker-compose.yml.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ services:
77
environment:
88
GUMO_BOT_TOKEN: "BOT_TOKEN_HERE"
99
GUMO_BOT_GOOGLE_API_SA_FILE: /path/to/the/service/account/file.json
10+
GUMO_BOT_DB_FILE: /path/to/database.db
1011
# GUMO_LOG_LEVEL: "INFO"

gumo/api/core.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
Define a client to interact with the Ori and the Blind Forest Randomizer API
33
"""
44

5+
import io
56
import logging
67
from urllib import parse
78
import random
89

10+
import discord
11+
912
import aiohttp
1013

1114
from gumo.api import models
@@ -33,7 +36,7 @@ class BFRandomizerApiClient:
3336
def __init__(self, *args, **kwargs):
3437
self._session = aiohttp.ClientSession(*args, **kwargs, raise_for_status=True)
3538

36-
async def get_data(self, seed_name: str = None, logic_mode: str = None, key_mode: str = None,
39+
async def _get_seed_data(self, seed_name: str = None, logic_mode: str = None, key_mode: str = None,
3740
goal_mode: str = None, spawn: str = None, variations: tuple = (), item_pool: str = None,
3841
relic_count: int = None):
3942
"""
@@ -47,6 +50,7 @@ async def get_data(self, seed_name: str = None, logic_mode: str = None, key_mode
4750
spawn (str, optional): Randomizer spawn location. Defaults to None.
4851
variations (tuple, optional): Randomizer variations. Defaults to ().
4952
item_pool (str, optional): Randomizer item pool. Defaults to None.
53+
relic_count (int, optional): Randomizer relic count (World Tour only). Defaults to None.
5054
5155
Returns:
5256
dict: The API response content
@@ -93,3 +97,33 @@ async def get_data(self, seed_name: str = None, logic_mode: str = None, key_mode
9397
logger.info("Outgoing request: %s", url)
9498
resp = await self._session.request('GET', url)
9599
return await resp.json()
100+
101+
async def get_seed(self, seed_name: str = None, logic_mode: str = None, key_mode: str = None,
102+
goal_mode: str = None, spawn: str = None, variations: tuple = (),
103+
item_pool: str = None, relic_count: int = None):
104+
"""Returns the seed data splitted into different dictionnary keys
105+
106+
Args:
107+
seed_name (str, optional): Seed name. Defaults to None.
108+
logic_mode (str, optional): Randomizer logic mode. Defaults to None.
109+
key_mode (str, optional): Randomizer key mode. Defaults to None.
110+
goal_mode (str, optional): Randomizer goal mode. Defaults to None.
111+
spawn (str, optional): Randomizer spawn location. Defaults to None.
112+
variations (tuple, optional): Randomizer variations. Defaults to ().
113+
item_pool (str, optional): Randomizer item pool. Defaults to None.
114+
relic_count (int, optional): Randomizer relic count (World Tour only). Defaults to None.
115+
116+
Returns:
117+
dict: The seed data in a dictonary format
118+
"""
119+
seed_data = await self._get_seed_data(seed_name=seed_name, logic_mode=logic_mode, key_mode=key_mode,
120+
goal_mode=goal_mode, spawn=spawn, variations=variations,
121+
item_pool=item_pool, relic_count=relic_count)
122+
seed_buffer = io.BytesIO(bytes(seed_data['players'][0]['seed'], encoding="utf8"))
123+
return {
124+
'seed_header': seed_data['players'][0]['seed'].split("\n")[0],
125+
'spoiler_url': f"{SEEDGEN_API_URL}{seed_data['players'][0]['spoiler_url']}",
126+
'map_url': f"{SEEDGEN_API_URL}{seed_data['map_url']}",
127+
'history_url': f"{SEEDGEN_API_URL}{seed_data['history_url']}",
128+
'seed_files': [discord.File(seed_buffer, filename='randomizer.dat')]
129+
}

gumo/api/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Define the mapping between Randomizer parameters presented to the user and the parameters passed in the API request.
33
"""
44

5+
from discord import app_commands
6+
57
LOGIC_MODES = {
68
'Casual': "Casual",
79
'Standard': "Standard",
@@ -89,3 +91,11 @@
8991
'Normal': "Normal",
9092
'Hard': "Hard"
9193
}
94+
95+
LOGIC_MODE_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in LOGIC_MODES.items()]
96+
KEY_MODE_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in KEY_MODES.items()]
97+
GOAL_MODE_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in GOAL_MODES.items()]
98+
SPAWN_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in SPAWNS.items()]
99+
VARIATION_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in VARIATIONS.items()]
100+
LOGIC_PATH_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in LOGIC_PATHS.items()]
101+
ITEM_POOL_CHOICES = [app_commands.Choice(name=name, value=name) for name, value in ITEM_POOLS.items()]

gumo/bot.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,18 @@
66
"""
77

88
import logging
9+
910
import discord
10-
from discord import app_commands
1111
from discord.ext import commands
1212

1313
logger = logging.getLogger(__name__)
1414

1515
MODULES = [
1616
"gumo.modules.emoji_chain",
17-
"gumo.modules.seed"
17+
"gumo.modules.seed",
18+
"gumo.modules.league",
1819
]
1920

20-
class CustomCommandTree(app_commands.CommandTree):
21-
"""Custom Command Tree class to override the default error handling"""
22-
23-
# pylint: disable=arguments-differ
24-
async def on_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError):
25-
command = interaction.command
26-
if command is not None:
27-
logger.error('Ignoring exception in command %r', command.qualified_name, exc_info=error)
28-
else:
29-
logger.error('Ignoring exception in command tree', exc_info=error)
30-
31-
3221
class Bot(commands.Bot):
3322
"""Custom Bot class to override the default behaviour and logging"""
3423

@@ -37,8 +26,7 @@ def __init__(self, *args, **kwargs):
3726
intents = discord.Intents.default()
3827
intents.message_content = True
3928
intents.members = True
40-
super().__init__(*args, **kwargs, intents=intents, tree_cls=CustomCommandTree)
41-
29+
super().__init__(*args, **kwargs, intents=intents)
4230
self.remove_command('help')
4331

4432
async def setup_hook(self):
@@ -55,10 +43,8 @@ async def on_interaction(self, interaction: discord.Interaction):
5543
message = f"Command invoked by {interaction.user.name} ({interaction.user.display_name}): " + \
5644
f"/{interaction.command.qualified_name}"
5745

58-
if "options" in interaction.data:
59-
options = interaction.data['options'][0]['options'] if interaction.command.parent \
60-
else interaction.data['options']
61-
arguments = [f"{opt['name']}='{opt['value']}'" for opt in options]
46+
if interaction.namespace:
47+
arguments = [f"{opt[0]}='{opt[1]}'" for opt in interaction.namespace]
6248
message += f" {' '.join(arguments)}"
6349

6450
logger.info(message)

0 commit comments

Comments
 (0)