#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright (C) 2013 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero 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 Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # See the file COPYING for details. from zipfile import ZipFile, ZIP_DEFLATED from cStringIO import StringIO from xml.etree.cElementTree import ElementTree, fromstring OOO_NS = "{urn:oasis:names:tc:opendocument:xmlns:text:1.0}" def _set_value_from_formula(value, context): value = value.strip() if value.startswith("ooow:") and len(value) >= 5: value = value[5:] if value.startswith('"') and value.endswith('"') and len(value) > 1: value = value[1:-1] elif value in context: value = unicode(context[value]) else: value = None return value def _parse_condition(condition, context): # parse only == and != operator operator = "" if "!=" in condition: operator = "!=" elif "==" in condition: operator = "==" else: return var1, var2 = condition.split(operator) var1 = _set_value_from_formula(var1, context) var2 = _set_value_from_formula(var2, context) res = var1 == var2 if operator == '!=': res = not res return res def _format_value(value, default_value): value = unicode(value) if value else default_value #if hasattr(value, 'strftime'): # value = value.strftime() return value def ooo_replace(infile, outfile, context, default_value=''): inzip = ZipFile(infile, 'r', ZIP_DEFLATED) outzip = ZipFile(outfile, 'w', ZIP_DEFLATED) content = ElementTree(fromstring(inzip.read('content.xml'))) missing_keys = set() for xp in ('variable-set', 'variable-get'): for p in content.findall(".//"+OOO_NS+xp): name = p.get(OOO_NS+"name") if name in context: value = context[name] p.text = _format_value(value, default_value) else: if default_value != None: p.text = default_value missing_keys.add(name) for p in content.findall(".//"+OOO_NS+"conditional-text"): condition = p.get(OOO_NS+"condition") res = 'true' if _parse_condition(condition, context) else 'false' value = p.get(OOO_NS+'string-value-if-' + res) value = _format_value(value, default_value) if value.strip() in context: value = context[value.strip()] p.text = value for f in inzip.infolist(): if f.filename == 'content.xml': s = StringIO() content.write(s) outzip.writestr('content.xml', s.getvalue()) else: outzip.writestr(f, inzip.read(f.filename)) inzip.close() outzip.close() return missing_keys if __name__ == '__main__': infile = "../archaeological_files/tests/AR_dossier_DRAC_modele_ishtar_1-MOD.odt" outfile = "../archaeological_files/tests/AR_dossier_DRAC_modele_ishtar-test.odt" rep = {"file_incharge_surname":u"Yann", "file_incharge_name":u"Le Jeune", "fileact_ref":u"ref"} ooo_replace(infile, outfile, rep, default_value="")