Initial commit: certgen — сервис генерации сертификатов
This commit is contained in:
commit
49bac43e16
23 files changed
+3046
No files matched your search
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Создать/обновить шаблон «Созидатели» из исходной картинки-примера.
|
||||
|
||||
Использование:
|
||||
python examples/make_sozidateli_template.py "Сертификат Созидатели.png"
|
||||
|
||||
Скрипт:
|
||||
* увеличивает фон x2 (для более чёткой печати),
|
||||
* сохраняет его в data/templates/custom/sozidateli/background.png,
|
||||
* регистрирует image-шаблон `sozidateli` с полем ФИО в нужной позиции.
|
||||
В исходной картинке заголовок, «Подтверждает, что», основной текст и подпись
|
||||
уже нарисованы — поэтому поверх накладывается только ФИО.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from PIL import Image # noqa: E402
|
||||
|
||||
from certgen import config, store # noqa: E402
|
||||
|
||||
SLUG = "sozidateli"
|
||||
SCALE = 2
|
||||
LAYOUT = [
|
||||
{"key": "fio", "x": 0.5, "y": 0.402, "size": 66, "font": "NotoSans-Bold",
|
||||
"color": "#ffffff", "align": "center", "max_width": 0.88, "line_spacing": 1.15},
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
src = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("Сертификат Созидатели.png")
|
||||
if not src.exists():
|
||||
raise SystemExit(f"Не найден файл: {src}")
|
||||
|
||||
store.init_db()
|
||||
img = Image.open(src).convert("RGB")
|
||||
bg = img.resize((img.width * SCALE, img.height * SCALE), Image.LANCZOS)
|
||||
bg_dir = config.TEMPLATES_DIR / "custom" / SLUG
|
||||
bg_dir.mkdir(parents=True, exist_ok=True)
|
||||
bg_path = bg_dir / "background.png"
|
||||
bg.save(bg_path, "PNG")
|
||||
|
||||
tpl = store.upsert_template(
|
||||
slug=SLUG,
|
||||
title="Сертификат «Созидатели»",
|
||||
kind="image",
|
||||
background=str(bg_path.relative_to(config.TEMPLATES_DIR)),
|
||||
layout=LAYOUT,
|
||||
page={"width": bg.width, "height": bg.height},
|
||||
defaults={"title": "СЕРТИФИКАТ", "body": ""},
|
||||
)
|
||||
print(f"Шаблон '{SLUG}' готов: {bg.width}x{bg.height}, фон {bg_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,4 @@
|
||||
ФИО;Текст;Дата;Префикс
|
||||
Смирнов Олег Петрович;за победу в олимпиаде по физике;;
|
||||
Волкова Мария Ивановна;за активное участие в проекте;;
|
||||
Кузнецов Дмитрий Олегович;за высокие результаты в обучении;;
|
||||
|
@@ -0,0 +1,32 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
/* Размер страницы для PDF. Скриншот делается в размере page.width/height. */
|
||||
@page { size: 297mm 210mm; margin: 0; }
|
||||
html, body { margin: 0; padding: 0; }
|
||||
/* 100vw/100vh — чтобы шаблон заполнял весь кадр скриншота. */
|
||||
.cert {
|
||||
width: 100vw; height: 100vh; box-sizing: border-box;
|
||||
border: 14px solid #c69e2d; background: #fffdf7;
|
||||
display: flex; flex-direction: column; justify-content: center; align-items: center;
|
||||
text-align: center; font-family: Georgia, "DejaVu Serif", serif;
|
||||
}
|
||||
h1 { font-size: 5.4vh; letter-spacing: .08em; color: #1b2a4a; margin: 0; }
|
||||
.sub { font-size: 2.4vh; color: #666; font-style: italic; margin-top: 2vh; }
|
||||
.name { font-size: 6.5vh; font-weight: bold; color: #7a1f2b; margin: 4vh 0; }
|
||||
.body { font-size: 2.8vh; color: #333; max-width: 70vw; }
|
||||
.meta { font-size: 2.2vh; color: #555; margin-top: 5vh; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="cert">
|
||||
<h1>{{title}}</h1>
|
||||
<div class="sub">настоящий сертификат подтверждает, что</div>
|
||||
<div class="name">{{fio}}</div>
|
||||
<div class="body">{{body}}</div>
|
||||
<div class="meta">{{date}} · № {{number}}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user