From 9ace6448bd90a97bddc3579cc1ba3c185e233e30 Mon Sep 17 00:00:00 2001 From: Kenio de Souza Date: Mon, 17 Nov 2025 11:54:15 -0300 Subject: [PATCH] =?UTF-8?q?feat():=20Fun=C3=A7=C3=A3o=20respons=C3=A1vel?= =?UTF-8?q?=20em=20descompactar=20conte=C3=BAdo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compress_decompress.py | 136 +++++++++++++----- 1 file changed, 97 insertions(+), 39 deletions(-) diff --git a/actions/compress_decompress/compress_decompress.py b/actions/compress_decompress/compress_decompress.py index cb9718a..fe10383 100644 --- a/actions/compress_decompress/compress_decompress.py +++ b/actions/compress_decompress/compress_decompress.py @@ -1,49 +1,107 @@ -@staticmethod -def decompress(vf_string): - """ - Descomprime e decodifica texto compactado ou codificado. +# Importa a biblioteca nativa 'zlib' usada para descompressão de dados binários. +import base64 +import zlib - Agora: - - Tenta automaticamente Base64 decode ANTES de tudo. - - Depois detecta zlib. - - Decodifica ISO-8859-1 se não for zlib. - """ - if not vf_string: - return "" +# Define uma classe utilitária chamada 'String', contendo apenas métodos estáticos. +# Essa abordagem permite o uso direto sem necessidade de instanciar a classe. +class String: + @staticmethod + def decompress(vf_string): + """ + Descomprime e decodifica texto de origem WPTools/Firebird. - # Caso seja stream (ex.: BLOB Firebird) - if hasattr(vf_string, "read"): - vf_string = vf_string.read() + Finalidade: + Converter o conteúdo de campos BLOB ou strings compactadas (como no Delphi) + em texto legível, detectando automaticamente se o conteúdo está: + - Compactado com zlib + - Codificado em ISO-8859-1 (padrão ANSI) + - Representado como bytes puros + """ + # Verifica se o valor recebido é nulo, vazio ou None. + # Se for, retorna string vazia para evitar erros de processamento. + if not vf_string: + return "" - # Garante bytes - if isinstance(vf_string, str): - vf_bytes = vf_string.encode("latin1", errors="ignore") - else: - vf_bytes = vf_string + # Caso seja um objeto tipo stream (ex: campo BLOB do Firebird) + # Campos BLOB geralmente possuem o método `.read()` para leitura de bytes. + if hasattr(vf_string, "read"): + vf_string = vf_string.read() # Lê o conteúdo completo do stream - # --- NOVO: TENTATIVA DE BASE64 DECODE ANTES --- - try: - # Remove quebras e espaços — comum em JSON, Firebird, Delphi - cleaned = vf_bytes.strip().replace(b"\n", b"").replace(b"\r", b"") - decoded = base64.b64decode(cleaned, validate=True) - vf_bytes = decoded - except Exception: - # Não era base64, segue normalmente - pass + # Garante que o valor trabalhado é uma sequência de bytes (não string) + # Se o dado já for texto (str), converte para bytes em codificação Latin-1, + # que é compatível com ISO-8859-1 usado por sistemas Delphi/Firebird. + if isinstance(vf_string, str): + vf_bytes = vf_string.encode("latin1", errors="ignore") + else: + vf_bytes = vf_string # Já está em bytes, então apenas reaproveita - # Detecta assinatura zlib - is_zlib = len(vf_bytes) > 2 and vf_bytes[0] == 0x78 and vf_bytes[1] in (0x9C, 0xDA) + # Detecta se o conteúdo foi compactado com zlib. + # A assinatura padrão do formato zlib começa com bytes: 0x78 0x9C ou 0x78 0xDA. + is_zlib = ( + len(vf_bytes) > 2 and vf_bytes[0] == 0x78 and vf_bytes[1] in (0x9C, 0xDA) + ) - if is_zlib: + # Se a detecção confirmar que o conteúdo é zlib, tenta descompactar. + if is_zlib: + try: + # Descompacta os bytes e decodifica o texto usando ISO-8859-1 (ANSI), + # que preserva corretamente acentuação e caracteres especiais. + text = zlib.decompress(vf_bytes).decode("iso-8859-1", errors="ignore") + return text + except Exception: + # Caso falhe (por dados corrompidos ou não comprimidos de fato), + # o fluxo continua normalmente sem interromper a execução. + pass + + # Se não for zlib, tenta tratar o conteúdo como texto puro (não compactado) try: - text = zlib.decompress(vf_bytes).decode("iso-8859-1", errors="ignore") - return text + # Decodifica os bytes diretamente de ISO-8859-1 (padrão usado pelo Delphi) + return vf_bytes.decode("iso-8859-1", errors="ignore") except Exception: - pass + # Como fallback, converte para string bruta para evitar falhas. + return str(vf_string) - # Caso não seja zlib, tenta apenas decodificar ISO-8859-1 - try: - return vf_bytes.decode("iso-8859-1", errors="ignore") - except Exception: - return str(vf_string) + # >>> NOVO MÉTODO <<< + @staticmethod + def compress(text, *, encoding: str = "iso-8859-1", as_base64: bool = True): + """ + Comprime texto/dados com zlib. + + Parâmetros: + text: str | bytes | stream (com .read()) + encoding: encoding usado quando 'text' for str (padrão: ISO-8859-1) + as_base64: se True, retorna string Base64 do conteúdo comprimido; + caso False, retorna bytes comprimidos. + + Retorno: + - bytes (zlib) quando as_base64=False + - str (Base64) quando as_base64=True + + Observações: + - Use o mesmo 'encoding' ao descomprimir para simetria. + - Ideal para armazenar em BLOB ou trafegar seguro (Base64). + """ + if text is None or text == "": + return "" if as_base64 else b"" + + # Se for stream (ex.: BLOB do Firebird) + if hasattr(text, "read"): + raw = text.read() + else: + raw = text + + # Garante bytes + if isinstance(raw, str): + raw_bytes = raw.encode(encoding, errors="ignore") + else: + raw_bytes = bytes(raw) + + # Comprime com zlib + comp = zlib.compress(raw_bytes) + + # Opcional: codifica em Base64 para transporte/JSON + if as_base64: + return base64.b64encode(comp).decode("ascii") + + return comp