# Importa a biblioteca nativa 'zlib' usada para compressão/descompressão de dados binários. import zlib # Importa a função 'rtf_to_text' da biblioteca 'striprtf', # responsável por converter documentos RTF em texto plano legível. from striprtf.striprtf import rtf_to_text # Define uma classe utilitária chamada 'Text', contendo apenas métodos estáticos. # Essa abordagem permite o uso direto sem necessidade de instanciar a classe. class Text: @staticmethod def decompress(vf_string): """ Descomprime e decodifica texto de origem WPTools/Firebird. 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. if not vf_string: return "" # Caso seja um objeto tipo stream (ex: campo BLOB do Firebird) if hasattr(vf_string, "read"): vf_string = vf_string.read() # Garante que o valor trabalhado é uma sequência de bytes if isinstance(vf_string, str): vf_bytes = vf_string.encode("latin1", errors="ignore") else: vf_bytes = vf_string # Detecta assinatura zlib (0x78 0x9C ou 0x78 0xDA) is_zlib = ( len(vf_bytes) > 2 and vf_bytes[0] == 0x78 and vf_bytes[1] in (0x9C, 0xDA) ) # Se for zlib, tenta descompactar if is_zlib: try: return zlib.decompress(vf_bytes).decode("iso-8859-1", errors="ignore") except Exception: pass # Caso não seja zlib, trata como texto puro try: return vf_bytes.decode("iso-8859-1", errors="ignore") except Exception: return str(vf_string) @staticmethod def compress(text, *, encoding: str = "iso-8859-1"): """ Comprime texto/dados com zlib SEM Base64. Parâmetros: text: str | bytes | stream (com .read()) encoding: encoding usado quando 'text' for str (padrão: ISO-8859-1) Retorno: - bytes comprimidos (zlib) Observações: - Ideal para armazenamento direto em BLOB (Firebird, PostgreSQL, etc.) - Evita overhead e custo do Base64 - Totalmente compatível com 'decompress' """ if text is None or text == "": return 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 e retorna bytes return zlib.compress(raw_bytes) @staticmethod def to_text(raw_text: str) -> str: """ Converte o conteúdo RTF em texto simples e retorna como string. Finalidade: - Detectar automaticamente se o conteúdo está em formato RTF. - Converter para texto plano usando a função 'rtf_to_text'. - Retornar uma string limpa e pronta para uso. """ if not raw_text: return "" # Detecta cabeçalho RTF if raw_text.strip().startswith("{\\rtf"): try: return rtf_to_text(raw_text).strip() except Exception: return raw_text return raw_text.strip()