Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-relatorio for 
openSUSE:Factory checked in at 2021-09-16 23:14:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-relatorio (Old)
 and      /work/SRC/openSUSE:Factory/.python-relatorio.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-relatorio"

Thu Sep 16 23:14:50 2021 rev:13 rq:919444 version:0.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-relatorio/python-relatorio.changes        
2021-09-08 21:37:04.697920899 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-relatorio.new.1899/python-relatorio.changes  
    2021-09-16 23:17:26.075969920 +0200
@@ -1,0 +2,13 @@
+Thu Sep 16 06:56:49 UTC 2021 - pgaj...@suse.com
+
+- python_alternative relatorio-render
+
+-------------------------------------------------------------------
+Sun Sep 12 15:46:17 UTC 2021 - Axel Braun <axel.br...@gmx.de>
+
+- version 0.10.0
+  * Add relatorio-render script
+  * Add templating of meta in opendocument
+  * Remove support for Python older than 3.5
+
+-------------------------------------------------------------------

Old:
----
  relatorio-0.9.3.tar.gz

New:
----
  relatorio-0.10.0.tar.gz

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

Other differences:
------------------
++++++ python-relatorio.spec ++++++
--- /var/tmp/diff_new_pack.y2cXDT/_old  2021-09-16 23:17:26.791970662 +0200
+++ /var/tmp/diff_new_pack.y2cXDT/_new  2021-09-16 23:17:26.791970662 +0200
@@ -20,7 +20,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define         mod_name relatorio
 Name:           python-relatorio
-Version:        0.9.3
+Version:        0.10.0
 Release:        0
 Summary:        Python module to create reports from Python objects
 License:        GPL-3.0-or-later
@@ -38,6 +38,8 @@
 Requires:       python-lxml
 Requires:       python-pycha
 Requires:       python-python-magic
+Requires(post): update-alternatives
+Requires(preun):update-alternatives
 BuildArch:      noarch
 %python_subpackages
 
@@ -55,6 +57,7 @@
 %install
 %python_install
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
+%python_clone -a %{buildroot}%{_bindir}/relatorio-render
 
 %check
 # https://relatorio.tryton.org/bug65
@@ -62,9 +65,16 @@
 mv relatorio relatorio_hide
 %pyunittest discover -v
 
