diff --git a/modules/server/containers/apps/favicon.nix b/modules/server/containers/apps/favicon.nix index 785b8b3..b4c9e4f 100644 --- a/modules/server/containers/apps/favicon.nix +++ b/modules/server/containers/apps/favicon.nix @@ -3,6 +3,7 @@ let serverCfg = config.syscfg.server; mediaCfg = config.syscfg.media; port = 8080; + assetSize = 64; cacheControl = containerCfg.extra.cacheControl or "public, max-age=86400"; priority = toString (containerCfg.extra.priority or 2147482647); logoSvgFileName = builtins.baseNameOf (toString mediaCfg.logo.svg); @@ -48,6 +49,7 @@ let CACHE_DIR = Path(os.environ.get("FAVICON_CACHE_DIR", "/cache")) LISTEN_HOST = os.environ.get("FAVICON_LISTEN_HOST", "0.0.0.0") LISTEN_PORT = int(os.environ.get("FAVICON_PORT", "8080")) + ASSET_SIZE = int(os.environ.get("FAVICON_ASSET_SIZE", "${toString assetSize}")) DEFAULT_CACHE_CONTROL = "public, max-age=86400" with open(CONFIG_PATH, "r", encoding="utf-8") as fh: @@ -66,44 +68,31 @@ let def _color(value, fallback): return value if isinstance(value, str) and value else fallback + def _replace_svg_color(svg, attribute, color): + if attribute in {"fill", "stroke"}: + svg = re.sub( + rf'{attribute}="(?!none\\b)[^"]*"', + f'{attribute}="{color}"', + svg, + flags=re.IGNORECASE, + ) + svg = re.sub( + rf"{attribute}='(?!none\\b)[^']*'", + f"{attribute}='{color}'", + svg, + flags=re.IGNORECASE, + ) + return re.sub( + rf"{attribute}\\s*:\\s*(?!none\\b)[^;\"\\']+", + f"{attribute}:{color}", + svg, + flags=re.IGNORECASE, + ) + def _tinted_logo_data_uri(color): svg = LOGO_BYTES.decode("utf-8") - svg = re.sub( - r'fill="(?!none\b)[^"]*"', - f'fill="{color}"', - svg, - flags=re.IGNORECASE, - ) - svg = re.sub( - r"fill='(?!none\b)[^']*'", - f"fill='{color}'", - svg, - flags=re.IGNORECASE, - ) - svg = re.sub( - r'stroke="(?!none\b)[^"]*"', - f'stroke="{color}"', - svg, - flags=re.IGNORECASE, - ) - svg = re.sub( - r"stroke='(?!none\b)[^']*'", - f"stroke='{color}'", - svg, - flags=re.IGNORECASE, - ) - svg = re.sub( - r'fill\s*:\s*(?!none\b)[^;"\']+', - f"fill:{color}", - svg, - flags=re.IGNORECASE, - ) - svg = re.sub( - r'stroke\s*:\s*(?!none\b)[^;"\']+', - f"stroke:{color}", - svg, - flags=re.IGNORECASE, - ) + svg = _replace_svg_color(svg, "fill", color) + svg = _replace_svg_color(svg, "stroke", color) return "data:image/svg+xml;base64," + base64.b64encode(svg.encode("utf-8")).decode("ascii") def _border_radius(): @@ -133,9 +122,9 @@ let CACHE_DIR.mkdir(parents=True, exist_ok=True) svg = _render_svg(profile).encode("utf-8") - png_bytes = cairosvg.svg2png(bytestring=svg, output_width=64, output_height=64) + png_bytes = cairosvg.svg2png(bytestring=svg, output_width=ASSET_SIZE, output_height=ASSET_SIZE) image = Image.open(BytesIO(png_bytes)) - image.save(target, format="ICO", sizes=[(64, 64)]) + image.save(target, format="ICO", sizes=[(ASSET_SIZE, ASSET_SIZE)]) image.close() return target @@ -177,8 +166,6 @@ let tag = "1"; contents = [ pythonEnv - pkgs.fontconfig - pkgs.dejavu_fonts pkgs.cacert pkgs.tzdata ]; @@ -207,8 +194,7 @@ in { FAVICON_LOGO = logoSvgMount; FAVICON_CACHE_DIR = "/cache"; FAVICON_PORT = toString port; - FONTCONFIG_FILE = "${pkgs.fontconfig.out}/etc/fonts/fonts.conf"; - FONTCONFIG_PATH = "${pkgs.fontconfig.out}/etc/fonts"; + FAVICON_ASSET_SIZE = toString assetSize; }; extraLabels = { "traefik.enable" = "true";