import os import requests from core import config, utils def download_font(font_name): if not font_name: font_name = "Roboto" if not os.path.exists(config.FONTS_DIR): os.makedirs(config.FONTS_DIR) if "," in font_name: font_name = font_name.split(",")[0].strip() if font_name.lower().endswith(('.ttf', '.otf')): font_name = os.path.splitext(font_name)[0] font_name = font_name.strip().strip("'").strip('"') for suffix in ["-Regular", " Regular", " regular", "Regular", " Bold", " Italic"]: if font_name.endswith(suffix): font_name = font_name[:-len(suffix)] font_name = font_name.strip() clean_name = font_name.replace(" ", "").lower() font_filename = f"{clean_name}.ttf" font_path = os.path.join(config.FONTS_DIR, font_filename) if os.path.exists(font_path) and os.path.getsize(font_path) > 1000: utils.log("ASSETS", f"Using cached font: {font_path}") return font_path utils.log("ASSETS", f"Downloading font: {font_name}...") compact_name = font_name.replace(" ", "") title_compact = "".join(x.title() for x in font_name.split()) patterns = [ f"static/{title_compact}-Regular.ttf", f"{title_compact}-Regular.ttf", f"{title_compact}[wght].ttf", f"{title_compact}[wdth,wght].ttf", f"static/{compact_name}-Regular.ttf", f"{compact_name}-Regular.ttf", f"{title_compact}-Regular.otf", ] headers = {"User-Agent": "Mozilla/5.0 (BookApp/1.0)"} for license_type in ["ofl", "apache", "ufl"]: base_url = f"https://github.com/google/fonts/raw/main/{license_type}/{clean_name}" for pattern in patterns: try: r = requests.get(f"{base_url}/{pattern}", headers=headers, timeout=6) if r.status_code == 200 and len(r.content) > 1000: with open(font_path, 'wb') as f: f.write(r.content) utils.log("ASSETS", f"✅ Downloaded {font_name} to {font_path}") return font_path except requests.exceptions.Timeout: utils.log("ASSETS", f" Font download timeout for {font_name} ({pattern}). Trying next...") continue except Exception: continue if clean_name != "roboto": utils.log("ASSETS", f"⚠️ Font '{font_name}' not found on Google Fonts. Falling back to Roboto.") return download_font("Roboto") utils.log("ASSETS", "⚠️ Roboto fallback also failed. PIL will use built-in default font.") return None