+%post
+%python_install_alternative relatorio-render
+
+%postun
+%python_uninstall_alternative relatorio-render
+
 %files %{python_files}
 %license LICENSE
 %doc README COPYRIGHT README
 %{python_sitelib}/*
+%python_alternative %{_bindir}/relatorio-render
 
 %changelog

++++++ relatorio-0.9.3.tar.gz -> relatorio-0.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/.drone.yml 
new/relatorio-0.10.0/.drone.yml
--- old/relatorio-0.9.3/.drone.yml      2020-12-19 13:41:40.000000000 +0100
+++ new/relatorio-0.10.0/.drone.yml     2021-09-10 11:32:24.000000000 +0200
@@ -11,16 +11,12 @@
         image: ${IMAGE}
         commands:
             - pip install tox
-            - apt-get update
-            - apt-get install -y python-cairo
             - tox -e "${TOXENV}"
         volumes:
              - cache:/root/.cache
 
 matrix:
     include:
-        - IMAGE: python:2.7
-          TOXENV: py27
         - IMAGE: python:3.5
           TOXENV: py35
         - IMAGE: python:3.6
@@ -31,3 +27,5 @@
           TOXENV: py38
         - IMAGE: python:3.9
           TOXENV: py39
+        - IMAGE: pypy:3
+          TOXENV: pypy3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/.hgtags new/relatorio-0.10.0/.hgtags
--- old/relatorio-0.9.3/.hgtags 2021-05-07 13:51:51.000000000 +0200
+++ new/relatorio-0.10.0/.hgtags        2021-09-11 23:24:35.000000000 +0200
@@ -29,3 +29,4 @@
 34f63c525603ed1fe903703725a51d28cdfa622f 0.9.1
 9c0efe3507a42762e2128f9ad475f463da253c2b 0.9.2
 b190bcec6e4440fd4d21400bb1a6b01291448e41 0.9.3
+ef956866045d0ef69164574cdda0a95be63e1f20 0.10.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/CHANGELOG 
new/relatorio-0.10.0/CHANGELOG
--- old/relatorio-0.9.3/CHANGELOG       2021-05-07 12:11:09.000000000 +0200
+++ new/relatorio-0.10.0/CHANGELOG      2021-09-11 23:10:17.000000000 +0200
@@ -1,3 +1,8 @@
+* 0.10.0 - 20210911
+* Remove support for Python older than 3.5
+* Add relatorio-render script
+* Add templating of meta in opendocument
+
 0.9.3 - 20210507
 * Support empty image in opendocument
 * Add support for Python 3.9
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/COPYRIGHT 
new/relatorio-0.10.0/COPYRIGHT
--- old/relatorio-0.9.3/COPYRIGHT       2020-02-23 17:24:17.000000000 +0100
+++ new/relatorio-0.10.0/COPYRIGHT      2021-09-11 23:10:27.000000000 +0200
@@ -1,7 +1,8 @@
-Copyright (C) 2008-2017 Nicolas ??vrard
+Copyright (C) 2008-2021 Nicolas ??vrard
 Copyright (C) 2008-2009 Ga??tan de Menten
-Copyright (C) 2008-2020 C??dric Krier
+Copyright (C) 2008-2021 C??dric Krier
 Copyright (C) 2008 Udo Spallek
+Copyright (C) 2007-2008 OpenHex SPRL
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/PKG-INFO 
new/relatorio-0.10.0/PKG-INFO
--- old/relatorio-0.9.3/PKG-INFO        2021-05-07 13:52:49.767762200 +0200
+++ new/relatorio-0.10.0/PKG-INFO       2021-09-11 23:25:22.633879000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: relatorio
-Version: 0.9.3
+Version: 0.10.0
 Summary: A templating library able to output odt and pdf files
 Home-page: https://pypi.python.org/pypi/relatorio
 Author: Tryton
@@ -32,9 +32,14 @@
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: GNU General Public License (GPL)
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Topic :: Text Processing
+Requires-Python: >=3.5
 Provides-Extra: chart
 Provides-Extra: fodt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/doc/conf.py 
new/relatorio-0.10.0/doc/conf.py
--- old/relatorio-0.9.3/doc/conf.py     2020-08-06 09:14:00.000000000 +0200
+++ new/relatorio-0.10.0/doc/conf.py    2021-09-10 11:23:00.000000000 +0200
@@ -34,8 +34,8 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'relatorio'
-copyright = u'2015, Nicolas ??vrard, CGa??tan de Menten, C??dric Krier'
+project = 'relatorio'
+copyright = '2015, Nicolas ??vrard, CGa??tan de Menten, C??dric Krier'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -44,7 +44,7 @@
 # The short X.Y version.
 version = '0.9'
 # The full version, including alpha/beta/rc tags.
-release = '0.9.3'
+release = '0.9.4'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -179,8 +179,8 @@
 # (source start file, target name, title, author, documentclass
 # [howto/manual]).
 latex_documents = [
-    ('index', 'relatorio.tex', u'relatorio Documentation',
-        u'Nicolas ??vrard, CGa??tan de Menten, C??dric Krier', 'manual'),
+    ('index', 'relatorio.tex', 'relatorio Documentation',
+        'Nicolas ??vrard, CGa??tan de Menten, C??dric Krier', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -209,8 +209,8 @@
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('index', 'relatorio', u'relatorio Documentation',
-     [u'Nicolas ??vrard, CGa??tan de Menten, C??dric Krier'], 1)
+    ('index', 'relatorio', 'relatorio Documentation',
+     ['Nicolas ??vrard, CGa??tan de Menten, C??dric Krier'], 1)
 ]
 
 # If true, show URL addresses after external links.
@@ -223,8 +223,8 @@
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    ('index', 'relatorio', u'relatorio Documentation',
-        u'Nicolas ??vrard, CGa??tan de Menten, C??dric Krier', 'relatorio',
+    ('index', 'relatorio', 'relatorio Documentation',
+        'Nicolas ??vrard, CGa??tan de Menten, C??dric Krier', 'relatorio',
         'a templating library',
         'Templating'),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/examples/demo_context.py 
new/relatorio-0.10.0/examples/demo_context.py
--- old/relatorio-0.9.3/examples/demo_context.py        2018-11-09 
16:41:53.000000000 +0100
+++ new/relatorio-0.10.0/examples/demo_context.py       2021-09-10 
11:23:00.000000000 +0200
@@ -1,4 +1,4 @@
-from __future__ import print_function
+
 from os.path import abspath, join, dirname
 from relatorio import Report
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/examples/demo_odf.py 
new/relatorio-0.10.0/examples/demo_odf.py
--- old/relatorio-0.9.3/examples/demo_odf.py    2018-11-09 22:48:09.000000000 
+0100
+++ new/relatorio-0.10.0/examples/demo_odf.py   2021-09-10 11:23:00.000000000 
+0200
@@ -1,4 +1,4 @@
-from __future__ import print_function
+
 from os.path import abspath, join, dirname
 from relatorio import Report
 from relatorio.templates import opendocument
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/examples/demo_repository.py 
new/relatorio-0.10.0/examples/demo_repository.py
--- old/relatorio-0.9.3/examples/demo_repository.py     2018-11-09 
16:41:53.000000000 +0100
+++ new/relatorio-0.10.0/examples/demo_repository.py    2021-09-10 
11:23:00.000000000 +0200
@@ -1,4 +1,4 @@
-from __future__ import print_function
+
 import relatorio
 from common import Invoice, inv
 from os.path import join, dirname
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/__init__.py 
new/relatorio-0.10.0/relatorio/__init__.py
--- old/relatorio-0.9.3/relatorio/__init__.py   2020-08-06 09:14:07.000000000 
+0200
+++ new/relatorio-0.10.0/relatorio/__init__.py  2021-09-11 23:10:01.000000000 
+0200
@@ -12,5 +12,5 @@
 from .reporting import MIMETemplateLoader, ReportRepository, Report
 from . import templates
 
-__version__ = '0.9.3'
+__version__ = '0.10.0'
 __all__ = ['MIMETemplateLoader', 'ReportRepository', 'Report', 'templates']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/reporting.py 
new/relatorio-0.10.0/relatorio/reporting.py
--- old/relatorio-0.9.3/relatorio/reporting.py  2020-07-30 15:52:07.000000000 
+0200
+++ new/relatorio-0.10.0/relatorio/reporting.py 2021-08-12 23:08:56.000000000 
+0200
@@ -1,23 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import os
 import sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/templates/__init__.py 
new/relatorio-0.10.0/relatorio/templates/__init__.py
--- old/relatorio-0.9.3/relatorio/templates/__init__.py 2018-08-18 
13:27:26.000000000 +0200
+++ new/relatorio-0.10.0/relatorio/templates/__init__.py        2021-08-12 
23:08:56.000000000 +0200
@@ -1,23 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 plugins = ['base', 'opendocument', 'pdf', 'chart']
 
 for name in plugins:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/templates/base.py 
new/relatorio-0.10.0/relatorio/templates/base.py
--- old/relatorio-0.9.3/relatorio/templates/base.py     2020-03-01 
00:38:56.000000000 +0100
+++ new/relatorio-0.10.0/relatorio/templates/base.py    2021-08-12 
23:08:56.000000000 +0200
@@ -1,23 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import genshi.core
 from genshi.template import NewTextTemplate, MarkupTemplate
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/templates/chart.py 
new/relatorio-0.10.0/relatorio/templates/chart.py
--- old/relatorio-0.9.3/relatorio/templates/chart.py    2018-11-09 
22:48:09.000000000 +0100
+++ new/relatorio-0.10.0/relatorio/templates/chart.py   2021-08-12 
23:08:56.000000000 +0200
@@ -1,24 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2014 Cedric Krier.
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 from io import BytesIO, StringIO
 
 import genshi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/templates/opendocument.py 
new/relatorio-0.10.0/relatorio/templates/opendocument.py
--- old/relatorio-0.9.3/relatorio/templates/opendocument.py     2021-03-27 
12:52:33.000000000 +0100
+++ new/relatorio-0.10.0/relatorio/templates/opendocument.py    2021-09-10 
11:25:31.000000000 +0200
@@ -1,24 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2009-2017 Cedric Krier.
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import re
 try:
     # requires python 2.5+
@@ -30,7 +11,7 @@
 import mimetypes
 import sys
 import time
-import urllib
+import urllib.parse
 import zipfile
 from io import BytesIO
 from copy import deepcopy
@@ -57,15 +38,6 @@
 except ImportError:
     ChartTemplate = None
 
-try:
-    basestring
-except NameError:
-    basestring = str
-try:
-    long
-except NameError:
-    long = int
-
 __metaclass__ = type
 warnings.filterwarnings('always', module='relatorio.templates.opendocument')
 
@@ -95,7 +67,7 @@
 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]')
+    '[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]')
 
 # A note regarding OpenDocument namespaces:
 #
@@ -260,7 +232,7 @@
 
 def escape_xml_invalid_chars(value, repl=' '):
     "Replace invalid characters for XML."
-    if isinstance(value, basestring):
+    if isinstance(value, str):
         return XML_INVALID_CHAR_EXPR.sub(repl, value)
     else:
         return value
@@ -270,7 +242,16 @@
 
     def __init__(self, source, filepath=None, filename=None, loader=None,
                  encoding=None, lookup='strict', allow_exec=True):
-        self.namespaces = {}
+        # assign default/fake namespaces so that documents do not need to
+        # define them if they don't use them
+        self.namespaces = {
+            "text": "urn:text",
+            "draw": "urn:draw",
+            "table": "urn:table",
+            "office": "urn:office",
+            "xlink": "urn:xlink",
+            "svg": "urn:svg",
+        }
         self.inner_docs = []
         self.has_col_loop = False
         self._source = None
@@ -300,29 +281,37 @@
         zf = get_zip_file(source)
         content = zf.read('content.xml')
         styles = zf.read('styles.xml')
+        meta = zf.read('meta.xml')
 
         template = super(Template, self)
         content = template._parse(self.insert_directives(content), encoding)
         styles = template._parse(self.insert_directives(styles), encoding)
+        meta = template._parse(self.insert_directives(meta), encoding)
         content_files = [('content.xml', content)]
         styles_files = [('styles.xml', styles)]
+        meta_files = [('meta.xml', meta)]
 
         while self.inner_docs:
             doc = self.inner_docs.pop()
-            c_path, s_path = doc + '/content.xml', doc + '/styles.xml'
+            c_path, s_path, m_path = (
+                doc + '/content.xml', doc + '/styles.xml', doc + '/meta.xml')
             content = zf.read(c_path)
             styles = zf.read(s_path)
+            meta = zf.read(m_path)
 
             c_parsed = template._parse(self.insert_directives(content),
                                        encoding)
             s_parsed = template._parse(self.insert_directives(styles),
                                        encoding)
+            m_parsed = template._parse(self.insert_directives(meta),
+                                       encoding)
             content_files.append((c_path, c_parsed))
             styles_files.append((s_path, s_parsed))
+            meta_files.append((m_path, m_parsed))
         zf.close()
 
         parsed = []
-        for fpath, fparsed in content_files + styles_files:
+        for fpath, fparsed in content_files + styles_files + meta_files:
             self._files.add(fpath)
             parsed.append((genshi.core.PI, ('relatorio', fpath), None))
             parsed += fparsed
@@ -335,16 +324,6 @@
         tree = lxml.etree.parse(BytesIO(content))
         root = tree.getroot()
 
-        # assign default/fake namespaces so that documents do not need to
-        # define them if they don't use them
-        self.namespaces = {
-            "text": "urn:text",
-            "draw": "urn:draw",
-            "table": "urn:table",
-            "office": "urn:office",
-            "xlink": "urn:xlink",
-            "svg": "urn:svg",
-        }
         # but override them with the real namespaces
         self.namespaces.update(root.nsmap)
 
@@ -356,6 +335,7 @@
 
         self._remove_soft_page_break(tree)
         self._invert_style(tree)
+        self._handle_meta(tree)
         self._handle_relatorio_tags(tree)
         self._handle_images(tree)
         self._handle_innerdocs(tree)
@@ -405,7 +385,8 @@
             if statement.tag == placeholder:
                 expr = statement.text[1:-1]
             elif statement.tag == text_a:
-                expr = urllib.unquote(statement.attrib[xlink_href_attrib][12:])
+                expr = urllib.parse.unquote(
+                    statement.attrib[xlink_href_attrib][12:])
 
             if not expr:
                 raise OOTemplateError("No expression in the tag",
@@ -446,6 +427,45 @@
         assert not opened_tags
         return r_statements, closing_tags
 
+    def _handle_meta(self, tree):
+        """updates meta
+        and adds py:content into meta:user-defined and dc:* nodes"""
+        root = tree.getroot()
+        if root.tag != '{%s}document-meta' % self.namespaces['office']:
+            return
+        xpath_expr = ("//meta:user-defined[starts-with(., 'relatorio://')]"
+                      "|//dc:*[starts-with(., 'relatorio://')]")
+        genshi_content = '{%s}content' % self.namespaces['py']
+        for node in tree.xpath(xpath_expr, namespaces=self.namespaces):
+            node.attrib[genshi_content] = node.text[len('relatorio://'):]
+
+        def set(name, value):
+            meta = root.find('{%s}%s' % (self.namespaces['meta'], name))
+            if meta is None:
+                meta = EtreeElement(
+                    '{%s}%s' % (self.namespaces['meta'], name),
+                    nsmap=self.namespaces)
+                root.append(meta)
+            meta.text = value
+
+        def remove(name, namespace='meta'):
+            meta = tree.find('{%s}%s' % (self.namespaces[namespace], name))
+            if meta is not None:
+                tree.remove(meta)
+
+        now = datetime.datetime.now()
+        set('creation-date', now.isoformat())
+        set('date', now.isoformat())
+        remove('document-statistic')
+        set('editing-cycles', '1')
+        remove('editing-duration')
+        set('generator', 'relatorio/%s' % relatorio.__version__)
+        remove('initial-creator')
+        remove('print-date')
+        remove('printed-by')
+        remove('creator', 'dc')
+        remove('date', 'dc')
+
     def _handle_relatorio_tags(self, tree):
         """
         Will treat all relatorio tag (py:if/for/choose/when/otherwise)
@@ -589,8 +609,8 @@
         repeat_tag = '{%s}repeat' % RELATORIO_URI
 
         # table node (it is not necessarily the direct parent of ancestor)
-        table_node = ancestor.iterancestors('{%s}table' % table_namespace) \
-                             .next()
+        table_node = next(
+            ancestor.iterancestors('{%s}table' % table_namespace))
         table_name = table_node.attrib['{%s}name' % table_namespace]
 
         # add counting instructions
@@ -729,7 +749,7 @@
         assert row_node.tag == table_row_tag
         next_rows = row_node.itersiblings(table_row_tag)
         for row_idx in range(rows_spanned - 1):
-            next_row_node = next_rows.next()
+            next_row_node = next(next_rows)
             rows_to_wrap.append(next_row_node)
             # compute the start and end nodes
             first = next_row_node[opening_pos]
@@ -793,7 +813,7 @@
     def _escape_values(self, tree):
         "escapes element values"
         for element in tree.iter():
-            for attrs in element.keys():
+            for attrs in list(element.keys()):
                 if not attrs.startswith('{%s}' % GENSHI_URI):
                     element.attrib[attrs] = element.attrib[attrs]\
                             .replace(PREFIX, PREFIX * 2)
@@ -819,9 +839,9 @@
         elif isinstance(val, datetime.date):
             type_ = 'date'
             val = val.isoformat()
-        elif isinstance(val, (int, float, long, Decimal)):
+        elif isinstance(val, (int, float, Decimal)):
             type_ = 'float'
-        elif isinstance(val, basestring):
+        elif isinstance(val, str):
             type_ = 'string'
             val = escape_xml_invalid_chars(val)
         elif isinstance(val, datetime.timedelta):
@@ -945,7 +965,7 @@
         xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"/>
         ''')
     manifest.add_file_entry('/', mimetype)
-    for fname, document in documents.iteritems():
+    for fname, document in documents.items():
         document_string = lxml.etree.tostring(document, encoding='UTF-8',
                                               xml_declaration=True)
         odt_zip.writestr('%s.xml' % fname, document_string)
@@ -1015,51 +1035,6 @@
             self.root.remove(entry)
 
 
-class Meta(object):
-
-    def __init__(self, content):
-        self.tree = lxml.etree.parse(BytesIO(content))
-        root = self.tree.getroot()
-        self.namespaces = root.nsmap
-        path = '/office:document-meta/office:meta'
-        self.office_meta, = self.tree.xpath(path, namespaces=self.namespaces)
-
-    def set(self, name, value, namespace='meta'):
-        namespace = self.namespaces[namespace]
-        meta = self.office_meta.find('{%s}%s' % (namespace, name))
-        if meta is None:
-            meta = EtreeElement('{%s}%s' % (namespace, name),
-                                nsmap={'meta': namespace})
-            self.office_meta.append(meta)
-        meta.text = value
-
-    def remove(self, name, namespace='meta'):
-        namespace = self.namespaces[namespace]
-        meta = self.office_meta.find('{%s}%s' % (namespace, name))
-        if meta is not None:
-            self.office_meta.remove(meta)
-
-    def __str__(self):
-        now = datetime.datetime.now()
-        self.set('creation-date', now.isoformat())
-        self.set('date', now.isoformat())
-        self.remove('document-statistic')
-        self.set('editing-cycles', '1')
-        self.remove('editing-duration')
-        self.set('generator', 'relatorio/%s' % relatorio.__version__)
-        self.remove('initial-creator')
-        self.remove('print-date')
-        self.remove('printed-by')
-        self.remove('creator', 'dc')
-        self.remove('date', 'dc')
-        val = lxml.etree.tostring(self.tree, encoding='UTF-8',
-                                  xml_declaration=True)
-        # In Python 3, val will be bytes
-        if not isinstance(val, str):
-            return str(val, 'utf-8')
-        return val
-
-
 class _AbstractZipWriteSplitStream(object):
     def __init__(self, zipfile, chunksize=64):
         self.zipfile = zipfile
@@ -1141,7 +1116,6 @@
     def __init__(self, source, files, chunksize=64):
         self.inzip = get_zip_file(source)
         self.manifest = Manifest(self.inzip.read(MANIFEST))
-        self.meta = Meta(self.inzip.read(META))
         self.xml_serializer = genshi.output.XMLSerializer()
         self._files = files
         self.chunksize = chunksize
@@ -1171,8 +1145,6 @@
                 files[f_info.filename] = new_info
             elif f_info.filename == MANIFEST:
                 manifest_info = f_info
-            elif f_info.filename == META:
-                self.outzip.writestr(f_info, str(self.meta))
             elif f_info.filename.startswith(THUMBNAILS + '/'):
                 self.manifest.remove_file_entry(f_info.filename)
             else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/templates/pdf.py 
new/relatorio-0.10.0/relatorio/templates/pdf.py
--- old/relatorio-0.9.3/relatorio/templates/pdf.py      2018-11-09 
22:48:09.000000000 +0100
+++ new/relatorio-0.10.0/relatorio/templates/pdf.py     2021-08-12 
23:08:56.000000000 +0200
@@ -1,24 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2014 Cedric Krier.
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import os
 import shutil
 import tempfile
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/tests/__init__.py 
new/relatorio-0.10.0/relatorio/tests/__init__.py
--- old/relatorio-0.9.3/relatorio/tests/__init__.py     2020-03-01 
00:41:43.000000000 +0100
+++ new/relatorio-0.10.0/relatorio/tests/__init__.py    2021-08-12 
23:08:56.000000000 +0200
@@ -1,23 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2015 Cedric Krier.
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import sys
 import os
 import unittest
Binary files old/relatorio-0.9.3/relatorio/tests/test.odt and 
new/relatorio-0.10.0/relatorio/tests/test.odt differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/tests/test_api.py 
new/relatorio-0.10.0/relatorio/tests/test_api.py
--- old/relatorio-0.9.3/relatorio/tests/test_api.py     2018-08-18 
13:27:26.000000000 +0200
+++ new/relatorio-0.10.0/relatorio/tests/test_api.py    2021-09-10 
11:23:00.000000000 +0200
@@ -1,25 +1,5 @@
-###############################################################################
-#
-# Copyright (c) 2014 Cedric Krier.
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import os
 import unittest
 
@@ -30,7 +10,7 @@
 class StubObject(object):
 
     def __init__(self, **kwargs):
-        for key, val in kwargs.iteritems():
+        for key, val in kwargs.items():
             setattr(self, key, val)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio/tests/test_odt.py 
new/relatorio-0.10.0/relatorio/tests/test_odt.py
--- old/relatorio-0.9.3/relatorio/tests/test_odt.py     2021-03-27 
12:57:46.000000000 +0100
+++ new/relatorio-0.10.0/relatorio/tests/test_odt.py    2021-09-10 
11:25:51.000000000 +0200
@@ -1,26 +1,6 @@
 # -*- encoding: utf-8 -*-
-###############################################################################
-#
-# Copyright (c) 2014-2017 Cedric Krier.
-# Copyright (c) 2007, 2008 OpenHex SPRL. (http://openhex.com) All Rights
-# Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-###############################################################################
-
-
+# This file is part of relatorio.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
 import os
 import unittest
 from io import StringIO, BytesIO
@@ -34,11 +14,6 @@
     GENSHI_URI, RELATORIO_URI, fod2od, remove_node_keeping_tail, \
     escape_xml_invalid_chars
 
-try:
-    unicode
-except NameError:
-    unicode = str
-
 OO_TABLE_NS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0"
 
 
@@ -47,16 +22,16 @@
                'Bonjour,': 'Hello,',
                'Je suis un test de templating en odt.':
                'I am an odt templating test',
-               'Felix da housecat': u'F??lix le chat de la maison',
-               'We sell stuff': u'On vend des choses',
+               'Felix da housecat': 'F??lix le chat de la maison',
+               'We sell stuff': 'On vend des choses',
               }
     return catalog.get(string, string)
 
 
 def stream_to_string(stream):
     # In Python 3, stream will be bytes
-    if not isinstance(stream, unicode):
-        return unicode(stream, 'utf-8')
+    if not isinstance(stream, str):
+        return str(stream, 'utf-8')
     return stream
 
 
@@ -67,22 +42,25 @@
         filepath = os.path.join(thisdir, 'test.odt')
         self._source = open(filepath, mode='rb')
         self.oot = Template(self._source)
-        self.data = {'first_name': u'Trente',
-                     'last_name': u'M??ller',
-                     'ville': u'Li??ge',
-                     'friends': [{'first_name': u'Camille',
-                                  'last_name': u'Salauhpe'},
-                                 {'first_name': u'Mathias',
-                                  'last_name': u'Lechat'}],
-                     'hobbies': [u'Music', u'Dancing', u'DJing'],
-                     'animals': [u'Felix da housecat', u'Dog eat Dog'],
+        self.data = {'first_name': 'Trente',
+                     'last_name': 'M??ller',
+                     'ville': 'Li??ge',
+                     'friends': [{'first_name': 'Camille',
+                                  'last_name': 'Salauhpe'},
+                                 {'first_name': 'Mathias',
+                                  'last_name': 'Lechat'}],
+                     'hobbies': ['Music', 'Dancing', 'DJing'],
+                     'animals': ['Felix da housecat', 'Dog eat Dog'],
                      'images': [(open(os.path.join(thisdir, 'one.jpg'), 'rb'),
                                  'image/jpeg', None, None, 'One'),
                                 (open(os.path.join(thisdir, 'two.png'), 'rb'),
                                  'image/png', '2cm', '2.2cm', 'Two'),
                                 (None, None)],
                      'oeuf': open(os.path.join(thisdir, 'egg.jpg'), 'rb'),
-                     'footer': u'We sell stuff'}
+                     'footer': 'We sell stuff',
+                     'salutation': 'Greating',
+                     'title': 'Testing Letter',
+                     }
 
     def tearDown(self):
         self._source.close()
@@ -396,13 +374,20 @@
         self.assertRaises(UndefinedError,
             lambda: stream.events.render(encoding='utf-8'))
 
+    def test_meta(self):
+        "Testing that meta get rendered"
+        stream = self.oot.generate(**self.data)
+        rendered = stream_to_string(stream.events.render(encoding='utf-8'))
+        self.assertTrue("Greating" in rendered)
+        self.assertTrue("Testing Letter" in rendered)
+
     def test_generate(self):
         "Testing that content get rendered"
         stream = self.oot.generate(**self.data)
         rendered = stream_to_string(stream.events.render(encoding='utf-8'))
         self.assertTrue('Bonjour,' in rendered)
         self.assertTrue('Trente' in rendered)
-        self.assertTrue(u'M??ller' in rendered)
+        self.assertTrue('M??ller' in rendered)
         self.assertTrue('Dog eat Dog' in rendered)
         self.assertTrue('Felix da housecat' in rendered)
 
@@ -415,7 +400,7 @@
         self.assertTrue("Hello," in translated_xml)
         self.assertTrue("I am an odt templating test" in translated_xml)
         self.assertTrue('Felix da housecat' not in translated_xml)
-        self.assertTrue(u'F??lix le chat de la maison' in translated_xml)
+        self.assertTrue('F??lix le chat de la maison' in translated_xml)
         self.assertTrue('We sell stuff' not in translated_xml)
         self.assertTrue('On vend des choses' in translated_xml)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio.egg-info/PKG-INFO 
new/relatorio-0.10.0/relatorio.egg-info/PKG-INFO
--- old/relatorio-0.9.3/relatorio.egg-info/PKG-INFO     2021-05-07 
13:52:49.000000000 +0200
+++ new/relatorio-0.10.0/relatorio.egg-info/PKG-INFO    2021-09-11 
23:25:21.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: relatorio
-Version: 0.9.3
+Version: 0.10.0
 Summary: A templating library able to output odt and pdf files
 Home-page: https://pypi.python.org/pypi/relatorio
 Author: Tryton
@@ -32,9 +32,14 @@
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: GNU General Public License (GPL)
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Topic :: Text Processing
+Requires-Python: >=3.5
 Provides-Extra: chart
 Provides-Extra: fodt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/relatorio.egg-info/SOURCES.txt 
new/relatorio-0.10.0/relatorio.egg-info/SOURCES.txt
--- old/relatorio-0.9.3/relatorio.egg-info/SOURCES.txt  2021-05-07 
13:52:49.000000000 +0200
+++ new/relatorio-0.10.0/relatorio.egg-info/SOURCES.txt 2021-09-11 
23:25:22.000000000 +0200
@@ -68,4 +68,5 @@
 relatorio/tests/templates/include.tmpl
 relatorio/tests/templates/other.tmpl
 relatorio/tests/templates/test.tmpl
-relatorio/tests/templates/time.tmpl
\ No newline at end of file
+relatorio/tests/templates/time.tmpl
+scripts/relatorio-render
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/scripts/relatorio-render 
new/relatorio-0.10.0/scripts/relatorio-render
--- old/relatorio-0.9.3/scripts/relatorio-render        1970-01-01 
01:00:00.000000000 +0100
+++ new/relatorio-0.10.0/scripts/relatorio-render       2021-08-20 
12:55:01.000000000 +0200
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+import json
+import mimetypes
+import os
+from argparse import ArgumentParser, FileType
+
+from relatorio import Report
+
+
+def main(input_, data, output=None):
+    input_ = os.path.abspath(input_)
+    mimetype, _ = mimetypes.guess_type(input_)
+    report = Report(input_, mimetype)
+    content = report(**data).render().getvalue()
+    if output:
+        with open(output, 'wb') as fp:
+            fp.write(content)
+
+
+def run():
+    parser = ArgumentParser()
+    parser.add_argument('-i', '--input', dest='input', required=True)
+    parser.add_argument('-o', '--output', dest='output')
+    parser.add_argument('-d', '--data', dest='data', type=FileType('r'),
+        help="JSON file with data to render")
+
+    args = parser.parse_args()
+    if args.data:
+        data = json.load(args.data)
+    else:
+        data = {}
+    main(args.input, data, args.output)
+
+
+if __name__ == '__main__':
+    run()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/setup.py 
new/relatorio-0.10.0/setup.py
--- old/relatorio-0.9.3/setup.py        2020-02-23 17:20:17.000000000 +0100
+++ new/relatorio-0.10.0/setup.py       2021-09-10 13:44:20.000000000 +0200
@@ -37,6 +37,8 @@
         'relatorio.tests': [
             '*.jpg', '*.odt', '*.fodt', '*.png', 'templates/*.tmpl'],
         },
+    scripts=['scripts/relatorio-render'],
+    python_requires='>=3.5',
     install_requires=[
         "Genshi >= 0.5",
         "lxml >= 2.0"
@@ -50,11 +52,15 @@
         "Intended Audience :: Developers",
         "License :: OSI Approved :: GNU General Public License (GPL)",
         "Operating System :: OS Independent",
-        "Programming Language :: Python :: 2",
         "Programming Language :: Python :: 3",
+        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
         "Topic :: Software Development :: Libraries :: Python Modules",
         "Topic :: Text Processing",
     ],
     test_suite="relatorio.tests",
     tests_require=['python-magic'],
-    use_2to3=True)
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/relatorio-0.9.3/tox.ini new/relatorio-0.10.0/tox.ini
--- old/relatorio-0.9.3/tox.ini 2020-12-19 13:41:50.000000000 +0100
+++ new/relatorio-0.10.0/tox.ini        2021-09-10 11:27:11.000000000 +0200
@@ -4,7 +4,7 @@
 # and then run "tox" from this directory.
 
 [tox]
-envlist = py26, py27, py32, py33, py34, py35, py36, py37, py38, py39, pypy
+envlist = py35, py36, py37, py38, py39, pypy3
 
 [testenv]
 commands = {envpython} setup.py test

Reply via email to