Initial commit: certgen — сервис генерации сертификатов
This commit is contained in:
commit
49bac43e16
23 files changed
+3046
No files matched your search
@@ -0,0 +1,86 @@
|
||||
"""Поиск системных шрифтов (в т.ч. с кириллицей)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
SEARCH_DIRS = [
|
||||
Path(__file__).resolve().parent / "assets" / "fonts", # шрифты, вложенные в проект
|
||||
Path("/usr/share/fonts"),
|
||||
Path("/usr/local/share/fonts"),
|
||||
Path.home() / ".local/share/fonts",
|
||||
Path("/Library/Fonts"),
|
||||
Path("/System/Library/Fonts"),
|
||||
Path("C:/Windows/Fonts"),
|
||||
]
|
||||
|
||||
ALIASES = {
|
||||
"serif": "DejaVuSerif",
|
||||
"serif-bold": "DejaVuSerif-Bold",
|
||||
"serif-italic": "DejaVuSerif-Italic",
|
||||
"serif-bolditalic": "DejaVuSerif-BoldItalic",
|
||||
"sans": "DejaVuSans",
|
||||
"sans-bold": "DejaVuSans-Bold",
|
||||
"sans-italic": "DejaVuSans-Oblique",
|
||||
"sans-bolditalic": "DejaVuSans-BoldOblique",
|
||||
"mono": "DejaVuSansMono",
|
||||
}
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _index() -> dict[str, str]:
|
||||
idx: dict[str, str] = {}
|
||||
for d in SEARCH_DIRS:
|
||||
if not d.exists():
|
||||
continue
|
||||
for f in d.rglob("*"):
|
||||
if f.suffix.lower() in (".ttf", ".otf", ".ttc"):
|
||||
idx.setdefault(f.stem.lower(), str(f))
|
||||
idx.setdefault(f.name.lower(), str(f))
|
||||
return idx
|
||||
|
||||
|
||||
def _fallback() -> str:
|
||||
idx = _index()
|
||||
for key in ("dejavusans", "dejavuserif", "liberationsans", "notosans",
|
||||
"arial", "arialunicode"):
|
||||
if key in idx:
|
||||
return idx[key]
|
||||
return next(iter(idx.values()), "")
|
||||
|
||||
|
||||
@lru_cache(maxsize=256)
|
||||
def find_font(name: str | None) -> str:
|
||||
"""Вернуть путь к файлу шрифта по имени или алиасу."""
|
||||
name = (name or "sans").strip()
|
||||
p = Path(name)
|
||||
if p.is_absolute() and p.exists():
|
||||
return str(p)
|
||||
|
||||
key = ALIASES.get(name.lower(), name).lower()
|
||||
idx = _index()
|
||||
|
||||
if key in idx:
|
||||
return idx[key]
|
||||
if key + ".ttf" in idx:
|
||||
return idx[key + ".ttf"]
|
||||
|
||||
# частичное совпадение
|
||||
matches = [v for k, v in idx.items() if key in k]
|
||||
if matches:
|
||||
return matches[0]
|
||||
|
||||
# спросим fontconfig
|
||||
try:
|
||||
out = subprocess.run(
|
||||
["fc-match", "-f", "%{file}", name],
|
||||
capture_output=True, text=True, timeout=10,
|
||||
)
|
||||
path = out.stdout.strip()
|
||||
if path and Path(path).exists():
|
||||
return path
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return _fallback()
|
||||
Reference in new issue
Block a user