Run bottleclip generator as subprocess

This commit is contained in:
polyfloyd 2025-05-09 17:13:53 +02:00
parent 3a721d9e29
commit deced2d3a7
4 changed files with 46 additions and 55 deletions

38
bottleclip.py Normal file
View file

@ -0,0 +1,38 @@
import os
import subprocess
from os.path import abspath, join
from tempfile import NamedTemporaryFile
from typing import List
def resource_dir() -> str:
p = os.getenv("BOTTLECLIP_RESOURCES")
assert p is not None
return p
def list_icons() -> List[str]:
files = os.listdir(join(resource_dir(), "icons"))
return sorted(set(files) - {"README.md"})
def create_stl(label: str, icon: str, ears: bool) -> NamedTemporaryFile:
icon_path = abspath(join(resource_dir(), "icons", icon))
ears_str = "true" if ears else "false"
scad = NamedTemporaryFile(dir=resource_dir(), suffix=".scad")
with open(join(resource_dir(), "bottle-clip.scad"), "rb") as f:
scad.write(f.read())
scad.write(b"\n\n")
scad.write(
f'bottle_clip(name="{label}", logo="{icon_path}", ears={ears_str});'.encode(
"utf-8"
)
)
scad.flush()
stl = NamedTemporaryFile(suffix=".scad")
subprocess.run(["openscad", scad.name, "--export-format", "binstl", "-o", stl.name])
stl.seek(0)
return stl

60
main.py
View file

@ -5,13 +5,14 @@ import os
import sys import sys
from time import sleep from time import sleep
import aiohttp
import aiomqtt import aiomqtt
import pytz import pytz
from discord import Intents from discord import File, Intents
from discord.ext import commands from discord.ext import commands
from discord_webhook import DiscordEmbed, DiscordWebhook from discord_webhook import DiscordEmbed, DiscordWebhook
import bottleclip as clip
mqtt_host = os.getenv("MQTT_HOST") mqtt_host = os.getenv("MQTT_HOST")
if not mqtt_host: if not mqtt_host:
print("MQTT_HOST unset") print("MQTT_HOST unset")
@ -27,11 +28,6 @@ if not webhook_url:
print("DISCORD_WEBHOOK_URL unset") print("DISCORD_WEBHOOK_URL unset")
sys.exit(1) sys.exit(1)
bottleclip_git_token = os.getenv("BOTTLECLIP_GIT_TOKEN")
if not bottleclip_git_token:
print("BOTTLECLIP_GIT_TOKEN unset")
sys.exit(1)
timezone = pytz.timezone("Europe/Amsterdam") timezone = pytz.timezone("Europe/Amsterdam")
# Discord bot stuff # Discord bot stuff
@ -116,28 +112,7 @@ async def np(ctx):
# !bottleclip # !bottleclip
@HobbyBot.command(description="Generate a bottle-clip STL file suitable for printing") @HobbyBot.command(description="Generate a bottle-clip STL file suitable for printing")
async def bottleclip(ctx, icon: str = "", ears: bool = False): async def bottleclip(ctx, icon: str = "", ears: bool = False):
git_api = "https://git.bitlair.nl/api/v1" icons = clip.list_icons()
owner = "bitlair"
repo = "bottle-clip"
flow = "stl.yaml"
auth = {
"Authorization": f"Bearer {bottleclip_git_token}",
}
icons = {
"thing-logos/glider.dxf",
"thing-logos/Club_mate_logo.dxf",
"thing-logos/chaosknoten.dxf",
"thing-logos/camprocket.dxf",
"pixel-cats/laying-left.svg",
"pixel-cats/laying-right.svg",
"pixel-cats/sitting-left.svg",
"pixel-cats/sitting-right.svg",
"pixel-cats/spooked-left.svg",
"pixel-cats/spooked-right.svg",
"pixel-cats/standing-left.svg",
"pixel-cats/standing-right.svg",
}
if icon not in icons: if icon not in icons:
await ctx.reply( await ctx.reply(
f"usage: `!bottleclip <icon> [<ears y|n>]`\n* `icon` must be one of {', '.join(icons)}" f"usage: `!bottleclip <icon> [<ears y|n>]`\n* `icon` must be one of {', '.join(icons)}"
@ -145,30 +120,11 @@ async def bottleclip(ctx, icon: str = "", ears: bool = False):
return return
async with ctx.typing(): async with ctx.typing():
async with aiohttp.ClientSession() as sess: label = ctx.author.nick or ctx.author.global_name
dispatch_body = { stl_file = clip.create_stl(label, icon, ears)
"inputs": {
"label": ctx.author.nick,
"icon": icon,
"ears": "true" if ears else "false",
},
"ref": "main",
"return_run_info": True,
}
async with sess.post(
f"{git_api}/repos/{owner}/{repo}/actions/workflows/{flow}/dispatches",
headers=auth,
json=dispatch_body,
) as response:
if response.status != 201:
await ctx.reply("Meh, stuk")
return
r = await response.json()
run_number = r["run_number"]
await ctx.reply( attach = File(stl_file.name, filename=f"{label}.stl")
f"https://git.bitlair.nl/bitlair/bottle-clip/actions/runs/{run_number}" await ctx.reply("Ok! Hier is je flessenclip", file=attach)
)
def webhook_message(msg): def webhook_message(msg):

View file

@ -5,7 +5,6 @@ description = "Bitlair Discord Bot"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [
"aiohttp>=3.11.18",
"aiomqtt>=2.4.0", "aiomqtt>=2.4.0",
"discord-py>=2.5.2", "discord-py>=2.5.2",
"discord-webhook>=1.4.1", "discord-webhook>=1.4.1",

2
uv.lock generated
View file

@ -186,7 +186,6 @@ name = "discord-bot"
version = "0.1.0" version = "0.1.0"
source = { virtual = "." } source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "aiohttp" },
{ name = "aiomqtt" }, { name = "aiomqtt" },
{ name = "discord-py" }, { name = "discord-py" },
{ name = "discord-webhook" }, { name = "discord-webhook" },
@ -195,7 +194,6 @@ dependencies = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "aiohttp", specifier = ">=3.11.18" },
{ name = "aiomqtt", specifier = ">=2.4.0" }, { name = "aiomqtt", specifier = ">=2.4.0" },
{ name = "discord-py", specifier = ">=2.5.2" }, { name = "discord-py", specifier = ">=2.5.2" },
{ name = "discord-webhook", specifier = ">=1.4.1" }, { name = "discord-webhook", specifier = ">=1.4.1" },