norma_para_toda_obra/gerarQRCODE.py
Rafael Tavares Juliani 9ceca45ccf INÍCIO
2025-09-04 15:47:05 -03:00

302 lines
11 KiB
Python
Executable File

import os
import shutil
import re
import yaml
import qrcode
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import RoundedModuleDrawer, GappedSquareModuleDrawer
from qrcode.image.styles.colormasks import SolidFillColorMask
import PIL
from PIL import Image, ImageDraw, ImageFont
# ============================================ FUNÇÕES ==================================================
def extract_qrcode_info(filename, quantidade, pasta, config):
cor = config['cor']
site_de_publicacao = config['site_de_publicacao']
livro_url = config['livro_url']
ark = None
if 'ark' in config:
ark = 'https://n2t.net/'+config['ark']
with open(filename, 'r', encoding='utf-8') as file:
markdown_text = file.read()
# Definindo o padrão de expressão regular para capturar o conteúdo entre ::: { e }
pattern = r':::\s*\{([^{}]*)\}\s*(.*?)\s*:::'
matches = re.findall(pattern, markdown_text, re.DOTALL)
# Loop pelas correspondências encontradas
for match in matches:
div_attributes = match[0].strip()
content = match[1].strip()
# Verifica se a div tem a classe .qrcode
if '.qrcode' in div_attributes:
quantidade += 1
print("------------ INICIO -------------", quantidade)
print("Atributos:", div_attributes)
print("Conteúdo:", content)
# Verifica se a div tem a classe .content-visible
content_visible = '.content-visible' in div_attributes
if content_visible:
print("Tem a classe .content-visible")
# Extrai o valor do atributo when-format
when_format_match = re.search(r'when-format="([^"]+)"', div_attributes)
print("whenformat: ", when_format_match)
if when_format_match:
start_index = when_format_match.start()
end_index = when_format_match.end()
when_format_text = div_attributes[start_index:end_index]
print("FORMA: ",when_format_text)
else:
print("Não tem a classe .content-visible")
qrcor_attr = re.search(r'qrcor="([^"]+)"', div_attributes)
if qrcor_attr:
start_index = qrcor_attr.start()
end_index = qrcor_attr.end()
qrcor_text = div_attributes[start_index:end_index]
padrao = r'"(.*?)"'
resultados = re.findall(padrao, qrcor_text)
print("RESULTADOS: ",resultados)
if resultados[0] == "0":
qrcor = False
else:
qrcor = True
else:
qrcor = True
# ================================ GERAR QRCODE ================================
if not hasattr(PIL.Image, 'Resampling'):
PIL.Image.Resampling = PIL.Image
hex_color = cor
rgb_color = hex_to_rgb(hex_color)
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H)
# ++++++++++++++++++++ DEFININDO OS LINKS DOS QR CODES +++++++++++++++++++++++++++++++++++++++++++++
# define qual será a base para os links internos no qrcode +
if ark is not None:
base = ark
else:
base = site_de_publicacao+'/'+livro_url
# verifica se o link é externo ou interno
if not 'http' in content and '#' in content:
#link interno
# Verifica se é para o um capítulo diferente do avaliado. Se tiver a barra, entao é para outro capítulo
if '/' in content:
content = base +'/'+ content
else:
cap = filename.split('.')[0]
content = base +'/'+ cap +'/'+ content
qr.add_data(content)
qr_inner_eyes_img = qr.make_image(image_factory=StyledPilImage,
eye_drawer=RoundedModuleDrawer(radius_ratio=1),
color_mask=SolidFillColorMask(front_color=(rgb_color['red'], rgb_color['green'], rgb_color['blue'])))
qr_outer_eyes_img = qr.make_image(image_factory=StyledPilImage,
eye_drawer=RoundedModuleDrawer(radius_ratio=1))
qr_img = qr.make_image(image_factory=StyledPilImage,
module_drawer=GappedSquareModuleDrawer(),
embeded_image_path="editora/logo_roxo.png")
inner_eye_mask = style_inner_eyes(qr_img)
outer_eye_mask = style_outer_eyes(qr_img)
intermediate_img = Image.composite(qr_inner_eyes_img, qr_img, inner_eye_mask)
final_image = Image.composite(qr_outer_eyes_img, intermediate_img, outer_eye_mask)
final_image = final_image.convert('CMYK')
# Verifica se tem que ser preto e branco
if not qrcor:
final_image = final_image.convert('L')
final_image = final_image.convert('CMYK')
# Separa os canais CMYK
c, m, y, k = final_image.split()
# Cria novos canais C, M e Y com todos os valores definidos como zero
c_new = c.point(lambda x: 0)
m_new = m.point(lambda x: 0)
y_new = y.point(lambda x: 0)
# Cria uma nova imagem CMYK com os canais ajustados e o canal K original
final_image = Image.merge('CMYK', (c_new, m_new, y_new, k))
arq = "qrcode_" + str(quantidade) + ".jpg"
caminho_e_arq = os.path.join(pasta, arq)
final_image.save(caminho_e_arq, quality=100)
print("QRCOR: ",qrcor)
print("------------ FIM -------------")
return quantidade
def obter_capitulos(arquivo_yaml):
with open(arquivo_yaml, 'r') as file:
# Carrega o conteúdo do arquivo YAML
conteudo = yaml.safe_load(file)
# Verifica se a chave 'capítulos' está presente no YAML
if 'capitulos' in conteudo:
return conteudo['capitulos']
else:
print("A chave 'capítulos' não foi encontrada no YAML.")
return None
# A ideia aqui é obter as configuracoes do qrcode bem como o identificador ark e o site para publicacao
def obter_metadados(arquivo_yaml):
metadados = {}
with open(arquivo_yaml, 'r') as file:
# Carrega o conteúdo do arquivo YAML
conteudo = yaml.safe_load(file)
# Verifica se a chave 'capítulos' está presente no YAML
if 'qrcode' in conteudo:
metadados['cor'] = conteudo['qrcode']['cor']
if 'site-de-publicacao' in conteudo:
metadados['site_de_publicacao'] = conteudo['site-de-publicacao']
metadados['livro_url'] = conteudo['pasta-livro-finalizado']['html']
with open('_quarto-html.yml', 'r') as file:
conteudo_1 = yaml.safe_load(file)
if 'ark' in conteudo_1['moan-dados']:
metadados['ark'] = conteudo_1['moan-dados']['ark']
return metadados
def criar_ou_limpar_pasta(nome_pasta):
# Verifica se o diretório já existe
if os.path.exists(nome_pasta):
# Remove todo o conteúdo da pasta
for filename in os.listdir(nome_pasta):
file_path = os.path.join(nome_pasta, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print(f"Erro ao remover {file_path}: {e}")
else:
# Cria a pasta se não existir
try:
os.makedirs(nome_pasta)
except OSError as e:
print(f"Erro ao criar a pasta {nome_pasta}: {e}")
# ============================================ FUNÇÕES QRCODE ==================================================
def hex_to_rgb(hex_color):
# Remover o '#' se presente
hex_color = hex_color.lstrip('#')
# Converter para valores RGB
red = int(hex_color[0:2], 16)
green = int(hex_color[2:4], 16)
blue = int(hex_color[4:6], 16)
# Retornar como um dicionário
return {'red': red, 'green': green, 'blue': blue}
# Custom function for eye styling. These create the eye masks
def style_inner_eyes(img):
img_size = img.size[0]
eye_size = 70 # default
quiet_zone = 40 # default
mask = Image.new('L', img.size, 0)
draw = ImageDraw.Draw(mask)
draw.rectangle((60, 60, 90, 90), fill=255) #top left eye
draw.rectangle((img_size-90, 60, img_size-60, 90), fill=255) #top right eye
draw.rectangle((60, img_size-90, 90, img_size-60), fill=255) #bottom left eye
return mask
def style_outer_eyes(img):
img_size = img.size[0]
eye_size = 70 # default
quiet_zone = 40 # default
mask = Image.new('L', img.size, 0)
draw = ImageDraw.Draw(mask)
draw.rectangle((40, 40, 110, 110), fill=255) #top left eye
draw.rectangle((img_size-110, 40, img_size-40, 110), fill=255) #top right eye
draw.rectangle((40, img_size-110, 110, img_size-40), fill=255) #bottom left eye
draw.rectangle((60, 60, 90, 90), fill=0) #top left eye
draw.rectangle((img_size-90, 60, img_size-60, 90), fill=0) #top right eye
draw.rectangle((60, img_size-90, 90, img_size-60), fill=0) #bottom left eye
return mask
# ============================================ FIM DAS FUNÇÕES QRCODE ==================================================
# ============================================ FIM DAS FUNÇÕES GERAIS==================================================
contador = 0
# Caminho para o arquivo YAML
caminho_arquivo = '_moan-config.yml'
# Obtém os capítulos do arquivo YAML
capitulos = obter_capitulos(caminho_arquivo)
# metadados qrcode
config = obter_metadados(caminho_arquivo)
pasta_qr = "qr_code"
criar_ou_limpar_pasta(pasta_qr)
if capitulos:
for capitulo in capitulos:
# Usando a função para extrair informações de um arquivo .qmd
contador = extract_qrcode_info(capitulo, contador, pasta_qr,config)
else:
print("Nenhum capítulo encontrado no arquivo YAML.")
# Aguardar entrada do usuário antes de fechar o terminal
input("Pressione Enter para fechar o terminal...")