A PyQT GUI application for converting InfoLease report outputs into Excel files. Handles parsing and summarizing. Learns where files are meant to be store and compiles monthly and yearly summaries.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
InfoLeaseExtract/venv/Lib/site-packages/openpyxl/packaging/manifest.py

210 lines
5.5 KiB

# Copyright (c) 2010-2022 openpyxl
"""
File manifest
"""
from mimetypes import MimeTypes
import os.path
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import String, Sequence
from openpyxl.xml.functions import fromstring
from openpyxl.xml.constants import (
ARC_CORE,
ARC_CONTENT_TYPES,
ARC_WORKBOOK,
ARC_APP,
ARC_THEME,
ARC_STYLE,
ARC_SHARED_STRINGS,
EXTERNAL_LINK,
THEME_TYPE,
STYLES_TYPE,
XLSX,
XLSM,
XLTM,
XLTX,
WORKSHEET_TYPE,
COMMENTS_TYPE,
SHARED_STRINGS,
DRAWING_TYPE,
CHART_TYPE,
CHARTSHAPE_TYPE,
CHARTSHEET_TYPE,
CONTYPES_NS,
ACTIVEX,
CTRL,
VBA,
)
from openpyxl.xml.functions import tostring
# initialise mime-types
mimetypes = MimeTypes()
mimetypes.add_type('application/xml', ".xml")
mimetypes.add_type('application/vnd.openxmlformats-package.relationships+xml', ".rels")
mimetypes.add_type("application/vnd.ms-office.vbaProject", ".bin")
mimetypes.add_type("application/vnd.openxmlformats-officedocument.vmlDrawing", ".vml")
mimetypes.add_type("image/x-emf", ".emf")
class FileExtension(Serialisable):
tagname = "Default"
Extension = String()
ContentType = String()
def __init__(self, Extension, ContentType):
self.Extension = Extension
self.ContentType = ContentType
class Override(Serialisable):
tagname = "Override"
PartName = String()
ContentType = String()
def __init__(self, PartName, ContentType):
self.PartName = PartName
self.ContentType = ContentType
DEFAULT_TYPES = [
FileExtension("rels", "application/vnd.openxmlformats-package.relationships+xml"),
FileExtension("xml", "application/xml"),
]
DEFAULT_OVERRIDE = [
Override("/" + ARC_STYLE, STYLES_TYPE), # Styles
Override("/" + ARC_THEME, THEME_TYPE), # Theme
Override("/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"),
Override("/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml")
]
class Manifest(Serialisable):
tagname = "Types"
Default = Sequence(expected_type=FileExtension, unique=True)
Override = Sequence(expected_type=Override, unique=True)
path = "[Content_Types].xml"
__elements__ = ("Default", "Override")
def __init__(self,
Default=(),
Override=(),
):
if not Default:
Default = DEFAULT_TYPES
self.Default = Default
if not Override:
Override = DEFAULT_OVERRIDE
self.Override = Override
@property
def filenames(self):
return [part.PartName for part in self.Override]
@property
def extensions(self):
"""
Map content types to file extensions
Skip parts without extensions
"""
exts = {os.path.splitext(part.PartName)[-1] for part in self.Override}
return [(ext[1:], mimetypes.types_map[True][ext]) for ext in sorted(exts) if ext]
def to_tree(self):
"""
Custom serialisation method to allow setting a default namespace
"""
defaults = [t.Extension for t in self.Default]
for ext, mime in self.extensions:
if ext not in defaults:
mime = FileExtension(ext, mime)
self.Default.append(mime)
tree = super(Manifest, self).to_tree()
tree.set("xmlns", CONTYPES_NS)
return tree
def __contains__(self, content_type):
"""
Check whether a particular content type is contained
"""
for t in self.Override:
if t.ContentType == content_type:
return True
def find(self, content_type):
"""
Find specific content-type
"""
try:
return next(self.findall(content_type))
except StopIteration:
return
def findall(self, content_type):
"""
Find all elements of a specific content-type
"""
for t in self.Override:
if t.ContentType == content_type:
yield t
def append(self, obj):
"""
Add content object to the package manifest
# needs a contract...
"""
ct = Override(PartName=obj.path, ContentType=obj.mime_type)
self.Override.append(ct)
def _write(self, archive, workbook):
"""
Write manifest to the archive
"""
self.append(workbook)
self._write_vba(workbook)
self._register_mimetypes(filenames=archive.namelist())
archive.writestr(self.path, tostring(self.to_tree()))
def _register_mimetypes(self, filenames):
"""
Make sure that the mime type for all file extensions is registered
"""
for fn in filenames:
ext = os.path.splitext(fn)[-1]
if not ext:
continue
mime = mimetypes.types_map[True][ext]
fe = FileExtension(ext[1:], mime)
self.Default.append(fe)
def _write_vba(self, workbook):
"""
Add content types from cached workbook when keeping VBA
"""
if workbook.vba_archive:
node = fromstring(workbook.vba_archive.read(ARC_CONTENT_TYPES))
mf = Manifest.from_tree(node)
filenames = self.filenames
for override in mf.Override:
if override.PartName not in (ACTIVEX, CTRL, VBA):
continue
if override.PartName not in filenames:
self.Override.append(override)