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 []`\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)