fix: Add socket module import to build-sd-fonts script (#2504) (#2505)

This commit is contained in:
Justin Mitchell
2026-07-01 12:10:15 -04:00
committed by GitHub
parent 6f08a88b12
commit e7f3406704
+35 -7
View File
@@ -33,6 +33,7 @@ import sys
import tempfile
import threading
import time
import socket
import urllib.request
from concurrent.futures import ProcessPoolExecutor, as_completed
from pathlib import Path
@@ -49,17 +50,44 @@ INSTANCE_DIR = SCRIPT_DIR / "instanced_fonts"
DEFAULT_FALLBACK_FONT = EPDFONTS_DIR / "builtinFonts/source/NotoSans/NotoSans-Regular.ttf"
def download_font(url: str, dest: Path) -> Path:
"""Download a font file if not already cached. Returns the local path."""
_orig_getaddrinfo = socket.getaddrinfo
def _ipv4_only_getaddrinfo(*args, **kwargs):
"""getaddrinfo variant that drops AAAA records (IPv4 only)."""
return [ai for ai in _orig_getaddrinfo(*args, **kwargs) if ai[0] == socket.AF_INET]
def download_font(url: str, dest: Path, retries: int = 3) -> Path:
"""Download a font file if not already cached. Returns the local path.
Some sources (e.g. mirrors.ctan.org) are round-robin redirectors that land
on a different mirror each request; a mirror may advertise an IPv6 address a
host without an IPv6 route cannot reach ([Errno 101] Network is unreachable).
Retry on failure, forcing IPv4 resolution after the first attempt.
"""
if dest.exists():
return dest
dest.parent.mkdir(parents=True, exist_ok=True)
print(f" Downloading {dest.name}...")
try:
urllib.request.urlretrieve(url, dest)
except Exception as e:
dest.unlink(missing_ok=True)
raise RuntimeError(f"Failed to download {url}: {e}") from e
last_err = None
for attempt in range(1, retries + 1):
force_ipv4 = attempt > 1
if force_ipv4:
socket.getaddrinfo = _ipv4_only_getaddrinfo
try:
urllib.request.urlretrieve(url, dest)
break
except Exception as e: # noqa: BLE001 - reported via RuntimeError below
last_err = e
dest.unlink(missing_ok=True)
if attempt < retries:
print(f" Attempt {attempt} failed ({e}); retrying (IPv4-only)...")
finally:
if force_ipv4:
socket.getaddrinfo = _orig_getaddrinfo
else:
raise RuntimeError(f"Failed to download {url}: {last_err}") from last_err
size_kb = dest.stat().st_size / 1024
print(f" Downloaded {dest.name} ({size_kb:.0f} KB)")
return dest