[Python-modules-commits] [python-odf] 64/118: Updated the userfield class to use odfpy API and avoid xml.sax.saxutils.XMLGenerator
Wolfgang Borgert
debacle at moszumanska.debian.org
Fri Oct 3 21:27:23 UTC 2014
This is an automated email from the git hooks/post-receive script.
debacle pushed a commit to reference refs/remotes/upstream/master
in repository python-odf.
commit 4da1bca7c60657444f9a5a71b9bcefe852f9a5b1
Author: Søren Roug <soren.roug at eea.europa.eu>
Date: Sun Oct 11 20:16:48 2009 +0000
Updated the userfield class to use odfpy API
and avoid xml.sax.saxutils.XMLGenerator
---
odf/element.py | 2 +
odf/userfield.py | 240 +++++++++++--------------------------------------------
2 files changed, 47 insertions(+), 195 deletions(-)
diff --git a/odf/element.py b/odf/element.py
index d376f94..9754c25 100644
--- a/odf/element.py
+++ b/odf/element.py
@@ -56,6 +56,8 @@ def _quoteattr(data, entities={}):
the optional entities parameter. The keys and values must all be
strings; each key will be replaced with its corresponding value.
"""
+ entities['\n']='
'
+ entities['\r']=''
data = _escape(data, entities)
if '"' in data:
if "'" in data:
diff --git a/odf/userfield.py b/odf/userfield.py
index 5bf40c0..196bae1 100644
--- a/odf/userfield.py
+++ b/odf/userfield.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-# Copyright (C) 2006-2007 Søren Roug, European Environment Agency
+# Copyright (C) 2006-2009 Søren Roug, European Environment Agency
#
# This is free software. You may redistribute it under the terms
# of the Apache license and the GNU General Public License Version
@@ -22,16 +22,11 @@
"""Class to show and manipulate user fields in odf documents."""
import sys
-import time
import zipfile
-import xml.sax
-import xml.sax.handler
-import xml.sax.saxutils
-
-from odf.namespaces import OFFICENS, TEXTNS
-
-from cStringIO import StringIO
+from odf.text import UserFieldDecl
+from odf.namespaces import OFFICENS
+from odf.opendocument import load
OUTENCODING = "utf-8"
@@ -64,6 +59,26 @@ class UserFields(object):
"""
self.src_file = src
self.dest_file = dest
+ self.document = None
+
+ def loaddoc(self):
+ if isinstance(self.src_file, basestring):
+ # src_file is a filename, check if it is a zip-file
+ if not zipfile.is_zipfile(self.src_file):
+ raise TypeError("%s is no odt file." % self.src_file)
+ elif self.src_file is None:
+ # use stdin if no file given
+ self.src_file = sys.stdin
+
+ self.document = load(self.src_file)
+
+ def savedoc(self):
+ # write output
+ if self.dest_file is None:
+ # use stdout if no filename given
+ self.document.save('-')
+ else:
+ self.document.save(self.dest_file)
def list_fields(self):
"""List (extract) all known user-fields.
@@ -81,15 +96,21 @@ class UserFields(object):
Returns list of tuples (<field name>, <field type>, <value>).
"""
+ self.loaddoc()
found_fields = []
- def _callback(field_name, value_type, value, attrs):
+ all_fields = self.document.getElementsByType(UserFieldDecl)
+ for f in all_fields:
+ value_type = f.getAttribute('valuetype')
+ if value_type == 'string':
+ value = f.getAttribute('stringvalue')
+ else:
+ value = f.getAttribute('value')
+ field_name = f.getAttribute('name')
+
if field_names is None or field_name in field_names:
found_fields.append((field_name.encode(OUTENCODING),
value_type.encode(OUTENCODING),
value.encode(OUTENCODING)))
- return attrs
-
- self._content_handler(_callback)
return found_fields
def list_values(self, field_names):
@@ -133,187 +154,16 @@ class UserFields(object):
Returns None
"""
- def _callback(field_name, value_type, value, attrs):
- if field_name in data:
- valattr = VALUE_TYPES.get(value_type)
- attrs = dict(attrs.items())
- # Take advantage that startElementNS can take a normal
- # dict as attrs
- attrs[valattr] = data[field_name]
- return attrs
- self._content_handler(_callback, write_file=True)
-
- def _content_handler(self, callback_func, write_file=False):
- """Handle the content using the callback function and write result if
- necessary.
-
- callback_func ... function called for each field found in odf document
- signature: field_name ... name of current field
- value_type ... type of current field
- value ... value of current field
- attrs ... tuple of attrs of current field
- returns: tuple or dict of attrs
- write_file ... boolean telling wether write result to file
-
- """
- class DevNull(object):
- """IO-object which behaves like /dev/null."""
- def write(self, str):
- pass
-
- # get input
- if isinstance(self.src_file, basestring):
- # src_file is a filename, check if it is a zip-file
- if not zipfile.is_zipfile(self.src_file):
- raise TypeError("%s is no odt file." % self.src_file)
- elif self.src_file is None:
- # use stdin if no file given
- self.src_file = sys.stdin
-
- zin = zipfile.ZipFile(self.src_file, 'r')
- content_xml = zin.read('content.xml')
-
- # prepare output
- if write_file:
- output_io = StringIO()
- if self.dest_file is None:
- # use stdout if no filename given
- self.dest_file = sys.stdout
- zout = zipfile.ZipFile(self.dest_file, 'w')
- else:
- output_io = DevNull()
-
-
- # parse input
- odfs = ODFContentParser(callback_func, output_io)
- parser = xml.sax.make_parser()
- parser.setFeature(xml.sax.handler.feature_namespaces, 1)
- parser.setContentHandler(odfs)
- parser.parse(StringIO(content_xml))
-
- # write output
- if write_file:
- # Loop through the input zipfile and copy the content to
- # the output until we get to the content.xml. Then
- # substitute.
- for zinfo in zin.infolist():
- if zinfo.filename == "content.xml":
- # Write meta
- zi = zipfile.ZipInfo("content.xml", time.localtime()[:6])
- zi.compress_type = zipfile.ZIP_DEFLATED
- zout.writestr(zi, odfs.content())
+ self.loaddoc()
+ all_fields = self.document.getElementsByType(UserFieldDecl)
+ for f in all_fields:
+ field_name = f.getAttribute('name')
+ if data.has_key(field_name):
+ value_type = f.getAttribute('valuetype')
+ value = data.get(field_name)
+ if value_type == 'string':
+ f.setAttribute('stringvalue', value)
else:
- payload = zin.read(zinfo.filename)
- zout.writestr(zinfo, payload)
- zout.close()
- zin.close()
-
-
-class ODFContentParser(xml.sax.saxutils.XMLGenerator):
-
- def __init__(self, callback_func, out=None, encoding=OUTENCODING):
- """Constructor.
-
- callback_func ... function called for each field found in odf document
- signature: field_name ... name of current field
- value_type ... type of current field
- value ... value of current field
- attrs ... tuple of attrs of current field
- returns: tuple or dict of attrs
- out ... file like object for output
- encoding ... encoding for output
-
- """
- 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'))
- value_type = attrs.get((OFFICENS, u'value-type'))
- if value_type == 'string':
- value = attrs.get((OFFICENS, u'string-value'))
- else:
- value = attrs.get((OFFICENS, u'value'))
-
- attrs = self._callback_func(field_name, value_type, value, attrs)
-
- self._startElementNS(name, qname, attrs)
-
- def _startElementNS(self, name, qname, attrs):
- # copy of xml.sax.saxutils.XMLGenerator.startElementNS
- # necessary because we have to provide our own writeattr
- # function which is called by this method
- if name[0] is None:
- name = name[1]
- elif self._current_context[name[0]] is None:
- # default namespace
- name = name[1]
- else:
- name = self._current_context[name[0]] + ":" + name[1]
- self._out.write('<' + name)
-
- for k,v in self._undeclared_ns_maps:
- if k is None:
- self._out.write(' xmlns="%s"' % (v or ''))
- else:
- self._out.write(' xmlns:%s="%s"' % (k,v))
- self._undeclared_ns_maps = []
+ f.setAttribute('value', value)
+ self.savedoc()
- for (name, value) in attrs.items():
- name = self._qname(name)
- self._out.write(' %s=' % name)
- writeattr(self._out, value)
- self._out.write('>')
-
- def content(self):
- return self._out.getvalue()
-
-
-ATTR_ENTITIES = {
- '\n': '
' # convert newlines into entities inside attributes
- }
-
-
-def writetext(stream, text, entities={}):
- text = xml.sax.saxutils.escape(text, entities)
- try:
- stream.write(text)
- except UnicodeError:
- for c in text:
- try:
- stream.write(c)
- except UnicodeError:
- stream.write(u"&#%d;" % ord(c))
-
-def writeattr(stream, text):
- # copied from xml.sax.saxutils.writeattr added support for an
- # additional entity mapping
- countdouble = text.count('"')
- entities = ATTR_ENTITIES.copy()
- if countdouble:
- countsingle = text.count("'")
- if countdouble <= countsingle:
- entities['"'] = """
- quote = '"'
- else:
- entities["'"] = "'"
- quote = "'"
- else:
- quote = '"'
- stream.write(quote)
- writetext(stream, text, entities)
- stream.write(quote)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-odf.git
More information about the Python-modules-commits
mailing list