import asyncio import datetime import html import json import os import threading import time import weakref from typing import Optional, Callable import aiohttp from aiohttp import web import supybot.log as log from .store import SongRequest as SongRequestModel, Session, VALID_STATUSES TEMPLATES_DIR = os.path.join(os.path.dirname(__file__), "templates") STATIC_DIR = os.path.join(os.path.dirname(__file__), "static") def _render_alternates(request_id: int, alternates_json: str, status: str) -> str: """Render alternate tracks as a collapsible details section.""" if not alternates_json: return "" try: alts = json.loads(alternates_json) except (json.JSONDecodeError, TypeError): return "" if not alts: return "" esc = html.escape show_approve = status == "pending" items = [] for idx, alt in enumerate(alts): artwork = esc(alt.get("artwork_url", "").replace("600x600", "100x100")) title = esc(alt.get("title", "")) artist = esc(alt.get("artist", "")) url = esc(alt.get("apple_music_url", "")) approve_btn = "" if show_approve: approve_btn = ( f'' ) items.append( f'