IGN:Update odfpy and make copying in rtf2xml a little nicer

This commit is contained in:
Kovid Goyal 2009-01-30 11:31:19 -08:00
parent d547891422
commit 3ca3d84384
6 changed files with 2024 additions and 1994 deletions

View File

@ -15,7 +15,8 @@
# #
# #
#########################################################################
import sys, os
import sys, os, shutil
class Copy:
"""Copy each changed file to a directory for debugging purposes"""
__dir = ""
@ -64,25 +65,7 @@ class Copy:
of cp. Otherwise, use a safe python method.
"""
write_file = os.path.join(Copy.__dir,new_file)
platform = sys.platform
if platform[:5] == 'linux':
command = 'cp %(file)s %(write_file)s' % vars()
os.system(command)
else:
read_obj = open(file,'r')
write_obj = open(write_file, 'w')
line = "dummy"
while line:
line = read_obj.read(1000)
write_obj.write(line )
read_obj.close()
write_obj.close()
shutil.copyfile(file, write_file)
def rename(self, source, dest):
read_obj = open(source, 'r')
write_obj = open(dest, 'w')
line = 1
while line:
line = read_obj.readline()
write_obj.write(line)
read_obj.close()
write_obj.close()
shutil.copyfile(source, dest)

View File

@ -624,7 +624,7 @@ allowed_children = {
(TEXTNS,u'object-index'),
(TEXTNS,u'p'),
(TEXTNS,u'section'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'table-index'),
(TEXTNS,u'table-of-content'),
(TEXTNS,u'user-index'),
@ -1073,7 +1073,7 @@ allowed_children = {
(TEXTNS,u'page-sequence'),
(TEXTNS,u'section'),
(TEXTNS,u'sequence-decls'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'table-index'),
(TEXTNS,u'table-of-content'),
(TEXTNS,u'tracked-changes'),
@ -1529,7 +1529,7 @@ allowed_children = {
(TEXTNS,u'object-index'),
(TEXTNS,u'p'),
(TEXTNS,u'section'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'table-index'),
(TEXTNS,u'table-of-content'),
(TEXTNS,u'user-index'),
@ -1759,7 +1759,7 @@ allowed_children = {
(TABLENS,u'table') : (
(OFFICENS,u'dde-source'),
(OFFICENS,u'forms'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TABLENS,u'scenario'),
(TABLENS,u'shapes'),
(TABLENS,u'table-column'),
@ -1807,7 +1807,7 @@ allowed_children = {
(TEXTNS,u'object-index'),
(TEXTNS,u'p'),
(TEXTNS,u'section'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'table-index'),
(TEXTNS,u'table-of-content'),
(TEXTNS,u'user-index'),
@ -1828,7 +1828,7 @@ allowed_children = {
),
(TABLENS,u'table-header-rows') : (
(TABLENS,u'table-row'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
),
(TABLENS,u'table-row') : (
(TABLENS,u'covered-table-cell'),
@ -1842,7 +1842,7 @@ allowed_children = {
),
(TABLENS,u'table-rows') : (
(TABLENS,u'table-row'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
),
(TABLENS,u'table-source') : (
),
@ -2060,6 +2060,8 @@ allowed_children = {
),
(TEXTNS,u'chapter') : (
),
(TEXTNS,u'character-count') : (
),
(TEXTNS,u'conditional-text') : (
),
(TEXTNS,u'creation-date') : (
@ -2126,7 +2128,7 @@ allowed_children = {
(TEXTNS,u'object-index'),
(TEXTNS,u'p'),
(TEXTNS,u'section'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'table-index'),
(TEXTNS,u'table-of-content'),
(TEXTNS,u'user-index'),
@ -2254,7 +2256,7 @@ allowed_children = {
(TEXTNS,u'sequence'),
(TEXTNS,u'sequence-ref'),
(TEXTNS,u'sheet-name'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'span'),
(TEXTNS,u'subject'),
(TEXTNS,u'tab'),
@ -2294,6 +2296,8 @@ allowed_children = {
(TEXTNS,u'illustration-index-entry-template'),
(TEXTNS,u'index-title-template'),
),
(TEXTNS,u'image-count') : (
),
# allowed_children
(TEXTNS,u'index-body') : (
(DR3DNS,u'scene'),
@ -2328,7 +2332,7 @@ allowed_children = {
(TEXTNS,u'object-index'),
(TEXTNS,u'p'),
(TEXTNS,u'section'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'table-index'),
(TEXTNS,u'table-of-content'),
(TEXTNS,u'user-index'),
@ -2423,7 +2427,7 @@ allowed_children = {
(TEXTNS,u'list'),
(TEXTNS,u'number'),
(TEXTNS,u'p'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
),
(TEXTNS,u'list-level-style-bullet') : (
(STYLENS,u'list-level-properties'),
@ -2635,7 +2639,7 @@ allowed_children = {
(TEXTNS,u'sequence'),
(TEXTNS,u'sequence-ref'),
(TEXTNS,u'sheet-name'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'soft-page-break'),
(TEXTNS,u'span'),
(TEXTNS,u'subject'),
(TEXTNS,u'tab'),
@ -2661,6 +2665,8 @@ allowed_children = {
),
(TEXTNS,u'page') : (
),
(TEXTNS,u'page-count') : (
),
(TEXTNS,u'page-continuation') : (
),
(TEXTNS,u'page-number') : (
@ -2672,6 +2678,8 @@ allowed_children = {
),
(TEXTNS,u'page-variable-set') : (
),
(TEXTNS,u'paragraph-count') : (
),
(TEXTNS,u'placeholder') : (
),
(TEXTNS,u'print-date') : (
@ -2686,6 +2694,8 @@ allowed_children = {
),
(TEXTNS,u'reference-mark-start') : (
),
(TEXTNS,u'reference-ref') : (
),
(TEXTNS,u'ruby') : (
(TEXTNS,u'ruby-base'),
(TEXTNS,u'ruby-text'),
@ -3035,6 +3045,8 @@ allowed_children = {
),
(TEXTNS,u'tab') : (
),
(TEXTNS,u'table-count') : (
),
(TEXTNS,u'table-formula') : (
),
(TEXTNS,u'table-index') : (
@ -3132,6 +3144,8 @@ allowed_children = {
),
(TEXTNS,u'variable-set') : (
),
(TEXTNS,u'word-count') : (
),
}
struct_elements = ( # Unused?
@ -3182,6 +3196,7 @@ allows_text = (
(PRESENTATIONNS,u'footer-decl'),
(PRESENTATIONNS,u'header-decl'),
(SVGNS,u'desc'),
(SVGNS,u'title'),
(TEXTNS,u'a'),
(TEXTNS,u'author-initials'),
(TEXTNS,u'author-name'),
@ -3403,7 +3418,6 @@ required_attributes = {
(DRAWNS,u'glue-point'): (
(SVGNS,u'y'),
(SVGNS,u'x'),
(DRAWNS,u'align'),
(DRAWNS,u'id'),
),
(DRAWNS,u'gradient'): (
@ -4297,35 +4311,47 @@ allowed_attributes = {
(ANIMNS,u'value'),
),
(ANIMNS,u'seq'):(
(PRESENTATIONNS,u'node-type'),
(SMILNS,u'decelerate'),
(SMILNS,u'begin'),
(SMILNS,u'end'),
(PRESENTATIONNS,u'group-id'),
(SMILNS,u'accelerate'),
(SMILNS,u'repeatDur'),
(SMILNS,u'endsync'),
(SMILNS,u'restartDefault'),
(PRESENTATIONNS,u'preset-class'),
(SMILNS,u'fillDefault'),
(PRESENTATIONNS,u'preset-id'),
(SMILNS,u'autoReverse'),
(PRESENTATIONNS,u'preset-sub-type'),
(SMILNS,u'repeatCount'),
(SMILNS,u'dur'),
(SMILNS,u'fill'),
(ANIMNS,u'id'),
(SMILNS,u'restart'),
(PRESENTATIONNS,u'group-id'),
(PRESENTATIONNS,u'master-element'),
(PRESENTATIONNS,u'node-type'),
(PRESENTATIONNS,u'preset-class'),
(PRESENTATIONNS,u'preset-id'),
(PRESENTATIONNS,u'preset-sub-type'),
(SMILNS,u'accelerate'),
(SMILNS,u'autoReverse'),
(SMILNS,u'begin'),
(SMILNS,u'decelerate'),
(SMILNS,u'dur'),
(SMILNS,u'end'),
(SMILNS,u'endsync'),
(SMILNS,u'fill'),
(SMILNS,u'fillDefault'),
(SMILNS,u'repeatCount'),
(SMILNS,u'repeatDur'),
(SMILNS,u'restart'),
(SMILNS,u'restartDefault'),
),
(ANIMNS,u'set'):(
(ANIMNS,u'sub-item'),
(SMILNS,u'accelerate'),
(SMILNS,u'accumulate'),
(SMILNS,u'autoReverse'),
(SMILNS,u'additive'),
(SMILNS,u'attributeName'),
(SMILNS,u'to'),
(ANIMNS,u'sub-item'),
(SMILNS,u'targetElement'),
(SMILNS,u'accumulate'),
(SMILNS,u'begin'),
(SMILNS,u'decelerate'),
(SMILNS,u'dur'),
(SMILNS,u'end'),
(SMILNS,u'fill'),
(SMILNS,u'fillDefault'),
(SMILNS,u'repeatCount'),
(SMILNS,u'repeatDur'),
(SMILNS,u'restart'),
(SMILNS,u'restartDefault'),
(SMILNS,u'targetElement'),
(SMILNS,u'to'),
),
(ANIMNS,u'transitionFilter'):(
(SMILNS,u'direction'),
@ -5789,6 +5815,8 @@ allowed_attributes = {
(MANIFESTNS,'salt'),
(MANIFESTNS,'iteration-count'),
),
(MANIFESTNS,u'manifest'):(
),
# allowed_attributes
(METANS,u'auto-reload'):(
(METANS,u'delay'),
@ -6096,7 +6124,7 @@ allowed_attributes = {
(CHARTNS,u'gap-width'),
(CHARTNS,u'interpolation'),
(CHARTNS,u'interval-major'),
(CHARTNS,u'interval-minor'),
(CHARTNS,u'interval-minor-divisor'),
(CHARTNS,u'japanese-candle-stick'),
(CHARTNS,u'label-arrangement'),
(CHARTNS,u'lines'),
@ -6117,6 +6145,7 @@ allowed_attributes = {
(CHARTNS,u'spline-resolution'),
(CHARTNS,u'stacked'),
(CHARTNS,u'symbol-height'),
(CHARTNS,u'symbol-name'),
(CHARTNS,u'symbol-type'),
(CHARTNS,u'symbol-width'),
(CHARTNS,u'text-overlap'),
@ -6236,11 +6265,9 @@ allowed_attributes = {
),
(STYLENS,u'footer'):(
(STYLENS,u'display'),
(STYLENS,u'dynamic-spacing'),
),
(STYLENS,u'footer-left'):(
(STYLENS,u'display'),
(STYLENS,u'dynamic-spacing'),
),
(STYLENS,u'footer-style'):(
),
@ -6437,7 +6464,6 @@ allowed_attributes = {
),
(STYLENS,u'header'):(
(STYLENS,u'display'),
(STYLENS,u'dynamic-spacing'),
),
(STYLENS,u'header-footer-properties'): (
(FONS,u'background-color'),
@ -6468,7 +6494,6 @@ allowed_attributes = {
),
(STYLENS,u'header-left'):(
(STYLENS,u'display'),
(STYLENS,u'dynamic-spacing'),
),
(STYLENS,u'header-style'):(
),
@ -6480,6 +6505,7 @@ allowed_attributes = {
(STYLENS,u'font-name'),
(STYLENS,u'vertical-pos'),
(STYLENS,u'vertical-rel'),
(SVGNS,u'y'),
(TEXTNS,u'min-label-distance'),
(TEXTNS,u'min-label-width'),
(TEXTNS,u'space-before'),
@ -6534,12 +6560,10 @@ allowed_attributes = {
(STYLENS,u'layout-grid-print'),
(STYLENS,u'layout-grid-ruby-below'),
(STYLENS,u'layout-grid-ruby-height'),
(STYLENS,u'name'),
(STYLENS,u'num-format'),
(STYLENS,u'num-letter-sync'),
(STYLENS,u'num-prefix'),
(STYLENS,u'num-suffix'),
(STYLENS,u'page-usage'),
(STYLENS,u'paper-tray-name'),
(STYLENS,u'print'),
(STYLENS,u'print-orientation'),
@ -7156,7 +7180,6 @@ allowed_attributes = {
(TABLENS,u'cell-range-address'),
),
(TABLENS,u'null-date'):(
(TABLENS,u'date-value-type'),
(TABLENS,u'value-type'),
),
(TABLENS,u'odd-columns'):(

View File

@ -39,15 +39,3 @@ def Algorithm(**args):
def KeyDerivation(**args):
return Element(qname = (MANIFESTNS,'key-derivation'), **args)
if __name__ == "__main__":
import cStringIO
xml=cStringIO.StringIO()
m = Manifest()
f = FileEntry(mediatype="text/xml", fullpath="content.xml")
m.addElement(f)
m.toXml(0,xml)
print xml.getvalue()

View File

@ -17,7 +17,7 @@
#
# Contributor(s):
#
TOOLSVERSION = u"ODFPY/0.8.1dev"
TOOLSVERSION = u"ODFPY/0.8.2dev"
ANIMNS = u"urn:oasis:names:tc:opendocument:xmlns:animation:1.0"
DBNS = u"urn:oasis:names:tc:opendocument:xmlns:database:1.0"
@ -49,7 +49,7 @@ TABLENS = u"urn:oasis:names:tc:opendocument:xmlns:table:1.0"
TEXTNS = u"urn:oasis:names:tc:opendocument:xmlns:text:1.0"
XFORMSNS = u"http://www.w3.org/2002/xforms"
XLINKNS = u"http://www.w3.org/1999/xlink"
XMLNS = "http://www.w3.org/XML/1998/namespace"
XMLNS = u"http://www.w3.org/XML/1998/namespace"
nsdict = {

View File

@ -64,6 +64,12 @@ odmimetypes = {
'application/vnd.oasis.opendocument.text-web': '.oth',
}
class OpaqueObject:
def __init__(self, filename, mediatype, content=None):
self.mediatype = mediatype
self.filename = filename
self.content = content
class OpenDocument:
""" A class to hold the content of an OpenDocument document
Use the xml method to write the XML
@ -76,6 +82,7 @@ class OpenDocument:
def __init__(self, mimetype, add_generator=True):
self.mimetype = mimetype
self.childobjects = []
self._extra = []
self.folder = "" # Always empty for toplevel documents
self.topnode = Document(mimetype=self.mimetype)
self.topnode.ownerDocument = self
@ -303,12 +310,15 @@ class OpenDocument:
else:
self.thumbnail = filecontent
def addObject(self, document):
def addObject(self, document, objectname=None):
""" Add an object. The object must be an OpenDocument class
The return value will be the folder in the zipfile the object is stored in
"""
self.childobjects.append(document)
document.folder = "%s/Object %d" % (self.folder, len(self.childobjects))
if objectname is None:
document.folder = "%s/Object %d" % (self.folder, len(self.childobjects))
else:
document.folder = objectname
return ".%s" % document.folder
def _savePictures(self, object, folder):
@ -348,7 +358,7 @@ class OpenDocument:
else:
if addsuffix:
outputfile = outputfile + odmimetypes.get(self.mimetype,'.xxx')
outputfp = zipfile.ZipFile(outputfile,"w")
outputfp = zipfile.ZipFile(outputfile, "w")
self._zipwrite(outputfp)
outputfp.close()
@ -382,6 +392,14 @@ class OpenDocument:
zi.external_attr = UNIXPERMS
self._z.writestr(zi, self.thumbnail)
# Write any extra files
for op in self._extra:
self.manifest.addElement(manifest.FileEntry(fullpath=op.filename, mediatype=op.mediatype))
zi = zipfile.ZipInfo(op.filename.encode('utf-8'), self._now)
zi.compress_type = zipfile.ZIP_DEFLATED
zi.external_attr = UNIXPERMS
if op.content is not None:
self._z.writestr(zi, op.content)
# Write manifest
zi = zipfile.ZipInfo("META-INF/manifest.xml", self._now)
zi.compress_type = zipfile.ZIP_DEFLATED
@ -528,15 +546,20 @@ def load(odffile):
parser.parse(inpsrc)
del doc._parsing
except KeyError, v: pass
# Add the thumbnail here
# Add the images here
# FIXME: Add subobjects correctly here
for mentry,mvalue in manifest.items():
if mentry[:9] == "Pictures/" and len(mentry) > 9:
doc.addPicture(mvalue['full-path'], mvalue['media-type'], z.read(mentry))
elif mentry == "Thumbnails/thumbnail.png":
doc.addThumbnail(z.read(mentry))
elif mentry in ('settings.xml', 'meta.xml', 'content.xml', 'styles.xml'):
pass
else:
pass # Add the SUN junk here to the struct somewhere
if mvalue['full-path'][-1] == '/':
doc._extra.append(OpaqueObject(mvalue['full-path'], mvalue['media-type'], None))
else:
doc._extra.append(OpaqueObject(mvalue['full-path'], mvalue['media-type'], z.read(mentry)))
# Add the SUN junk here to the struct somewhere
# It is cached data, so it can be out-of-date
z.close()
b = doc.getElementsByType(Body)

View File

@ -231,6 +231,19 @@ class ODFContentParser(xml.sax.saxutils.XMLGenerator):
self._callback_func = callback_func
xml.sax.saxutils.XMLGenerator.__init__(self, out, encoding)
def _qname(self, name):
"""Builds a qualified name from a (ns_url, localname) pair"""
if name[0]:
if name[0] == u'http://www.w3.org/XML/1998/namespace':
return u'xml' + ":" + name[1]
# The name is in a non-empty namespace
prefix = self._current_context[name[0]]
if prefix:
# If it is not the default namespace, prepend the prefix
return prefix + ":" + name[1]
# Return the unqualified name
return name[1]
def startElementNS(self, name, qname, attrs):
if name == (TEXTNS, u'user-field-decl'):
field_name = attrs.get((TEXTNS, u'name'))