import os from datetime import datetime, timedelta from pathlib import Path from time import time from flask import ( Blueprint, abort, make_response, render_template, request, send_file, ) import magic from htmlmin import minify from musicbrainzngs import get_image_front from .modules.api.lb import data as lb_data from .modules.api.steam import data as steam_data def tmsmp(sec: int) -> str: if sec == 0: return 0 elif sec < 60: return f"{sec} s" elif sec < 60*60: minutes = round(sec / 60, 1) return f"{minutes:.0f} m" if minutes.is_integer() else f"{minutes:.1f} m" elif sec < 60*60*24: hours = round(sec / 3600, 1) return f"{hours:.0f} h" if hours.is_integer() else f"{hours:.1f} h" else: days = round(sec / 86400, 1) return f"{days:.0f} d" if days.is_integer() else f"{days:.1f} d" def utmsmp(unix: int) -> str: return datetime \ .utcfromtimestamp(unix) \ .strftime('%Y-%m-%d %H:%M:%S') def rtmsmp(unix: int) -> str: return tmsmp(int(time() - unix)) bp = Blueprint( "risdeveau", __name__, subdomain="risdeveau", template_folder="..", static_folder=None ) def render_tmpl(filename: str, **kwargs) -> str: template_path = os.path.join("risdeveau/templates", filename) return minify( render_template(template_path, **kwargs), remove_empty_space=True ) @bp.route("/static/") def static(filename: str): static_folders = ("static", "../root/static") for dir in static_folders: if os.path.exists(path := os.path.join("blueprints/risdeveau", dir, filename)): return send_file(path) return abort(404) @bp.route("/asset/mb/") def mb_cover(mbid): r = make_response(image := get_image_front(mbid, "250")) r.headers['Content-Type'] = magic.from_buffer(image[:2048], mime=True) r.headers['Cache-Control'] = 'public, max-age=86400' r.headers['Expires'] = (datetime.now() + timedelta(days=1)) \ .strftime('%a, %d %b %Y %H:%M:%S GMT') return r args = { "lb": lb_data, "steam": steam_data, "tmsmp": tmsmp, "utmsmp": utmsmp, "rtmsmp": rtmsmp } @bp.route("/") def index(): return render_tmpl('index.pug', **args) @bp.route("/m/") def module(module): if none_match := request.headers.get('if-none-match'): match module: case "listenbrainz": if none_match == lb_data['etag']: return '', 304 case "steam": if none_match == steam_data['etag']: return '', 304 return render_tmpl(f'{module}.pug', **args)