Initial commit, with actual code
This commit is contained in:
parent
2b53ee39b9
commit
156c71a0ec
7 changed files with 141 additions and 0 deletions
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Dev
|
||||||
|
.mypy_cache/
|
||||||
|
.python-version
|
||||||
|
poetry.lock
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# Secrets and static files
|
||||||
|
.env
|
||||||
|
store/
|
||||||
|
attachments/
|
21
pyproject.toml
Normal file
21
pyproject.toml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
[tool.poetry]
|
||||||
|
name = "tomservobot"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["jodhus <josh@jodh.us>"]
|
||||||
|
readme = "README.md"
|
||||||
|
packages = [{include = "tomservobot", from = "src"}]
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = ">=3.12,<3.13"
|
||||||
|
nio-bot = {extras = ["cli", "e2ee"], version = "^1.1.0.post3"}
|
||||||
|
python-decouple = "^3.8"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
pylint = "^3.2.3"
|
||||||
|
mypy = "^1.10.0"
|
||||||
|
black = "^24.4.2"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
42
src/main.py
Normal file
42
src/main.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from decouple import config
|
||||||
|
from niobot import Context, NioBot, SyncResponse
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = config("DEBUG", default=False, cast=bool)
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
else:
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
bot = NioBot(
|
||||||
|
homeserver=config("HOMESERVER", cast=str),
|
||||||
|
user_id=config("USER_ID", cast=str),
|
||||||
|
device_id=config("DEVICE_ID", default="deez-nutz", cast=str),
|
||||||
|
store_path=config("STORE_PATH", default="./store", cast=str),
|
||||||
|
command_prefix="!",
|
||||||
|
case_insensitive=True,
|
||||||
|
owner_id=config("OWNER_ID", cast=str),
|
||||||
|
)
|
||||||
|
|
||||||
|
bot.mount_module("tomservobot.chance")
|
||||||
|
bot.mount_module("tomservobot.reactions")
|
||||||
|
|
||||||
|
|
||||||
|
@bot.on_event("ready")
|
||||||
|
async def on_ready(_: SyncResponse):
|
||||||
|
"""Triggers when the bot is completely loaded."""
|
||||||
|
print("Bot is ready!")
|
||||||
|
|
||||||
|
|
||||||
|
@bot.on_event("command_error")
|
||||||
|
async def on_command_error(_: Context, error: Exception):
|
||||||
|
"""Triggers when an error occurs in a command so we can handle it."""
|
||||||
|
print(f"Error: {error}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
bot.run(access_token=config("ACCESS_TOKEN", cast=str))
|
0
src/tomservobot/__init__.py
Normal file
0
src/tomservobot/__init__.py
Normal file
45
src/tomservobot/chance.py
Normal file
45
src/tomservobot/chance.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
from random import randint
|
||||||
|
import re
|
||||||
|
|
||||||
|
import niobot
|
||||||
|
from niobot import (
|
||||||
|
CommandParserError,
|
||||||
|
Context,
|
||||||
|
Module,
|
||||||
|
NioBot,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ChanceModule(Module):
|
||||||
|
"""Commands that simulate chance (Dice rolls, card selection, etc)."""
|
||||||
|
|
||||||
|
def __init__(self, bot: NioBot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@niobot.command()
|
||||||
|
async def roll(self, ctx: Context, dice: str):
|
||||||
|
"""Roll some dice with an optional modifier."""
|
||||||
|
valid = re.match(r"(\d+)d(\d+)([\+-/\*]\d+)?", dice)
|
||||||
|
if valid is None:
|
||||||
|
await ctx.respond("Error: Invalid dice roll notation.")
|
||||||
|
raise CommandParserError("Invalid dice roll notation.")
|
||||||
|
dice_parts = (int(valid.group(1)), int(valid.group(2)), valid.group(3))
|
||||||
|
|
||||||
|
if not 1 <= dice_parts[0] <= 100:
|
||||||
|
await ctx.respond("Error: Can only roll between 1 and 100 dice.")
|
||||||
|
raise CommandParserError("Can only roll between 1 and 100 dice.")
|
||||||
|
|
||||||
|
if not 2 <= dice_parts[1] <= 100:
|
||||||
|
await ctx.respond("Error: Dice must have between 2 and 100 faces.")
|
||||||
|
raise CommandParserError("Dice must have between 2 and 100 faces.")
|
||||||
|
|
||||||
|
rolls: list[int] = []
|
||||||
|
for _ in range(dice_parts[0]):
|
||||||
|
rolls.append(randint(1, dice_parts[1]))
|
||||||
|
total = sum(rolls)
|
||||||
|
|
||||||
|
await ctx.respond(f"{dice}: {total} ({rolls})")
|
||||||
|
|
||||||
|
# await ctx.client.send_message(
|
||||||
|
# ctx.room, f"{dice_parts[0]}, {dice_parts[1]}, {dice_parts[2]}"
|
||||||
|
# )
|
21
src/tomservobot/reactions.py
Normal file
21
src/tomservobot/reactions.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from decouple import config
|
||||||
|
import niobot
|
||||||
|
|
||||||
|
|
||||||
|
ATTACH_PATH = Path(config("ATTACH_PATH", default="./attachments/", cast=str))
|
||||||
|
|
||||||
|
|
||||||
|
class ReactionsModule(niobot.Module):
|
||||||
|
"""Specifically for reactions/replies to certain comments/events."""
|
||||||
|
|
||||||
|
def __init__(self, bot: niobot.NioBot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@niobot.command()
|
||||||
|
async def weekend(self, ctx: niobot.Context):
|
||||||
|
"""Ladies and gentlemen--the weekend. . ."""
|
||||||
|
print(ATTACH_PATH / "weekend.mp4")
|
||||||
|
attachment = await niobot.VideoAttachment.from_file(ATTACH_PATH / "weekend.mp4")
|
||||||
|
await ctx.client.send_message(ctx.room, None, attachment)
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
Loading…
Reference in a new issue