from pathlib import Path from urllib.parse import urlparse import cherrypy from mako.template import Template import config import ovenapi class Viewer: def __init__(self): self.webcall_template = Path("template/webcall.mako").read_text(encoding="utf-8") self.single_template = Path("template/single.mako").read_text(encoding="utf-8") self.api = ovenapi.get_api_handle(username=config.API_USER, password=config.API_PASS) def app_is_okay(self, app_name): # If we can't access the API, we can't check if an app exists, just okay it if not config.is_api_ready(): return True return self.api.app_exists(app_name) def _cp_dispatch(self, vpath): # Extract an app and a page, a la match1/slot1 if len(vpath): cherrypy.request.params["app"] = vpath.pop(0) if len(vpath): cherrypy.request.params["page"] = vpath.pop(0) # This should leave `/` as our path, triggering index() return self @cherrypy.expose def index(self, **params: dict) -> bytes | str: if "app" in params and isinstance(params["app"], str): # Check if the app even exists. If not, fast 404 if not self.app_is_okay(params["app"]): cherrypy.response.status = 404 return "App not found" # Get domain for templates domain = urlparse(cherrypy.request.base).netloc # Any subpath is presumed to be a single player interface for app/stream if "page" in params: return Template(self.single_template).render( domain=domain, app_name=params["app"], stream_name=params["page"] ) # No stream key = pass webcall interface return Template(self.webcall_template).render(domain=domain, app_name=params["app"]) # If we have no subpath at all, return a blank page return ""