Hello community,

here is the log from the commit of package python-relatorio for 
openSUSE:Factory checked in at 2018-10-04 19:02:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-relatorio (Old)
 and      /work/SRC/openSUSE:Factory/.python-relatorio.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-relatorio"

Thu Oct  4 19:02:02 2018 rev:6 rq:639874 version:0.8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-relatorio/python-relatorio.changes        
2017-12-14 10:57:29.287600635 +0100
+++ /work/SRC/openSUSE:Factory/.python-relatorio.new/python-relatorio.changes   
2018-10-04 19:02:15.835154854 +0200
@@ -1,0 +2,10 @@
+Wed Oct  3 20:01:38 UTC 2018 - Axel Braun <[email protected]>
+
+- version 0.8.1
+  * Add support for Python 3.7
+  * Escape invalid XML characters
+  * Enforce closing tag to be the same directive as the opening
+  * Use compression for zip file
+  * Write mimetype as first file of the zip file
+
+-------------------------------------------------------------------

Old:
----
  relatorio-0.8.0.tar.gz

New:
----
  relatorio-0.8.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-relatorio.spec ++++++
--- /var/tmp/diff_new_pack.AIlrl7/_old  2018-10-04 19:02:17.219153399 +0200
+++ /var/tmp/diff_new_pack.AIlrl7/_new  2018-10-04 19:02:17.227153390 +0200
@@ -1,8 +1,8 @@
 #
 # spec file for package python-relatorio
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
-# Copyright (c) 2016-2017 Dr. Axel Braun
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016-2018 Dr. Axel Braun
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -21,7 +21,7 @@
 %bcond_with tests
 %define         mod_name relatorio
 Name:           python-relatorio
-Version:        0.8.0
+Version:        0.8.1
 Release:        0
 Summary:        Python module to create reports from Python objects
 License:        GPL-3.0+
@@ -61,7 +61,8 @@
 %endif
 
 %files %{python_files}
