This commit is contained in:
2025-06-03 20:13:07 -03:00
parent 957f9c4a72
commit c3e6ed4a50
13 changed files with 312 additions and 75 deletions

Binary file not shown.

View File

@@ -1,8 +1,12 @@
import base64
import io
import locale
from datetime import date
from uuid import uuid4
import qrcode
from jinja2 import Template
from PIL import Image
from weasyprint import HTML
locale.setlocale(locale.LC_TIME, 'pt_BR')
@@ -17,6 +21,22 @@ def cpf_fmt(s: str) -> str:
return '{}.{}.{}-{}'.format(s[:3], s[3:6], s[6:9], s[9:])
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=3,
)
qr.add_data('https://eduseg.com.br')
qr.make(fit=True)
img = qr.make_image(fill_color='black', back_color='white')
img = img.resize((120, 120), Image.NEAREST)
buffer = io.BytesIO()
img.save(buffer, format='PNG')
img_str = base64.b64encode(buffer.getvalue()).decode('utf-8')
qrcode_base64 = f'data:image/png;base64,{img_str}'
template = Template(html)
html_rendered = template.render(
id=uuid4(),
@@ -27,6 +47,7 @@ html_rendered = template.render(
today=today.strftime('%-d de %B de %Y'),
started_date=today.strftime('%d/%m/%Y'),
finished_date=today.strftime('%d/%m/%Y'),
qrcode=qrcode_base64,
)
HTML(string=html_rendered, base_url='').write_pdf('cert.pdf')

View File

@@ -3,14 +3,14 @@
<head>
<meta charset="utf-8" />
<title>NR-10 Complementar (SEP)</title>
<link href="style.css" rel="stylesheet" />
<meta name="author" content="EDUSEG® <https://eduseg.com.br>" />
<meta name="dcterms.created" content="{{ dcterms.created }}" />
<style>
html,
body,
div,
h1,
h2,
ul,
p,
a {
margin: 0;
@@ -43,9 +43,6 @@
break-after: page;
box-sizing: border-box;
padding: 5rem;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
strong {
@@ -55,11 +52,35 @@
#cover {
background-color: #a7e400;
justify-content: center;
position: relative;
display: flex;
flex-direction: column;
gap: 1rem;
}
#cover h1 {
font-weight: bolder;
font-size: 24pt;
font-size: 26pt;
}
#cover .qrcode {
width: 120px;
height: 120px;
background-color: #fff;
position: absolute;
top: 5rem;
right: 5rem;
}
#cover .signatures {
display: flex;
justify-content: space-between;
margin-top: 2.5rem;
}
.sign1 {
width: 250px;
border-top: #000 solid 1px;
}
#back {
@@ -79,8 +100,12 @@
padding-left: 1rem;
}
.space-y > :not(:last-child) {
margin-bottom: 1rem;
.space-y-0\.5 > :not(:last-child) {
margin-bottom: 0.125rem;
}
.space-y-2\.5 > :not(:last-child) {
margin-bottom: 0.625rem;
}
</style>
</head>
@@ -156,12 +181,24 @@
de
<strong>{{ progress }}%</strong>
</p>
<p>Realizado entre {{ start_date }} e {{ finish_date }}</p>
<p>Realizado entre {{ started_date }} e {{ finished_date }}</p>
<p>Florianópolis, SC, {{ today }}</p>
<div class="signatures">
<div class="sign1"></div>
<div class="sign2">
<p>Tiago Maciel do Santos</p>
<p>CEO/Diretor</p>
</div>
</div>
<div class="qrcode">
<img src="{{ qrcode }}" />
</div>
</section>
<section id="back">
<div class="space-y">
<div class="space-y-2.5">
<h1>Conteúdo programático ministrado</h1>
<ul>
<li>Organização do sistema elétrico de potência</li>
@@ -193,18 +230,20 @@
</ul>
</div>
<div class="space-y">
<dd>
<div class="space-y-2.5">
<dd class="space-y-0.5">
<h2>Carga horária</h2>
<p>40 horas</p>
</dd>
<dd>
<dd class="space-y-0.5">
<h2>Instrutor e responsável técnico</h2>
<p>Francis Ricardo Baretta</p>
<p>CPF 039.539.409-02</p>
<p>Eng. de Segurança no Trabalho Eng. Eletricista</p>
<p>CREA/SC 126693-0</p>
<div>
<p>Francis Ricardo Baretta</p>
<p>CPF 039.539.409-02</p>
<p>Eng. de Segurança no Trabalho Eng. Eletricista</p>
<p>CREA/SC 126693-0</p>
</div>
</dd>
</div>
</section>

View File

@@ -7,6 +7,7 @@ requires-python = ">=3.13"
dependencies = [
"jinja2>=3.1.6",
"layercake",
"qrcode>=8.2",
]
[tool.uv.sources]

26
certs/uv.lock generated
View File

@@ -184,6 +184,7 @@ source = { virtual = "." }
dependencies = [
{ name = "jinja2" },
{ name = "layercake" },
{ name = "qrcode" },
]
[package.dev-dependencies]
@@ -195,6 +196,7 @@ dev = [
requires-dist = [
{ name = "jinja2", specifier = ">=3.1.6" },
{ name = "layercake", directory = "../layercake" },
{ name = "qrcode", specifier = ">=8.2" },
]
[package.metadata.requires-dev]
@@ -244,6 +246,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
]
[[package]]
name = "cryptography"
version = "44.0.3"
@@ -471,7 +482,7 @@ wheels = [
[[package]]
name = "layercake"
version = "0.2.15"
version = "0.6.5"
source = { directory = "../layercake" }
dependencies = [
{ name = "arnparse" },
@@ -517,7 +528,6 @@ dev = [
{ name = "jsonlines", specifier = ">=4.0.0" },
{ name = "pytest", specifier = ">=8.3.5" },
{ name = "pytest-cov", specifier = ">=6.0.0" },
{ name = "pytest-env", specifier = ">=1.1.5" },
{ name = "ruff", specifier = ">=0.11.1" },
]
@@ -765,6 +775,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
]
[[package]]
name = "qrcode"
version = "8.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8f/b2/7fc2931bfae0af02d5f53b174e9cf701adbb35f39d69c2af63d4a39f81a9/qrcode-8.2.tar.gz", hash = "sha256:35c3f2a4172b33136ab9f6b3ef1c00260dd2f66f858f24d88418a015f446506c", size = 43317, upload-time = "2025-05-01T15:44:24.726Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/dd/b8/d2d6d731733f51684bbf76bf34dab3b70a9148e8f2cef2bb544fccec681a/qrcode-8.2-py3-none-any.whl", hash = "sha256:16e64e0716c14960108e85d853062c9e8bba5ca8252c0b4d0231b9df4060ff4f", size = 45986, upload-time = "2025-05-01T15:44:22.781Z" },
]
[[package]]
name = "requests"
version = "2.32.3"