common/tcommon/views/favicon.py

64 lines
2.1 KiB
Python
Raw Normal View History

2024-12-20 23:44:40 -05:00
from cairosvg import svg2png
from django.http import HttpResponse, HttpResponseServerError
2024-12-23 13:22:20 -05:00
from django.views.decorators.cache import cache_control, cache_page
2024-12-20 23:44:40 -05:00
favicon = """<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
<rect width="64" height="64" x=".253" y=".167" fill="{{ BASE }}" rx="16"/>
<path fill="{{ ACCENT }}" d="M34.906 7v11.057H47.75v8.901H34.906v16.516q0 2.712 1.08 3.669 1.078.956 4.28.956h6.405V57H35.985q-7.379 0-10.459-3.077t-3.08-10.449V26.958H16.25v-8.901h6.196V7Z"/>
</svg>"""
colors = {
"base": {
"light": "#eff1f5",
"dark": "#1e1e2e"
},
"accent": {
"light": {
"rosewater": "#dc8a78",
"flamingo": "#dd7878",
"pink": "#ea76cb",
"mauve": "#8839ef",
"red": "#d20f39",
"maroon": "#e64553",
"peach": "#fe640b",
"yellow": "#df8e1d",
"green": "#40a02b",
"teal": "#179299",
"sky": "#04a5e5",
"sapphire": "#209fb5",
"blue": "#1e66f5",
"lavender": "#7287fd"
},
"dark": {
"rosewater": "#f5e0dc",
"flamingo": "#f2cdcd",
"pink": "#f5c2e7",
"mauve": "#cba6f7",
"red": "#f38ba8",
"maroon": "#eba0ac",
"peach": "#fab387",
"yellow": "#f9e2af",
"green": "#a6e3a1",
"teal": "#94e2d5",
"sky": "#89dceb",
"sapphire": "#74c7ec",
"blue": "#89b4fa",
"lavender": "#b4befe"
}
}
}
2024-12-23 13:22:20 -05:00
@cache_control(**{"max-age": 60 * 60 * 24 * 30})
2024-12-20 23:44:40 -05:00
@cache_page(60 * 60 * 2)
def generate_favicon(request, theme, accent) -> HttpResponse | HttpResponseServerError:
png_data: bytes | None = svg2png(
favicon.replace("{{ BASE }}", colors["base"][theme]).replace("{{ ACCENT }}", colors["accent"][theme][accent]),
output_width=64,
output_height=64
)
if not isinstance(png_data, bytes):
return HttpResponseServerError("500 Internal Server Error")
return HttpResponse(png_data, content_type="image/png")