Spaces:
Sleeping
Sleeping
| import os | |
| from typing import List, Tuple | |
| from PyPDF2 import PdfReader | |
| from docx import Document | |
| import mimetypes | |
| def extract_documents_content(document_files: List[str]) -> str: | |
| """ | |
| Extrai o conteúdo de múltiplos arquivos de documentos (PDF, DOC, DOCX, TXT, etc.). | |
| Args: | |
| document_files: Lista de caminhos para os arquivos de documentos | |
| Returns: | |
| String contendo o conteúdo de todos os documentos no formato: | |
| [NOME_DO_ARQUIVO] | |
| [CONTEUDO_EXTRAIDO] | |
| [NOME_DO_ARQUIVO2] | |
| [CONTEUDO_EXTRAIDO2] | |
| ... | |
| """ | |
| results = [] | |
| for file_path in document_files: | |
| try: | |
| # Verifica se o arquivo existe | |
| if not os.path.exists(file_path): | |
| error_msg = f"ERRO: Arquivo não encontrado - {file_path}" | |
| results.append((os.path.basename(file_path), error_msg)) | |
| continue | |
| # Obtém apenas o nome do arquivo (sem o caminho) | |
| filename = os.path.basename(file_path) | |
| # Determina o tipo de arquivo | |
| file_extension = os.path.splitext(file_path)[1].lower() | |
| # Extrai conteúdo baseado no tipo de arquivo | |
| content = extract_single_document_content(file_path, file_extension) | |
| results.append((filename, content)) | |
| except Exception as e: | |
| error_msg = f"ERRO: {str(e)}" | |
| results.append((os.path.basename(file_path), error_msg)) | |
| # Constrói o texto final no formato solicitado | |
| final_text = "" | |
| for filename, content in results: | |
| final_text += f"Nome Identificador do arquivo: {filename}\n" | |
| final_text += f"[{content}]\n\n" | |
| return final_text.strip() | |
| def extract_single_document_content(file_path: str, file_extension: str = None) -> str: | |
| """ | |
| Extrai o conteúdo de um único arquivo de documento. | |
| Args: | |
| file_path: Caminho para o arquivo | |
| file_extension: Extensão do arquivo (opcional, será detectada automaticamente se não fornecida) | |
| Returns: | |
| Conteúdo extraído do documento como string | |
| """ | |
| if file_extension is None: | |
| file_extension = os.path.splitext(file_path)[1].lower() | |
| try: | |
| if file_extension == '.pdf': | |
| return extract_pdf_content(file_path) | |
| elif file_extension in ['.docx', '.doc']: | |
| return extract_word_content(file_path) | |
| elif file_extension == '.txt': | |
| return extract_txt_content(file_path) | |
| else: | |
| return f"ERRO: Tipo de arquivo não suportado - {file_extension}" | |
| except Exception as e: | |
| return f"ERRO ao extrair conteúdo: {str(e)}" | |
| def extract_pdf_content(pdf_path: str) -> str: | |
| """Extrai conteúdo de arquivo PDF.""" | |
| with open(pdf_path, 'rb') as file: | |
| pdf_reader = PdfReader(file) | |
| content = "" | |
| for page_num in range(len(pdf_reader.pages)): | |
| page = pdf_reader.pages[page_num] | |
| page_content = page.extract_text() | |
| content += page_content + "\n" | |
| # Limpa e reorganiza o conteúdo | |
| cleaned_content = clean_pdf_content(content) | |
| return cleaned_content.strip() | |
| def clean_pdf_content(content: str) -> str: | |
| """ | |
| Limpa e reorganiza o conteúdo extraído do PDF para melhor legibilidade. | |
| Args: | |
| content: Conteúdo bruto extraído do PDF | |
| Returns: | |
| Conteúdo limpo e reorganizado | |
| """ | |
| if not content: | |
| return "" | |
| # Remove caracteres especiais problemáticos | |
| content = content.replace('\x00', '') # NULL bytes | |
| content = content.replace('\x0b', '') # Vertical tab | |
| content = content.replace('\x0c', '') # Form feed | |
| # Divide em linhas | |
| lines = content.split('\n') | |
| cleaned_lines = [] | |
| for line in lines: | |
| line = line.strip() | |
| if line: # Remove linhas vazias | |
| # Remove espaços múltiplos | |
| line = ' '.join(line.split()) | |
| cleaned_lines.append(line) | |
| # Reorganiza o conteúdo para melhor estrutura | |
| reorganized_content = [] | |
| current_section = [] | |
| for line in cleaned_lines: | |
| # Se a linha parece ser um cabeçalho ou título (maiúsculas) | |
| if line.isupper() and len(line) > 3: | |
| # Se temos conteúdo na seção atual, adiciona ao resultado | |
| if current_section: | |
| reorganized_content.extend(current_section) | |
| reorganized_content.append("") # Linha em branco para separar | |
| current_section = [line] | |
| else: | |
| current_section.append(line) | |
| # Adiciona a última seção | |
| if current_section: | |
| reorganized_content.extend(current_section) | |
| # Junta tudo de volta | |
| result = '\n'.join(reorganized_content) | |
| # Remove linhas em branco múltiplas | |
| while '\n\n\n' in result: | |
| result = result.replace('\n\n\n', '\n\n') | |
| return result | |
| def extract_word_content(doc_path: str) -> str: | |
| """Extrai conteúdo de arquivo Word (DOCX/DOC).""" | |
| doc = Document(doc_path) | |
| content = "" | |
| for paragraph in doc.paragraphs: | |
| content += paragraph.text + "\n" | |
| return content.strip() | |
| def extract_txt_content(txt_path: str) -> str: | |
| """Extrai conteúdo de arquivo de texto.""" | |
| with open(txt_path, 'r', encoding='utf-8') as file: | |
| return file.read().strip() | |
| def extract_documents_content_list(document_files: List[str]) -> List[Tuple[str, str]]: | |
| """ | |
| Versão alternativa que retorna uma lista de tuplas em vez de texto concatenado. | |
| Args: | |
| document_files: Lista de caminhos para os arquivos de documentos | |
| Returns: | |
| Lista de tuplas contendo (nome_do_arquivo, conteúdo_extraído) | |
| """ | |
| results = [] | |
| for file_path in document_files: | |
| try: | |
| if not os.path.exists(file_path): | |
| results.append((os.path.basename(file_path), f"ERRO: Arquivo não encontrado")) | |
| continue | |
| filename = os.path.basename(file_path) | |
| file_extension = os.path.splitext(file_path)[1].lower() | |
| content = extract_single_document_content(file_path, file_extension) | |
| results.append((filename, content)) | |
| except Exception as e: | |
| results.append((os.path.basename(file_path), f"ERRO: {str(e)}")) | |
| return results | |
| # Funções de compatibilidade (mantidas para não quebrar código existente) | |
| def extract_pdfs_content(pdf_files: List[str]) -> List[Tuple[str, str]]: | |
| """Função de compatibilidade - agora usa a nova implementação.""" | |
| return extract_documents_content_list(pdf_files) | |
| def extract_single_pdf_content(pdf_path: str) -> Tuple[str, str]: | |
| """Função de compatibilidade - agora usa a nova implementação.""" | |
| return extract_documents_content_list([pdf_path])[0] | |
| # Exemplo de uso | |
| if __name__ == "__main__": | |
| # Exemplo com diferentes tipos de arquivos | |
| document_files = [ | |
| "caminho/para/arquivo1.pdf", | |
| "caminho/para/arquivo2.docx", | |
| "caminho/para/arquivo3.txt", | |
| "caminho/para/arquivo4.doc" | |
| ] | |
| # Extrai e retorna como texto grande | |
| large_text = extract_documents_content(document_files) | |
| print(large_text) | |
| print("\n" + "="*80 + "\n") | |
| # Ou extrai como lista de tuplas | |
| results = extract_documents_content_list(document_files) | |
| for filename, content in results: | |
| print(f"[{filename}]") | |
| print(f"[{content}]") | |
| print("-" * 50) | |