-%doc README AUTHORS LICENSE
+%license LICENSE
+%doc README AUTHORS 
 %{python_sitelib}/*
 
 %changelog

++++++ relatorio-0.8.0.tar.gz -> relatorio-0.8.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/.drone.yml 
new/relatorio-0.8.1/.drone.yml
--- old/relatorio-0.8.0/.drone.yml      2017-11-20 11:04:12.000000000 +0100
+++ new/relatorio-0.8.1/.drone.yml      2018-08-18 13:27:26.000000000 +0200
@@ -17,11 +17,11 @@
     include:
         - IMAGE: python:2.7
           TOXENV: py27
-        - IMAGE: python:3.3
-          TOXENV: py33
         - IMAGE: python:3.4
           TOXENV: py34
         - IMAGE: python:3.5
           TOXENV: py35
         - IMAGE: python:3.6
           TOXENV: py36
+        - IMAGE: python:3.7
+          TOXENV: py37
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/.hgtags new/relatorio-0.8.1/.hgtags
--- old/relatorio-0.8.0/.hgtags 2017-12-04 16:25:33.000000000 +0100
+++ new/relatorio-0.8.1/.hgtags 2018-09-30 14:43:38.000000000 +0200
@@ -24,3 +24,4 @@
 50115e7464e35bc1517b23ed4fd4eed1d284273a 0.7.0
 8ee1d7515d35918944151d3a44003063e1ab6a18 0.7.1
 0775b131b51d40c2147b1ae104f760698a8d9f9e 0.8.0
+a9a586fec08da03f86ec781472a981949d4c455a 0.8.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/CHANGES new/relatorio-0.8.1/CHANGES
--- old/relatorio-0.8.0/CHANGES 2017-12-03 22:12:27.000000000 +0100
+++ new/relatorio-0.8.1/CHANGES 2018-09-30 14:42:26.000000000 +0200
@@ -1,3 +1,10 @@
+0.8.1 - 20180930
+* Add support for Python 3.7
+* Escape invalid XML characters
+* Enforce closing tag to be the same directive as the opening
+* Use compression for zip file
+* Write mimetype as first file of the zip file
+
 0.8.0 - 20171204
 * Do not guess_type on styled cell content
 * Remove type attributes when guessing type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/PKG-INFO new/relatorio-0.8.1/PKG-INFO
--- old/relatorio-0.8.0/PKG-INFO        2017-12-04 16:26:16.000000000 +0100
+++ new/relatorio-0.8.1/PKG-INFO        2018-09-30 14:44:06.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: relatorio
-Version: 0.8.0
+Version: 0.8.1
 Summary: A templating library able to output odt and pdf files
 Home-page: http://relatorio.tryton.org/
 Author: Cedric Krier
 Author-email: [email protected]
 License: GPL License
+Description-Content-Type: UNKNOWN
 Description: Relatorio
         =========
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/doc/conf.py 
new/relatorio-0.8.1/doc/conf.py
--- old/relatorio-0.8.0/doc/conf.py     2017-12-03 22:11:45.000000000 +0100
+++ new/relatorio-0.8.1/doc/conf.py     2018-08-18 13:27:26.000000000 +0200
@@ -50,7 +50,7 @@
 # The short X.Y version.
 version = '0.8'
 # The full version, including alpha/beta/rc tags.
-release = '0.8.0'
+release = '0.8.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/relatorio/__init__.py 
new/relatorio-0.8.1/relatorio/__init__.py
--- old/relatorio-0.8.0/relatorio/__init__.py   2017-12-03 22:11:59.000000000 
+0100
+++ new/relatorio-0.8.1/relatorio/__init__.py   2018-08-18 13:27:26.000000000 
+0200
@@ -12,5 +12,5 @@
 from .reporting import MIMETemplateLoader, ReportRepository, Report
 from . import templates
 
-__version__ = '0.8.0'
+__version__ = '0.8.1'
 __all__ = ['MIMETemplateLoader', 'ReportRepository', 'Report', 'templates']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/relatorio/templates/opendocument.py 
new/relatorio-0.8.1/relatorio/templates/opendocument.py
--- old/relatorio-0.8.0/relatorio/templates/opendocument.py     2017-11-20 
11:57:58.000000000 +0100
+++ new/relatorio-0.8.1/relatorio/templates/opendocument.py     2018-08-18 
13:27:26.000000000 +0200
@@ -83,6 +83,9 @@
 THUMBNAILS = 'Thumbnails'
 output_encode = genshi.output.encode
 EtreeElement = lxml.etree.Element
+XML_INVALID_CHAR_EXPR = re.compile(
+    # from https://www.w3.org/TR/REC-xml/#charsets
+    u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]')
 
 # A note regarding OpenDocument namespaces:
 #
@@ -245,6 +248,14 @@
                 (node.attrib[py_attrs_attr], value)
 
 
+def escape_xml_invalid_chars(value, repl=' '):
+    "Replace invalid characters for XML."
+    if isinstance(value, basestring):
+        return XML_INVALID_CHAR_EXPR.sub(repl, value)
+    else:
+        return value
+
+
 class Template(MarkupTemplate):
 
     def __init__(self, source, filepath=None, filename=None, loader=None,
@@ -408,9 +419,14 @@
             if directive in GENSHI_CLOSING_DIRECTIVE:
                 # map closing tags with their opening tag
                 if is_opening:
-                    opened_tags.append(statement)
+                    opened_tags.append((statement, directive))
                 else:
-                    closing_tags[id(opened_tags.pop())] = statement
+                    opening_statement, opening_directive = opened_tags.pop()
+                    assert directive == opening_directive, (
+                        "Wrong pairing tags between '%s' and '%s'"
+                        % (opening_statement.text.encode('utf-8'),
+                           statement.text.encode('utf-8')))
+                    closing_tags[id(opening_statement)] = statement
             # - we only need to return opening statements
             if is_opening:
                 r_statements.append((statement,
@@ -526,7 +542,8 @@
                 if (grand_parent is None
                         or grand_parent.tag != table_cell_tag
                         ) or len(grand_parent) != 1 or has_style(parent):
-                    r_node.attrib[py_replace] = expr
+                    r_node.attrib[py_replace] = (
+                        '__relatorio_escape_invalid_chars(%s)' % expr)
                     continue
 
                 cache_id = id(r_node)
@@ -790,6 +807,7 @@
             type_ = 'float'
         elif isinstance(val, basestring):
             type_ = 'string'
+            val = escape_xml_invalid_chars(val)
         elif isinstance(val, datetime.timedelta):
             type_ = 'time'
             val = 'P%sD%sS' % (val.days, val.seconds)
@@ -810,6 +828,7 @@
                                                     kwargs)
         kwargs['__relatorio_make_dimension'] = ImageDimension(self.namespaces)
         kwargs['__relatorio_guess_type'] = self._guess_type
+        kwargs['__relatorio_escape_invalid_chars'] = escape_xml_invalid_chars
 
         counter = ColumnCounter()
         kwargs['__relatorio_reset_col_count'] = counter.reset
@@ -874,7 +893,8 @@
 def fod2od(source):
     "Convert Flat OpenDocument to OpenDocument"
     odt_io = BytesIO()
-    odt_zip = zipfile.ZipFile(odt_io, mode='w')
+    odt_zip = zipfile.ZipFile(
+        odt_io, mode='w', compression=zipfile.ZIP_DEFLATED)
     fodt_tree = lxml.etree.parse(source)
     fodt_root = fodt_tree.getroot()
     office_ns = fodt_root.nsmap['office']
@@ -889,6 +909,8 @@
         '{%s}body' % office_ns: ['content'],
         }
     mimetype = fodt_root.attrib['{%s}mimetype' % office_ns]
+    # mimetype should be written first to let detection through 'magic number'
+    odt_zip.writestr('mimetype', mimetype, zipfile.ZIP_STORED)
     documents = {}
     images = []
     for child in fodt_root:
@@ -917,7 +939,6 @@
         odt_zip.writestr(fname, data)
         manifest.add_file_entry(fname, mime_type)
     odt_zip.writestr(MANIFEST, str(manifest))
-    odt_zip.writestr('mimetype', mimetype)
     odt_zip.close()
     return odt_io
 
@@ -1027,7 +1048,8 @@
         self.manifest = Manifest(self.inzip.read(MANIFEST))
         self.meta = Meta(self.inzip.read(META))
         self.new_oo = BytesIO()
-        self.outzip = zipfile.ZipFile(self.new_oo, 'w')
+        self.outzip = zipfile.ZipFile(
+            self.new_oo, mode='w', compression=zipfile.ZIP_DEFLATED)
         self.xml_serializer = genshi.output.XMLSerializer()
 
     def __call__(self, stream):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/relatorio/tests/test_odt.py 
new/relatorio-0.8.1/relatorio/tests/test_odt.py
--- old/relatorio-0.8.0/relatorio/tests/test_odt.py     2017-11-20 
10:47:38.000000000 +0100
+++ new/relatorio-0.8.1/relatorio/tests/test_odt.py     2018-08-18 
13:27:26.000000000 +0200
@@ -31,7 +31,8 @@
 from genshi.template.eval import UndefinedError
 
 from relatorio.templates.opendocument import Template, GENSHI_EXPR,\
-    GENSHI_URI, RELATORIO_URI, fod2od, remove_node_keeping_tail
+    GENSHI_URI, RELATORIO_URI, fod2od, remove_node_keeping_tail, \
+    escape_xml_invalid_chars
 
 OO_TABLE_NS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0"
 
@@ -100,7 +101,8 @@
         root_interpolated = lxml.etree.parse(interpolated).getroot()
         child = root_interpolated[0]
         self.assertEqual(
-            child.get('{http://genshi.edgewall.org/}replace'), 'foo')
+            child.get('{http://genshi.edgewall.org/}replace'),
+            '__relatorio_escape_invalid_chars(foo)')
 
     def test_column_looping(self):
         xml = b'''
@@ -412,3 +414,23 @@
         self.assertEqual(
             lxml.etree.tostring(tree),
             b'''<parent><previous/>tailtail</parent>''')
+
+
+class TestEscapeXMLInvalidChars(unittest.TestCase):
+
+    def test_valid(self):
+        "Test escape valid"
+        self.assertEqual(escape_xml_invalid_chars("foo"), "foo")
+
+    def test_valid_control(self):
+        "Test escape valid control"
+        self.assertEqual(escape_xml_invalid_chars("foo \x09"), "foo \x09")
+
+    def test_invalid(self):
+        "Test escape invalid"
+        self.assertEqual(escape_xml_invalid_chars("foo \x00 bar"), "foo   bar")
+
+    def test_replacement(self):
+        "Test replacement"
+        self.assertEqual(
+            escape_xml_invalid_chars("foo \x00 bar", "?"), "foo ? bar")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/relatorio.egg-info/PKG-INFO 
new/relatorio-0.8.1/relatorio.egg-info/PKG-INFO
--- old/relatorio-0.8.0/relatorio.egg-info/PKG-INFO     2017-12-04 
16:26:14.000000000 +0100
+++ new/relatorio-0.8.1/relatorio.egg-info/PKG-INFO     2018-09-30 
14:44:06.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: relatorio
-Version: 0.8.0
+Version: 0.8.1
 Summary: A templating library able to output odt and pdf files
 Home-page: http://relatorio.tryton.org/
 Author: Cedric Krier
 Author-email: [email protected]
 License: GPL License
+Description-Content-Type: UNKNOWN
 Description: Relatorio
         =========
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/relatorio.egg-info/requires.txt 
new/relatorio-0.8.1/relatorio.egg-info/requires.txt
--- old/relatorio-0.8.0/relatorio.egg-info/requires.txt 2017-12-04 
16:26:14.000000000 +0100
+++ new/relatorio-0.8.1/relatorio.egg-info/requires.txt 2018-09-30 
14:44:06.000000000 +0200
@@ -1,8 +1,8 @@
-Genshi >= 0.5
-lxml >= 2.0
+Genshi>=0.5
+lxml>=2.0
 
 [chart]
-pycha >= 0.4.0
+pycha>=0.4.0
 pyyaml
 
 [fodt]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.8.0/tox.ini new/relatorio-0.8.1/tox.ini
--- old/relatorio-0.8.0/tox.ini 2017-11-20 11:04:12.000000000 +0100
+++ new/relatorio-0.8.1/tox.ini 2018-08-18 13:27:26.000000000 +0200
@@ -4,7 +4,7 @@
 # and then run "tox" from this directory.
 
 [tox]
-envlist = py26, py27, py32, py33, py34, py35, py36, pypy
+envlist = py26, py27, py32, py33, py34, py35, py36, py37, pypy
 
 [testenv]
 commands = {envpython} setup.py test


Reply via email to