[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': '&#x0a;' # 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