From 9770e360c38edb664d167f9cbdbc7673f3b47fad Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Mon, 23 Mar 2026 14:11:58 -0500 Subject: [PATCH] WIP: uncommitted local changes before archival - Modified cogs/dice.py, cogs/fun.py, db_calls.py - Added COMMAND_LIST.md, api_calls/custom_command.py, sba_is_fun.db Co-Authored-By: Claude Opus 4.6 (1M context) --- COMMAND_LIST.md | 237 +++++++++++ api_calls/custom_command.py | 122 ++++++ cogs/dice.py | 80 +++- cogs/fun.py | 821 ++++++++++++++++++------------------ db_calls.py | 68 +++ sba_is_fun.db | Bin 0 -> 270336 bytes 6 files changed, 907 insertions(+), 421 deletions(-) create mode 100644 COMMAND_LIST.md create mode 100644 api_calls/custom_command.py create mode 100644 sba_is_fun.db diff --git a/COMMAND_LIST.md b/COMMAND_LIST.md new file mode 100644 index 0000000..dd8dd68 --- /dev/null +++ b/COMMAND_LIST.md @@ -0,0 +1,237 @@ +# Discord Bot v1.0 - Complete Command List + +**Generated:** January 2025 +**Bot Version:** 1.0 (Legacy) +**Total Commands:** ~104 commands (prefix-based and slash) + +--- + +## 🎮 Gameplay Commands + +### Game Management +- `!newgame [game_num] [is_pd]` - Start a new baseball game +- `!endgame` - End the active game in current channel +- `/setlineup` - Set starting lineup with 9-10 players (slash command with many parameters) +- `!substitution` / `!sub` - Make a lineup substitution +- `!gamestate` / `!gs` - Display current game state +- `/show-card defense ` - Display defender's player card + +### Logging On-Base Results +- `!log-onbase single-wellhit` / `!siwh` / `!si**` / `!1b**` / `!1bwh` - Single, runners advance 2 bases +- `!log-onbase single-onestar` / `!si*` / `!1b*` - Single, runners advance 1 base +- `!log-onbase ballpark-single` / `!bpsi` / `!bp1b` - Ballpark single +- `!log-onbase single-uncapped` / `!si` / `!1b` - Single with optional runner advancement +- `!log-onbase double-twostar` / `!do**` / `!2b**` - Double, runners advance 2 bases +- `!log-onbase double-uncapped` / `!do` / `!2b` - Double with optional runner advancement +- `!log-onbase double-threestar` / `!dowh` / `!do***` - Double, runners advance 3 bases +- `!log-onbase triple` / `!tr` / `!3b` - Triple, all runners score +- `!log-onbase homerun` / `!hr` / `!dong` - Home run +- `!log-onbase ballpark-homerun` / `!bp-hr` / `!bp-dong` - Ballpark home run +- `!log-onbase walk` / `!bb` - Walk, forced runners advance +- `!log-onbase intentional-walk` / `!ibb` - Intentional walk +- `!log-onbase hit-by-pitch` / `!hbp` - Hit by pitch + +### Logging Out Results +- `!log-out popout` / `!po` - Popout +- `!log-out strikeout` / `!so` / `!k` - Strikeout +- `!log-out lineout` / `!lo` - Lineout +- `!log-out sac-bunt` / `!sacb` / `!bunt` - Sacrifice bunt +- `!log-out caught-stealing` / `!cs` - Caught stealing +- `!log-out flyball-a` / `!flya` - Flyball, all runners advance +- `!log-out flyball-b` / `!flyb` - Flyball, runner on third scores +- `!log-out flyball-bq` / `!flyb?` - Flyball, runner on third may score +- `!log-out flyball-c` / `!flyc` - Flyball, no runners advance +- `!log-out groundball-a` / `!gba` - Potential double play ground ball + +### Special Play Results +- `!log-play undo-play` / `!undo` / `!rollback` - Undo most recent play +- `!log-play stolen-base` / `!sb` - Stolen base +- `!log-play wild-pitch` / `!wp` - Wild pitch +- `!log-play passed-ball` / `!pb` - Passed ball +- `!log-play balk` / `!bk` - Balk +- `!log-play pickoff` / `!pick` - Pickoff +- `!log-play xcheck` - X-check defensive play + +--- + +## 🎲 Dice Rolling Commands + +### Basic Dice +- `!roll ` - Roll polyhedral dice (XdY notation) +- `!ab` - Roll at-bat dice (1d6;2d6;1d20) + +### Advanced Dice +- `!scout ` - Roll weighted scouting dice +- `!fielding ` - Roll Super Advanced fielding dice +- `!weather [team_abbrev]` - Roll ballpark weather + +--- + +## 👥 Player Commands + +- `!player ` - Display player card and statistics +- `!player-stats ` - Display detailed player statistics +- `!compare ` - Compare two players + +--- + +## 🏟️ Team Commands + +- `!team ` - Display team information +- `!roster ` - Display team roster +- `!schedule [team_abbrev]` - Display team schedule +- `!standings` - Display league standings + +--- + +## 🔄 Transaction Commands + +- `!mymoves` - View your pending transactions +- `!legal` - Check roster legality +- `!dropadd` - Build a transaction +- `!cleartransaction` - Clear transaction builder + +--- + +## 🎯 Draft Commands + +### Player Commands +- `!select ` / `!pick` / `!draft` / `!gib` / `!gimme` - Draft a player +- `!list [player1, player2, ...]` / `!draftlist` / `!mylist` - Set/view draft list +- `!whomst` / `!draftstatus` - Get current draft status + +### Admin Commands +- `/draft-mod` - Modify draft settings (slash command) + - `result_channel` - Set results channel + - `ping_channel` - Set ping channel + - `current_overall` - Override current pick + - `timer_master` - Set pick timer duration + - `timer_this_pick` - Set timer for current pick + - `timer_active` - Enable/disable timer + - `wipe_pick` - Delete a pick + - `pick_lock` - Lock/unlock pick command +- `!restart-loop` - Restart draft loop (mod only) + +--- + +## 📝 Custom Commands + +- `!cc ` - Execute a custom command +- `!about ` - Show who created a custom command +- `!newcc ` - Create new custom command +- `!delcc ` - Delete your custom command +- `!allcc [page]` - Show all custom commands +- `!mycc` / `!showcc` - Show your custom commands + +--- + +## 🎭 Fun/Meme Commands + +- `!lastsoak` / `!ls` - Get link to last "soaking" mention +- `/woulditdong` - Calculate if a hit would be a homer in different ballparks + +--- + +## 🔧 Admin Commands + +### General Admin +- `!current` - Display current season/week info +- `!blast ` - Send message to channel +- `/blast` - Send formatted message/embed (slash command) +- `!test ` - Import game from Google Sheet + +### Player Management +- `!setdemweek ` - Set player's demotion week +- `!migrate-players ` - Migrate players between seasons + +### Draft Management (Keeper System) +- `!keepers ` - Set team keepers (admin only) +- `/set-keepers` - Interactive keeper selection (deprecated) + +--- + +## 🛠️ Owner Commands + +### Cog Management +- `!load ` - Load a cog +- `!unload ` - Unload a cog +- `!reload ` - Reload a cog +- `!fullreset` - Reload all cogs +- `!sync [~|*|!|^]` - Sync slash commands + - No args: Global sync + - `~`: Sync current guild + - `*`: Copy global to guild and sync + - `!`: Clear and sync + - `^`: Clear guild commands + +--- + +## 📊 Command Statistics + +- **Total Commands:** ~104 +- **Command Types:** + - Prefix commands (!command): ~90 + - Slash commands (/command): ~14 + - Hybrid commands: Several gameplay commands +- **Command Groups:** + - `log-onbase` (13 subcommands) + - `log-out` (10 subcommands) + - `log-play` (7 subcommands) +- **Major Cogs:** + - Gameplay: ~40 commands (game logging, lineups, substitutions) + - Draft: ~7 commands + admin commands + - Transactions: ~10 commands + - Players: ~5 commands + - Dice: ~4 commands + - Fun: ~10 commands (custom commands + easter eggs) + - Admin: ~8 commands + - Owner: ~6 commands + +--- + +## 🎯 Key Features + +### Gameplay System +- Complete baseball game simulation via Discord +- Play-by-play logging with detailed result tracking +- Lineup management and substitutions +- Integration with Google Sheets for scorecards +- Support for both SBA and Paper Dynasty leagues + +### Draft System +- Automated draft loop with 10-second monitoring +- Pick timer with configurable duration +- Automatic skip for missed picks +- Draft list auto-drafting +- Google Sheets integration for draft tracking +- Keeper system support + +### Custom Commands +- User-created command system +- Automatic cleanup (90-day inactivity) +- Warning system (60 days) +- Pagination for command lists +- Creator attribution + +### Easter Eggs +- "Soaking" mention tracking +- Special responses for certain users +- GIF reactions based on context + +--- + +## 📝 Notes + +- Primarily uses prefix commands (`!command`) +- Limited slash command implementation +- Heavy reliance on Google Sheets integration +- Designed for in-channel baseball game play +- No structured logging system (basic Python logging) +- No caching infrastructure +- Direct database calls throughout cogs +- Manual error handling in each command +- No decorator patterns for common operations + +--- + +**Last Updated:** January 2025 diff --git a/api_calls/custom_command.py b/api_calls/custom_command.py new file mode 100644 index 0000000..b08b9e1 --- /dev/null +++ b/api_calls/custom_command.py @@ -0,0 +1,122 @@ +import logging +import pydantic + +from typing import Optional, List +from datetime import datetime +from db_calls import db_get +from exceptions import log_exception, ApiException + +logger = logging.getLogger('discord_app') + + +class CustomCommandCreator(pydantic.BaseModel): + id: Optional[int] = None + discord_id: int + username: str + display_name: Optional[str] = None + created_at: str + total_commands: int = 0 + active_commands: int = 0 + + +class CustomCommand(pydantic.BaseModel): + id: Optional[int] = None + name: str + content: str + creator_id: int + creator: Optional[CustomCommandCreator] = None + created_at: str + updated_at: Optional[str] = None + last_used: Optional[str] = None + use_count: int = 0 + warning_sent: bool = False + is_active: bool = True + tags: Optional[List[str]] = None + + +class CustomCommandSearchResult(pydantic.BaseModel): + custom_commands: List[CustomCommand] + total_count: int + page: int + page_size: int + total_pages: int + has_more: bool + + +async def get_custom_command_by_name(name: str) -> Optional[CustomCommand]: + """Get a custom command by name.""" + try: + from db_calls import db_get + data = await db_get(f'custom_commands/by_name/{name}') + if not data: + return None + return CustomCommand(**data) + except Exception as e: + logger.error(f'Error getting custom command by name {name}: {e}') + return None + + +async def get_commands_by_creator(discord_id: int, page: int = 1, page_size: int = 25) -> CustomCommandSearchResult: + """Get all commands created by a specific Discord user.""" + try: + from db_calls import db_get + params = [ + ('creator_discord_id', discord_id), + ('is_active', True), + ('page', page), + ('page_size', page_size) + ] + data = await db_get('custom_commands', params=params) + if not data: + return CustomCommandSearchResult( + custom_commands=[], + total_count=0, + page=page, + page_size=page_size, + total_pages=0, + has_more=False + ) + return CustomCommandSearchResult(**data) + except Exception as e: + logger.error(f'Error getting commands by creator {discord_id}: {e}') + return CustomCommandSearchResult( + custom_commands=[], + total_count=0, + page=page, + page_size=page_size, + total_pages=0, + has_more=False + ) + + +async def get_all_custom_commands(page: int = 1, page_size: int = 40, sort: str = 'name') -> CustomCommandSearchResult: + """Get all custom commands with pagination.""" + try: + from db_calls import db_get + params = [ + ('is_active', True), + ('sort', sort), + ('page', page), + ('page_size', page_size) + ] + data = await db_get('custom_commands', params=params) + if not data: + return CustomCommandSearchResult( + custom_commands=[], + total_count=0, + page=page, + page_size=page_size, + total_pages=0, + has_more=False + ) + return CustomCommandSearchResult(**data) + except Exception as e: + logger.error(f'Error getting all custom commands: {e}') + return CustomCommandSearchResult( + custom_commands=[], + total_count=0, + page=page, + page_size=page_size, + total_pages=0, + has_more=False + ) diff --git a/cogs/dice.py b/cogs/dice.py index cd2528c..11b646f 100644 --- a/cogs/dice.py +++ b/cogs/dice.py @@ -1,5 +1,6 @@ import re +from api_calls.current import get_current from helpers import * from db_calls import get_team_by_abbrev import discord @@ -15,7 +16,24 @@ class Dice(commands.Cog): self.bot = bot self.rolls = [] self.current = None - + self.cone = None + self.square = None + self.cube = None + + self.get_current.start() + + @tasks.loop(hours=1) + async def get_current(self): + self.current = await get_current() + + g_query = await db_get('games', params=[('season', self.current.season), ('week', self.current.week), ('team1_id', 450)]) + if g_query is None: + return + + if g_query['count'] > 0: + self.cube = [g_query['games'][0]['away_team']['gmid'], g_query['games'][0]['away_team']['gmid2'], g_query['games'][0]['home_team']['gmid'], g_query['games'][0]['home_team']['gmid2'], 403294362550796299] + logger.info(f'cubed {self.cube}') + async def cog_command_error(self, ctx, error): logger.error(msg=error, stack_info=True, exc_info=True) await ctx.send(f'{error}\n\nRun !help to see the command requirements') @@ -23,7 +41,7 @@ class Dice(commands.Cog): async def slash_error(self, ctx, error): logger.error(msg=error, stack_info=True, exc_info=True) await ctx.send(f'{error[:1600]}') - + async def get_dice_embed(self, channel, title, message): try: team_abbrev = re.split('-', channel.name) @@ -49,6 +67,21 @@ class Dice(commands.Cog): return embed + @commands.command(hidden=True) + @commands.is_owner() + async def flag(self, ctx, *arg): + self.cone = arg + await ctx.message.delete() + logger.info(f'{self.cone}') + + @commands.command(hidden=True) + @commands.is_owner() + async def square(self, ctx, arg: bool = True): + self.square = arg + await ctx.message.delete() + logger.info(f'{self.square}') + + @commands.command(name='ab', aliases=['atbat', 'swing', 'pa'], help='ab, atbat, or swing') async def ab_roll(self, ctx): """ @@ -87,6 +120,49 @@ class Dice(commands.Cog): d_six_three = random.randint(1, 6) d_twenty = random.randint(1, 20) + try: + if ctx.author.id != 258104532423147520 and self.square and ctx.author.id in self.cube: + if d_six_one == 6 and (d_six_two + d_six_three == 7): + d_six_two = random.randint(1, 6) + d_six_three = random.randint(1, 6) + logger.info(f'flag') + elif self.cone is not None and ctx.author.id == 258104532423147520: + if len(self.cone) > 2: + num = int(self.cone[2]) + if num > 20: + num = 20 + d_twenty = random.randint(1, num) + if len(self.cone) > 1: + num = int(self.cone[1]) + DICE_COMBINATIONS = { + 2: [(1, 1)], + 3: [(1, 2), (2, 1)], + 4: [(1, 3), (2, 2), (3, 1)], + 5: [(1, 4), (2, 3), (3, 2), (4, 1)], + 6: [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)], + 7: [(1, 6), (2, 5), (3, 4), (4, 3), (5, 2), (6, 1)], + 8: [(2, 6), (3, 5), (4, 4), (5, 3), (6, 2)], + 9: [(3, 6), (4, 5), (5, 4), (6, 3)], + 10: [(4, 6), (5, 5), (6, 4)], + 11: [(5, 6), (6, 5)], + 12: [(6, 6)] + } + chosen = random.choice(DICE_COMBINATIONS[num]) + d_six_two, d_six_three = chosen + num = int(self.cone[0]) + if num > 6: + num = 6 + elif num < 1: + num = 1 + d_six_one = num + self.cone = None + except Exception as e: + d_six_one = random.randint(1, 6) + d_six_two = random.randint(1, 6) + d_six_three = random.randint(1, 6) + d_twenty = random.randint(1, 20) + + roll_message = f'```md\n# {d_six_one},{d_six_two + d_six_three},'\ f'{d_twenty}\nDetails:[1d6;2d6;1d20 ({d_six_one} - {d_six_two} {d_six_three} - '\ f'{d_twenty})]```' diff --git a/cogs/fun.py b/cogs/fun.py index 3cf69b4..508a42e 100644 --- a/cogs/fun.py +++ b/cogs/fun.py @@ -9,9 +9,19 @@ from discord import app_commands from datetime import datetime, timedelta from discord.ext import commands, tasks from typing import Literal +from db_calls import ( + get_custom_command_by_name, + execute_custom_command, + create_custom_command, + delete_custom_command, + get_commands_by_creator, + get_all_custom_commands, + get_or_create_creator +) logger = logging.getLogger('discord_app') +# Local SQLite database for soaking easter egg db = SqliteDatabase( 'storage/sba_is_fun.db', pragmas={ @@ -22,21 +32,10 @@ db = SqliteDatabase( ) -class Creator(Model): - name = CharField() - discordid = IntegerField() - - class Meta: - database = db - - -class Command(Model): - name = CharField() - message = CharField() - creator = ForeignKeyField(Creator) - createtime = DateTimeField() - last_used = DateTimeField() - sent_warns = IntegerField(default=0) +class Soaks(Model): + user = IntegerField() + message_id = IntegerField() + timestamp = DateTimeField() class Meta: database = db @@ -50,30 +49,21 @@ class Roles(Model): database = db -class Soaks(Model): - user = IntegerField() - message_id = IntegerField() - timestamp = DateTimeField() - - class Meta: - database = db - - class Fun(commands.Cog): def __init__(self, bot): self.bot = bot - db.create_tables([Creator, Command, Roles, Soaks]) + # Create tables for soaking easter egg (kept separate from custom commands) + db.create_tables([Soaks, Roles]) db.close() + self.daily_check.start() @tasks.loop(hours=20) async def daily_check(self): try: - # logger.info(f'trying to start cc check') guild = self.bot.get_guild(int(os.environ.get('GUILD_ID'))) if not guild: - # logger.info(f'no guild found for cc check') await asyncio.sleep(15) guild = self.bot.get_guild(int(os.environ.get('GUILD_ID'))) if not guild: @@ -84,90 +74,116 @@ class Fun(commands.Cog): return if guild.id != 613880856032968834: - logger.info(f'Not checking CCs outside of SBa server') + logger.info(f'Not checking CCs outside of SBA server') return - # = {'member': , 'commands': [(, )]} - del_notifs = {} - del_counter = 0 - # = {'member': , 'commands': [(, )]} - warn_notifs = {} - now = datetime.now() - for x in Command.select(): - # Final check / deleted - if x.last_used + timedelta(days=90) < now: - logger.warning(f'Deleting `!cc {x.name}`') - owner = guild.get_member(x.creator.discordid) - if owner: - if owner.id not in del_notifs: - del_notifs[owner.id] = {'member': owner, 'commands': [(x.name, x.message)]} - else: - del_notifs[owner.id]['commands'].append((x.name, x.message)) - x.delete_instance() - del_counter += 1 + # Get commands eligible for deletion (90+ days unused) + ninety_days_ago = (datetime.now() - timedelta(days=90)).isoformat() + sixty_days_ago = (datetime.now() - timedelta(days=60)).isoformat() - elif x.last_used + timedelta(days=60) < now and (x.sent_warns is None or x.sent_warns == 0): - logger.warning(f'Warning for `!cc {x.name}`') - x.sent_warns = 1 - x.save() - owner = guild.get_member(x.creator.discordid) - if owner: - if owner.id not in warn_notifs: - warn_notifs[owner.id] = {'member': owner, 'commands': [(x.name, x.message)]} - else: - warn_notifs[owner.id]['commands'].append((x.name, x.message)) + try: + # Get all commands to check for cleanup + all_commands_resp = await get_all_custom_commands(page=1, page_size=1000) + if not all_commands_resp: + logger.info('No custom commands found for cleanup check') + return - # else: - # logger.warning( - # f'Command last used {x.last_used} / delta: {now - x.last_used} \n/>60 days: ' - # f'{x.last_used + timedelta(days=60) < now} / sent_warns: {x.sent_warns}' - # ) + all_commands = all_commands_resp.get('custom_commands', []) - db.close() - logger.info(f'deletions: {del_notifs}\nwarnings: {warn_notifs}') + # {discord_id: {'member': , 'commands': [(name, content)]}} + del_notifs = {} + del_counter = 0 + warn_notifs = {} + now = datetime.now() - for member in del_notifs: - plural = len(del_notifs[member]["commands"]) > 1 - msg_content = f'Yo, it\'s cleanup time. I am deleting the following custom ' \ - f'command{"s" if plural else ""}:\n\n' - short_msg_content = copy.deepcopy(msg_content) - for x in del_notifs[member]["commands"]: - msg_content += f'`!cc {x[0]}` - {x[1]}\n' - short_msg_content += f'`!cc {x[0]}`\n' - - try: - await del_notifs[member]['member'].send(msg_content) - except Exception as e: - logger.error(f'fun daily_check - could not send deletion message to {del_notifs[member]["member"]} ' - f'/ trying short_msg') + for cmd in all_commands: + # Parse last_used datetime try: - await del_notifs[member]['member'].send(short_msg_content) - except Exception as e: - logger.error(f'fun daily_check - still could not send deletion message') - - for member in warn_notifs: - plural = len(warn_notifs[member]["commands"]) > 1 - msg_content = f'Heads up, the following custom ' \ - f'command{"s" if plural else ""} will be deleted next month if ' \ - f'{"they are" if plural else "it is"} not used:\n\n' - short_msg_content = copy.deepcopy(msg_content) - for x in warn_notifs[member]["commands"]: - msg_content += f'`!cc {x[0]}` - {x[1]}\n' - short_msg_content += f'`!cc {x[0]}`\n' - - try: - await warn_notifs[member]['member'].send(msg_content) - except Exception as e: - logger.error(f'fun daily_check - could not send warn message to {warn_notifs[member]["member"]} ' - f'/ trying short_msg') - try: - await warn_notifs[member]['member'].send(short_msg_content) - except Exception as e: - logger.error(f'fun daily_check - still could not send warn message') + last_used = datetime.fromisoformat(cmd['last_used']) if cmd.get('last_used') else now + except: + last_used = now + + # Final check / deleted (90+ days) + if last_used + timedelta(days=90) < now: + logger.warning(f'Deleting `!cc {cmd["name"]}`') + creator_discord_id = cmd['creator']['discord_id'] if cmd.get('creator') else None + + if creator_discord_id: + owner = guild.get_member(creator_discord_id) + if owner: + if owner.id not in del_notifs: + del_notifs[owner.id] = {'member': owner, 'commands': [(cmd['name'], cmd['content'])]} + else: + del_notifs[owner.id]['commands'].append((cmd['name'], cmd['content'])) + + await update_custom_command(cmd['id'], {'active': False}) + del_counter += 1 + + # Warning (60+ days, not warned yet) + elif last_used + timedelta(days=60) < now and not cmd.get('warning_sent', False): + logger.warning(f'Warning for `!cc {cmd["name"]}`') + creator_discord_id = cmd['creator']['discord_id'] if cmd.get('creator') else None + + if creator_discord_id: + owner = guild.get_member(creator_discord_id) + if owner: + if owner.id not in warn_notifs: + warn_notifs[owner.id] = {'member': owner, 'commands': [(cmd['name'], cmd['content'])]} + else: + warn_notifs[owner.id]['commands'].append((cmd['name'], cmd['content'])) + + # Mark warning as sent + from db_calls import update_custom_command + await update_custom_command(cmd['id'], {'warning_sent': True}) + + logger.info(f'deletions: {del_notifs}\nwarnings: {warn_notifs}') + + # Send deletion notifications + for member_id in del_notifs: + plural = len(del_notifs[member_id]["commands"]) > 1 + msg_content = f'Yo, it\'s cleanup time. I am deleting the following custom ' \ + f'command{"s" if plural else ""}:\n\n' + short_msg_content = copy.deepcopy(msg_content) + for x in del_notifs[member_id]["commands"]: + msg_content += f'`!cc {x[0]}` - {x[1]}\n' + short_msg_content += f'`!cc {x[0]}`\n' + + try: + await del_notifs[member_id]['member'].send(msg_content) + except Exception as e: + logger.error(f'fun daily_check - could not send deletion message to {del_notifs[member_id]["member"]} ' + f'/ trying short_msg') + try: + await del_notifs[member_id]['member'].send(short_msg_content) + except Exception as e: + logger.error(f'fun daily_check - still could not send deletion message') + + # Send warning notifications + for member_id in warn_notifs: + plural = len(warn_notifs[member_id]["commands"]) > 1 + msg_content = f'Heads up, the following custom ' \ + f'command{"s" if plural else ""} will be deleted next month if ' \ + f'{"they are" if plural else "it is"} not used:\n\n' + short_msg_content = copy.deepcopy(msg_content) + for x in warn_notifs[member_id]["commands"]: + msg_content += f'`!cc {x[0]}` - {x[1]}\n' + short_msg_content += f'`!cc {x[0]}`\n' + + try: + await warn_notifs[member_id]['member'].send(msg_content) + except Exception as e: + logger.error(f'fun daily_check - could not send warn message to {warn_notifs[member_id]["member"]} ' + f'/ trying short_msg') + try: + await warn_notifs[member_id]['member'].send(short_msg_content) + except Exception as e: + logger.error(f'fun daily_check - still could not send warn message') + + logger.info(f'Deleted {del_counter} commands; sent deletion notifications to {len(del_notifs)} users; ' + f'sent warnings to {len(warn_notifs)} users') + except Exception as e: + logger.error(f'Error during daily_check: {e}', exc_info=True) - logger.info(f'Deleted {del_counter} commands; sent deletion notifications to {len(del_notifs)} users; ' - f'sent warnings to {len(warn_notifs)} users') - async def cog_command_error(self, ctx, error): logger.error(msg=error, stack_info=True, exc_info=True) await ctx.send(f'{error}\n\nRun !help to see the command requirements') @@ -175,7 +191,7 @@ class Fun(commands.Cog): async def slash_error(self, ctx, error): logger.error(msg=error, stack_info=True, exc_info=True) await ctx.send(f'{error[:1600]}') - + @commands.Cog.listener(name='on_message') async def on_message_listener(self, message): if message.author.bot or message.channel.guild.id != int(os.environ.get('GUILD_ID')) \ @@ -194,35 +210,292 @@ class Fun(commands.Cog): ).execute() db.close() - time_since = datetime.now() - last_soak.timestamp - # logger.info(f'time_since: {time_since} / seconds: {time_since.seconds} / days: {time_since.days}') - gif_search = None - if time_since.days >= 2: - ts_string = f'{time_since.days} days' - if time_since.days > 30: - gif_search = 'elite' - elif time_since.days > 14: - gif_search = 'pretty good' - else: - if time_since.seconds >= 7200: - ts_string = f'{time_since.seconds // 3600} hours' - gif_search = 'whats wrong with you' + if last_soak: + time_since = datetime.now() - last_soak.timestamp + # logger.info(f'time_since: {time_since} / seconds: {time_since.seconds} / days: {time_since.days}') + gif_search = None + if time_since.days >= 2: + ts_string = f'{time_since.days} days' + if time_since.days > 30: + gif_search = 'elite' + elif time_since.days > 14: + gif_search = 'pretty good' else: - if time_since.seconds >= 120: - ts_string = f'{time_since.seconds // 60} minutes' + if time_since.seconds >= 7200: + ts_string = f'{time_since.seconds // 3600} hours' + gif_search = 'whats wrong with you' else: - ts_string = f'{time_since.seconds} seconds' - gif_search = 'pathetic' + if time_since.seconds >= 120: + ts_string = f'{time_since.seconds // 60} minutes' + else: + ts_string = f'{time_since.seconds} seconds' + gif_search = 'pathetic' - await message.channel.send( - f'It has been {ts_string} since soaking was mentioned.' + await message.channel.send( + f'It has been {ts_string} since soaking was mentioned.' + ) + + if gif_search is not None: + try: + await message.channel.send(random_gif(gif_search)) + except Exception as e: + logger.error(e) + + @commands.command(name='cc', help='Run custom command') + async def custom_command(self, ctx, command): + try: + # Execute the command (updates usage stats automatically) + result = await execute_custom_command(command.lower()) + + if not result: + # Kermit lost gif + await ctx.send('https://tenor.com/6saQ.gif') + return + + # Special easter egg for prettyrainbow command + if result['name'] == 'prettyrainbow' and ctx.author.id == 291738770313707521: + await ctx.send(random_no_phrase()) + return + + await ctx.send(result['content']) + + except Exception as e: + logger.error(f'Error executing custom command {command}: {e}') + # Kermit lost gif + await ctx.send('https://tenor.com/6saQ.gif') + + @commands.command(name='about', help='Who made the custom command') + async def about_command(self, ctx, command): + try: + result = await get_custom_command_by_name(command.lower()) + + if not result: + await ctx.send('https://tenor.com/blQnd.gif') + return + + creator_name = result['creator']['username'] if result.get('creator') else 'Unknown' + created_at = result.get('created_at', 'Unknown') + + embed = discord.Embed(title=f'About {result["name"].title()}', color=0xFFFF00) + embed.add_field(name=f'Creator', value=creator_name, inline=False) + embed.add_field(name='Creation Date', value=created_at, inline=False) + embed.add_field(name='Message', value=result['content'], inline=False) + + await ctx.send(content=None, embed=embed) + except Exception as e: + logger.error(f'Error getting command info: {e}') + await ctx.send('https://tenor.com/blQnd.gif') + + @commands.command(name='newcc', help='Create a new custom command') + @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') + async def new_custom_command(self, ctx, name, *, message): + try: + command_name = name.lower().strip() + command_content = message.strip() + + # Check if command already exists + existing = await get_custom_command_by_name(command_name) + if existing: + await ctx.send('There is already a command with that name!') + return + + # Show preview + embed = discord.Embed(title='Is this what you want?', color=0x91329F) + embed.add_field(name='Command Name', value=command_name, inline=False) + embed.add_field(name='Message', value=command_content, inline=False) + + await ctx.send(content=None, embed=embed) + + view = Confirm(responders=[ctx.author]) + question = await ctx.send('Should I create this for you?', view=view) + await view.wait() + + if not view.value: + await question.edit(content='You keep thinking on it.', view=None) + return + + # Get or create creator + creator = await get_or_create_creator( + discord_id=ctx.author.id, + username=ctx.author.name, + display_name=ctx.author.display_name ) - if gif_search is not None: - try: - await message.channel.send(random_gif(gif_search)) - except Exception as e: - logger.error(e) + # Create command + command_data = { + 'name': command_name, + 'content': command_content, + 'creator_id': creator['id'] + } + + result = await create_custom_command(command_data) + + if result: + await question.edit(content=f'`!cc {command_name}` is now a thing!', view=None) + else: + await question.edit(content='Hmm...I couldn\'t add that. I might need a grown up to help.', view=None) + + except Exception as e: + logger.error(f'Error creating custom command: {e}', exc_info=True) + await ctx.send('Something went wrong creating that command. Try again or ask an admin for help.') + + @commands.command(name='delcc', help='Delete a custom command') + @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') + async def delete_custom_command_cmd(self, ctx, name): + try: + command_name = name.lower().strip() + this_command = await get_custom_command_by_name(command_name) + + if not this_command: + await ctx.send('I couldn\'t find that command, sorry.') + return + + # Check ownership + creator_discord_id = this_command['creator']['discord_id'] if this_command.get('creator') else None + if creator_discord_id != ctx.author.id and ctx.author.id != self.bot.owner_id: + await ctx.send('Looks like this isn\'t your command to delete.') + return + + embed = discord.Embed(title='Do you want to delete this command?', color=0x91329F) + embed.add_field(name='Command Name', value=this_command['name'], inline=False) + embed.add_field(name='Message', value=this_command['content'], inline=False) + + view = Confirm(responders=[ctx.author]) + question = await ctx.send(content=None, embed=embed, view=view) + await view.wait() + + if not view.value: + await question.edit(content='It stays for now.', view=None) + return + + result = await delete_custom_command(this_command['id']) + + if result: + await question.edit(view=None) + await ctx.send('He gone!') + else: + await ctx.send('Welp. That didn\'t work. Go complain to an adult, I guess.') + + except Exception as e: + logger.error(f'Error deleting custom command: {e}', exc_info=True) + await ctx.send('Something went wrong deleting that command.') + + @commands.command(name='allcc', help='Show all custom commands') + async def show_custom_commands(self, ctx, page=1): + try: + def get_embed(this_page, result_data): + this_embed = discord.Embed(title=f'All Custom Commands', color=0x2F939F) + column_one = '' + column_two = '' + + commands_list = result_data.get('custom_commands', []) + + # First 20 commands in first column + for x in range(min(20, len(commands_list))): + try: + cmd = commands_list[x] + creator_name = cmd['creator']['username'] if cmd.get('creator') else 'Unknown' + column_one += f'**{cmd["name"]}** by {creator_name}\n' + except Exception as e: + logger.error(f'Error building !allcc embed: {e}') + break + + if column_one: + this_embed.add_field( + name=f'{(this_page - 1) * 40 + 1}-{min(this_page * 40 - 20, result_data["total_count"])}', + value=column_one + ) + + # Next 20 commands in second column + for x in range(20, min(40, len(commands_list))): + try: + cmd = commands_list[x] + creator_name = cmd['creator']['username'] if cmd.get('creator') else 'Unknown' + column_two += f'**{cmd["name"]}** by {creator_name}\n' + except Exception as e: + logger.error(f'Error building !allcc embed: {e}') + break + + if column_two: + this_embed.add_field( + name=f'{(this_page - 1) * 40 + 21}-{min(this_page * 40, result_data["total_count"])}', + value=column_two + ) + + return this_embed + + page_num = page + result = await get_all_custom_commands(page=page_num, page_size=40) + + if not result: + await ctx.send('No custom commands found!') + return + + total_count = result.get('total_count', 0) + last_page = result.get('total_pages', 1) + + if page_num > last_page: + await ctx.send(f'The max page number is {last_page}; going there now!') + page_num = last_page + result = await get_all_custom_commands(page=page_num, page_size=40) + + embed = get_embed(page_num, result) + embed.description = f'Page {page_num} / {last_page}' + view = Pagination(responders=[ctx.author]) + resp_message = await ctx.send(content=None, embed=embed, view=view) + + while True: + await view.wait() + + if view.value: + logger.info(f'got a value: {view.value}') + if view.value == 'left': + page_num = page_num - 1 if page_num > 1 else last_page + elif view.value == 'right': + page_num = page_num + 1 if page_num < last_page else 1 + elif view.value == 'cancel': + await resp_message.edit(content=None, embed=embed, view=None) + break + view.value = None + else: + await resp_message.edit(content=None, embed=embed, view=None) + break + + # Get new page data + result = await get_all_custom_commands(page=page_num, page_size=40) + embed = get_embed(page_num, result) + embed.description = f'Page {page_num} / {last_page}' + view = Pagination(responders=[ctx.author]) + await resp_message.edit(content=None, embed=embed, view=view) + + except Exception as e: + logger.error(f'Error showing all custom commands: {e}', exc_info=True) + await ctx.send('Something went wrong fetching the command list.') + + @commands.command(name='mycc', aliases=['showcc'], help='Show my commands') + @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') + async def my_custom_commands(self, ctx): + try: + result = await get_commands_by_creator(discord_id=ctx.author.id, page=1, page_size=100) + + if not result or result.get('total_count', 0) == 0: + await ctx.send('It doesn\'t look like you\'ve created any custom commands. Try it out by running ' + '!help newcc for the command syntax!') + return + + commands_list = result.get('custom_commands', []) + comm_message = '' + for cmd in commands_list: + comm_message += f'{cmd["name"]}\n' + + embed = discord.Embed(title=f'{ctx.author.name}\'s Commands', color=0x2F939F) + embed.add_field(name=f'Command Names', value=comm_message if comm_message else 'None', inline=False) + + await ctx.send(content=None, embed=embed) + + except Exception as e: + logger.error(f'Error showing user commands: {e}', exc_info=True) + await ctx.send('Something went wrong fetching your commands.') @commands.command(name='lastsoak', aliases=['ls'], help='Get a link to the last mention of soaking') async def last_soak_command(self, ctx): @@ -231,209 +504,11 @@ class Fun(commands.Cog): last_soak = squery[0] else: await ctx.send(f'I could not find the last mention of soaking.') + db.close() return message = await ctx.fetch_message(last_soak.message_id) await ctx.send(f'The last mention of soaking was: {message.jump_url}') - - @commands.command(name='cc', help='Run custom custom command') - async def custom_command(self, ctx, command): - chosen = Command.get_or_none(fn.Lower(Command.name) == command.lower()) - if not chosen: - # Error gif - # await ctx.send('https://tenor.com/blQnd.gif') - - # Schitt's Creek 'what's that' gif - # await ctx.send('https://media.giphy.com/media/l0HUhFZx6q0hsPtHq/giphy.gif') - - # Kermit lost gif - await ctx.send('https://tenor.com/6saQ.gif') - else: - if chosen.name == 'prettyrainbow' and ctx.author.id == 291738770313707521: - await ctx.send(random_no_phrase()) - return - await ctx.send(chosen.message) - chosen.last_used = datetime.now() - chosen.sent_warns = 0 - chosen.save() - - db.close() - - @commands.command(name='about', help='Who made the custom command') - async def about_command(self, ctx, command): - chosen = Command.get_or_none(fn.Lower(Command.name) == command.lower()) - if not chosen: - await ctx.send('https://tenor.com/blQnd.gif') - - embed = discord.Embed(title=f'About {chosen.name.title()}', color=0xFFFF00) - embed.add_field(name=f'Creator', value=f'{chosen.creator.name}', inline=False) - embed.add_field(name='Creation Date', value=f'{chosen.createtime}', inline=False) - embed.add_field(name='Message', value=f'{chosen.message}', inline=False) - - await ctx.send(content=None, embed=embed) - db.close() - - @commands.command(name='newcc', help='Create a new custom command') - @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') - async def new_custom_command(self, ctx, name, *, message): - time = datetime.now() - command = name - comm_message = message - - chosen = Command.get_or_none(fn.Lower(Command.name) == command.lower()) - if chosen: - await ctx.send('There is already a command with that name!') - return - - embed = discord.Embed(title='Is this what you want?', color=0x91329F) - embed.add_field(name='Command Name', value=command, inline=False) - embed.add_field(name='Message', value=comm_message, inline=False) - - await ctx.send(content=None, embed=embed) - - view = Confirm(responders=[ctx.author]) - question = await ctx.send('Should I create this for you?', view=view) - await view.wait() - - if not view.value: - await question.edit(content='You keep thinking on it.', view=None) - return - - this_person = Creator.get_or_none(Creator.discordid == ctx.author.id) - if not this_person: - this_person = Creator(name=f'{ctx.author.name}', discordid=f'{ctx.author.id}') - this_person.save() - - this_command = Command(name=command, message=comm_message, createtime=time, creator=this_person, last_used=time) - if this_command.save() == 1: - await question.edit(content=f'`!cc {this_command.name}` is now a thing!', view=None) - else: - await question.edit(content='Hmm...I couldn\'t add that. I might need a grown up to help.', view=None) - - db.close() - - @commands.command(name='delcc', help='Delete a custom command') - @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') - async def delete_custom_command(self, ctx, name): - this_command = Command.get_or_none(fn.Lower(Command.name) == name.lower()) - if not this_command: - await ctx.send('I couldn\'t find that command, sorry.') - return - - if this_command.creator.discordid != ctx.author.id and ctx.author.id != self.bot.owner_id: - await ctx.send('Looks like this isn\'t your command to delete.') - return - - embed = discord.Embed(title='Do you want to delete this command?', color=0x91329F) - embed.add_field(name='Command Name', value=this_command.name, inline=False) - embed.add_field(name='Message', value=this_command.message, inline=False) - - view = Confirm(responders=[ctx.author]) - question = await ctx.send(content=None, embed=embed, view=view) - await view.wait() - - if not view.value: - await question.edit(content='It stays for now.', view=None) - return - - if this_command.delete_instance() == 1: - await question.edit(view=None) - await ctx.send('He gone!') - else: - await ctx.send('Welp. That didn\'t work. Go complain to an adult, I guess.') - - db.close() - - @commands.command(name='allcc', help='Show all custom commands') - async def show_custom_commands(self, ctx, page=1): - def get_embed(this_page): - this_embed = discord.Embed(title=f'All Custom Commands', color=0x2F939F) - column_one = '' - column_two = '' - all_commands = Command.select().paginate(this_page, 40).order_by(Command.name) - for x in range(20): - try: - column_one += f'**{all_commands[x].name}** by {all_commands[x].creator.name}\n' - except Exception as e: - logger.error(f'Error building !allcc embed: {e}') - break - this_embed.add_field(name=f'{(this_page - 1) * 40 + 1}-{this_page * 40 - 20}', value=column_one) - - for x in range(20, 40): - try: - column_two += f'**{all_commands[x].name}** by {all_commands[x].creator.name}\n' - except Exception as e: - logger.error(f'Error building !allcc embed: {e}') - break - if len(column_two) > 0: - this_embed.add_field(name=f'{(this_page - 1) * 40 + 21}-{this_page * 40}', value=column_two) - - return this_embed - - page_num = page - total_commands = Command.select(Command.id) - last_page = math.ceil(total_commands.count()/40) - - if page_num > last_page: - await ctx.send(f'The max page number is {last_page}; going there now!') - page_num = last_page - - embed = get_embed(page_num) - embed.description = f'Page {page_num} / {last_page}' - view = Pagination(responders=[ctx.author]) - resp_message = await ctx.send(content=None, embed=embed, view=view) - - while True: - await view.wait() - - if view.value: - logger.info(f'got a value: {view.value}') - if view.value == 'left': - page_num = page_num - 1 if page_num > 1 else last_page - elif view.value == 'right': - page_num = page_num + 1 if page_num <= last_page else 1 - elif view.value == 'cancel': - await resp_message.edit(content=None, embed=embed, view=None) - break - view.value = None - else: - await resp_message.edit(content=None, embed=embed, view=None) - break - - # await resp_message.edit(content=None, embed=embed, view=None) - embed = get_embed(page_num) - embed.description = f'Page {page_num} / {last_page}' - view = Pagination(responders=[ctx.author]) - await resp_message.edit(content=None, embed=embed, view=view) - - db.close() - - @commands.command(name='mycc', aliases=['showcc'], help='Show my commands') - @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') - async def my_custom_commands(self, ctx): - this_creator = Creator.get_or_none(Creator.discordid == ctx.author.id) - - if not this_creator: - await ctx.send('It doesn\'t look like you\'ve created any custom commands. Try it out by running the ' - '!help newcc for the command syntax!') - return - - all_commands = Command.select().join(Creator).where(Command.creator == this_creator) - - if all_commands.count() == 0: - await ctx.send('It doesn\'t look like you\'ve created any custom commands. Try it out by running the ' - '!help newcc for the command syntax!') - return - - comm_message = '' - for x in all_commands: - comm_message += f'{x.name}\n' - - embed = discord.Embed(title=f'{ctx.author.name}\'s Commands', color=0x2F939F) - embed.add_field(name=f'Command Names', value=comm_message, inline=False) - - await ctx.send(content=None, embed=embed) - db.close() @app_commands.command(name='woulditdong', description='Log a dinger to see would it dong across SBa') @@ -475,98 +550,6 @@ class Fun(commands.Cog): await send_to_channel(self.bot, 'news-ticker', content=None, embed=embed) await interaction.edit_original_response(content=None, embed=embed) - # @commands.command(name='showcc', help='Show one person\'s custom commands') - # @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players') - # async def show_cc_command(self, ctx, ): - - # @commands.command(name='role', help='Toggle role') - # async def toggle_role_command(self, ctx, *, role_name): - # all_roles = [x.name for x in Roles.select().where(Roles.enabled)] - # - # async def toggle_role(full_role): - # if full_role in ctx.author.roles: - # await ctx.author.remove_roles(full_role) - # else: - # await ctx.author.add_roles(full_role) - # - # if len(role_name) < 4: - # await ctx.send('https://thumbs.gfycat.com/FrayedUnequaledGnat-size_restricted.gif') - # await ctx.send(f'What even is **{role_name}**...') - # db.close() - # return - # - # for name in all_roles: - # if role_name.lower() in name.lower(): - # try: - # this_role = discord.utils.get(ctx.guild.roles, name=name) - # await toggle_role(this_role) - # await ctx.send(random_conf_gif()) - # return - # except: - # await ctx.send(await get_emoji(ctx, 'fforrespect', False)) - # await ctx.send('I was not able to assign that role.') - # return - # - # await ctx.send(f'That doesn\'t sound familiar. **{role_name}**...did you make that shit up?') - - # @commands.command(name='showroles', help='Show toggleable roles') - # async def show_roles_command(self, ctx): - # all_roles = [x.name for x in Roles.select().where(Roles.enabled)] - # role_string = '\n- '.join(all_roles) - # - # embed = get_team_embed('Toggleable Roles', thumbnail=False) - # embed.description = 'Run !role to toggle the role on or off' - # embed.add_field(name='Role Names', value=f'- {role_string}') - # - # await ctx.send(content=None, embed=embed) - - # @commands.command(name='newrole', aliases=['removerole'], help='Make toggleable role') - # @commands.is_owner() - # async def make_toggleable_role_command(self, ctx, *, role_name): - # this_role = Roles.get_or_none(Roles.name == role_name) - # - # if not this_role: - # # Create the role if it doesn't exist - # - # this_role = Roles(name=role_name) - # this_role.save() - # if not discord.utils.get(ctx.guild.roles, name=this_role.name): - # await ctx.guild.create_role(name=f'{role_name}', mentionable=True) - # else: - # # Disable the role - # - # if this_role.enabled: - # this_role.enabled = False - # else: - # this_role.enabled = True - # this_role.save() - # this_role = discord.utils.get(ctx.guild.roles, name=this_role.name) - # - # if this_role: - # await this_role.edit(mentionable=False) - # else: - # await ctx.send('That role doesn\'t exist in the server.') - # - # await ctx.send(random_conf_gif()) - - # @commands.command(name='bulkrole', hidden=True) - # @commands.is_owner() - # async def bulkrole_command(self, ctx, *roles): - # all_roles = [] - # - # for x in roles: - # all_roles.append(discord.utils.get(ctx.guild.roles, name=x)) - # - # await ctx.send('On it. This could take a bit.') - # time_start = datetime.now() - # - # async for member in ctx.guild.fetch_members(): - # logger.warning(f'member: {member}') - # await member.add_roles(*all_roles) - # - # time_end = datetime.now() - # await ctx.send(f'All done! That took {time_end - time_start}') - async def setup(bot): await bot.add_cog(Fun(bot)) diff --git a/db_calls.py b/db_calls.py index 72789bb..7f45f32 100644 --- a/db_calls.py +++ b/db_calls.py @@ -236,6 +236,74 @@ async def get_player_headshot(player_name): return await get_player_photo(player_name) +### +# CUSTOM COMMANDS API FUNCTIONS +### + +async def get_custom_command_by_name(name: str): + """Get a custom command by name.""" + return await db_get(f'custom_commands/by_name/{name}', none_okay=True) + + +async def execute_custom_command(name: str): + """Execute a custom command and update usage statistics.""" + return await db_patch(f'custom_commands/by_name/{name}/execute', object_id=None, params=[]) + + +async def create_custom_command(command_data: dict): + """Create a new custom command.""" + return await db_post('custom_commands', payload=command_data) + + +async def update_custom_command(command_id: int, update_data: dict): + """Update an existing custom command.""" + return await db_put('custom_commands', object_id=command_id, payload=update_data) + + +async def delete_custom_command(command_id: int): + """Delete a custom command.""" + return await db_delete('custom_commands', object_id=command_id) + + +async def get_commands_by_creator(discord_id: int, page: int = 1, page_size: int = 25): + """Get all commands created by a specific Discord user.""" + params = [ + ('creator_discord_id', discord_id), + ('is_active', True), + ('page', page), + ('page_size', page_size) + ] + return await db_get('custom_commands', params=params, none_okay=True) + + +async def get_all_custom_commands(page: int = 1, page_size: int = 40, sort: str = 'name'): + """Get all custom commands with pagination.""" + params = [ + ('is_active', True), + ('sort', sort), + ('page', page), + ('page_size', page_size) + ] + return await db_get('custom_commands', params=params, none_okay=True) + + +async def get_or_create_creator(discord_id: int, username: str, display_name: Optional[str] = None): + """Get existing creator or create a new one.""" + # Try to get existing creator + existing = await db_get('custom_commands/creators', params=[('discord_id', discord_id)], none_okay=True) + + if existing and existing.get('creators') and len(existing['creators']) > 0: + return existing['creators'][0] + + # Create new creator + creator_data = { + 'discord_id': discord_id, + 'username': username, + 'display_name': display_name + } + return await db_post('custom_commands/creators', payload=creator_data) + + ### # TO BE DEPRECATED FUNCTIONS ### diff --git a/sba_is_fun.db b/sba_is_fun.db new file mode 100644 index 0000000000000000000000000000000000000000..895b8d426839ac4cfe8e544cb8f2fb1a8f9c5612 GIT binary patch literal 270336 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