From 5d37a3d2a1a59d463a42b20a5e5662eb2dd959ac Mon Sep 17 00:00:00 2001 From: Kenio de Souza Date: Fri, 14 Nov 2025 11:11:48 -0300 Subject: [PATCH] =?UTF-8?q?feat():=20Criado=20fun=C3=A7=C3=A3o=20que=20san?= =?UTF-8?q?itiza=20nomes=20de=20arquivos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- actions/sanitize/sanitize_filename.py | 21 +++++++++++++++++++ .../ato_documento_save_multiple_repository.py | 3 ++- .../ato_principal_save_multiple_repository.py | 3 ++- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 actions/sanitize/sanitize_filename.py diff --git a/actions/sanitize/sanitize_filename.py b/actions/sanitize/sanitize_filename.py new file mode 100644 index 0000000..30aae4c --- /dev/null +++ b/actions/sanitize/sanitize_filename.py @@ -0,0 +1,21 @@ +import unicodedata +import re + + +# Remove caracteres inválidos de nomes de arquivos +def sanitize_filename(filename: str) -> str: + # Normaliza Unicode (NFC) + filename = unicodedata.normalize("NFKD", filename) + filename = filename.encode("ascii", "ignore").decode("ascii") + + # Remove caracteres inválidos + filename = re.sub(r'[<>:"/\\|?*\x00-\x1F]', "", filename) + + # Substitui espaços múltiplos por um espaço + filename = re.sub(r"\s+", " ", filename).strip() + + # Garante extensão + if "." not in filename: + filename += ".pdf" + + return filename diff --git a/packages/v1/administrativo/repositories/ato_documento/ato_documento_save_multiple_repository.py b/packages/v1/administrativo/repositories/ato_documento/ato_documento_save_multiple_repository.py index 902f9a7..1af3aeb 100644 --- a/packages/v1/administrativo/repositories/ato_documento/ato_documento_save_multiple_repository.py +++ b/packages/v1/administrativo/repositories/ato_documento/ato_documento_save_multiple_repository.py @@ -5,6 +5,7 @@ from sqlalchemy import func from sqlalchemy.orm import Session from database.mysql import SessionLocal, get_database_settings from actions.file.save_file_from_base64 import save_file_from_base64 +from actions.sanitize.sanitize_filename import sanitize_filename from packages.v1.administrativo.models.ato_principal_model import AtoPrincipal from packages.v1.administrativo.models.ato_documento_model import AtoDocumento from packages.v1.administrativo.schemas.ato_documento_schema import ( @@ -75,7 +76,7 @@ class SaveMultipleRepository: unique_id = uuid.uuid4().hex[:8] file_name = f"documento_{timestamp}_{unique_id}.pdf" else: - file_name = doc_schema.nome_documento + file_name = sanitize_filename(doc_schema.nome_documento) # Salva o arquivo físico file_url_path = save_file_from_base64( diff --git a/packages/v1/administrativo/repositories/ato_principal/ato_principal_save_multiple_repository.py b/packages/v1/administrativo/repositories/ato_principal/ato_principal_save_multiple_repository.py index 2910e53..4cddfd9 100644 --- a/packages/v1/administrativo/repositories/ato_principal/ato_principal_save_multiple_repository.py +++ b/packages/v1/administrativo/repositories/ato_principal/ato_principal_save_multiple_repository.py @@ -5,6 +5,7 @@ from sqlalchemy import func from sqlalchemy.orm import Session # Importação para tipagem da session from database.mysql import SessionLocal, get_database_settings from actions.file.save_file_from_base64 import save_file_from_base64 +from actions.sanitize.sanitize_filename import sanitize_filename from packages.v1.administrativo.models.ato_principal_model import AtoPrincipal from packages.v1.administrativo.models.ato_parte_model import AtoParte from packages.v1.administrativo.models.ato_documento_model import AtoDocumento @@ -140,7 +141,7 @@ class SaveMultipleRepository: unique_id = uuid.uuid4().hex[:8] # reduzido para ficar mais limpo file_name = f"documento_{timestamp}_{unique_id}{file_ext}" else: - file_name = doc.nome_documento + file_name = sanitize_filename(doc.nome_documento) file_url_path = save_file_from_base64( base64_content, file_name, new_ato_id, UPLOAD_DIR, GROUP_SIZE