Source code for dedoc.metadata_extractors.concrete_metadata_extractors.docx_metadata_extractor
import os
from datetime import datetime
from typing import Optional
import docx
from docx.opc.exceptions import PackageNotFoundError
from dedoc.data_structures.unstructured_document import UnstructuredDocument
from dedoc.metadata_extractors.concrete_metadata_extractors.base_metadata_extractor import BaseMetadataExtractor
[docs]class DocxMetadataExtractor(BaseMetadataExtractor):
"""
This class is used to extract metadata from docx documents.
It expands metadata retrieved by :class:`~dedoc.metadata_extractors.BaseMetadataExtractor`.
In addition to them, the following fields can be added to the metadata other fields:
- document subject;
- keywords;
- category;
- comments;
- author;
- author who last modified the file;
- created, modified and last printed date.
"""
[docs] def can_extract(self,
document: UnstructuredDocument,
directory: str,
filename: str,
converted_filename: str,
original_filename: str,
parameters: Optional[dict] = None,
other_fields: Optional[dict] = None) -> bool:
"""
Check if the document has .docx extension.
Look to the :meth:`~dedoc.metadata_extractors.AbstractMetadataExtractor.can_extract` documentation to get the information about parameters.
"""
return converted_filename.lower().endswith("docx")
[docs] def add_metadata(self,
document: UnstructuredDocument,
directory: str,
filename: str,
converted_filename: str,
original_filename: str,
parameters: dict = None,
other_fields: Optional[dict] = None) -> UnstructuredDocument:
"""
Add the predefined list of metadata for the docx documents.
Look to the :meth:`~dedoc.metadata_extractors.AbstractMetadataExtractor.add_metadata` documentation to get the information about parameters.
"""
parameters = {} if parameters is None else parameters
result = super().add_metadata(document=document, directory=directory, filename=filename, converted_filename=converted_filename,
original_filename=original_filename, parameters=parameters, other_fields=other_fields)
file_path = os.path.join(directory, converted_filename)
docx_other_fields = self._get_docx_fields(file_path)
result.metadata["other_fields"] = {**result.metadata.get("other_fields", {}), **docx_other_fields}
return result
def __convert_date(self, date: Optional[datetime]) -> Optional[int]:
if date is not None:
return int(date.timestamp())
return None
def _get_docx_fields(self, file_path: str) -> dict:
assert os.path.isfile(file_path)
try:
doc = docx.Document(file_path)
properties = doc.core_properties
parameters = {
"document_subject": properties.subject,
"keywords": properties.keywords,
"category": properties.category,
"comments": properties.comments,
"author": properties.author,
"last_modified_by": properties.last_modified_by,
"created_date": self.__convert_date(properties.created),
"modified_date": self.__convert_date(properties.modified),
"last_printed_date": self.__convert_date(properties.last_printed),
}
return parameters
except PackageNotFoundError:
return {"broken_docx": True}