bot/commands/bottleclip.py

64 lines
1.8 KiB
Python

import os
import subprocess
from os.path import abspath, join, splitext
from tempfile import NamedTemporaryFile
from typing import List
from discord import File
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"
font_path = abspath(join(resource_dir(), "write/orbitron.dxf"))
scad = NamedTemporaryFile(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}, font="{font_path}");'.encode(
"utf-8"
)
)
scad.flush()
stl = NamedTemporaryFile(suffix=".scad")
subprocess.run(
["openscad", scad.name, "--export-format", "binstl", "-o", stl.name],
env={
"OPENSCADPATH": resource_dir(),
},
)
stl.seek(0)
return stl
async def command(ctx, icon: str = "", ears: bool = False):
icons = list_icons()
if icon not in icons:
await ctx.reply(
f"usage: `!bottleclip <icon> [<ears y|n>]`\n* `icon` must be one of {', '.join(icons)}"
)
return
async with ctx.typing():
label = ctx.author.nick or ctx.author.global_name
stl_file = create_stl(label, icon, ears)
icon_name, _ = splitext(icon)
with_ears = "_ears" if ears else ""
attach = File(stl_file.name, filename=f"{label}_{icon_name}{with_ears}.stl")
await ctx.reply("Ok! Hier is je flessenclip", file=attach)