adiciona o aplicativo de diarios
This commit is contained in:
105
diarios/management/commands/importar_diarios_com_ocr.py
Normal file
105
diarios/management/commands/importar_diarios_com_ocr.py
Normal file
@ -0,0 +1,105 @@
|
||||
import os
|
||||
import time
|
||||
from django.core.files import File
|
||||
from django.core.management.base import BaseCommand
|
||||
from diarios.models import DiarioOficial
|
||||
from diarios.signals import update_document, delete_document
|
||||
from django.db.models.signals import post_save, post_delete
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Importa arquivos PDF de diários oficiais e associa aos objetos existentes no banco."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"pasta",
|
||||
type=str,
|
||||
help="Caminho para a pasta contendo os arquivos PDF (nomes devem conter o número do diário)",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
post_save.disconnect(update_document, sender=DiarioOficial)
|
||||
post_delete.disconnect(delete_document, sender=DiarioOficial)
|
||||
|
||||
pasta = options["pasta"]
|
||||
if not os.path.isdir(pasta):
|
||||
self.stderr.write(
|
||||
self.style.ERROR(f"A pasta fornecida não existe: {pasta}")
|
||||
)
|
||||
return
|
||||
|
||||
arquivos_pdf = [
|
||||
f
|
||||
for f in os.listdir(pasta)
|
||||
if f.lower().endswith(".pdf") and "Diário_Oficial_Eletrônico_nº_" in f
|
||||
]
|
||||
|
||||
if not arquivos_pdf:
|
||||
self.stdout.write(
|
||||
self.style.WARNING("Nenhum arquivo PDF válido encontrado na pasta.")
|
||||
)
|
||||
return
|
||||
|
||||
total = len(arquivos_pdf)
|
||||
erros = []
|
||||
atualizados = []
|
||||
start_time = time.time()
|
||||
|
||||
# Mapeia os números aos nomes de arquivos
|
||||
numero_para_arquivo = {
|
||||
f.replace("Diário_Oficial_Eletrônico_nº_", "")
|
||||
.replace(".pdf", "")
|
||||
.strip("_-"): f
|
||||
for f in arquivos_pdf
|
||||
}
|
||||
|
||||
# Busca todos os objetos de uma vez
|
||||
diarios_existentes = DiarioOficial.objects.in_bulk(
|
||||
numero_para_arquivo.keys(), field_name="numero"
|
||||
)
|
||||
|
||||
for idx, (numero, nome_arquivo) in enumerate(
|
||||
numero_para_arquivo.items(), start=1
|
||||
):
|
||||
try:
|
||||
diario = diarios_existentes.get(numero)
|
||||
if not diario:
|
||||
raise DiarioOficial.DoesNotExist()
|
||||
|
||||
caminho_pdf = os.path.join(pasta, nome_arquivo)
|
||||
with open(caminho_pdf, "rb") as f:
|
||||
diario.arquivo.save(nome_arquivo, File(f), save=True)
|
||||
|
||||
atualizados.append(diario.pk)
|
||||
elapsed = time.time() - start_time
|
||||
remaining = (elapsed / idx) * (total - idx)
|
||||
self.stdout.write(
|
||||
f"[{idx}/{total}] Atualizado: {nome_arquivo} | Estimativa restante: {remaining:.1f}s"
|
||||
)
|
||||
|
||||
except DiarioOficial.DoesNotExist:
|
||||
msg = f"Não encontrado no banco: {nome_arquivo}"
|
||||
erros.append(msg)
|
||||
self.stderr.write(self.style.WARNING(msg))
|
||||
|
||||
except Exception as e:
|
||||
msg = f"Erro ao processar {nome_arquivo}: {str(e)}"
|
||||
erros.append(msg)
|
||||
self.stderr.write(self.style.ERROR(msg))
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f"{len(atualizados)} arquivos importados com sucesso.")
|
||||
)
|
||||
self.stdout.write(self.style.WARNING(f"{len(erros)} arquivos com erro."))
|
||||
|
||||
if erros:
|
||||
caminho_log = os.path.join(pasta, "erros_importacao.txt")
|
||||
with open(caminho_log, "w", encoding="utf-8") as erro_file:
|
||||
for linha in erros:
|
||||
erro_file.write(f"{linha}\n")
|
||||
self.stdout.write(
|
||||
self.style.WARNING(f"Erros registrados em: {caminho_log}")
|
||||
)
|
||||
|
||||
post_save.connect(update_document, sender=DiarioOficial)
|
||||
post_delete.connect(delete_document, sender=DiarioOficial)
|
||||
Reference in New Issue
Block a user