Source code for dedoc.metadata_extractors.concrete_metadata_extractors.pdf_metadata_extractor
from typing import Optional
from dedoc.metadata_extractors.abstract_metadata_extractor import AbstractMetadataExtractor
from dedoc.metadata_extractors.concrete_metadata_extractors.base_metadata_extractor import BaseMetadataExtractor
[docs]class PdfMetadataExtractor(AbstractMetadataExtractor):
"""
This class is used to extract metadata from pdf 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:
- producer;
- creator;
- author;
- title;
- subject;
- keywords;
- creation date;
- modification date.
"""
def __init__(self, *, config: Optional[dict] = None) -> None:
from dedoc.extensions import recognized_extensions, recognized_mimes
super().__init__(config=config, recognized_extensions=recognized_extensions.pdf_like_format, recognized_mimes=recognized_mimes.pdf_like_format)
self.base_extractor = BaseMetadataExtractor(config=config)
self.keys = {
"/Producer": "producer",
"/Creator": "creator",
"/Author": "author",
"/Title": "title",
"/Subject": "subject",
"/Keywords": "keywords"
}
self.keys_date = {
"/CreationDate": "creation_date",
"/ModDate": "modification_date",
}
[docs] def extract(self,
file_path: str,
converted_filename: Optional[str] = None,
original_filename: Optional[str] = None,
parameters: Optional[dict] = None) -> dict:
"""
Add the predefined list of metadata for the pdf documents.
Look to the :meth:`~dedoc.metadata_extractors.AbstractMetadataExtractor.extract` documentation to get the information about parameters.
"""
import os
file_dir, file_name, converted_filename, original_filename = self._get_names(file_path, converted_filename, original_filename)
base_fields = self.base_extractor.extract(
file_path=file_path, converted_filename=converted_filename, original_filename=original_filename, parameters=parameters
)
pdf_fields = self._get_pdf_info(os.path.join(file_dir, converted_filename))
result = {**base_fields, **pdf_fields}
return result
def _get_pdf_info(self, path: str) -> dict:
from pypdf import PdfReader
from pypdf.errors import PdfReadError
try:
with open(path, "rb") as file:
document = PdfReader(file)
document_info = document.metadata if document.metadata is not None else {}
result = self.__prettify_metadata(document_info)
return result
except PdfReadError:
return {"broken_pdf": True}
except Exception as e:
self.logger.warning(f"exception while extract pdf metadata: {path} {e}")
if self.config.get("debug_mode", False):
raise e
return {"broken_pdf": True}
def __prettify_metadata(self, document_info: dict) -> dict:
from dedoc.utils.utils import convert_datetime
result = {}
for key, value in document_info.items():
if isinstance(value, str) and len(value) > 0:
if key in self.keys:
result[self.keys[key]] = value
elif key in self.keys_date:
try:
date = convert_datetime(value)
except Exception:
date = None
if date is not None:
result[self.keys_date[key]] = date
return result