From 26f29e6de7735970dda7ef026781beb6d452d88e Mon Sep 17 00:00:00 2001 From: Interitio Date: Wed, 3 Sep 2025 20:36:22 +1000 Subject: [PATCH] Initial commit --- README.md | 0 __init__.py | 0 data/koans.sql | 0 koans/__init__.py | 7 +++ koans/data.py | 0 koans/koans.py | 0 koans/twitch/component.py | 123 ++++++++++++++++++++++++++++++++++++++ requirements.txt | 0 8 files changed, 130 insertions(+) create mode 100644 README.md create mode 100644 __init__.py create mode 100644 data/koans.sql create mode 100644 koans/__init__.py create mode 100644 koans/data.py create mode 100644 koans/koans.py create mode 100644 koans/twitch/component.py create mode 100644 requirements.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/data/koans.sql b/data/koans.sql new file mode 100644 index 0000000..e69de29 diff --git a/koans/__init__.py b/koans/__init__.py new file mode 100644 index 0000000..4070a96 --- /dev/null +++ b/koans/__init__.py @@ -0,0 +1,7 @@ +import logging + +logger = logging.getLogger(__name__) + +async def setup(bot): + from .component import KoanComponent + await bot.add_component(KoanComponent(bot)) diff --git a/koans/data.py b/koans/data.py new file mode 100644 index 0000000..e69de29 diff --git a/koans/koans.py b/koans/koans.py new file mode 100644 index 0000000..e69de29 diff --git a/koans/twitch/component.py b/koans/twitch/component.py new file mode 100644 index 0000000..b0fb7ce --- /dev/null +++ b/koans/twitch/component.py @@ -0,0 +1,123 @@ +from typing import Optional +import random +import twitchio +from twitchio.ext import commands as cmds + +from datamodels import Koan, Communities + +from . import logger + + +class KoanComponent(cmds.Component): + def __init__(self, bot): + self.bot = bot + + @cmds.Component.listener() + async def event_message(self, payload: twitchio.ChatMessage) -> None: + print(f"[{payload.broadcaster.name}] - {payload.chatter.name}: {payload.text}") + + @cmds.group(invoke_fallback=True) + async def koans(self, ctx: cmds.Context) -> None: + """ + List the (names of the) koans in this channel. + + !koans + """ + community = await Communities.fetch_or_create(twitchid=ctx.channel.id, name=ctx.channel.name) + cid = community.communityid + + koans = await Koan.fetch_where(communityid=cid) + if koans: + names = ', '.join(koan.name for koan in koans) + await ctx.reply( + f"Koans: {names}" + ) + else: + await ctx.reply("No koans have been made in this channel!") + + @koans.command(name='add', aliases=['new', 'create']) + async def koans_add(self, ctx: cmds.Context, name: str, *, text: str): + """ + Add or overwrite a koan to this channel. + + !koans add wind This is a wind koan + """ + community = await Communities.fetch_or_create(twitchid=ctx.channel.id, name=ctx.channel.name) + cid = community.communityid + + name = name.lower() + + assert isinstance(ctx.author, twitchio.Chatter) + if (ctx.author.moderator or ctx.author.broadcaster): + # Delete the koan with this name if it exists + existing = await Koan.table.delete_where( + communityid=cid, + name=name, + ) + + # Insert the new koan + await Koan.create( + communityid=cid, + name=name, + message=text + ) + + # Ack + if existing: + await ctx.reply(f"Updated the koan '{name}'") + else: + await ctx.reply(f"Created the new koan '{name}'") + + @koans.command(name='del', aliases=['delete', 'rm', 'remove']) + async def koans_del(self, ctx: cmds.Context, name: str): + """ + Remove a koan from this channel by name. + + !koans del wind + """ + community = await Communities.fetch_or_create(twitchid=ctx.channel.id, name=ctx.channel.name) + cid = community.communityid + + name = name.lower() + + assert isinstance(ctx.author, twitchio.Chatter) + if (ctx.author.moderator or ctx.author.broadcaster): + # Delete the koan with this name if it exists + existing = await Koan.table.delete_where( + communityid=cid, + name=name, + ) + if existing: + await ctx.reply(f"Deleted the koan '{name}'") + else: + await ctx.reply(f"The koan '{name}' does not exist to delete!") + + @cmds.command(name='koan') + async def koan(self, ctx: cmds.Context, name: Optional[str] = None): + """ + Show a koan from this channel. Optionally by name. + + !koan + !koan wind + """ + community = await Communities.fetch_or_create(twitchid=ctx.channel.id, name=ctx.channel.name) + cid = community.communityid + + if name is not None: + name = name.lower() + koans = await Koan.fetch_where( + communityid=cid, + name=name + ) + if koans: + koan = koans[0] + await ctx.reply(koan.message) + else: + await ctx.reply(f"The requested koan '{name}' does not exist! Use '{ctx.prefix}koans' to see all the koans.") + else: + koans = await Koan.fetch_where(communityid=cid) + if koans: + koan = random.choice(koans) + await ctx.reply(koan.message) + else: + await ctx.reply("This channel doesn't have any koans!") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e69de29