From be731f8ff8cb205ed65d61a6842610126a7b0c09 Mon Sep 17 00:00:00 2001 From: Cesa-V Date: Mon, 15 Jun 2026 15:36:40 -0300 Subject: [PATCH] Preprocess inspection PDF --- .../documento_joaomarcos_inspecoes.csv | 19 ++ .../documento_joaomarcos_inspecoes.json | 309 ++++++++++++++++++ pre_process/documento_joaomarcos_texto.txt | 46 +++ pre_process/preprocess_pdf.py | 181 ++++++++++ 4 files changed, 555 insertions(+) create mode 100644 pre_process/documento_joaomarcos_inspecoes.csv create mode 100644 pre_process/documento_joaomarcos_inspecoes.json create mode 100644 pre_process/documento_joaomarcos_texto.txt create mode 100644 pre_process/preprocess_pdf.py diff --git a/pre_process/documento_joaomarcos_inspecoes.csv b/pre_process/documento_joaomarcos_inspecoes.csv new file mode 100644 index 0000000..004ae57 --- /dev/null +++ b/pre_process/documento_joaomarcos_inspecoes.csv @@ -0,0 +1,19 @@ +seq;sigla_mnt;descricao_mnt;referencia;tipo_vencimento;zera;controle_original;intervalo_horas_voo;intervalo_meses_continuos;intervalo_pousos;intervalos +2;INSP 1A;INSPEÇÃO CHECK 1A;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;A B 3 3 D;300:00 HORAS DE VOO;8 MESES CONTÍNUOS;;300:00 HORAS DE VOO | 8 MESES CONTÍNUOS +3;INSP 2A;INSPEÇÃO CHECK 2A;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;A B 10 4 D;600:00 HORAS DE VOO;16 MESES CONTÍNUOS;;600:00 HORAS DE VOO | 16 MESES CONTÍNUOS +4;INSP 3A;INSPEÇÃO CHECK 3A;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;A B 10 5 D;900:00 HORAS DE VOO;24 MESES CONTÍNUOS;;900:00 HORAS DE VOO | 24 MESES CONTÍNUOS +5;INSP 2Y;INSPEÇÃO CALENDÁRICA DE 2 YEARS;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;B B 5 5 D;;24 MESES CONTÍNUOS;;24 MESES CONTÍNUOS +6;CHECK 300;CHECK OPERACIONAL DE 300FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;A O 6 H;300:00 HORAS DE VOO;;;300:00 HORAS DE VOO +7;CHECK 400;CHECK OPERACIONAL DE 400FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;A O 6 H;400:00 HORAS DE VOO;;;400:00 HORAS DE VOO +8;1-INSP AOL;INSPEÇÃO AOL 295-019;Última inspeção;Término da Anterior;N;B 1 D;;;3800 POUSOS;3800 POUSOS +9;2-INSP AOL;INSPEÇÃO AOL 295-019;Última Inspeção Específica 8 1-INSP AOL;Término da Anterior;N;B 1 D;;;2000 POUSOS;2000 POUSOS +10;3-INSP AOL;INSPEÇÃO AOL 295-019;Última Inspeção Específica 9 2-INSP AOL;Término da Anterior;N;B 1 D;;;2000 POUSOS;2000 POUSOS +14;INSP 8Y;INSPEÇÃO CALENDÁRICA DE 8 YEARS;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;B P 15 20 D;;96 MESES CONTÍNUOS;;96 MESES CONTÍNUOS +15;INSP 1C;INSPEÇÃO CHECK 1C;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;C P 10 65 D;2400:00 HORAS DE VOO;48 MESES CONTÍNUOS;;2400:00 HORAS DE VOO | 48 MESES CONTÍNUOS +16;INSP 2C;INSPEÇÃO GERAL CHECK 2C;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;C P 60 10 D;4800:00 HORAS DE VOO;96 MESES CONTÍNUOS;;4800:00 HORAS DE VOO | 96 MESES CONTÍNUOS +17;INSP 4Y;INSPEÇÃO CALENDÁRICA DE 4 YEARS;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;B P 10 10 D;;48 MESES CONTÍNUOS;;48 MESES CONTÍNUOS +18;INSP 100FH BR01;INSPEÇÃO DE 100 FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;O 1 H;100:00 HORAS DE VOO;;;100:00 HORAS DE VOO +19;INSP 2400F BR01;INPEÇÃO 2400FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;O 3 H;2400:00 HORAS DE VOO;;;2400:00 HORAS DE VOO +20;INSP 3000F BR01;INSPEÇÃO 3000FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;B 1 D;3000:00 HORAS DE VOO;;;3000:00 HORAS DE VOO +22;INSP 1000F;INPEÇÃO 1000FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;B 1 D;1000:00 HORAS DE VOO;;;1000:00 HORAS DE VOO +23;INSP 50FH;INSPEÇÃO 50 FH;Especial (a contar dela mesma - Tipo D);Término da Anterior;N;B 1 D;50:00 HORAS DE VOO;;;50:00 HORAS DE VOO diff --git a/pre_process/documento_joaomarcos_inspecoes.json b/pre_process/documento_joaomarcos_inspecoes.json new file mode 100644 index 0000000..fe8c354 --- /dev/null +++ b/pre_process/documento_joaomarcos_inspecoes.json @@ -0,0 +1,309 @@ +{ + "fonte": "raw\\documento joaomarcos.pdf", + "metadados": { + "data_relatorio": "15/06/2026", + "hora_relatorio": "13:23:38", + "pn": "ANV C-105", + "cff": "0117B", + "nomenclatura": "AERONAVE, ASA FIXA, CASA 295 (C-105 AMAZONAS)", + "sn": "038", + "matricula": "2805", + "modelo": "C-105", + "ciclo_atual": "3650007082" + }, + "inspecoes": [ + { + "seq": 2, + "sigla_mnt": "INSP 1A", + "descricao_mnt": "INSPEÇÃO CHECK 1A", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "A B 3 3 D", + "intervalo_horas_voo": "300:00 HORAS DE VOO", + "intervalo_meses_continuos": "8 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "300:00 HORAS DE VOO", + "8 MESES CONTÍNUOS" + ], + "linha_original": "2 INSP 1A INSPEÇÃO CHECK 1A Especial (a contar dela mesma Término da Anterior N A B 3 3 D 300:00 HORAS DE VÔO - Tipo D) 8 MESES CONTÍNUOS" + }, + { + "seq": 3, + "sigla_mnt": "INSP 2A", + "descricao_mnt": "INSPEÇÃO CHECK 2A", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "A B 10 4 D", + "intervalo_horas_voo": "600:00 HORAS DE VOO", + "intervalo_meses_continuos": "16 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "600:00 HORAS DE VOO", + "16 MESES CONTÍNUOS" + ], + "linha_original": "3 INSP 2A INSPEÇÃO CHECK 2A Especial (a contar dela mesma Término da Anterior N A B 10 4 D 600:00 HORAS DE VÔO - Tipo D) 16 MESES CONTÍNUOS" + }, + { + "seq": 4, + "sigla_mnt": "INSP 3A", + "descricao_mnt": "INSPEÇÃO CHECK 3A", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "A B 10 5 D", + "intervalo_horas_voo": "900:00 HORAS DE VOO", + "intervalo_meses_continuos": "24 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "900:00 HORAS DE VOO", + "24 MESES CONTÍNUOS" + ], + "linha_original": "4 INSP 3A INSPEÇÃO CHECK 3A Especial (a contar dela mesma Término da Anterior N A B 10 5 D 900:00 HORAS DE VÔO - Tipo D) 24 MESES CONTÍNUOS" + }, + { + "seq": 5, + "sigla_mnt": "INSP 2Y", + "descricao_mnt": "INSPEÇÃO CALENDÁRICA DE 2 YEARS", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B B 5 5 D", + "intervalo_horas_voo": "", + "intervalo_meses_continuos": "24 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "24 MESES CONTÍNUOS" + ], + "linha_original": "5 INSP 2Y INSPEÇÃO CALENDÁRICA DE 2 YEARS Especial (a contar dela mesma Término da Anterior N B B 5 5 D 24 MESES CONTÍNUOS - Tipo D)" + }, + { + "seq": 6, + "sigla_mnt": "CHECK 300", + "descricao_mnt": "CHECK OPERACIONAL DE 300FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "A O 6 H", + "intervalo_horas_voo": "300:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "300:00 HORAS DE VOO" + ], + "linha_original": "6 CHECK 300 CHECK OPERACIONAL DE 300FH Especial (a contar dela mesma Término da Anterior N A O 6 H 300:00 HORAS DE VÔO - Tipo D)" + }, + { + "seq": 7, + "sigla_mnt": "CHECK 400", + "descricao_mnt": "CHECK OPERACIONAL DE 400FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "A O 6 H", + "intervalo_horas_voo": "400:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "400:00 HORAS DE VOO" + ], + "linha_original": "7 CHECK 400 CHECK OPERACIONAL DE 400FH Especial (a contar dela mesma Término da Anterior N A O 6 H 400:00 HORAS DE VÔO - Tipo D)" + }, + { + "seq": 8, + "sigla_mnt": "1-INSP AOL", + "descricao_mnt": "INSPEÇÃO AOL 295-019", + "referencia": "Última inspeção", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B 1 D", + "intervalo_horas_voo": "", + "intervalo_meses_continuos": "", + "intervalo_pousos": "3800 POUSOS", + "intervalos": [ + "3800 POUSOS" + ], + "linha_original": "8 1-INSP AOL INSPEÇÃO AOL 295-019 Última inspeção Término da Anterior N B 1 D 3800 POUSOS" + }, + { + "seq": 9, + "sigla_mnt": "2-INSP AOL", + "descricao_mnt": "INSPEÇÃO AOL 295-019", + "referencia": "Última Inspeção Específica 8 1-INSP AOL", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B 1 D", + "intervalo_horas_voo": "", + "intervalo_meses_continuos": "", + "intervalo_pousos": "2000 POUSOS", + "intervalos": [ + "2000 POUSOS" + ], + "linha_original": "9 2-INSP AOL INSPEÇÃO AOL 295-019 Última Inspeção Específica 8 1-INSP AOL Término da Anterior N B 1 D 2000 POUSOS" + }, + { + "seq": 10, + "sigla_mnt": "3-INSP AOL", + "descricao_mnt": "INSPEÇÃO AOL 295-019", + "referencia": "Última Inspeção Específica 9 2-INSP AOL", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B 1 D", + "intervalo_horas_voo": "", + "intervalo_meses_continuos": "", + "intervalo_pousos": "2000 POUSOS", + "intervalos": [ + "2000 POUSOS" + ], + "linha_original": "10 3-INSP AOL INSPEÇÃO AOL 295-019 Última Inspeção Específica 9 2-INSP AOL Término da Anterior N B 1 D 2000 POUSOS" + }, + { + "seq": 14, + "sigla_mnt": "INSP 8Y", + "descricao_mnt": "INSPEÇÃO CALENDÁRICA DE 8 YEARS", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B P 15 20 D", + "intervalo_horas_voo": "", + "intervalo_meses_continuos": "96 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "96 MESES CONTÍNUOS" + ], + "linha_original": "14 INSP 8Y INSPEÇÃO CALENDÁRICA DE 8 YEARS Especial (a contar dela mesma Término da Anterior N B P 15 20 D 96 MESES CONTÍNUOS - Tipo D)" + }, + { + "seq": 15, + "sigla_mnt": "INSP 1C", + "descricao_mnt": "INSPEÇÃO CHECK 1C", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "C P 10 65 D", + "intervalo_horas_voo": "2400:00 HORAS DE VOO", + "intervalo_meses_continuos": "48 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "2400:00 HORAS DE VOO", + "48 MESES CONTÍNUOS" + ], + "linha_original": "15 INSP 1C INSPEÇÃO CHECK 1C Especial (a contar dela mesma Término da Anterior N C P 10 65 D 2400:00 HORAS DE VÔO - Tipo D) 48 MESES CONTÍNUOS" + }, + { + "seq": 16, + "sigla_mnt": "INSP 2C", + "descricao_mnt": "INSPEÇÃO GERAL CHECK 2C", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "C P 60 10 D", + "intervalo_horas_voo": "4800:00 HORAS DE VOO", + "intervalo_meses_continuos": "96 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "4800:00 HORAS DE VOO", + "96 MESES CONTÍNUOS" + ], + "linha_original": "16 INSP 2C INSPEÇÃO GERAL CHECK 2C Especial (a contar dela mesma Término da Anterior N C P 60 10 D 4800:00 HORAS DE VÔO - Tipo D) 96 MESES CONTÍNUOS" + }, + { + "seq": 17, + "sigla_mnt": "INSP 4Y", + "descricao_mnt": "INSPEÇÃO CALENDÁRICA DE 4 YEARS", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B P 10 10 D", + "intervalo_horas_voo": "", + "intervalo_meses_continuos": "48 MESES CONTÍNUOS", + "intervalo_pousos": "", + "intervalos": [ + "48 MESES CONTÍNUOS" + ], + "linha_original": "17 INSP 4Y INSPEÇÃO CALENDÁRICA DE 4 YEARS Especial (a contar dela mesma Término da Anterior N B P 10 10 D 48 MESES CONTÍNUOS - Tipo D)" + }, + { + "seq": 18, + "sigla_mnt": "INSP 100FH BR01", + "descricao_mnt": "INSPEÇÃO DE 100 FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "O 1 H", + "intervalo_horas_voo": "100:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "100:00 HORAS DE VOO" + ], + "linha_original": "18 INSP 100FH BR01 INSPEÇÃO DE 100 FH Especial (a contar dela mesma Término da Anterior N O 1 H 100:00 HORAS DE VÔO - Tipo D)" + }, + { + "seq": 19, + "sigla_mnt": "INSP 2400F BR01", + "descricao_mnt": "INPEÇÃO 2400FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "O 3 H", + "intervalo_horas_voo": "2400:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "2400:00 HORAS DE VOO" + ], + "linha_original": "19 INSP 2400F BR01 INPEÇÃO 2400FH Especial (a contar dela mesma Término da Anterior N O 3 H 2400:00 HORAS DE VÔO - Tipo D)" + }, + { + "seq": 20, + "sigla_mnt": "INSP 3000F BR01", + "descricao_mnt": "INSPEÇÃO 3000FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B 1 D", + "intervalo_horas_voo": "3000:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "3000:00 HORAS DE VOO" + ], + "linha_original": "20 INSP 3000F BR01 INSPEÇÃO 3000FH Especial (a contar dela mesma Término da Anterior N B 1 D 3000:00 HORAS DE VÔO - Tipo D)" + }, + { + "seq": 22, + "sigla_mnt": "INSP 1000F", + "descricao_mnt": "INPEÇÃO 1000FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B 1 D", + "intervalo_horas_voo": "1000:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "1000:00 HORAS DE VOO" + ], + "linha_original": "22 INSP 1000F INPEÇÃO 1000FH Especial (a contar dela mesma Término da Anterior N B 1 D 1000:00 HORAS DE VÔO - Tipo D)" + }, + { + "seq": 23, + "sigla_mnt": "INSP 50FH", + "descricao_mnt": "INSPEÇÃO 50 FH", + "referencia": "Especial (a contar dela mesma - Tipo D)", + "tipo_vencimento": "Término da Anterior", + "zera": "N", + "controle_original": "B 1 D", + "intervalo_horas_voo": "50:00 HORAS DE VOO", + "intervalo_meses_continuos": "", + "intervalo_pousos": "", + "intervalos": [ + "50:00 HORAS DE VOO" + ], + "linha_original": "23 INSP 50FH INSPEÇÃO 50 FH Especial (a contar dela mesma Término da Anterior N B 1 D 50:00 HORAS DE VÔO - Tipo D)" + } + ] +} diff --git a/pre_process/documento_joaomarcos_texto.txt b/pre_process/documento_joaomarcos_texto.txt new file mode 100644 index 0000000..8b0e489 --- /dev/null +++ b/pre_process/documento_joaomarcos_texto.txt @@ -0,0 +1,46 @@ +SISTEMA INTEGRADO DE LOGÍSTICA DE MATERIAL E DE SERVIÇOS Pág.: 1 de 1 +BASE AÉREA DE MANAUS Data: 15/06/2026 +Hora: 13:23:38 +RELATÓRIO DE CICLO DE INSPEÇÕES DO EQUIPAMENTO +CTR0142R v.10.5 +PN: ANV C-105 CFF: 0117B Nomenclatura: AERONAVE, ASA FIXA, CASA 295 (C-105 AMAZONAS) +SN: 038 Matrícula: 2805 Modelo: C-105 Ciclo Atual: 3650007082 +Seq. Sigla da MNT Descrição da MNT Referência Referência Tipo"E" Vencimento Zera TSO Letra Nível Var. Média Duração Intervalo Controle +2 INSP 1A INSPEÇÃO CHECK 1A Especial (a contar dela mesma Término da Anterior N A B 3 3 D 300:00 HORAS DE VÔO +- Tipo D) +8 MESES CONTÍNUOS +3 INSP 2A INSPEÇÃO CHECK 2A Especial (a contar dela mesma Término da Anterior N A B 10 4 D 600:00 HORAS DE VÔO +- Tipo D) +16 MESES CONTÍNUOS +4 INSP 3A INSPEÇÃO CHECK 3A Especial (a contar dela mesma Término da Anterior N A B 10 5 D 900:00 HORAS DE VÔO +- Tipo D) +24 MESES CONTÍNUOS +5 INSP 2Y INSPEÇÃO CALENDÁRICA DE 2 YEARS Especial (a contar dela mesma Término da Anterior N B B 5 5 D 24 MESES CONTÍNUOS +- Tipo D) +6 CHECK 300 CHECK OPERACIONAL DE 300FH Especial (a contar dela mesma Término da Anterior N A O 6 H 300:00 HORAS DE VÔO +- Tipo D) +7 CHECK 400 CHECK OPERACIONAL DE 400FH Especial (a contar dela mesma Término da Anterior N A O 6 H 400:00 HORAS DE VÔO +- Tipo D) +8 1-INSP AOL INSPEÇÃO AOL 295-019 Última inspeção Término da Anterior N B 1 D 3800 POUSOS +9 2-INSP AOL INSPEÇÃO AOL 295-019 Última Inspeção Específica 8 1-INSP AOL Término da Anterior N B 1 D 2000 POUSOS +10 3-INSP AOL INSPEÇÃO AOL 295-019 Última Inspeção Específica 9 2-INSP AOL Término da Anterior N B 1 D 2000 POUSOS +14 INSP 8Y INSPEÇÃO CALENDÁRICA DE 8 YEARS Especial (a contar dela mesma Término da Anterior N B P 15 20 D 96 MESES CONTÍNUOS +- Tipo D) +15 INSP 1C INSPEÇÃO CHECK 1C Especial (a contar dela mesma Término da Anterior N C P 10 65 D 2400:00 HORAS DE VÔO +- Tipo D) +48 MESES CONTÍNUOS +16 INSP 2C INSPEÇÃO GERAL CHECK 2C Especial (a contar dela mesma Término da Anterior N C P 60 10 D 4800:00 HORAS DE VÔO +- Tipo D) +96 MESES CONTÍNUOS +17 INSP 4Y INSPEÇÃO CALENDÁRICA DE 4 YEARS Especial (a contar dela mesma Término da Anterior N B P 10 10 D 48 MESES CONTÍNUOS +- Tipo D) +18 INSP 100FH BR01 INSPEÇÃO DE 100 FH Especial (a contar dela mesma Término da Anterior N O 1 H 100:00 HORAS DE VÔO +- Tipo D) +19 INSP 2400F BR01 INPEÇÃO 2400FH Especial (a contar dela mesma Término da Anterior N O 3 H 2400:00 HORAS DE VÔO +- Tipo D) +20 INSP 3000F BR01 INSPEÇÃO 3000FH Especial (a contar dela mesma Término da Anterior N B 1 D 3000:00 HORAS DE VÔO +- Tipo D) +22 INSP 1000F INPEÇÃO 1000FH Especial (a contar dela mesma Término da Anterior N B 1 D 1000:00 HORAS DE VÔO +- Tipo D) +23 INSP 50FH INSPEÇÃO 50 FH Especial (a contar dela mesma Término da Anterior N B 1 D 50:00 HORAS DE VÔO +- Tipo D) diff --git a/pre_process/preprocess_pdf.py b/pre_process/preprocess_pdf.py new file mode 100644 index 0000000..9f1ea3a --- /dev/null +++ b/pre_process/preprocess_pdf.py @@ -0,0 +1,181 @@ +import csv +import json +import re +from pathlib import Path + +import pdfplumber + + +ROOT = Path(__file__).resolve().parents[1] +PDF_PATH = ROOT / "raw" / "documento joaomarcos.pdf" +TXT_PATH = ROOT / "pre_process" / "documento_joaomarcos_texto.txt" +JSON_PATH = ROOT / "pre_process" / "documento_joaomarcos_inspecoes.json" +CSV_PATH = ROOT / "pre_process" / "documento_joaomarcos_inspecoes.csv" + +ROW_START_RE = re.compile(r"^(?P\d+)\s+") +INTERVAL_RE = re.compile( + r"(?P\d+(?::\d+)?\s*(?:HORAS DE V[ÔO]O|MESES CONT[ÍI]NUOS|POUSOS))", + re.IGNORECASE, +) + + +def extract_text(pdf_path): + pages = [] + with pdfplumber.open(pdf_path) as pdf: + for page in pdf.pages: + pages.append(page.extract_text(x_tolerance=1, y_tolerance=3) or "") + return "\n\n".join(pages).strip() + + +def normalize_interval(value): + return re.sub(r"\s+", " ", value.replace("VÔO", "VOO")).strip() + + +def split_records(text): + records = [] + current = [] + + for raw_line in text.splitlines(): + line = re.sub(r"\s+", " ", raw_line).strip() + if not line: + continue + if ROW_START_RE.match(line) and " Término da Anterior " in line: + if current: + records.append(" ".join(current)) + current = [line] + elif current: + current.append(line) + + if current: + records.append(" ".join(current)) + + return records + + +def parse_header(text): + header = {} + + patterns = { + "data_relatorio": r"Data:\s*(\d{2}/\d{2}/\d{4})", + "hora_relatorio": r"Hora:\s*(\d{2}:\d{2}:\d{2})", + "pn": r"PN:\s*(.*?)\s+CFF:", + "cff": r"CFF:\s*(.*?)\s+Nomenclatura:", + "nomenclatura": r"Nomenclatura:\s*(.*?)\s+SN:", + "sn": r"SN:\s*(.*?)\s+Matrícula:", + "matricula": r"Matrícula:\s*(.*?)\s+Modelo:", + "modelo": r"Modelo:\s*(.*?)\s+Ciclo Atual:", + "ciclo_atual": r"Ciclo Atual:\s*(\S+)", + } + + compact_text = re.sub(r"\s+", " ", text) + for key, pattern in patterns.items(): + match = re.search(pattern, compact_text) + if match: + header[key] = match.group(1).strip() + + return header + + +def parse_record(record): + record = record.replace("- Tipo D)", " - Tipo D)") + has_tipo_d = " - Tipo D)" in record + left, right = record.split(" Término da Anterior ", 1) + + seq_match = ROW_START_RE.match(left) + seq = int(seq_match.group("seq")) + left_body = left[seq_match.end() :] + + intervalos = [normalize_interval(m.group("intervalo")) for m in INTERVAL_RE.finditer(right)] + right_before_interval = INTERVAL_RE.split(right, maxsplit=1)[0].strip() + tokens = right_before_interval.split() + + zera = tokens[0] if tokens else "" + controle = " ".join(tokens[1:]) + + especial_marker = " Especial (a contar dela mesma" + if especial_marker in left_body: + before_ref, referencia = left_body.split(especial_marker, 1) + referencia = "Especial (a contar dela mesma" + if has_tipo_d: + referencia += " - Tipo D)" + else: + ref_match = re.search(r"(Última .*)$", left_body) + referencia = ref_match.group(1).strip() if ref_match else "" + before_ref = left_body[: ref_match.start()].strip() if ref_match else left_body + + upper_before_ref = before_ref.upper() + desc_idx = upper_before_ref.find("INSPEÇÃO") + if desc_idx == -1: + desc_idx = upper_before_ref.find("INPEÇÃO") + if desc_idx == -1: + desc_idx = upper_before_ref.find("CHECK OPERACIONAL") + + if desc_idx != -1: + sigla = before_ref[:desc_idx].strip() + descricao = before_ref[desc_idx:].strip() + else: + parts = before_ref.split(maxsplit=1) + sigla = parts[0] if parts else "" + descricao = parts[1] if len(parts) > 1 else "" + + intervalo_horas_voo = next((item for item in intervalos if "HORAS DE VOO" in item), "") + intervalo_meses_continuos = next((item for item in intervalos if "MESES CONTÍNUOS" in item), "") + intervalo_pousos = next((item for item in intervalos if "POUSOS" in item), "") + + return { + "seq": seq, + "sigla_mnt": sigla, + "descricao_mnt": descricao, + "referencia": referencia, + "tipo_vencimento": "Término da Anterior", + "zera": zera, + "controle_original": controle, + "intervalo_horas_voo": intervalo_horas_voo, + "intervalo_meses_continuos": intervalo_meses_continuos, + "intervalo_pousos": intervalo_pousos, + "intervalos": intervalos, + "linha_original": record, + } + + +def main(): + text = extract_text(PDF_PATH) + TXT_PATH.write_text(text + "\n", encoding="utf-8") + + payload = { + "fonte": str(PDF_PATH.relative_to(ROOT)), + "metadados": parse_header(text), + "inspecoes": [parse_record(record) for record in split_records(text)], + } + + JSON_PATH.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + + fields = [ + "seq", + "sigla_mnt", + "descricao_mnt", + "referencia", + "tipo_vencimento", + "zera", + "controle_original", + "intervalo_horas_voo", + "intervalo_meses_continuos", + "intervalo_pousos", + "intervalos", + ] + with CSV_PATH.open("w", newline="", encoding="utf-8-sig") as csv_file: + writer = csv.DictWriter(csv_file, fieldnames=fields, delimiter=";") + writer.writeheader() + for row in payload["inspecoes"]: + csv_row = {key: row[key] for key in fields} + csv_row["intervalos"] = " | ".join(row["intervalos"]) + writer.writerow(csv_row) + + print(f"Gerado: {TXT_PATH.relative_to(ROOT)}") + print(f"Gerado: {JSON_PATH.relative_to(ROOT)}") + print(f"Gerado: {CSV_PATH.relative_to(ROOT)}") + print(f"Inspeções extraídas: {len(payload['inspecoes'])}") + + +if __name__ == "__main__": + main()