95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
## Copyright © 2026 Olaf Kolkman
|
|
## SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from pathlib import Path
|
|
from urllib.request import urlopen
|
|
|
|
|
|
FONT_SOURCES = {
|
|
'Asset-Regular.ttf': 'https://fonts.gstatic.com/s/asset/v30/SLXGc1na-mM4cWIm.ttf',
|
|
'DMSans-Regular.ttf': 'https://fonts.gstatic.com/s/dmsans/v17/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAopxhTg.ttf',
|
|
'DMSans-Medium.ttf': 'https://fonts.gstatic.com/s/dmsans/v17/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAkJxhTg.ttf',
|
|
'DMSans-SemiBold.ttf': 'https://fonts.gstatic.com/s/dmsans/v17/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAfJthTg.ttf',
|
|
'DMSans-Bold.ttf': 'https://fonts.gstatic.com/s/dmsans/v17/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwARZthTg.ttf',
|
|
'SpaceGrotesk-Medium.ttf': 'https://fonts.gstatic.com/s/spacegrotesk/v22/V8mQoQDjQSkFtoMM3T6r8E7mF71Q-gOoraIAEj7aUUsj.ttf',
|
|
'SpaceGrotesk-SemiBold.ttf': 'https://fonts.gstatic.com/s/spacegrotesk/v22/V8mQoQDjQSkFtoMM3T6r8E7mF71Q-gOoraIAEj42Vksj.ttf',
|
|
'SpaceGrotesk-Bold.ttf': 'https://fonts.gstatic.com/s/spacegrotesk/v22/V8mQoQDjQSkFtoMM3T6r8E7mF71Q-gOoraIAEj4PVksj.ttf',
|
|
}
|
|
|
|
FONT_CSS = """@font-face {
|
|
font-family: 'Asset';
|
|
font-style: normal;
|
|
font-weight: 400;
|
|
font-display: swap;
|
|
src: url('Asset-Regular.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'DM Sans';
|
|
font-style: normal;
|
|
font-weight: 400;
|
|
font-display: swap;
|
|
src: url('DMSans-Regular.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'DM Sans';
|
|
font-style: normal;
|
|
font-weight: 500;
|
|
font-display: swap;
|
|
src: url('DMSans-Medium.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'DM Sans';
|
|
font-style: normal;
|
|
font-weight: 600;
|
|
font-display: swap;
|
|
src: url('DMSans-SemiBold.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'DM Sans';
|
|
font-style: normal;
|
|
font-weight: 700;
|
|
font-display: swap;
|
|
src: url('DMSans-Bold.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Space Grotesk';
|
|
font-style: normal;
|
|
font-weight: 500;
|
|
font-display: swap;
|
|
src: url('SpaceGrotesk-Medium.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Space Grotesk';
|
|
font-style: normal;
|
|
font-weight: 600;
|
|
font-display: swap;
|
|
src: url('SpaceGrotesk-SemiBold.ttf') format('truetype');
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Space Grotesk';
|
|
font-style: normal;
|
|
font-weight: 700;
|
|
font-display: swap;
|
|
src: url('SpaceGrotesk-Bold.ttf') format('truetype');
|
|
}
|
|
"""
|
|
|
|
|
|
def main() -> None:
|
|
target_dir = Path('frontend/static/fonts')
|
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
for filename, url in FONT_SOURCES.items():
|
|
with urlopen(url, timeout=30) as response:
|
|
(target_dir / filename).write_bytes(response.read())
|
|
(target_dir / 'fonts.css').write_text(FONT_CSS, encoding='utf-8')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main() |