Merge pull request #801 from wiredfool/doc_cleanup

More Docs Cleanup.
This commit is contained in:
Hugo 2014-07-16 11:31:34 +03:00
commit 793dff5a6b
5 changed files with 479 additions and 108 deletions

View File

@ -1,31 +1,29 @@
#!/usr/local/bin/python
# -*- coding: latin-1 -*-
"""
OleFileIO_PL:
Module to read Microsoft OLE2 files (also called Structured Storage or
Microsoft Compound Document File Format), such as Microsoft Office
documents, Image Composer and FlashPix files, Outlook messages, ...
This version is compatible with Python 2.6+ and 3.x
## OleFileIO_PL:
## Module to read Microsoft OLE2 files (also called Structured Storage or
## Microsoft Compound Document File Format), such as Microsoft Office
## documents, Image Composer and FlashPix files, Outlook messages, ...
## This version is compatible with Python 2.6+ and 3.x
version 0.30 2014-02-04 Philippe Lagadec - http://www.decalage.info
## version 0.30 2014-02-04 Philippe Lagadec - http://www.decalage.info
Project website: http://www.decalage.info/python/olefileio
## Project website: http://www.decalage.info/python/olefileio
Improved version of the OleFileIO module from PIL library v1.1.6
See: http://www.pythonware.com/products/pil/index.htm
## Improved version of the OleFileIO module from PIL library v1.1.6
## See: http://www.pythonware.com/products/pil/index.htm
The Python Imaging Library (PIL) is
## The Python Imaging Library (PIL) is
Copyright (c) 1997-2005 by Secret Labs AB
Copyright (c) 1995-2005 by Fredrik Lundh
## Copyright (c) 1997-2005 by Secret Labs AB
## Copyright (c) 1995-2005 by Fredrik Lundh
OleFileIO_PL changes are Copyright (c) 2005-2014 by Philippe Lagadec
## OleFileIO_PL changes are Copyright (c) 2005-2014 by Philippe Lagadec
See source code and LICENSE.txt for information on usage and redistribution.
## See source code and LICENSE.txt for information on usage and redistribution.
## WARNING: THIS IS (STILL) WORK IN PROGRESS.
WARNING: THIS IS (STILL) WORK IN PROGRESS.
"""
# Starting with OleFileIO_PL v0.30, only Python 2.6+ and 3.x is supported
# This import enables print() as a function rather than a keyword
@ -373,8 +371,9 @@ for key in list(vars().keys()):
def isOleFile (filename):
"""
Test if file is an OLE container (according to its header).
filename: file name or path (str, unicode)
return: True if OLE, False otherwise.
:param filename: file name or path (str, unicode)
:returns: True if OLE, False otherwise.
"""
f = open(filename, 'rb')
header = f.read(len(MAGIC))
@ -400,8 +399,8 @@ def i16(c, o = 0):
"""
Converts a 2-bytes (16 bits) string to an integer.
c: string containing bytes to convert
o: offset of bytes to convert in string
:param c: string containing bytes to convert
:param o: offset of bytes to convert in string
"""
return i8(c[o]) | (i8(c[o+1])<<8)
@ -410,8 +409,8 @@ def i32(c, o = 0):
"""
Converts a 4-bytes (32 bits) string to an integer.
c: string containing bytes to convert
o: offset of bytes to convert in string
:param c: string containing bytes to convert
:param o: offset of bytes to convert in string
"""
## return int(ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24))
## # [PL]: added int() because "<<" gives long int since Python 2.4
@ -422,7 +421,8 @@ def i32(c, o = 0):
def _clsid(clsid):
"""
Converts a CLSID to a human-readable string.
clsid: string of length 16.
:param clsid: string of length 16.
"""
assert len(clsid) == 16
# if clsid is only made of null bytes, return an empty string:
@ -442,8 +442,8 @@ def _unicode(s, errors='replace'):
"""
Map unicode string to Latin 1. (Python with Unicode support)
s: UTF-16LE unicode string to convert to Latin-1
errors: 'replace', 'ignore' or 'strict'.
:param s: UTF-16LE unicode string to convert to Latin-1
:param errors: 'replace', 'ignore' or 'strict'.
"""
#TODO: test if it OleFileIO works with Unicode strings, instead of
# converting to Latin-1.
@ -653,14 +653,14 @@ class _OleStream(io.BytesIO):
"""
Constructor for _OleStream class.
fp : file object, the OLE container or the MiniFAT stream
sect : sector index of first sector in the stream
size : total size of the stream
offset : offset in bytes for the first FAT or MiniFAT sector
sectorsize: size of one sector
fat : array/list of sector indexes (FAT or MiniFAT)
filesize : size of OLE file (for debugging)
return : a BytesIO instance containing the OLE stream
:param fp : file object, the OLE container or the MiniFAT stream
:param sect : sector index of first sector in the stream
:param size : total size of the stream
:param offset : offset in bytes for the first FAT or MiniFAT sector
:param sectorsize: size of one sector
:param fat : array/list of sector indexes (FAT or MiniFAT)
:param filesize : size of OLE file (for debugging)
:returns : a BytesIO instance containing the OLE stream
"""
debug('_OleStream.__init__:')
debug(' sect=%d (%X), size=%d, offset=%d, sectorsize=%d, len(fat)=%d, fp=%s'
@ -796,9 +796,9 @@ class _OleDirectoryEntry:
Constructor for an _OleDirectoryEntry object.
Parses a 128-bytes entry from the OLE Directory stream.
entry : string (must be 128 bytes long)
sid : index of this directory entry in the OLE file directory
olefile: OleFileIO containing this directory entry
:param entry : string (must be 128 bytes long)
:param sid : index of this directory entry in the OLE file directory
:param olefile: OleFileIO containing this directory entry
"""
self.sid = sid
# ref to olefile is stored for future use
@ -992,7 +992,7 @@ class _OleDirectoryEntry:
"""
Return modification time of a directory entry.
return: None if modification time is null, a python datetime object
:returns: None if modification time is null, a python datetime object
otherwise (UTC timezone)
new in version 0.26
@ -1006,7 +1006,7 @@ class _OleDirectoryEntry:
"""
Return creation time of a directory entry.
return: None if modification time is null, a python datetime object
:returns: None if modification time is null, a python datetime object
otherwise (UTC timezone)
new in version 0.26
@ -1023,7 +1023,8 @@ class OleFileIO:
OLE container object
This class encapsulates the interface to an OLE 2 structured
storage file. Use the {@link listdir} and {@link openstream} methods to
storage file. Use the :py:meth:`~PIL.OleFileIO.OleFileIO.listdir` and
:py:meth:`~PIL.OleFileIO.OleFileIO.openstream` methods to
access the contents of this file.
Object names are given as a list of strings, one for each subentry
@ -1051,8 +1052,8 @@ class OleFileIO:
"""
Constructor for OleFileIO class.
filename: file to open.
raise_defects: minimal level for defects to be raised as exceptions.
:param filename: file to open.
:param raise_defects: minimal level for defects to be raised as exceptions.
(use DEFECT_FATAL for a typical application, DEFECT_INCORRECT for a
security-oriented application, see source code for details)
"""
@ -1071,13 +1072,13 @@ class OleFileIO:
It may raise an IOError exception according to the minimal level chosen
for the OleFileIO object.
defect_level: defect level, possible values are:
:param defect_level: defect level, possible values are:
DEFECT_UNSURE : a case which looks weird, but not sure it's a defect
DEFECT_POTENTIAL : a potential defect
DEFECT_INCORRECT : an error according to specifications, but parsing can go on
DEFECT_FATAL : an error which cannot be ignored, parsing is impossible
message: string describing the defect, used with raised exception.
exception_type: exception class to be raised, IOError by default
:param message: string describing the defect, used with raised exception.
:param exception_type: exception class to be raised, IOError by default
"""
# added by [PL]
if defect_level >= self._raise_defects_level:
@ -1092,7 +1093,7 @@ class OleFileIO:
Open an OLE2 file.
Reads the header, FAT and directory.
filename: string-like or file-like object
:param filename: string-like or file-like object
"""
#[PL] check if filename is a string-like or file-like object:
# (it is better to check for a read() method)
@ -1279,8 +1280,8 @@ class OleFileIO:
Checks if a stream has not been already referenced elsewhere.
This method should only be called once for each known stream, and only
if stream size is not null.
first_sect: index of first sector of the stream in FAT
minifat: if True, stream is located in the MiniFAT, else in the FAT
:param first_sect: index of first sector of the stream in FAT
:param minifat: if True, stream is located in the MiniFAT, else in the FAT
"""
if minifat:
debug('_check_duplicate_stream: sect=%d in MiniFAT' % first_sect)
@ -1374,8 +1375,9 @@ class OleFileIO:
def loadfat_sect(self, sect):
"""
Adds the indexes of the given sector to the FAT
sect: string containing the first FAT sector, or array of long integers
return: index of last FAT sector.
:param sect: string containing the first FAT sector, or array of long integers
:returns: index of last FAT sector.
"""
# a FAT sector is an array of ulong integers.
if isinstance(sect, array.array):
@ -1508,8 +1510,9 @@ class OleFileIO:
def getsect(self, sect):
"""
Read given sector from file on disk.
sect: sector index
returns a string containing the sector data.
:param sect: sector index
:returns: a string containing the sector data.
"""
# [PL] this original code was wrong when sectors are 4KB instead of
# 512 bytes:
@ -1533,7 +1536,8 @@ class OleFileIO:
def loaddirectory(self, sect):
"""
Load the directory.
sect: sector index of directory stream.
:param sect: sector index of directory stream.
"""
# The directory is stored in a standard
# substream, independent of its size.
@ -1570,9 +1574,10 @@ class OleFileIO:
Load a directory entry from the directory.
This method should only be called once for each storage/stream when
loading the directory.
sid: index of storage/stream in the directory.
return: a _OleDirectoryEntry object
raise: IOError if the entry has always been referenced.
:param sid: index of storage/stream in the directory.
:returns: a _OleDirectoryEntry object
:exception IOError: if the entry has always been referenced.
"""
# check if SID is OK:
if sid<0 or sid>=len(self.direntries):
@ -1601,9 +1606,9 @@ class OleFileIO:
Open a stream, either in FAT or MiniFAT according to its size.
(openstream helper)
start: index of first sector
size: size of stream (or nothing if size is unknown)
force_FAT: if False (default), stream will be opened in FAT or MiniFAT
:param start: index of first sector
:param size: size of stream (or nothing if size is unknown)
:param force_FAT: if False (default), stream will be opened in FAT or MiniFAT
according to size. If True, it will always be opened in FAT.
"""
debug('OleFileIO.open(): sect=%d, size=%d, force_FAT=%s' %
@ -1633,11 +1638,11 @@ class OleFileIO:
def _list(self, files, prefix, node, streams=True, storages=False):
"""
(listdir helper)
files: list of files to fill in
prefix: current location in storage tree (list of names)
node: current node (_OleDirectoryEntry object)
streams: bool, include streams if True (True by default) - new in v0.26
storages: bool, include storages if True (False by default) - new in v0.26
:param files: list of files to fill in
:param prefix: current location in storage tree (list of names)
:param node: current node (_OleDirectoryEntry object)
:param streams: bool, include streams if True (True by default) - new in v0.26
:param storages: bool, include storages if True (False by default) - new in v0.26
(note: the root storage is never included)
"""
prefix = prefix + [node.name]
@ -1660,9 +1665,9 @@ class OleFileIO:
"""
Return a list of streams stored in this file
streams: bool, include streams if True (True by default) - new in v0.26
storages: bool, include storages if True (False by default) - new in v0.26
(note: the root storage is never included)
:param streams: bool, include streams if True (True by default) - new in v0.26
:param storages: bool, include storages if True (False by default) - new in v0.26
(note: the root storage is never included)
"""
files = []
self._list(files, [], self.root, streams, storages)
@ -1674,12 +1679,13 @@ class OleFileIO:
Returns directory entry of given filename. (openstream helper)
Note: this method is case-insensitive.
filename: path of stream in storage tree (except root entry), either:
:param filename: path of stream in storage tree (except root entry), either:
- a string using Unix path syntax, for example:
'storage_1/storage_1.2/stream'
- a list of storage filenames, path to the desired stream/storage.
Example: ['storage_1', 'storage_1.2', 'stream']
return: sid of requested filename
:returns: sid of requested filename
raise IOError if file not found
"""
@ -1703,15 +1709,15 @@ class OleFileIO:
"""
Open a stream as a read-only file object (BytesIO).
filename: path of stream in storage tree (except root entry), either:
:param filename: path of stream in storage tree (except root entry), either:
- a string using Unix path syntax, for example:
'storage_1/storage_1.2/stream'
- a list of storage filenames, path to the desired stream/storage.
Example: ['storage_1', 'storage_1.2', 'stream']
return: file object (read-only)
raise IOError if filename not found, or if this is not a stream.
:returns: file object (read-only)
:exception IOError: if filename not found, or if this is not a stream.
"""
sid = self._find(filename)
entry = self.direntries[sid]
@ -1725,8 +1731,8 @@ class OleFileIO:
Test if given filename exists as a stream or a storage in the OLE
container, and return its type.
filename: path of stream in storage tree. (see openstream for syntax)
return: False if object does not exist, its entry type (>0) otherwise:
:param filename: path of stream in storage tree. (see openstream for syntax)
:returns: False if object does not exist, its entry type (>0) otherwise:
- STGTY_STREAM: a stream
- STGTY_STORAGE: a storage
@ -1744,10 +1750,10 @@ class OleFileIO:
"""
Return modification time of a stream/storage.
filename: path of stream/storage in storage tree. (see openstream for
syntax)
return: None if modification time is null, a python datetime object
otherwise (UTC timezone)
:param filename: path of stream/storage in storage tree. (see openstream for
syntax)
:returns: None if modification time is null, a python datetime object
otherwise (UTC timezone)
new in version 0.26
"""
@ -1760,10 +1766,10 @@ class OleFileIO:
"""
Return creation time of a stream/storage.
filename: path of stream/storage in storage tree. (see openstream for
syntax)
return: None if creation time is null, a python datetime object
otherwise (UTC timezone)
:param filename: path of stream/storage in storage tree. (see openstream for
syntax)
:returns: None if creation time is null, a python datetime object
otherwise (UTC timezone)
new in version 0.26
"""
@ -1777,8 +1783,8 @@ class OleFileIO:
Test if given filename exists as a stream or a storage in the OLE
container.
filename: path of stream in storage tree. (see openstream for syntax)
return: True if object exist, else False.
:param filename: path of stream in storage tree. (see openstream for syntax)
:returns: True if object exist, else False.
"""
try:
sid = self._find(filename)
@ -1791,9 +1797,10 @@ class OleFileIO:
"""
Return size of a stream in the OLE container, in bytes.
filename: path of stream in storage tree (see openstream for syntax)
return: size in bytes (long integer)
raise: IOError if file not found, TypeError if this is not a stream.
:param filename: path of stream in storage tree (see openstream for syntax)
:returns: size in bytes (long integer)
:exception IOError: if file not found
:exception TypeError: if this is not a stream
"""
sid = self._find(filename)
entry = self.direntries[sid]
@ -1815,11 +1822,11 @@ class OleFileIO:
"""
Return properties described in substream.
filename: path of stream in storage tree (see openstream for syntax)
convert_time: bool, if True timestamps will be converted to Python datetime
no_conversion: None or list of int, timestamps not to be converted
(for example total editing time is not a real timestamp)
return: a dictionary of values indexed by id (integer)
:param filename: path of stream in storage tree (see openstream for syntax)
:param convert_time: bool, if True timestamps will be converted to Python datetime
:param no_conversion: None or list of int, timestamps not to be converted
(for example total editing time is not a real timestamp)
:returns: a dictionary of values indexed by id (integer)
"""
# make sure no_conversion is a list, just to simplify code below:
if no_conversion == None:

View File

@ -72,13 +72,6 @@ can be found here.
:undoc-members:
:show-inheritance:
:mod:`ImageMorph` Module
------------------------
.. automodule:: PIL.ImageMorph
:members:
:undoc-members:
:show-inheritance:
:mod:`ImageShow` Module
-----------------------
@ -104,14 +97,6 @@ can be found here.
:undoc-members:
:show-inheritance:
:mod:`OleFileIO` Module
-----------------------
.. automodule:: PIL.OleFileIO
:members:
:undoc-members:
:show-inheritance:
:mod:`PaletteFile` Module
-------------------------

View File

@ -0,0 +1,13 @@
.. py:module:: PIL.ImageMorph
.. py:currentmodule:: PIL.ImageMorph
:py:mod:`ImageMorph` Module
===========================
The :py:mod:`ImageMorph` module provides morphology operations on images.
.. automodule:: PIL.ImageMorph
:members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@ -0,0 +1,364 @@
.. py:module:: PIL.OleFileIO
.. py:currentmodule:: PIL.OleFileIO
:py:mod:`OleFileIO` Module
===========================
The :py:mod:`OleFileIO` module reads Microsoft OLE2 files (also called
Structured Storage or Microsoft Compound Document File Format), such
as Microsoft Office documents, Image Composer and FlashPix files, and
Outlook messages.
This module is the `OleFileIO\_PL`_ project by Philippe Lagadec, v0.30,
merged back into Pillow.
.. _OleFileIO\_PL: http://www.decalage.info/python/olefileio
How to use this module
----------------------
For more information, see also the file **PIL/OleFileIO.py**, sample
code at the end of the module itself, and docstrings within the code.
About the structure of OLE files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An OLE file can be seen as a mini file system or a Zip archive: It
contains **streams** of data that look like files embedded within the
OLE file. Each stream has a name. For example, the main stream of a MS
Word document containing its text is named "WordDocument".
An OLE file can also contain **storages**. A storage is a folder that
contains streams or other storages. For example, a MS Word document with
VBA macros has a storage called "Macros".
Special streams can contain **properties**. A property is a specific
value that can be used to store information such as the metadata of a
document (title, author, creation date, etc). Property stream names
usually start with the character '05'.
For example, a typical MS Word document may look like this:
::
\x05DocumentSummaryInformation (stream)
\x05SummaryInformation (stream)
WordDocument (stream)
Macros (storage)
PROJECT (stream)
PROJECTwm (stream)
VBA (storage)
Module1 (stream)
ThisDocument (stream)
_VBA_PROJECT (stream)
dir (stream)
ObjectPool (storage)
Test if a file is an OLE container
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use isOleFile to check if the first bytes of the file contain the Magic
for OLE files, before opening it. isOleFile returns True if it is an OLE
file, False otherwise.
.. code-block:: python
assert OleFileIO.isOleFile('myfile.doc')
Open an OLE file from disk
~~~~~~~~~~~~~~~~~~~~~~~~~~
Create an OleFileIO object with the file path as parameter:
.. code-block:: python
ole = OleFileIO.OleFileIO('myfile.doc')
Open an OLE file from a file-like object
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is useful if the file is not on disk, e.g. already stored in a
string or as a file-like object.
.. code-block:: python
ole = OleFileIO.OleFileIO(f)
For example the code below reads a file into a string, then uses BytesIO
to turn it into a file-like object.
.. code-block:: python
data = open('myfile.doc', 'rb').read()
f = io.BytesIO(data) # or StringIO.StringIO for Python 2.x
ole = OleFileIO.OleFileIO(f)
How to handle malformed OLE files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By default, the parser is configured to be as robust and permissive as
possible, allowing to parse most malformed OLE files. Only fatal errors
will raise an exception. It is possible to tell the parser to be more
strict in order to raise exceptions for files that do not fully conform
to the OLE specifications, using the raise\_defect option:
.. code-block:: python
ole = OleFileIO.OleFileIO('myfile.doc', raise_defects=DEFECT_INCORRECT)
When the parsing is done, the list of non-fatal issues detected is
available as a list in the parsing\_issues attribute of the OleFileIO
object:
.. code-block:: python
print('Non-fatal issues raised during parsing:')
if ole.parsing_issues:
for exctype, msg in ole.parsing_issues:
print('- %s: %s' % (exctype.__name__, msg))
else:
print('None')
Syntax for stream and storage path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Two different syntaxes are allowed for methods that need or return the
path of streams and storages:
1) Either a **list of strings** including all the storages from the root
up to the stream/storage name. For example a stream called
"WordDocument" at the root will have ['WordDocument'] as full path. A
stream called "ThisDocument" located in the storage "Macros/VBA" will
be ['Macros', 'VBA', 'ThisDocument']. This is the original syntax
from PIL. While hard to read and not very convenient, this syntax
works in all cases.
2) Or a **single string with slashes** to separate storage and stream
names (similar to the Unix path syntax). The previous examples would
be 'WordDocument' and 'Macros/VBA/ThisDocument'. This syntax is
easier, but may fail if a stream or storage name contains a slash.
Both are case-insensitive.
Switching between the two is easy:
.. code-block:: python
slash_path = '/'.join(list_path)
list_path = slash_path.split('/')
Get the list of streams
~~~~~~~~~~~~~~~~~~~~~~~
listdir() returns a list of all the streams contained in the OLE file,
including those stored in storages. Each stream is listed itself as a
list, as described above.
.. code-block:: python
print(ole.listdir())
Sample result:
.. code-block:: python
[['\x01CompObj'], ['\x05DocumentSummaryInformation'], ['\x05SummaryInformation']
, ['1Table'], ['Macros', 'PROJECT'], ['Macros', 'PROJECTwm'], ['Macros', 'VBA',
'Module1'], ['Macros', 'VBA', 'ThisDocument'], ['Macros', 'VBA', '_VBA_PROJECT']
, ['Macros', 'VBA', 'dir'], ['ObjectPool'], ['WordDocument']]
As an option it is possible to choose if storages should also be listed,
with or without streams:
.. code-block:: python
ole.listdir (streams=False, storages=True)
Test if known streams/storages exist:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
exists(path) checks if a given stream or storage exists in the OLE file.
.. code-block:: python
if ole.exists('worddocument'):
print("This is a Word document.")
if ole.exists('macros/vba'):
print("This document seems to contain VBA macros.")
Read data from a stream
~~~~~~~~~~~~~~~~~~~~~~~
openstream(path) opens a stream as a file-like object.
The following example extracts the "Pictures" stream from a PPT file:
.. code-block:: python
pics = ole.openstream('Pictures')
data = pics.read()
Get information about a stream/storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Several methods can provide the size, type and timestamps of a given
stream/storage:
get\_size(path) returns the size of a stream in bytes:
.. code-block:: python
s = ole.get_size('WordDocument')
get\_type(path) returns the type of a stream/storage, as one of the
following constants: STGTY\_STREAM for a stream, STGTY\_STORAGE for a
storage, STGTY\_ROOT for the root entry, and False for a non existing
path.
.. code-block:: python
t = ole.get_type('WordDocument')
get\_ctime(path) and get\_mtime(path) return the creation and
modification timestamps of a stream/storage, as a Python datetime object
with UTC timezone. Please note that these timestamps are only present if
the application that created the OLE file explicitly stored them, which
is rarely the case. When not present, these methods return None.
.. code-block:: python
c = ole.get_ctime('WordDocument')
m = ole.get_mtime('WordDocument')
The root storage is a special case: You can get its creation and
modification timestamps using the OleFileIO.root attribute:
.. code-block:: python
c = ole.root.getctime()
m = ole.root.getmtime()
Extract metadata
~~~~~~~~~~~~~~~~
get\_metadata() will check if standard property streams exist, parse all
the properties they contain, and return an OleMetadata object with the
found properties as attributes.
.. code-block:: python
meta = ole.get_metadata()
print('Author:', meta.author)
print('Title:', meta.title)
print('Creation date:', meta.create_time)
# print all metadata:
meta.dump()
Available attributes include:
::
codepage, title, subject, author, keywords, comments, template,
last_saved_by, revision_number, total_edit_time, last_printed, create_time,
last_saved_time, num_pages, num_words, num_chars, thumbnail,
creating_application, security, codepage_doc, category, presentation_target,
bytes, lines, paragraphs, slides, notes, hidden_slides, mm_clips,
scale_crop, heading_pairs, titles_of_parts, manager, company, links_dirty,
chars_with_spaces, unused, shared_doc, link_base, hlinks, hlinks_changed,
version, dig_sig, content_type, content_status, language, doc_version
See the source code of the OleMetadata class for more information.
Parse a property stream
~~~~~~~~~~~~~~~~~~~~~~~
get\_properties(path) can be used to parse any property stream that is
not handled by get\_metadata. It returns a dictionary indexed by
integers. Each integer is the index of the property, pointing to its
value. For example in the standard property stream
'05SummaryInformation', the document title is property #2, and the
subject is #3.
.. code-block:: python
p = ole.getproperties('specialprops')
By default as in the original PIL version, timestamp properties are
converted into a number of seconds since Jan 1,1601. With the option
convert\_time, you can obtain more convenient Python datetime objects
(UTC timezone). If some time properties should not be converted (such as
total editing time in '05SummaryInformation'), the list of indexes can
be passed as no\_conversion:
.. code-block:: python
p = ole.getproperties('specialprops', convert_time=True, no_conversion=[10])
Close the OLE file
~~~~~~~~~~~~~~~~~~
Unless your application is a simple script that terminates after
processing an OLE file, do not forget to close each OleFileIO object
after parsing to close the file on disk.
.. code-block:: python
ole.close()
Use OleFileIO as a script
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OleFileIO can also be used as a script from the command-line to
display the structure of an OLE file and its metadata, for example:
::
PIL/OleFileIO.py myfile.doc
You can use the option -c to check that all streams can be read fully,
and -d to generate very verbose debugging information.
How to contribute
-----------------
The code is available in `a Mercurial repository on
bitbucket <https://bitbucket.org/decalage/olefileio_pl>`_. You may use
it to submit enhancements or to report any issue.
If you would like to help us improve this module, or simply provide
feedback, please `contact me <http://decalage.info/contact>`_. You can
help in many ways:
- test this module on different platforms / Python versions
- find and report bugs
- improve documentation, code samples, docstrings
- write unittest test cases
- provide tricky malformed files
How to report bugs
------------------
To report a bug, for example a normal file which is not parsed
correctly, please use the `issue reporting
page <https://bitbucket.org/decalage/olefileio_pl/issues?status=new&status=open>`_,
or if you prefer to do it privately, use this `contact
form <http://decalage.info/contact>`_. Please provide all the
information about the context and how to reproduce the bug.
If possible please join the debugging output of OleFileIO. For this,
launch the following command :
::
PIL/OleFileIO.py -d -c file >debug.txt
Classes and Methods
-------------------
.. automodule:: PIL.OleFileIO
:members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@ -16,6 +16,7 @@ Reference
ImageFont
ImageGrab
ImageMath
ImageMorph
ImageOps
ImagePalette
ImagePath
@ -25,5 +26,6 @@ Reference
ImageTk
ImageWin
ExifTags
OleFileIO
PSDraw
../PIL