codekingpro/portable-devtools
114k
1import os2from pathlib import Path3from typing import Any, Iterator, List, Union4 5from langchain_core.documents import Document6 7from langchain_community.document_loaders.base import BaseLoader8from langchain_community.document_loaders.unstructured import (9 UnstructuredFileLoader,10 satisfies_min_unstructured_version,11)12 13 14class UnstructuredEmailLoader(UnstructuredFileLoader):15 """Load email files using `Unstructured`.16 17 Works with both18 .eml and .msg files. You can process attachments in addition to the19 e-mail message itself by passing process_attachments=True into the20 constructor for the loader. By default, attachments will be processed21 with the unstructured partition function. If you already know the document22 types of the attachments, you can specify another partitioning function23 with the attachment partitioner kwarg.24 25 Example26 -------27 from langchain_community.document_loaders import UnstructuredEmailLoader28 29 loader = UnstructuredEmailLoader("example_data/fake-email.eml", mode="elements")30 loader.load()31 32 Example33 -------34 from langchain_community.document_loaders import UnstructuredEmailLoader35 36 loader = UnstructuredEmailLoader(37 "example_data/fake-email-attachment.eml",38 mode="elements",39 process_attachments=True,40 )41 loader.load()42 """43 44 def __init__(45 self,46 file_path: Union[str, Path],47 mode: str = "single",48 **unstructured_kwargs: Any,49 ):50 process_attachments = unstructured_kwargs.get("process_attachments")51 attachment_partitioner = unstructured_kwargs.get("attachment_partitioner")52 53 if process_attachments and attachment_partitioner is None:54 from unstructured.partition.auto import partition55 56 unstructured_kwargs["attachment_partitioner"] = partition57 58 super().__init__(file_path=file_path, mode=mode, **unstructured_kwargs)59 60 def _get_elements(self) -> List:61 from unstructured.file_utils.filetype import FileType, detect_filetype62 63 filetype = detect_filetype(self.file_path)64 65 if filetype == FileType.EML:66 from unstructured.partition.email import partition_email67 68 return partition_email(filename=self.file_path, **self.unstructured_kwargs)69 elif satisfies_min_unstructured_version("0.5.8") and filetype == FileType.MSG:70 from unstructured.partition.msg import partition_msg71 72 return partition_msg(filename=self.file_path, **self.unstructured_kwargs)73 else:74 raise ValueError(75 f"Filetype {filetype} is not supported in UnstructuredEmailLoader."76 )77 78 79class OutlookMessageLoader(BaseLoader):80 """81 Loads Outlook Message files using extract_msg.82 83 https://github.com/TeamMsgExtractor/msg-extractor84 """85 86 def __init__(self, file_path: Union[str, Path]):87 """Initialize with a file path.88 89 Args:90 file_path: The path to the Outlook Message file.91 """92 93 self.file_path = str(file_path)94 95 if not os.path.isfile(self.file_path):96 raise ValueError(f"File path {self.file_path} is not a valid file")97 98 try:99 import extract_msg # noqa:F401100 except ImportError:101 raise ImportError(102 "extract_msg is not installed. Please install it with "103 "`pip install extract_msg`"104 )105 106 def lazy_load(self) -> Iterator[Document]:107 import extract_msg108 109 msg = extract_msg.Message(self.file_path)110 yield Document(111 page_content=msg.body,112 metadata={113 "source": self.file_path,114 "subject": msg.subject,115 "sender": msg.sender,116 "date": msg.date,117 },118 )119 msg.close()120 