SickGear/lib/hachoir_parser/misc/msoffice.py
echel0n 0d9fbc1ad7 Welcome to our SickBeard-TVRage Edition ...
This version of SickBeard uses both TVDB and TVRage to search and gather it's series data from allowing you to now have access to and download shows that you couldn't before because of being locked into only what TheTVDB had to offer.

Also this edition is based off the code we used in our XEM editon so it does come with scene numbering support as well as all the other features our XEM edition has to offer.

Please before using this with your existing database (sickbeard.db) please make a backup copy of it and delete any other database files such as cache.db and failed.db if present, we HIGHLY recommend starting out with no database files at all to make this a fresh start but the choice is at your own risk!

Enjoy!
2014-03-09 22:39:12 -07:00

131 lines
4.3 KiB
Python

"""
Parsers for the different streams and fragments found in an OLE2 file.
Documents:
- goffice source code
Author: Robert Xiao, Victor Stinner
Creation: 2006-04-23
"""
from lib.hachoir_parser import HachoirParser
from lib.hachoir_core.field import FieldSet, RootSeekableFieldSet, RawBytes
from lib.hachoir_core.endian import LITTLE_ENDIAN
from lib.hachoir_core.stream import StringInputStream
from lib.hachoir_parser.misc.msoffice_summary import SummaryFieldSet, CompObj
from lib.hachoir_parser.misc.word_doc import WordDocumentFieldSet
PROPERTY_NAME = {
u"\5DocumentSummaryInformation": "doc_summary",
u"\5SummaryInformation": "summary",
u"WordDocument": "word_doc",
}
class OfficeRootEntry(HachoirParser, RootSeekableFieldSet):
PARSER_TAGS = {
"description": "Microsoft Office document subfragments",
}
endian = LITTLE_ENDIAN
def __init__(self, stream, **args):
RootSeekableFieldSet.__init__(self, None, "root", stream, None, stream.askSize(self))
HachoirParser.__init__(self, stream, **args)
def validate(self):
return True
def createFields(self):
for index, property in enumerate(self.ole2.properties):
if index == 0:
continue
try:
name = PROPERTY_NAME[property["name"].value]
except LookupError:
name = property.name+"content"
for field in self.parseProperty(index, property, name):
yield field
def parseProperty(self, property_index, property, name_prefix):
ole2 = self.ole2
if not property["size"].value:
return
if property["size"].value >= ole2["header/threshold"].value:
return
name = "%s[]" % name_prefix
first = None
previous = None
size = 0
start = property["start"].value
chain = ole2.getChain(start, True)
blocksize = ole2.ss_size
desc_format = "Small blocks %s..%s (%s)"
while True:
try:
block = chain.next()
contiguous = False
if not first:
first = block
contiguous = True
if previous and block == (previous+1):
contiguous = True
if contiguous:
previous = block
size += blocksize
continue
except StopIteration:
block = None
self.seekSBlock(first)
desc = desc_format % (first, previous, previous-first+1)
size = min(size, property["size"].value*8)
if name_prefix in ("summary", "doc_summary"):
yield SummaryFieldSet(self, name, desc, size=size)
elif name_prefix == "word_doc":
yield WordDocumentFieldSet(self, name, desc, size=size)
elif property_index == 1:
yield CompObj(self, "comp_obj", desc, size=size)
else:
yield RawBytes(self, name, size//8, desc)
if block is None:
break
first = block
previous = block
size = ole2.sector_size
def seekSBlock(self, block):
self.seekBit(block * self.ole2.ss_size)
class FragmentGroup:
def __init__(self, parser):
self.items = []
self.parser = parser
def add(self, item):
self.items.append(item)
def createInputStream(self):
# FIXME: Use lazy stream creation
data = []
for item in self.items:
data.append( item["rawdata"].value )
data = "".join(data)
# FIXME: Use smarter code to send arguments
args = {"ole2": self.items[0].root}
tags = {"class": self.parser, "args": args}
tags = tags.iteritems()
return StringInputStream(data, "<fragment group>", tags=tags)
class CustomFragment(FieldSet):
def __init__(self, parent, name, size, parser, description=None, group=None):
FieldSet.__init__(self, parent, name, description, size=size)
if not group:
group = FragmentGroup(parser)
self.group = group
self.group.add(self)
def createFields(self):
yield RawBytes(self, "rawdata", self.size//8)
def _createInputStream(self, **args):
return self.group.createInputStream()