chore: automatic commit 2025-04-30 12:48
This commit is contained in:
225
utils/download_resources.py
Normal file
225
utils/download_resources.py
Normal file
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Dieses Skript lädt externe Ressourcen wie Font Awesome, Tailwind CSS und Alpine.js herunter
|
||||
und installiert sie lokal, um die Abhängigkeit von externen CDNs zu vermeiden und
|
||||
die Content Security Policy zu erfüllen.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import requests
|
||||
import zipfile
|
||||
import io
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# URLs für die Ressourcen
|
||||
RESOURCES = {
|
||||
'alpine.js': 'https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js',
|
||||
'font_awesome': 'https://use.fontawesome.com/releases/v6.4.0/fontawesome-free-6.4.0-web.zip',
|
||||
'inter_font_300': 'https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2',
|
||||
'inter_font_400': 'https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7SUc.woff2',
|
||||
'inter_font_500': 'https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7SUc.woff2',
|
||||
'inter_font_600': 'https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7SUc.woff2',
|
||||
'inter_font_700': 'https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7SUc.woff2',
|
||||
'jetbrains_font_400': 'https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxDcwg.woff2',
|
||||
'jetbrains_font_500': 'https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx3cwhsk.woff2',
|
||||
'jetbrains_font_700': 'https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxTcwhsk.woff2',
|
||||
}
|
||||
|
||||
# Zielverzeichnisse
|
||||
DIRECTORIES = {
|
||||
'js': os.path.join(BASE_DIR, 'static', 'js'),
|
||||
'css': os.path.join(BASE_DIR, 'static', 'css'),
|
||||
'fonts': os.path.join(BASE_DIR, 'static', 'fonts'),
|
||||
'webfonts': os.path.join(BASE_DIR, 'static', 'webfonts'),
|
||||
}
|
||||
|
||||
def download_file(url, filepath):
|
||||
"""Lädt eine Datei von einer URL herunter und speichert sie lokal."""
|
||||
response = requests.get(url, stream=True)
|
||||
if response.status_code == 200:
|
||||
with open(filepath, 'wb') as f:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
print(f"✅ Heruntergeladen: {os.path.basename(filepath)}")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Fehler beim Herunterladen von {url}: {response.status_code}")
|
||||
return False
|
||||
|
||||
def extract_zip(zip_data, extract_to):
|
||||
"""Extrahiert eine ZIP-Datei in das angegebene Verzeichnis."""
|
||||
with zipfile.ZipFile(io.BytesIO(zip_data)) as zip_ref:
|
||||
zip_ref.extractall(extract_to)
|
||||
|
||||
def setup_directories():
|
||||
"""Erstellt die benötigten Verzeichnisse, falls sie nicht existieren."""
|
||||
for directory in DIRECTORIES.values():
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
print(f"📁 Verzeichnis erstellt/überprüft: {directory}")
|
||||
|
||||
def download_alpine():
|
||||
"""Lädt Alpine.js herunter."""
|
||||
url = RESOURCES['alpine.js']
|
||||
filepath = os.path.join(DIRECTORIES['js'], 'alpine.min.js')
|
||||
download_file(url, filepath)
|
||||
|
||||
def download_font_awesome():
|
||||
"""Lädt Font Awesome herunter und extrahiert die Dateien."""
|
||||
url = RESOURCES['font_awesome']
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
# Temporäres Verzeichnis für die Extraktion
|
||||
temp_dir = os.path.join(BASE_DIR, 'temp_fontawesome')
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
|
||||
# ZIP-Datei extrahieren
|
||||
extract_zip(response.content, temp_dir)
|
||||
|
||||
# CSS-Datei kopieren
|
||||
fa_dir = os.path.join(temp_dir, 'fontawesome-free-6.4.0-web')
|
||||
css_source = os.path.join(fa_dir, 'css', 'all.min.css')
|
||||
css_dest = os.path.join(DIRECTORIES['css'], 'all.min.css')
|
||||
shutil.copyfile(css_source, css_dest)
|
||||
print(f"✅ Font Awesome CSS kopiert nach {css_dest}")
|
||||
|
||||
# Webfonts-Verzeichnis kopieren
|
||||
webfonts_source = os.path.join(fa_dir, 'webfonts')
|
||||
shutil.rmtree(DIRECTORIES['webfonts'], ignore_errors=True)
|
||||
shutil.copytree(webfonts_source, DIRECTORIES['webfonts'])
|
||||
print(f"✅ Font Awesome Webfonts kopiert nach {DIRECTORIES['webfonts']}")
|
||||
|
||||
# Temporäres Verzeichnis löschen
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Fehler beim Herunterladen von Font Awesome: {response.status_code}")
|
||||
return False
|
||||
|
||||
def download_google_fonts():
|
||||
"""Lädt die Google Fonts (Inter und JetBrains Mono) herunter."""
|
||||
font_files = {
|
||||
'inter-light.woff2': RESOURCES['inter_font_300'],
|
||||
'inter-regular.woff2': RESOURCES['inter_font_400'],
|
||||
'inter-medium.woff2': RESOURCES['inter_font_500'],
|
||||
'inter-semibold.woff2': RESOURCES['inter_font_600'],
|
||||
'inter-bold.woff2': RESOURCES['inter_font_700'],
|
||||
'jetbrainsmono-regular.woff2': RESOURCES['jetbrains_font_400'],
|
||||
'jetbrainsmono-medium.woff2': RESOURCES['jetbrains_font_500'],
|
||||
'jetbrainsmono-bold.woff2': RESOURCES['jetbrains_font_700'],
|
||||
}
|
||||
|
||||
for filename, url in font_files.items():
|
||||
filepath = os.path.join(DIRECTORIES['fonts'], filename)
|
||||
download_file(url, filepath)
|
||||
|
||||
def setup_tailwind():
|
||||
"""Richtet Tailwind CSS ein."""
|
||||
# Tailwind-Konfiguration erstellen, falls sie nicht existiert
|
||||
tailwind_config = os.path.join(BASE_DIR, 'tailwind.config.js')
|
||||
if not os.path.exists(tailwind_config):
|
||||
with open(tailwind_config, 'w') as f:
|
||||
f.write("""/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
"./templates/**/*.html",
|
||||
"./static/**/*.js",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'ui-sans-serif', 'system-ui', '-apple-system', 'sans-serif'],
|
||||
mono: ['JetBrains Mono', 'ui-monospace', 'monospace']
|
||||
},
|
||||
colors: {
|
||||
primary: {
|
||||
50: '#f5f3ff',
|
||||
100: '#ede9fe',
|
||||
200: '#ddd6fe',
|
||||
300: '#c4b5fd',
|
||||
400: '#a78bfa',
|
||||
500: '#8b5cf6',
|
||||
600: '#7c3aed',
|
||||
700: '#6d28d9',
|
||||
800: '#5b21b6',
|
||||
900: '#4c1d95'
|
||||
},
|
||||
secondary: {
|
||||
50: '#ecfdf5',
|
||||
100: '#d1fae5',
|
||||
200: '#a7f3d0',
|
||||
300: '#6ee7b7',
|
||||
400: '#34d399',
|
||||
500: '#10b981',
|
||||
600: '#059669',
|
||||
700: '#047857',
|
||||
800: '#065f46',
|
||||
900: '#064e3b'
|
||||
},
|
||||
dark: {
|
||||
500: '#374151',
|
||||
600: '#1f2937',
|
||||
700: '#111827',
|
||||
800: '#0e1220',
|
||||
900: '#0a0e19'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
""")
|
||||
print(f"✅ Tailwind-Konfiguration erstellt: {tailwind_config}")
|
||||
|
||||
# Input-CSS-Datei erstellen
|
||||
input_css_dir = os.path.join(DIRECTORIES['css'], 'src')
|
||||
os.makedirs(input_css_dir, exist_ok=True)
|
||||
|
||||
input_css = os.path.join(input_css_dir, 'input.css')
|
||||
if not os.path.exists(input_css):
|
||||
with open(input_css, 'w') as f:
|
||||
f.write("""@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
""")
|
||||
print(f"✅ Tailwind Input-CSS erstellt: {input_css}")
|
||||
|
||||
# Hinweis zur Kompilierung anzeigen
|
||||
print("\n📋 Um Tailwind CSS zu kompilieren, führe folgenden Befehl aus:")
|
||||
print("npm install -D tailwindcss")
|
||||
print(f"npx tailwindcss -i {input_css} -o {os.path.join(DIRECTORIES['css'], 'tailwind.min.css')} --minify")
|
||||
|
||||
def main():
|
||||
"""Hauptfunktion: Lädt alle benötigten Ressourcen herunter."""
|
||||
print("🚀 Starte den Download externer Ressourcen...")
|
||||
setup_directories()
|
||||
|
||||
# Alpine.js herunterladen
|
||||
print("\n📦 Lade Alpine.js herunter...")
|
||||
download_alpine()
|
||||
|
||||
# Font Awesome herunterladen
|
||||
print("\n📦 Lade Font Awesome herunter...")
|
||||
download_font_awesome()
|
||||
|
||||
# Google Fonts herunterladen
|
||||
print("\n📦 Lade Google Fonts herunter...")
|
||||
download_google_fonts()
|
||||
|
||||
# Tailwind CSS einrichten
|
||||
print("\n📦 Richte Tailwind CSS ein...")
|
||||
setup_tailwind()
|
||||
|
||||
print("\n✅ Alle Ressourcen wurden erfolgreich heruntergeladen und eingerichtet!")
|
||||
print("🔒 Die Webseite sollte nun ohne externe CDNs funktionieren und die Content Security Policy erfüllen.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user