Download processing.py from Nexialog/ESMA-GPT: direct link, hf CLI and curl.
- Browser
- Download file 6.54 kB
-
https://huggingface.co/spaces/Nexialog/ESMA-GPT/resolve/main/processing.py
- Command line
-
hf download hf://spaces/Nexialog/ESMA-GPT/processing.py
-
curl -L -o processing.py https://huggingface.co/spaces/Nexialog/ESMA-GPT/resolve/main/processing.py
6.54 kB
| from abc import ABC, abstractmethod | |
| from pathlib import Path | |
| from urllib.parse import urlparse | |
| import requests | |
| import fitz | |
| import io | |
| import re | |
| import hashlib | |
| import os | |
| class FileTypeError(Exception): | |
| """Raised when the file type does not match the expected file type.""" | |
| class FileSchemeError(Exception): | |
| """Raised when the file scheme does not match the expected file scheme.""" | |
| class FileProcessor(ABC): | |
| type = None | |
| def __init__(self, path): | |
| self.path = path | |
| self.file_scheme = self._get_file_scheme() | |
| self.__class__._check_file_type(path) | |
| def get_file_data(self): | |
| pass | |
| def _get_file_metadata(self): | |
| pass | |
| def _get_file_paragraphs(self): | |
| pass | |
| def _check_file_type(cls, path): | |
| file_type = Path(path).suffix.lower()[1:] | |
| if file_type != cls.type: | |
| raise FileTypeError( | |
| f"Invalid file type. {cls.__name__} expects a {cls.type} file" | |
| ) | |
| def _get_file_scheme(self): | |
| parsed_path = urlparse(self.path) | |
| if ( | |
| not parsed_path.scheme | |
| or parsed_path.scheme.lower() == "file" | |
| or os.path.isfile(self.path) | |
| ): | |
| return "local" | |
| elif parsed_path.scheme.lower() in ["http", "https", "ftp"]: | |
| return "url" | |
| else: | |
| raise FileSchemeError("Unknown scheme") | |
| def _preprocess_text(self, text): | |
| text = text.replace("\n", " ") | |
| text = re.sub("\s+", " ", text) | |
| text = text.encode("utf-8", "ignore").decode("utf-8", "ignore") | |
| return text | |
| def _generate_hash(self, string): | |
| hash_object = hashlib.md5() | |
| hash_object.update(string.encode("utf-8", "ignore")) | |
| hex_dig = hash_object.hexdigest() | |
| return hex_dig | |
| def generate_paragraphs(): | |
| raise NotImplementedError | |
| def generate_metadata(): | |
| raise NotImplementedError | |
| class PDFProcessor(FileProcessor): | |
| type = "pdf" | |
| def __init__(self, path): | |
| super().__init__(path) | |
| def get_file_data(self, merge_length=200): | |
| file = self._open_file() | |
| file_metadata = self._get_file_metadata(file) | |
| file_paragraphs = self._get_file_paragraphs( | |
| file, file_metadata, start_page=1, end_page=None, merge_length=merge_length | |
| ) | |
| file.close() | |
| return file_metadata, file_paragraphs | |
| def _get_file_metadata(self, file): | |
| file_metadata = dict() | |
| metadata = file.metadata | |
| unique_string = str(Path(self.path).name) + metadata["title"] | |
| file_metadata["id"] = self._generate_hash(unique_string) | |
| file_metadata["title"] = metadata["title"] | |
| file_metadata["author"] = metadata["author"] | |
| file_metadata["subject"] = metadata["subject"] | |
| file_metadata["creation_date"] = metadata["creationDate"] | |
| file_metadata["modification_date"] = metadata["modDate"] | |
| file_metadata["n_pages"] = file.page_count | |
| if self.file_scheme == "local": | |
| file_metadata["url"] = str(Path(self.path).resolve()) | |
| else: | |
| file_metadata["url"] = self.path | |
| file_metadata["file_name"] = Path(self.path).name | |
| file_metadata["short_name"] = Path(self.path).name | |
| file_metadata["release_date"] = "" | |
| file_metadata["report_type"] = "" | |
| file_metadata["source"] = "" | |
| return file_metadata | |
| def _get_file_paragraphs( | |
| self, file, file_metadata, start_page=1, end_page=None, merge_length=200 | |
| ): | |
| if end_page is None: | |
| end_page = file_metadata["n_pages"] | |
| file_paragraphs = [] | |
| for page_num in range(start_page - 1, end_page): | |
| page = file.load_page(page_num) | |
| blocks = page.get_text("blocks") | |
| for block in blocks: | |
| paragraph = self._process_block( | |
| block, page, page_num + start_page, file_metadata["id"] | |
| ) | |
| if paragraph is None: | |
| continue | |
| first_char = paragraph["content"][0] | |
| if len(file_paragraphs) > 0: | |
| if ( | |
| len(file_paragraphs[-1]["content"]) + len(paragraph["content"]) | |
| < merge_length | |
| ) or (first_char.islower() and first_char.isalpha()): | |
| file_paragraphs[-1]["content"] += " " + paragraph["content"] | |
| file_paragraphs[-1]["length"] = len( | |
| file_paragraphs[-1]["content"] | |
| ) | |
| else: | |
| file_paragraphs.append(paragraph) | |
| else: | |
| file_paragraphs.append(paragraph) | |
| return file_paragraphs | |
| def _open_file(self): | |
| if self.file_scheme == "url": | |
| response = requests.get(self.path) | |
| file = fitz.open(stream=io.BytesIO(response.content), filetype="pdf") | |
| elif self.file_scheme == "local": | |
| file = fitz.open(self.path) | |
| return file | |
| def _process_block(self, block, page, page_number, file_id): | |
| x0, y0, x1, y1, content, block_no, block_type = block | |
| if content.isspace() or block_type == 1: | |
| return None | |
| content = self._preprocess_text(content) | |
| unique_content_string = "_".join(map(str, block)) | |
| paragraph_id = self._generate_hash(unique_content_string) | |
| w, h = page.rect.width, page.rect.height | |
| paragraph = { | |
| "id": paragraph_id, | |
| "document_id": file_id, | |
| "content_type": "text" if block_type == 0 else "image", | |
| "content": content, | |
| "length": len(content), | |
| "idx_block": block_no, | |
| "page_number": page_number, | |
| "x0": x0 / h, | |
| "y0": y0 / w, | |
| "x1": x1 / h, | |
| "y1": y1 / w, | |
| } | |
| return paragraph | |
| class HTMLProcessor(FileProcessor): | |
| type = "html" | |
| def __init__(self, path): | |
| super().__init__(path) | |
| def get_file_data(self): | |
| pass | |
| def _get_file_metadata(self): | |
| pass | |
| def _get_file_paragraphs(self): | |
| pass | |
| def _open_file(self): | |
| if self.file_scheme == "url": | |
| response = requests.get(self.path) | |
| file = response.text | |
| elif self.file_scheme == "local": | |
| file = open(self.path, "r").read() | |
| return file | |