From e94c2df7ec6b331ddb4833146c389e6445b22183 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Apr 19 2014 10:29:35 +0000 Subject: simplify python3 patch --- diff --git a/0001-Resolves-fdo-70309-can-t-write-bytes-direct-to-stdou.patch b/0001-Resolves-fdo-70309-can-t-write-bytes-direct-to-stdou.patch index 24dca0d..e96aa8c 100644 --- a/0001-Resolves-fdo-70309-can-t-write-bytes-direct-to-stdou.patch +++ b/0001-Resolves-fdo-70309-can-t-write-bytes-direct-to-stdou.patch @@ -8,23 +8,10 @@ Subject: [PATCH] Resolves: fdo#70309 can't write bytes direct to stdout in unoconv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/unoconv2.py b/unoconv2.py +diff --git a/unoconv b/unoconv index a4f9490..2b0b0eb 100755 ---- a/unoconv2.py -+++ b/unoconv2.py -@@ -1146,7 +1146,7 @@ if __name__ == '__main__': - self.closed = 1 - - def writeBytes( self, seq ): -- sys.stdout.write( seq.value ) -+ sys.stdout.buffer.write( seq.value ) - - def flush( self ): - pass -diff --git a/unoconv3.py b/unoconv3.py -index a4f9490..2b0b0eb 100755 ---- a/unoconv3.py -+++ b/unoconv3.py +--- a/unoconv ++++ b/unoconv @@ -1146,7 +1146,7 @@ if __name__ == '__main__': self.closed = 1 diff --git a/0001-python3-added-compatibility.2.patch b/0001-python3-added-compatibility.2.patch new file mode 100644 index 0000000..d5416c7 --- /dev/null +++ b/0001-python3-added-compatibility.2.patch @@ -0,0 +1,384 @@ +From 34bbe9fa679d39921fd67002e01e7a9bf93b009a Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Sat, 19 Apr 2014 12:05:04 +0200 +Subject: [PATCH] 0001-python3-added-compatibility.2.patch + +--- + unoconv | 142 +++++++++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 86 insertions(+), 56 deletions(-) + +diff --git a/unoconv b/unoconv +index 30e6706..8c45ad9 100755 +--- a/unoconv ++++ b/unoconv +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/python + + ### 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 +@@ -203,7 +203,7 @@ def office_environ(office): + ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: + os.environ['UNO_PATH'] = office.unopath + +- ### Set URE_BOOTSTRAP so that "uno.getComponentContext()" bootstraps a complete ++ ### Set URE_BOOTSTRAP so that "global_uno.getComponentContext()" bootstraps a complete + ### UNO environment + if os.name in ( 'nt', 'os2' ): + os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') +@@ -277,6 +277,7 @@ def python_switch(office): + + try: + os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) ++ print(office.python, [office.python, ] + sys.argv[0:], osenviron) + except OSError: + ### Mac OS X versions prior to 10.6 do not support execv in + ### a process that contains multiple threads. Instead of +@@ -553,14 +554,14 @@ class Options: + if name in ('FilterOptions'): + self.exportfilteroptions = value + elif value in ('True', 'true'): +- self.exportfilter.append( PropertyValue( name, 0, True, 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) + elif value in ('False', 'false'): +- self.exportfilter.append( PropertyValue( name, 0, False, 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) + else: + try: +- self.exportfilter.append( PropertyValue( name, 0, int(value), 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) + except ValueError: +- self.exportfilter.append( PropertyValue( name, 0, value, 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) + else: + print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg + elif opt in ['-f', '--format']: +@@ -572,14 +573,14 @@ class Options: + if name in ('FilterOptions'): + self.importfilteroptions = value + elif value in ('True', 'true'): +- self.importfilter.append( PropertyValue( name, 0, True, 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) + elif value in ('False', 'false'): +- self.importfilter.append( PropertyValue( name, 0, False, 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) + else: + try: +- self.importfilter.append( PropertyValue( name, 0, int(value), 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) + except ValueError: +- self.importfilter.append( PropertyValue( name, 0, value, 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) + else: + print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg + elif opt in ['-l', '--listener']: +@@ -657,7 +658,7 @@ class Options: + + def version(self): + ### Get office product information +- product = uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) ++ product = global_uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) + + print 'unoconv %s' % VERSION + print 'Written by Dag Wieers ' +@@ -706,7 +707,7 @@ class Convertor: + unocontext = None + + ### Do the LibreOffice component dance +- self.context = uno.getComponentContext() ++ self.context = global_uno.getComponentContext() + self.svcmgr = self.context.ServiceManager + resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) + +@@ -714,7 +715,7 @@ class Convertor: + info(3, 'Connection type: %s' % op.connection) + try: + unocontext = resolver.resolve("uno:%s" % op.connection) +- except NoConnectException, e: ++ except UnoNoConnectException, e: + # info(3, "Existing listener not found.\n%s" % e) + info(3, "Existing listener not found.") + +@@ -724,7 +725,7 @@ class Convertor: + ### Start our own OpenOffice instance + info(3, "Launching our own listener using %s." % office.binary) + try: +- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) + if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): + ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) + else: +@@ -742,7 +743,7 @@ class Convertor: + try: + unocontext = resolver.resolve("uno:%s" % op.connection) + break +- except NoConnectException: ++ except UnoNoConnectException: + time.sleep(0.5) + timeout += 0.5 + except: +@@ -759,7 +760,7 @@ class Convertor: + ### And some more LibreOffice magic + unosvcmgr = unocontext.ServiceManager + self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) +- self.cwd = unohelper.systemPathToFileUrl( os.getcwd() ) ++ self.cwd = global_unohelper.systemPathToFileUrl( os.getcwd() ) + + ### List all filters + # self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) +@@ -824,22 +825,22 @@ class Convertor: + phase = "import" + + ### Load inputfile +- inputprops = UnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=QUIET_UPDATE) ++ inputprops = GlobalUnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=UNO_QUIET_UPDATE) + + # if op.password: +-# info = UnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") +-# inputprops += UnoProps(ModifyPasswordInfo=info) ++# info = GlobalUnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") ++# inputprops += GlobalUnoProps(ModifyPasswordInfo=info) + +- ### Cannot use UnoProps for FilterData property ++ ### Cannot use GlobalUnoProps for FilterData property + if op.importfilteroptions: + # print "Import filter options: %s" % op.importfilteroptions +- inputprops += UnoProps(FilterOptions=op.importfilteroptions) ++ inputprops += GlobalUnoProps(FilterOptions=op.importfilteroptions) + +- ### Cannot use UnoProps for FilterData property ++ ### Cannot use GlobalUnoProps for FilterData property + if op.importfilter: +- inputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) ++ inputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) + +- inputurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(inputfn)) ++ inputurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(inputfn)) + document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) + + if not document: +@@ -850,8 +851,8 @@ class Convertor: + if op.template: + if os.path.exists(op.template): + info(1, "Template file: %s" % op.template) +- templateprops = UnoProps(OverwriteStyles=True) +- templateurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(op.template)) ++ templateprops = GlobalUnoProps(OverwriteStyles=True) ++ templateurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(op.template)) + document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) + else: + print >>sys.stderr, 'unoconv: template file `%s\' does not exist.' % op.template +@@ -885,26 +886,26 @@ class Convertor: + ### Export phase + phase = "export" + +- outputprops = UnoProps(FilterName=outputfmt.filter, OutputStream=OutputStream(), Overwrite=True) ++ outputprops = GlobalUnoProps(FilterName=outputfmt.filter, OutputStream=GlobalOutputStream(), Overwrite=True) + + ### Set default filter options + if op.exportfilteroptions: + # print "Export filter options: %s" % op.exportfilteroptions +- outputprops += UnoProps(FilterOptions=op.exportfilteroptions) ++ outputprops += GlobalUnoProps(FilterOptions=op.exportfilteroptions) + else: + if outputfmt.filter == 'Text (encoded)': +- outputprops += UnoProps(FilterOptions="76,LF") ++ outputprops += GlobalUnoProps(FilterOptions="76,LF") + + elif outputfmt.filter == 'Text': +- outputprops += UnoProps(FilterOptions="76") ++ outputprops += GlobalUnoProps(FilterOptions="76") + + elif outputfmt.filter == 'Text - txt - csv (StarCalc)': +- outputprops += UnoProps(FilterOptions="44,34,76") ++ outputprops += GlobalUnoProps(FilterOptions="44,34,76") + + +- ### Cannot use UnoProps for FilterData property ++ ### Cannot use GlobalUnoProps for FilterData property + if op.exportfilter: +- outputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) ++ outputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) + + if not op.stdout: + (outputfn, ext) = os.path.splitext(inputfn) +@@ -917,14 +918,14 @@ class Convertor: + else: + outputfn = op.output + +- outputurl = unohelper.absolutize( self.cwd, unohelper.systemPathToFileUrl(outputfn) ) ++ outputurl = global_unohelper.absolutize( self.cwd, global_unohelper.systemPathToFileUrl(outputfn) ) + info(1, "Output file: %s" % outputfn) + else: + outputurl = "private:stream" + + try: + document.storeToURL(outputurl, tuple(outputprops) ) +- except IOException, e: ++ except UnoIOException, e: + raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) + + phase = "dispose" +@@ -935,24 +936,24 @@ class Convertor: + error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) + exitcode = 1 + +- except RuntimeException, e: ++ except UnoRuntimeException, e: + error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) + exitcode = 6 + +- except DisposedException, e: ++ except UnoDisposedException, e: + error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) + exitcode = 7 + +- except IllegalArgumentException, e: ++ except UnoIllegalArgumentException, e: + error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) + exitcode = 8 + +- except IOException, e: ++ except UnoIOException, e: + # for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) + error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) + exitcode = 3 + +- except CannotConvertException, e: ++ except UnoCannotConvertException, e: + # for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) + error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) + exitcode = 4 +@@ -975,14 +976,14 @@ class Listener: + global product + + info(1, "Start listener on %s:%s" % (op.server, op.port)) +- self.context = uno.getComponentContext() ++ self.context = global_uno.getComponentContext() + self.svcmgr = self.context.ServiceManager + try: + resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) +- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) + try: + unocontext = resolver.resolve("uno:%s" % op.connection) +- except NoConnectException, e: ++ except UnoNoConnectException, e: + pass + else: + info(1, "Existing %s listener found, nothing to do." % product.ooName) +@@ -1039,7 +1040,7 @@ def die(ret, msg=None): + info(3, 'Terminating %s instance.' % product.ooName) + try: + convertor.desktop.terminate() +- except DisposedException: ++ except UnoDisposedException: + info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) + try: + ooproc.terminate() +@@ -1080,7 +1081,7 @@ def main(): + for inputfn in op.filenames: + convertor.convert(inputfn) + +- except NoConnectException, e: ++ except UnoNoConnectException, e: + error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) + if op.connection: + info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) +@@ -1094,7 +1095,8 @@ def main(): + error("Warning: failed to launch Office suite. Aborting.") + + ### Main entrance +-if __name__ == '__main__': ++def run(): ++ global exitcode + exitcode = 0 + + info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) +@@ -1105,7 +1107,12 @@ if __name__ == '__main__': + office_environ(of) + # debug_office() + try: +- import uno, unohelper ++ global global_uno ++ global global_unohelper ++ ++ import uno as global_uno ++ import unohelper as global_unohelper ++ global office + office = of + break + except: +@@ -1121,17 +1128,30 @@ if __name__ == '__main__': + sys.exit(1) + + ### Now that we have found a working pyuno library, let's import some classes +- from com.sun.star.beans import PropertyValue +- from com.sun.star.connection import NoConnectException +- from com.sun.star.document.UpdateDocMode import QUIET_UPDATE +- from com.sun.star.lang import DisposedException, IllegalArgumentException +- from com.sun.star.io import IOException, XOutputStream +- from com.sun.star.script import CannotConvertException ++ global UnoPropertyValue ++ global UnoNoConnectException ++ global UNO_QUIET_UPDATE ++ global UnoDisposedException ++ global UnoIllegalArgumentException ++ global UnoIOException ++ global UnoXOutputStream ++ global UnoCannotConvertException ++ global UnoException ++ global UnoRuntimeException ++ ++ from com.sun.star.beans import PropertyValue as UnoPropertyValue ++ from com.sun.star.connection import NoConnectException as UnoNoConnectException ++ from com.sun.star.document.UpdateDocMode import QUIET_UPDATE as UNO_QUIET_UPDATE ++ from com.sun.star.lang import DisposedException as UnoDisposedException ++ from com.sun.star.lang import IllegalArgumentException as UnoIllegalArgumentException ++ from com.sun.star.io import IOException as UnoIOException ++ from com.sun.star.io import XOutputStream as UnoXOutputStream ++ from com.sun.star.script import CannotConvertException as UnoCannotConvertException + from com.sun.star.uno import Exception as UnoException +- from com.sun.star.uno import RuntimeException ++ from com.sun.star.uno import RuntimeException as UnoRuntimeException + + ### And now that we have those classes, build on them +- class OutputStream( unohelper.Base, XOutputStream ): ++ class OutputStream( global_unohelper.Base, UnoXOutputStream ): + def __init__( self ): + self.closed = 0 + +@@ -1144,15 +1164,22 @@ if __name__ == '__main__': + def flush( self ): + pass + ++ global GlobalOutputStream ++ GlobalOutputStream = OutputStream ++ + def UnoProps(**args): + props = [] + for key in args: +- prop = PropertyValue() ++ prop = UnoPropertyValue() + prop.Name = key + prop.Value = args[key] + props.append(prop) + return tuple(props) + ++ global GlobalUnoProps ++ GlobalUnoProps = UnoProps ++ ++ global op + op = Options(sys.argv[1:]) + + info(2, "Using office base path: %s" % office.basepath) +@@ -1163,3 +1190,6 @@ if __name__ == '__main__': + except KeyboardInterrupt, e: + die(6, 'Exiting on user request') + die(exitcode) ++ ++if __name__ == '__main__': ++ run() +-- +1.9.0 + diff --git a/0001-python3-added-compatibility.3.patch b/0001-python3-added-compatibility.3.patch new file mode 100644 index 0000000..18216c9 --- /dev/null +++ b/0001-python3-added-compatibility.3.patch @@ -0,0 +1,629 @@ +From 21b9a845ac7e8805b41d7dab1a6fbf8076689ae8 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Sat, 19 Apr 2014 12:06:27 +0200 +Subject: [PATCH] 0001-python3-added-compatibility.3.patch + +--- + unoconv | 248 ++++++++++++++++++++++++++++++++++++---------------------------- + 1 file changed, 139 insertions(+), 109 deletions(-) + +diff --git a/unoconv b/unoconv +index 30e6706..a13db44 100755 +--- a/unoconv ++++ b/unoconv +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/python3 + + ### 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 +@@ -77,11 +77,11 @@ def find_offices(): + else: + + if os.name in ( 'nt', 'os2' ): +- if 'PROGRAMFILES' in os.environ.keys(): ++ if 'PROGRAMFILES' in list(os.environ.keys()): + extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ + glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') + +- if 'PROGRAMFILES(X86)' in os.environ.keys(): ++ if 'PROGRAMFILES(X86)' in list(os.environ.keys()): + extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ + glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') + +@@ -203,7 +203,7 @@ def office_environ(office): + ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: + os.environ['UNO_PATH'] = office.unopath + +- ### Set URE_BOOTSTRAP so that "uno.getComponentContext()" bootstraps a complete ++ ### Set URE_BOOTSTRAP so that "global_uno.getComponentContext()" bootstraps a complete + ### UNO environment + if os.name in ( 'nt', 'os2' ): + os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') +@@ -233,18 +233,18 @@ def office_environ(office): + + def debug_office(): + if 'URE_BOOTSTRAP' in os.environ: +- print >>sys.stderr, 'URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'] ++ print('URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'], file=sys.stderr) + if 'UNO_PATH' in os.environ: +- print >>sys.stderr, 'UNO_PATH=%s' % os.environ['UNO_PATH'] ++ print('UNO_PATH=%s' % os.environ['UNO_PATH'], file=sys.stderr) + if 'UNO_TYPES' in os.environ: +- print >>sys.stderr, 'UNO_TYPES=%s' % os.environ['UNO_TYPES'] +- print 'PATH=%s' % os.environ['PATH'] ++ print('UNO_TYPES=%s' % os.environ['UNO_TYPES'], file=sys.stderr) ++ print('PATH=%s' % os.environ['PATH']) + if 'PYTHONHOME' in os.environ: +- print >>sys.stderr, 'PYTHONHOME=%s' % os.environ['PYTHONHOME'] ++ print('PYTHONHOME=%s' % os.environ['PYTHONHOME'], file=sys.stderr) + if 'PYTHONPATH' in os.environ: +- print >>sys.stderr, 'PYTHONPATH=%s' % os.environ['PYTHONPATH'] ++ print('PYTHONPATH=%s' % os.environ['PYTHONPATH'], file=sys.stderr) + if 'LD_LIBRARY_PATH' in os.environ: +- print >>sys.stderr, 'LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'] ++ print('LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'], file=sys.stderr) + + def python_switch(office): + if office.pythonhome: +@@ -277,6 +277,7 @@ def python_switch(office): + + try: + os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) ++ print((office.python, [office.python, ] + sys.argv[0:], osenviron)) + except OSError: + ### Mac OS X versions prior to 10.6 do not support execv in + ### a process that contains multiple threads. Instead of +@@ -335,11 +336,11 @@ class FmtList: + return ret + + def display(self, doctype): +- print >>sys.stderr, "The following list of %s formats are currently available:\n" % doctype ++ print("The following list of %s formats are currently available:\n" % doctype, file=sys.stderr) + for fmt in self.list: + if fmt.doctype == doctype: +- print >>sys.stderr, " %-8s - %s" % (fmt.name, fmt) +- print >>sys.stderr ++ print(" %-8s - %s" % (fmt.name, fmt), file=sys.stderr) ++ print(file=sys.stderr) + + fmts = FmtList() + +@@ -530,14 +531,14 @@ class Options: + 'outputpath', 'password=', 'pipe=', 'port=', 'server=', + 'timeout=', 'show', 'stdout', 'template', 'verbose', + 'version'] ) +- except getopt.error, exc: +- print 'unoconv: %s, try unoconv -h for a list of all the options' % str(exc) ++ except getopt.error as exc: ++ print('unoconv: %s, try unoconv -h for a list of all the options' % str(exc)) + sys.exit(255) + + for opt, arg in opts: + if opt in ['-h', '--help']: + self.usage() +- print ++ print() + self.help() + sys.exit(1) + elif opt in ['-c', '--connection']: +@@ -553,16 +554,16 @@ class Options: + if name in ('FilterOptions'): + self.exportfilteroptions = value + elif value in ('True', 'true'): +- self.exportfilter.append( PropertyValue( name, 0, True, 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) + elif value in ('False', 'false'): +- self.exportfilter.append( PropertyValue( name, 0, False, 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) + else: + try: +- self.exportfilter.append( PropertyValue( name, 0, int(value), 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) + except ValueError: +- self.exportfilter.append( PropertyValue( name, 0, value, 0 ) ) ++ self.exportfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) + else: +- print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg ++ print('Warning: Option %s cannot be parsed, ignoring.' % arg, file=sys.stderr) + elif opt in ['-f', '--format']: + self.format = arg + elif opt in ['-i', '--import']: +@@ -572,16 +573,16 @@ class Options: + if name in ('FilterOptions'): + self.importfilteroptions = value + elif value in ('True', 'true'): +- self.importfilter.append( PropertyValue( name, 0, True, 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) + elif value in ('False', 'false'): +- self.importfilter.append( PropertyValue( name, 0, False, 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) + else: + try: +- self.importfilter.append( PropertyValue( name, 0, int(value), 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) + except ValueError: +- self.importfilter.append( PropertyValue( name, 0, value, 0 ) ) ++ self.importfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) + else: +- print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg ++ print('Warning: Option %s cannot be parsed, ignoring.' % arg, file=sys.stderr) + elif opt in ['-l', '--listener']: + self.listener = True + elif opt in ['-n', '--no-launch']: +@@ -589,7 +590,7 @@ class Options: + elif opt in ['-o', '--output']: + self.output = arg + elif opt in ['--outputpath']: +- print >>sys.stderr, 'Warning: This option is deprecated by --output.' ++ print('Warning: This option is deprecated by --output.', file=sys.stderr) + self.output = arg + elif opt in ['--password']: + self.password = arg +@@ -615,13 +616,13 @@ class Options: + + ### Enable verbosity + if self.verbose >= 2: +- print >>sys.stderr, 'Verbosity set to level %d' % self.verbose ++ print('Verbosity set to level %d' % self.verbose, file=sys.stderr) + + self.filenames = args + + if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: +- print >>sys.stderr, 'unoconv: you have to provide a filename as argument' +- print >>sys.stderr, 'Try `unoconv -h\' for more information.' ++ print('unoconv: you have to provide a filename as argument', file=sys.stderr) ++ print('Try `unoconv -h\' for more information.', file=sys.stderr) + sys.exit(255) + + ### Set connection string +@@ -657,23 +658,23 @@ class Options: + + def version(self): + ### Get office product information +- product = uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) +- +- print 'unoconv %s' % VERSION +- print 'Written by Dag Wieers ' +- print 'Homepage at http://dag.wieers.com/home-made/unoconv/' +- print +- print 'platform %s/%s' % (os.name, sys.platform) +- print 'python %s' % sys.version +- print product.ooName, product.ooSetupVersion ++ product = global_uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ ++ print('unoconv %s' % VERSION) ++ print('Written by Dag Wieers ') ++ print('Homepage at http://dag.wieers.com/home-made/unoconv/') ++ print() ++ print('platform %s/%s' % (os.name, sys.platform)) ++ print('python %s' % sys.version) ++ print(product.ooName, product.ooSetupVersion) + # print + # print 'build revision $Rev$' + + def usage(self): +- print >>sys.stderr, 'usage: unoconv [options] file [file2 ..]' ++ print('usage: unoconv [options] file [file2 ..]', file=sys.stderr) + + def help(self): +- print >>sys.stderr, '''Convert from and to any format supported by LibreOffice ++ print('''Convert from and to any format supported by LibreOffice + + unoconv options: + -c, --connection=string use a custom connection string +@@ -698,7 +699,7 @@ unoconv options: + -t, --template=file import the styles from template (.ott) + -T, --timeout=secs timeout after secs if connection to listener fails + -v, --verbose be more and more verbose (-vvv for debugging) +-''' ++''', file=sys.stderr) + + class Convertor: + def __init__(self): +@@ -706,7 +707,7 @@ class Convertor: + unocontext = None + + ### Do the LibreOffice component dance +- self.context = uno.getComponentContext() ++ self.context = global_uno.getComponentContext() + self.svcmgr = self.context.ServiceManager + resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) + +@@ -714,7 +715,7 @@ class Convertor: + info(3, 'Connection type: %s' % op.connection) + try: + unocontext = resolver.resolve("uno:%s" % op.connection) +- except NoConnectException, e: ++ except UnoNoConnectException as e: + # info(3, "Existing listener not found.\n%s" % e) + info(3, "Existing listener not found.") + +@@ -724,7 +725,7 @@ class Convertor: + ### Start our own OpenOffice instance + info(3, "Launching our own listener using %s." % office.binary) + try: +- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) + if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): + ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) + else: +@@ -742,14 +743,14 @@ class Convertor: + try: + unocontext = resolver.resolve("uno:%s" % op.connection) + break +- except NoConnectException: ++ except UnoNoConnectException: + time.sleep(0.5) + timeout += 0.5 + except: + raise + else: + error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) +- except Exception, e: ++ except Exception as e: + raise + error("Launch of %s failed.\n%s" % (office.binary, e)) + +@@ -759,7 +760,7 @@ class Convertor: + ### And some more LibreOffice magic + unosvcmgr = unocontext.ServiceManager + self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) +- self.cwd = unohelper.systemPathToFileUrl( os.getcwd() ) ++ self.cwd = global_unohelper.systemPathToFileUrl( os.getcwd() ) + + ### List all filters + # self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) +@@ -799,9 +800,9 @@ class Convertor: + ### No format found, throw error + if not outputfmt: + if doctype: +- print >>sys.stderr, 'unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format) ++ print('unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format), file=sys.stderr) + else: +- print >>sys.stderr, 'unoconv: format [%s] is not known to unoconv.' % op.format ++ print('unoconv: format [%s] is not known to unoconv.' % op.format, file=sys.stderr) + die(1) + + return outputfmt +@@ -813,10 +814,10 @@ class Convertor: + outputfmt = self.getformat(inputfn) + + if op.verbose > 0: +- print >>sys.stderr, 'Input file:', inputfn ++ print('Input file:', inputfn, file=sys.stderr) + + if not os.path.exists(inputfn): +- print >>sys.stderr, 'unoconv: file `%s\' does not exist.' % inputfn ++ print('unoconv: file `%s\' does not exist.' % inputfn, file=sys.stderr) + exitcode = 1 + + try: +@@ -824,22 +825,22 @@ class Convertor: + phase = "import" + + ### Load inputfile +- inputprops = UnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=QUIET_UPDATE) ++ inputprops = GlobalUnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=UNO_QUIET_UPDATE) + + # if op.password: +-# info = UnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") +-# inputprops += UnoProps(ModifyPasswordInfo=info) ++# info = GlobalUnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") ++# inputprops += GlobalUnoProps(ModifyPasswordInfo=info) + +- ### Cannot use UnoProps for FilterData property ++ ### Cannot use GlobalUnoProps for FilterData property + if op.importfilteroptions: + # print "Import filter options: %s" % op.importfilteroptions +- inputprops += UnoProps(FilterOptions=op.importfilteroptions) ++ inputprops += GlobalUnoProps(FilterOptions=op.importfilteroptions) + +- ### Cannot use UnoProps for FilterData property ++ ### Cannot use GlobalUnoProps for FilterData property + if op.importfilter: +- inputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) ++ inputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) + +- inputurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(inputfn)) ++ inputurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(inputfn)) + document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) + + if not document: +@@ -850,11 +851,11 @@ class Convertor: + if op.template: + if os.path.exists(op.template): + info(1, "Template file: %s" % op.template) +- templateprops = UnoProps(OverwriteStyles=True) +- templateurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(op.template)) ++ templateprops = GlobalUnoProps(OverwriteStyles=True) ++ templateurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(op.template)) + document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) + else: +- print >>sys.stderr, 'unoconv: template file `%s\' does not exist.' % op.template ++ print('unoconv: template file `%s\' does not exist.' % op.template, file=sys.stderr) + exitcode = 1 + + ### Update document links +@@ -885,26 +886,26 @@ class Convertor: + ### Export phase + phase = "export" + +- outputprops = UnoProps(FilterName=outputfmt.filter, OutputStream=OutputStream(), Overwrite=True) ++ outputprops = GlobalUnoProps(FilterName=outputfmt.filter, OutputStream=GlobalOutputStream(), Overwrite=True) + + ### Set default filter options + if op.exportfilteroptions: + # print "Export filter options: %s" % op.exportfilteroptions +- outputprops += UnoProps(FilterOptions=op.exportfilteroptions) ++ outputprops += GlobalUnoProps(FilterOptions=op.exportfilteroptions) + else: + if outputfmt.filter == 'Text (encoded)': +- outputprops += UnoProps(FilterOptions="76,LF") ++ outputprops += GlobalUnoProps(FilterOptions="76,LF") + + elif outputfmt.filter == 'Text': +- outputprops += UnoProps(FilterOptions="76") ++ outputprops += GlobalUnoProps(FilterOptions="76") + + elif outputfmt.filter == 'Text - txt - csv (StarCalc)': +- outputprops += UnoProps(FilterOptions="44,34,76") ++ outputprops += GlobalUnoProps(FilterOptions="44,34,76") + + +- ### Cannot use UnoProps for FilterData property ++ ### Cannot use GlobalUnoProps for FilterData property + if op.exportfilter: +- outputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) ++ outputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) + + if not op.stdout: + (outputfn, ext) = os.path.splitext(inputfn) +@@ -917,47 +918,47 @@ class Convertor: + else: + outputfn = op.output + +- outputurl = unohelper.absolutize( self.cwd, unohelper.systemPathToFileUrl(outputfn) ) ++ outputurl = global_unohelper.absolutize( self.cwd, global_unohelper.systemPathToFileUrl(outputfn) ) + info(1, "Output file: %s" % outputfn) + else: + outputurl = "private:stream" + + try: + document.storeToURL(outputurl, tuple(outputprops) ) +- except IOException, e: ++ except UnoIOException as e: + raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) + + phase = "dispose" + document.dispose() + document.close(True) + +- except SystemError, e: ++ except SystemError as e: + error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) + exitcode = 1 + +- except RuntimeException, e: ++ except UnoRuntimeException as e: + error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) + exitcode = 6 + +- except DisposedException, e: ++ except UnoDisposedException as e: + error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) + exitcode = 7 + +- except IllegalArgumentException, e: ++ except UnoIllegalArgumentException as e: + error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) + exitcode = 8 + +- except IOException, e: ++ except UnoIOException as e: + # for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) + error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) + exitcode = 3 + +- except CannotConvertException, e: ++ except UnoCannotConvertException as e: + # for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) + error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) + exitcode = 4 + +- except UnoException, e: ++ except UnoException as e: + if hasattr(e, 'ErrCode'): + error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) + exitcode = e.ErrCode +@@ -975,14 +976,14 @@ class Listener: + global product + + info(1, "Start listener on %s:%s" % (op.server, op.port)) +- self.context = uno.getComponentContext() ++ self.context = global_uno.getComponentContext() + self.svcmgr = self.context.ServiceManager + try: + resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) +- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) + try: + unocontext = resolver.resolve("uno:%s" % op.connection) +- except NoConnectException, e: ++ except UnoNoConnectException as e: + pass + else: + info(1, "Existing %s listener found, nothing to do." % product.ooName) +@@ -991,25 +992,25 @@ class Listener: + subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) + else: + subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) +- except Exception, e: ++ except Exception as e: + error("Launch of %s failed.\n%s" % (office.binary, e)) + else: + info(1, "Existing %s listener found, nothing to do." % product.ooName) + + def error(msg): + "Output error message" +- print >>sys.stderr, msg ++ print(msg, file=sys.stderr) + + def info(level, msg): + "Output info message" + if 'op' not in globals(): + pass + elif op.verbose >= 3 and level >= 3: +- print >>sys.stderr, "DEBUG:", msg ++ print("DEBUG:", msg, file=sys.stderr) + elif not op.stdout and level <= op.verbose: +- print >>sys.stdout, msg ++ print(msg, file=sys.stdout) + elif level <= op.verbose: +- print >>sys.stderr, msg ++ print(msg, file=sys.stderr) + + def die(ret, msg=None): + "Print optional error and exit with errorcode" +@@ -1031,7 +1032,7 @@ def die(ret, msg=None): + subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) + ooproc.wait() + info(2, '%s listener successfully disabled.' % product.ooName) +- except Exception, e: ++ except Exception as e: + error("Terminate using %s failed.\n%s" % (office.binary, e)) + + ### If there is no GUI attached to the instance, terminate instance +@@ -1039,7 +1040,7 @@ def die(ret, msg=None): + info(3, 'Terminating %s instance.' % product.ooName) + try: + convertor.desktop.terminate() +- except DisposedException: ++ except UnoDisposedException: + info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) + try: + ooproc.terminate() +@@ -1080,7 +1081,7 @@ def main(): + for inputfn in op.filenames: + convertor.convert(inputfn) + +- except NoConnectException, e: ++ except UnoNoConnectException as e: + error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) + if op.connection: + info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) +@@ -1094,7 +1095,8 @@ def main(): + error("Warning: failed to launch Office suite. Aborting.") + + ### Main entrance +-if __name__ == '__main__': ++def run(): ++ global exitcode + exitcode = 0 + + info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) +@@ -1105,33 +1107,51 @@ if __name__ == '__main__': + office_environ(of) + # debug_office() + try: +- import uno, unohelper ++ global global_uno ++ global global_unohelper ++ ++ import uno as global_uno ++ import unohelper as global_unohelper ++ global office + office = of + break + except: + # debug_office() +- print >>sys.stderr, "unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of +- print >>sys.stderr, "ERROR:", sys.exc_info()[1] +- print >>sys.stderr ++ print("unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of, file=sys.stderr) ++ print("ERROR:", sys.exc_info()[1], file=sys.stderr) ++ print(file=sys.stderr) + else: + # debug_office() +- print >>sys.stderr, "unoconv: Cannot find a suitable office installation on your system." +- print >>sys.stderr, "ERROR: Please locate your office installation and send your feedback to:" +- print >>sys.stderr, " http://github.com/dagwieers/unoconv/issues" ++ print("unoconv: Cannot find a suitable office installation on your system.", file=sys.stderr) ++ print("ERROR: Please locate your office installation and send your feedback to:", file=sys.stderr) ++ print(" http://github.com/dagwieers/unoconv/issues", file=sys.stderr) + sys.exit(1) + + ### Now that we have found a working pyuno library, let's import some classes +- from com.sun.star.beans import PropertyValue +- from com.sun.star.connection import NoConnectException +- from com.sun.star.document.UpdateDocMode import QUIET_UPDATE +- from com.sun.star.lang import DisposedException, IllegalArgumentException +- from com.sun.star.io import IOException, XOutputStream +- from com.sun.star.script import CannotConvertException ++ global UnoPropertyValue ++ global UnoNoConnectException ++ global UNO_QUIET_UPDATE ++ global UnoDisposedException ++ global UnoIllegalArgumentException ++ global UnoIOException ++ global UnoXOutputStream ++ global UnoCannotConvertException ++ global UnoException ++ global UnoRuntimeException ++ ++ from com.sun.star.beans import PropertyValue as UnoPropertyValue ++ from com.sun.star.connection import NoConnectException as UnoNoConnectException ++ from com.sun.star.document.UpdateDocMode import QUIET_UPDATE as UNO_QUIET_UPDATE ++ from com.sun.star.lang import DisposedException as UnoDisposedException ++ from com.sun.star.lang import IllegalArgumentException as UnoIllegalArgumentException ++ from com.sun.star.io import IOException as UnoIOException ++ from com.sun.star.io import XOutputStream as UnoXOutputStream ++ from com.sun.star.script import CannotConvertException as UnoCannotConvertException + from com.sun.star.uno import Exception as UnoException +- from com.sun.star.uno import RuntimeException ++ from com.sun.star.uno import RuntimeException as UnoRuntimeException + + ### And now that we have those classes, build on them +- class OutputStream( unohelper.Base, XOutputStream ): ++ class OutputStream( global_unohelper.Base, UnoXOutputStream ): + def __init__( self ): + self.closed = 0 + +@@ -1144,15 +1164,22 @@ if __name__ == '__main__': + def flush( self ): + pass + ++ global GlobalOutputStream ++ GlobalOutputStream = OutputStream ++ + def UnoProps(**args): + props = [] + for key in args: +- prop = PropertyValue() ++ prop = UnoPropertyValue() + prop.Name = key + prop.Value = args[key] + props.append(prop) + return tuple(props) + ++ global GlobalUnoProps ++ GlobalUnoProps = UnoProps ++ ++ global op + op = Options(sys.argv[1:]) + + info(2, "Using office base path: %s" % office.basepath) +@@ -1160,6 +1187,9 @@ if __name__ == '__main__': + + try: + main() +- except KeyboardInterrupt, e: ++ except KeyboardInterrupt as e: + die(6, 'Exiting on user request') + die(exitcode) ++ ++if __name__ == '__main__': ++ run() +-- +1.9.0 + diff --git a/0001-python3-added-compatibility.patch b/0001-python3-added-compatibility.patch deleted file mode 100644 index e8d3bca..0000000 --- a/0001-python3-added-compatibility.patch +++ /dev/null @@ -1,3628 +0,0 @@ -From 6eba87f4654d3f142070c1fe9f272bf787885861 Mon Sep 17 00:00:00 2001 -From: Andres Gomez -Date: Thu, 4 Apr 2013 13:18:06 +0300 -Subject: [PATCH] python3: added compatibility - -Dodgy solution in which we create a python2 and -python3 compatible wrapper that would import the -old script, or a new automatically migrated -version. - -The automatic migration was done with the 2to3 -tool after modifying the original script so we can -invoke it as a module. - -This is needed since LibreOffice is providing its -own python3 bundled package since 4.x series. ---- - Makefile | 2 + - packaging/rpm/unoconv.spec | 2 + - unoconv | 1154 +----------------------------------------- - unoconv2.py | 1195 ++++++++++++++++++++++++++++++++++++++++++++ - unoconv3.py | 1195 ++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 2406 insertions(+), 1142 deletions(-) - create mode 100755 unoconv2.py - create mode 100755 unoconv3.py - -diff --git a/Makefile b/Makefile -index 9bb18f6..b950583 100644 ---- a/Makefile -+++ b/Makefile -@@ -111,6 +111,8 @@ install: - install -d -m0755 $(DESTDIR)$(bindir) - install -d -m0755 $(DESTDIR)$(mandir)/man1/ - install -p -m0755 unoconv $(DESTDIR)$(bindir)/unoconv -+ install -p -m0755 unoconv2.py $(DESTDIR)$(bindir)/unoconv2.py -+ install -p -m0755 unoconv3.py $(DESTDIR)$(bindir)/unoconv3.py - install -p -m0644 doc/unoconv.1 $(DESTDIR)$(mandir)/man1/unoconv.1 - - install-links: $(links) -diff --git a/packaging/rpm/unoconv.spec b/packaging/rpm/unoconv.spec -index 4801dd3..c077fec 100644 ---- a/packaging/rpm/unoconv.spec -+++ b/packaging/rpm/unoconv.spec -@@ -49,6 +49,8 @@ and many more... - %doc AUTHORS ChangeLog COPYING README* WISHLIST doc/ tests/ - %doc %{_mandir}/man1/unoconv.1* - %{_bindir}/unoconv -+%{_bindir}/unoconv2.py -+%{_bindir}/unoconv3.py - - %changelog - * Mon Sep 10 2012 Dag Wieers - 0.6-1 -diff --git a/unoconv b/unoconv -index 30e6706..ed603af 100755 ---- a/unoconv -+++ b/unoconv -@@ -12,1154 +12,24 @@ - ### You should have received a copy of the GNU General Public License - ### along with this program; if not, write to the Free Software - ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --### Copyright 2007-2010 Dag Wieers - --from distutils.version import LooseVersion --import getopt --import glob --import os --import subprocess - import sys --import time - --__version__ = "$Revision$" --# $Source$ -+### Extremely dodgy solution for running python2 or python3 versions -+### of the unoconv script - --VERSION = '0.6' -+### This is needed since LibreOffice is providing its own python3 -+### bundled package since 4.x series - --doctypes = ('document', 'graphics', 'presentation', 'spreadsheet') -+### A much more proper solution would be to modify the code so it -+### would be compatible with both versions or, if not possible, to -+### create real python modules out of the code and import them in a -+### proper way - --global convertor, office, ooproc, product --ooproc = None --exitcode = 0 -- --class Office: -- def __init__(self, basepath, urepath, unopath, pyuno, binary, python, pythonhome): -- self.basepath = basepath -- self.urepath = urepath -- self.unopath = unopath -- self.pyuno = pyuno -- self.binary = binary -- self.python = python -- self.pythonhome = pythonhome -- -- def __str__(self): -- return self.basepath -- -- def __repr__(self): -- return self.basepath -- --### Implement a path normalizer in order to make unoconv work on MacOS X --### (on which 'program' is a symlink to 'MacOSX' which seems to break unoconv) --def realpath(*args): -- ''' Implement a combination of os.path.join(), os.path.abspath() and -- os.path.realpath() in order to normalize path constructions ''' -- ret = '' -- for arg in args: -- ret = os.path.join(ret, arg) -- return os.path.realpath(os.path.abspath(ret)) -- --### The first thing we ought to do is find a suitable Office installation --### with a compatible pyuno library that we can import. --### --### See: http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p=166783 -- --def find_offices(): -- ret = [] -- extrapaths = [] -- -- ### Try using UNO_PATH first (in many incarnations, we'll see what sticks) -- if 'UNO_PATH' in os.environ: -- extrapaths += [ os.environ['UNO_PATH'], -- os.path.dirname(os.environ['UNO_PATH']), -- os.path.dirname(os.path.dirname(os.environ['UNO_PATH'])) ] -- -- else: -- -- if os.name in ( 'nt', 'os2' ): -- if 'PROGRAMFILES' in os.environ.keys(): -- extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ -- glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') -- -- if 'PROGRAMFILES(X86)' in os.environ.keys(): -- extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ -- glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') -- -- elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): -- extrapaths += [ '/Applications/LibreOffice.app/Contents', -- '/Applications/NeoOffice.app/Contents', -- '/Applications/OpenOffice.org.app/Contents' ] -- -- else: -- extrapaths += glob.glob('/usr/lib*/libreoffice*') + \ -- glob.glob('/usr/lib*/openoffice*') + \ -- glob.glob('/usr/lib*/ooo*') + \ -- glob.glob('/opt/libreoffice*') + \ -- glob.glob('/opt/openoffice*') + \ -- glob.glob('/opt/ooo*') + \ -- glob.glob('/usr/local/libreoffice*') + \ -- glob.glob('/usr/local/openoffice*') + \ -- glob.glob('/usr/local/ooo*') + \ -- glob.glob('/usr/local/lib/libreoffice*') -- -- ### Find a working set for python UNO bindings -- for basepath in extrapaths: -- if os.name in ( 'nt', 'os2' ): -- officelibraries = ( 'pyuno.pyd', ) -- officebinaries = ( 'soffice.exe' ,) -- pythonbinaries = ( 'python.exe', ) -- pythonhomes = () -- elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): -- officelibraries = ( 'pyuno.so', 'libpyuno.dylib' ) -- officebinaries = ( 'soffice.bin', ) -- pythonbinaries = ( 'python.bin', 'python' ) -- pythonhomes = ( 'OOoPython.framework/Versions/*/lib/python*', ) -- else: -- officelibraries = ( 'pyuno.so', ) -- officebinaries = ( 'soffice.bin', ) -- pythonbinaries = ( 'python.bin', 'python', ) -- pythonhomes = ( 'python-core-*', ) -- -- ### Older LibreOffice/OpenOffice and Windows use basis-link/ or basis/ -- libpath = 'error' -- for basis in ( 'basis-link', 'basis', '' ): -- for lib in officelibraries: -- if os.path.isfile(realpath(basepath, basis, 'program', lib)): -- libpath = realpath(basepath, basis, 'program') -- officelibrary = realpath(libpath, lib) -- info(3, "Found %s in %s" % (lib, libpath)) -- # Break the inner loop... -- break -- # Continue if the inner loop wasn't broken. -- else: -- continue -- # Inner loop was broken, break the outer. -- break -- else: -- continue -- -- ### MacOSX have soffice binaries installed in MacOS subdirectory, not program -- unopath = 'error' -- for basis in ( 'basis-link', 'basis', '' ): -- for bin in officebinaries: -- if os.path.isfile(realpath(basepath, basis, 'program', bin)): -- unopath = realpath(basepath, basis, 'program') -- officebinary = realpath(unopath, bin) -- info(3, "Found %s in %s" % (bin, unopath)) -- # Break the inner loop... -- break -- # Continue if the inner loop wasn't broken. -- else: -- continue -- # Inner loop was broken, break the outer. -- break -- else: -- continue -- -- ### Windows does not provide or need a URE/lib directory ? -- urepath = '' -- for basis in ( 'basis-link', 'basis', '' ): -- for ure in ( 'ure-link', 'ure', 'URE', '' ): -- if os.path.isfile(realpath(basepath, basis, ure, 'lib', 'unorc')): -- urepath = realpath(basepath, basis, ure) -- info(3, "Found %s in %s" % ('unorc', realpath(urepath, 'lib'))) -- # Break the inner loop... -- break -- # Continue if the inner loop wasn't broken. -- else: -- continue -- # Inner loop was broken, break the outer. -- break -- -- pythonhome = None -- for home in pythonhomes: -- if glob.glob(realpath(libpath, home)): -- pythonhome = glob.glob(realpath(libpath, home))[0] -- info(3, "Found %s in %s" % (home, pythonhome)) -- break -- --# if not os.path.isfile(realpath(basepath, program, officebinary)): --# continue --# info(3, "Found %s in %s" % (officebinary, realpath(basepath, program))) -- --# if not glob.glob(realpath(basepath, basis, program, 'python-core-*')): --# continue -- -- for pythonbinary in pythonbinaries: -- if os.path.isfile(realpath(unopath, pythonbinary)): -- info(3, "Found %s in %s" % (pythonbinary, unopath)) -- ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, -- realpath(unopath, pythonbinary), pythonhome)) -- else: -- info(3, "Considering %s" % basepath) -- ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, -- sys.executable, None)) -- return ret -- --def office_environ(office): -- ### Set PATH so that crash_report is found -- os.environ['PATH'] = realpath(office.basepath, 'program') + os.pathsep + os.environ['PATH'] -- -- ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: -- os.environ['UNO_PATH'] = office.unopath -- -- ### Set URE_BOOTSTRAP so that "uno.getComponentContext()" bootstraps a complete -- ### UNO environment -- if os.name in ( 'nt', 'os2' ): -- os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') -- else: -- os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamentalrc') -- -- ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: -- if 'LD_LIBRARY_PATH' in os.environ: -- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -- realpath(office.urepath, 'lib') + os.pathsep + \ -- os.environ['LD_LIBRARY_PATH'] -- else: -- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -- realpath(office.urepath, 'lib') -- -- if office.pythonhome: -- for libpath in ( realpath(office.pythonhome, 'lib'), -- realpath(office.pythonhome, 'lib', 'lib-dynload'), -- realpath(office.pythonhome, 'lib', 'lib-tk'), -- realpath(office.pythonhome, 'lib', 'site-packages'), -- office.unopath): -- sys.path.insert(0, libpath) -- else: -- ### Still needed for system python using LibreOffice UNO bindings -- ### Although we prefer to use a system UNO binding in this case -- sys.path.append(office.unopath) -- --def debug_office(): -- if 'URE_BOOTSTRAP' in os.environ: -- print >>sys.stderr, 'URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'] -- if 'UNO_PATH' in os.environ: -- print >>sys.stderr, 'UNO_PATH=%s' % os.environ['UNO_PATH'] -- if 'UNO_TYPES' in os.environ: -- print >>sys.stderr, 'UNO_TYPES=%s' % os.environ['UNO_TYPES'] -- print 'PATH=%s' % os.environ['PATH'] -- if 'PYTHONHOME' in os.environ: -- print >>sys.stderr, 'PYTHONHOME=%s' % os.environ['PYTHONHOME'] -- if 'PYTHONPATH' in os.environ: -- print >>sys.stderr, 'PYTHONPATH=%s' % os.environ['PYTHONPATH'] -- if 'LD_LIBRARY_PATH' in os.environ: -- print >>sys.stderr, 'LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'] -- --def python_switch(office): -- if office.pythonhome: -- os.environ['PYTHONHOME'] = office.pythonhome -- os.environ['PYTHONPATH'] = realpath(office.pythonhome, 'lib') + os.pathsep + \ -- realpath(office.pythonhome, 'lib', 'lib-dynload') + os.pathsep + \ -- realpath(office.pythonhome, 'lib', 'lib-tk') + os.pathsep + \ -- realpath(office.pythonhome, 'lib', 'site-packages') + os.pathsep + \ -- office.unopath -- -- os.environ['UNO_PATH'] = office.unopath -- -- info(3, "-> Switching from %s to %s" % (sys.executable, office.python)) -- if os.name in ('nt', 'os2'): -- ### os.execv is broken on Windows and can't properly parse command line -- ### arguments and executable name if they contain whitespaces. subprocess -- ### fixes that behavior. -- ret = subprocess.call([office.python] + sys.argv[0:]) -- sys.exit(ret) -- else: -- -- ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: -- if 'LD_LIBRARY_PATH' in os.environ: -- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -- realpath(office.urepath, 'lib') + os.pathsep + \ -- os.environ['LD_LIBRARY_PATH'] -- else: -- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -- realpath(office.urepath, 'lib') -- -- try: -- os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) -- except OSError: -- ### Mac OS X versions prior to 10.6 do not support execv in -- ### a process that contains multiple threads. Instead of -- ### re-executing in the current process, start a new one -- ### and cause the current process to exit. This isn't -- ### ideal since the new process is detached from the parent -- ### terminal and thus cannot easily be killed with ctrl-C, -- ### but it's better than not being able to autoreload at -- ### all. -- ### Unfortunately the errno returned in this case does not -- ### appear to be consistent, so we can't easily check for -- ### this error specifically. -- ret = os.spawnvpe(os.P_WAIT, office.python, [office.python, ] + sys.argv[0:], os.environ) -- sys.exit(ret) -- --class Fmt: -- def __init__(self, doctype, name, extension, summary, filter): -- self.doctype = doctype -- self.name = name -- self.extension = extension -- self.summary = summary -- self.filter = filter -- -- def __str__(self): -- return "%s [.%s]" % (self.summary, self.extension) -- -- def __repr__(self): -- return "%s/%s" % (self.name, self.doctype) -- --class FmtList: -- def __init__(self): -- self.list = [] -- -- def add(self, doctype, name, extension, summary, filter): -- self.list.append(Fmt(doctype, name, extension, summary, filter)) -- -- def byname(self, name): -- ret = [] -- for fmt in self.list: -- if fmt.name == name: -- ret.append(fmt) -- return ret -- -- def byextension(self, extension): -- ret = [] -- for fmt in self.list: -- if os.extsep + fmt.extension == extension: -- ret.append(fmt) -- return ret -- -- def bydoctype(self, doctype, name): -- ret = [] -- for fmt in self.list: -- if fmt.name == name and fmt.doctype == doctype: -- ret.append(fmt) -- return ret -- -- def display(self, doctype): -- print >>sys.stderr, "The following list of %s formats are currently available:\n" % doctype -- for fmt in self.list: -- if fmt.doctype == doctype: -- print >>sys.stderr, " %-8s - %s" % (fmt.name, fmt) -- print >>sys.stderr -- --fmts = FmtList() -- --### TextDocument --fmts.add('document', 'bib', 'bib', 'BibTeX', 'BibTeX_Writer') ### 22 --fmts.add('document', 'doc', 'doc', 'Microsoft Word 97/2000/XP', 'MS Word 97') ### 29 --fmts.add('document', 'doc6', 'doc', 'Microsoft Word 6.0', 'MS WinWord 6.0') ### 24 --fmts.add('document', 'doc95', 'doc', 'Microsoft Word 95', 'MS Word 95') ### 28 --fmts.add('document', 'docbook', 'xml', 'DocBook', 'DocBook File') ### 39 --fmts.add('document', 'docx', 'docx', 'Microsoft Office Open XML', 'Office Open XML Text') --fmts.add('document', 'docx7', 'docx', 'Microsoft Office Open XML', 'MS Word 2007 XML') --fmts.add('document', 'fodt', 'fodt', 'OpenDocument Text (Flat XML)', 'OpenDocument Text Flat XML') --fmts.add('document', 'html', 'html', 'HTML Document (OpenOffice.org Writer)', 'HTML (StarWriter)') ### 3 --fmts.add('document', 'latex', 'ltx', 'LaTeX 2e', 'LaTeX_Writer') ### 31 --fmts.add('document', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki') --fmts.add('document', 'odt', 'odt', 'ODF Text Document', 'writer8') ### 10 --fmts.add('document', 'ooxml', 'xml', 'Microsoft Office Open XML', 'MS Word 2003 XML') ### 11 --fmts.add('document', 'ott', 'ott', 'Open Document Text', 'writer8_template') ### 21 --fmts.add('document', 'pdb', 'pdb', 'AportisDoc (Palm)', 'AportisDoc Palm DB') --fmts.add('document', 'pdf', 'pdf', 'Portable Document Format', 'writer_pdf_Export') ### 18 --fmts.add('document', 'psw', 'psw', 'Pocket Word', 'PocketWord File') --fmts.add('document', 'rtf', 'rtf', 'Rich Text Format', 'Rich Text Format') ### 16 --fmts.add('document', 'sdw', 'sdw', 'StarWriter 5.0', 'StarWriter 5.0') ### 23 --fmts.add('document', 'sdw4', 'sdw', 'StarWriter 4.0', 'StarWriter 4.0') ### 2 --fmts.add('document', 'sdw3', 'sdw', 'StarWriter 3.0', 'StarWriter 3.0') ### 20 --fmts.add('document', 'stw', 'stw', 'Open Office.org 1.0 Text Document Template', 'writer_StarOffice_XML_Writer_Template') ### 9 --fmts.add('document', 'sxw', 'sxw', 'Open Office.org 1.0 Text Document', 'StarOffice XML (Writer)') ### 1 --fmts.add('document', 'text', 'txt', 'Text Encoded', 'Text (encoded)') ### 26 --fmts.add('document', 'txt', 'txt', 'Text', 'Text') ### 34 --fmts.add('document', 'uot', 'uot', 'Unified Office Format text','UOF text') ### 27 --fmts.add('document', 'vor', 'vor', 'StarWriter 5.0 Template', 'StarWriter 5.0 Vorlage/Template') ### 6 --fmts.add('document', 'vor4', 'vor', 'StarWriter 4.0 Template', 'StarWriter 4.0 Vorlage/Template') ### 5 --fmts.add('document', 'vor3', 'vor', 'StarWriter 3.0 Template', 'StarWriter 3.0 Vorlage/Template') ### 4 --fmts.add('document', 'xhtml', 'html', 'XHTML Document', 'XHTML Writer File') ### 33 -- --### WebDocument --fmts.add('web', 'etext', 'txt', 'Text Encoded (OpenOffice.org Writer/Web)', 'Text (encoded) (StarWriter/Web)') ### 14 --fmts.add('web', 'html10', 'html', 'OpenOffice.org 1.0 HTML Template', 'writer_web_StarOffice_XML_Writer_Web_Template') ### 11 --fmts.add('web', 'html', 'html', 'HTML Document', 'HTML') ### 2 --fmts.add('web', 'html', 'html', 'HTML Document Template', 'writerweb8_writer_template') ### 13 --fmts.add('web', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki_Web') ### 9 --fmts.add('web', 'pdf', 'pdf', 'PDF - Portable Document Format', 'writer_web_pdf_Export') ### 10 --fmts.add('web', 'sdw3', 'sdw', 'StarWriter 3.0 (OpenOffice.org Writer/Web)', 'StarWriter 3.0 (StarWriter/Web)') ### 3 --fmts.add('web', 'sdw4', 'sdw', 'StarWriter 4.0 (OpenOffice.org Writer/Web)', 'StarWriter 4.0 (StarWriter/Web)') ### 4 --fmts.add('web', 'sdw', 'sdw', 'StarWriter 5.0 (OpenOffice.org Writer/Web)', 'StarWriter 5.0 (StarWriter/Web)') ### 5 --fmts.add('web', 'txt', 'txt', 'OpenOffice.org Text (OpenOffice.org Writer/Web)', 'writerweb8_writer') ### 12 --fmts.add('web', 'text10', 'txt', 'OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)', 'writer_web_StarOffice_XML_Writer') ### 15 --fmts.add('web', 'text', 'txt', 'Text (OpenOffice.org Writer/Web)', 'Text (StarWriter/Web)') ### 8 --fmts.add('web', 'vor4', 'vor', 'StarWriter/Web 4.0 Template', 'StarWriter/Web 4.0 Vorlage/Template') ### 6 --fmts.add('web', 'vor', 'vor', 'StarWriter/Web 5.0 Template', 'StarWriter/Web 5.0 Vorlage/Template') ### 7 -- --### Spreadsheet --fmts.add('spreadsheet', 'csv', 'csv', 'Text CSV', 'Text - txt - csv (StarCalc)') ### 16 --fmts.add('spreadsheet', 'dbf', 'dbf', 'dBASE', 'dBase') ### 22 --fmts.add('spreadsheet', 'dif', 'dif', 'Data Interchange Format', 'DIF') ### 5 --fmts.add('spreadsheet', 'fods', 'fods', 'OpenDocument Spreadsheet (Flat XML)', 'OpenDocument Spreadsheet Flat XML') --fmts.add('spreadsheet', 'html', 'html', 'HTML Document (OpenOffice.org Calc)', 'HTML (StarCalc)') ### 7 --fmts.add('spreadsheet', 'ods', 'ods', 'ODF Spreadsheet', 'calc8') ### 15 --fmts.add('spreadsheet', 'ooxml', 'xml', 'Microsoft Excel 2003 XML', 'MS Excel 2003 XML') ### 23 --fmts.add('spreadsheet', 'ots', 'ots', 'ODF Spreadsheet Template', 'calc8_template') ### 14 --fmts.add('spreadsheet', 'pdf', 'pdf', 'Portable Document Format', 'calc_pdf_Export') ### 34 --fmts.add('spreadsheet', 'pxl', 'pxl', 'Pocket Excel', 'Pocket Excel') --fmts.add('spreadsheet', 'sdc', 'sdc', 'StarCalc 5.0', 'StarCalc 5.0') ### 31 --fmts.add('spreadsheet', 'sdc4', 'sdc', 'StarCalc 4.0', 'StarCalc 4.0') ### 11 --fmts.add('spreadsheet', 'sdc3', 'sdc', 'StarCalc 3.0', 'StarCalc 3.0') ### 29 --fmts.add('spreadsheet', 'slk', 'slk', 'SYLK', 'SYLK') ### 35 --fmts.add('spreadsheet', 'stc', 'stc', 'OpenOffice.org 1.0 Spreadsheet Template', 'calc_StarOffice_XML_Calc_Template') ### 2 --fmts.add('spreadsheet', 'sxc', 'sxc', 'OpenOffice.org 1.0 Spreadsheet', 'StarOffice XML (Calc)') ### 3 --fmts.add('spreadsheet', 'uos', 'uos', 'Unified Office Format spreadsheet', 'UOF spreadsheet') ### 9 --fmts.add('spreadsheet', 'vor3', 'vor', 'StarCalc 3.0 Template', 'StarCalc 3.0 Vorlage/Template') ### 18 --fmts.add('spreadsheet', 'vor4', 'vor', 'StarCalc 4.0 Template', 'StarCalc 4.0 Vorlage/Template') ### 19 --fmts.add('spreadsheet', 'vor', 'vor', 'StarCalc 5.0 Template', 'StarCalc 5.0 Vorlage/Template') ### 20 --fmts.add('spreadsheet', 'xhtml', 'xhtml', 'XHTML', 'XHTML Calc File') ### 26 --fmts.add('spreadsheet', 'xls', 'xls', 'Microsoft Excel 97/2000/XP', 'MS Excel 97') ### 12 --fmts.add('spreadsheet', 'xls5', 'xls', 'Microsoft Excel 5.0', 'MS Excel 5.0/95') ### 8 --fmts.add('spreadsheet', 'xls95', 'xls', 'Microsoft Excel 95', 'MS Excel 95') ### 10 --fmts.add('spreadsheet', 'xlt', 'xlt', 'Microsoft Excel 97/2000/XP Template', 'MS Excel 97 Vorlage/Template') ### 6 --fmts.add('spreadsheet', 'xlt5', 'xlt', 'Microsoft Excel 5.0 Template', 'MS Excel 5.0/95 Vorlage/Template') ### 28 --fmts.add('spreadsheet', 'xlt95', 'xlt', 'Microsoft Excel 95 Template', 'MS Excel 95 Vorlage/Template') ### 21 -- --### Graphics --fmts.add('graphics', 'bmp', 'bmp', 'Windows Bitmap', 'draw_bmp_Export') ### 21 --fmts.add('graphics', 'emf', 'emf', 'Enhanced Metafile', 'draw_emf_Export') ### 15 --fmts.add('graphics', 'eps', 'eps', 'Encapsulated PostScript', 'draw_eps_Export') ### 48 --fmts.add('graphics', 'fodg', 'fodg', 'OpenDocument Drawing (Flat XML)', 'OpenDocument Drawing Flat XML') --fmts.add('graphics', 'gif', 'gif', 'Graphics Interchange Format', 'draw_gif_Export') ### 30 --fmts.add('graphics', 'html', 'html', 'HTML Document (OpenOffice.org Draw)', 'draw_html_Export') ### 37 --fmts.add('graphics', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'draw_jpg_Export') ### 3 --fmts.add('graphics', 'met', 'met', 'OS/2 Metafile', 'draw_met_Export') ### 43 --fmts.add('graphics', 'odd', 'odd', 'OpenDocument Drawing', 'draw8') ### 6 --fmts.add('graphics', 'otg', 'otg', 'OpenDocument Drawing Template', 'draw8_template') ### 20 --fmts.add('graphics', 'pbm', 'pbm', 'Portable Bitmap', 'draw_pbm_Export') ### 14 --fmts.add('graphics', 'pct', 'pct', 'Mac Pict', 'draw_pct_Export') ### 41 --fmts.add('graphics', 'pdf', 'pdf', 'Portable Document Format', 'draw_pdf_Export') ### 28 --fmts.add('graphics', 'pgm', 'pgm', 'Portable Graymap', 'draw_pgm_Export') ### 11 --fmts.add('graphics', 'png', 'png', 'Portable Network Graphic', 'draw_png_Export') ### 2 --fmts.add('graphics', 'ppm', 'ppm', 'Portable Pixelmap', 'draw_ppm_Export') ### 5 --fmts.add('graphics', 'ras', 'ras', 'Sun Raster Image', 'draw_ras_Export') ## 31 --fmts.add('graphics', 'std', 'std', 'OpenOffice.org 1.0 Drawing Template', 'draw_StarOffice_XML_Draw_Template') ### 53 --fmts.add('graphics', 'svg', 'svg', 'Scalable Vector Graphics', 'draw_svg_Export') ### 50 --fmts.add('graphics', 'svm', 'svm', 'StarView Metafile', 'draw_svm_Export') ### 55 --fmts.add('graphics', 'swf', 'swf', 'Macromedia Flash (SWF)', 'draw_flash_Export') ### 23 --fmts.add('graphics', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing', 'StarOffice XML (Draw)') ### 26 --fmts.add('graphics', 'sxd3', 'sxd', 'StarDraw 3.0', 'StarDraw 3.0') ### 40 --fmts.add('graphics', 'sxd5', 'sxd', 'StarDraw 5.0', 'StarDraw 5.0') ### 44 --fmts.add('graphics', 'sxw', 'sxw', 'StarOffice XML (Draw)', 'StarOffice XML (Draw)') --fmts.add('graphics', 'tiff', 'tiff', 'Tagged Image File Format', 'draw_tif_Export') ### 13 --fmts.add('graphics', 'vor', 'vor', 'StarDraw 5.0 Template', 'StarDraw 5.0 Vorlage') ### 36 --fmts.add('graphics', 'vor3', 'vor', 'StarDraw 3.0 Template', 'StarDraw 3.0 Vorlage') ### 35 --fmts.add('graphics', 'wmf', 'wmf', 'Windows Metafile', 'draw_wmf_Export') ### 8 --fmts.add('graphics', 'xhtml', 'xhtml', 'XHTML', 'XHTML Draw File') ### 45 --fmts.add('graphics', 'xpm', 'xpm', 'X PixMap', 'draw_xpm_Export') ### 19 -- --### Presentation --fmts.add('presentation', 'bmp', 'bmp', 'Windows Bitmap', 'impress_bmp_Export') ### 15 --fmts.add('presentation', 'emf', 'emf', 'Enhanced Metafile', 'impress_emf_Export') ### 16 --fmts.add('presentation', 'eps', 'eps', 'Encapsulated PostScript', 'impress_eps_Export') ### 17 --fmts.add('presentation', 'fodp', 'fodp', 'OpenDocument Presentation (Flat XML)', 'OpenDocument Presentation Flat XML') --fmts.add('presentation', 'gif', 'gif', 'Graphics Interchange Format', 'impress_gif_Export') ### 18 --fmts.add('presentation', 'html', 'html', 'HTML Document (OpenOffice.org Impress)', 'impress_html_Export') ### 43 --fmts.add('presentation', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'impress_jpg_Export') ### 19 --fmts.add('presentation', 'met', 'met', 'OS/2 Metafile', 'impress_met_Export') ### 20 --fmts.add('presentation', 'odg', 'odg', 'ODF Drawing (Impress)', 'impress8_draw') ### 29 --fmts.add('presentation', 'odp', 'odp', 'ODF Presentation', 'impress8') ### 9 --fmts.add('presentation', 'otp', 'otp', 'ODF Presentation Template', 'impress8_template') ### 38 --fmts.add('presentation', 'pbm', 'pbm', 'Portable Bitmap', 'impress_pbm_Export') ### 21 --fmts.add('presentation', 'pct', 'pct', 'Mac Pict', 'impress_pct_Export') ### 22 --fmts.add('presentation', 'pdf', 'pdf', 'Portable Document Format', 'impress_pdf_Export') ### 23 --fmts.add('presentation', 'pgm', 'pgm', 'Portable Graymap', 'impress_pgm_Export') ### 24 --fmts.add('presentation', 'png', 'png', 'Portable Network Graphic', 'impress_png_Export') ### 25 --fmts.add('presentation', 'potm', 'potm', 'Microsoft PowerPoint 2007/2010 XML Template', 'Impress MS PowerPoint 2007 XML Template') --fmts.add('presentation', 'pot', 'pot', 'Microsoft PowerPoint 97/2000/XP Template', 'MS PowerPoint 97 Vorlage') ### 3 --fmts.add('presentation', 'ppm', 'ppm', 'Portable Pixelmap', 'impress_ppm_Export') ### 26 --fmts.add('presentation', 'pptx', 'pptx', 'Microsoft PowerPoint 2007/2010 XML', 'Impress MS PowerPoint 2007 XML') ### 36 --fmts.add('presentation', 'pps', 'pps', 'Microsoft PowerPoint 97/2000/XP (Autoplay)', 'MS PowerPoint 97 Autoplay') ### 36 --fmts.add('presentation', 'ppt', 'ppt', 'Microsoft PowerPoint 97/2000/XP', 'MS PowerPoint 97') ### 36 --fmts.add('presentation', 'pwp', 'pwp', 'PlaceWare', 'placeware_Export') ### 30 --fmts.add('presentation', 'ras', 'ras', 'Sun Raster Image', 'impress_ras_Export') ### 27 --fmts.add('presentation', 'sda', 'sda', 'StarDraw 5.0 (OpenOffice.org Impress)', 'StarDraw 5.0 (StarImpress)') ### 8 --fmts.add('presentation', 'sdd', 'sdd', 'StarImpress 5.0', 'StarImpress 5.0') ### 6 --fmts.add('presentation', 'sdd3', 'sdd', 'StarDraw 3.0 (OpenOffice.org Impress)', 'StarDraw 3.0 (StarImpress)') ### 42 --fmts.add('presentation', 'sdd4', 'sdd', 'StarImpress 4.0', 'StarImpress 4.0') ### 37 --fmts.add('presentation', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)', 'impress_StarOffice_XML_Draw') ### 31 --fmts.add('presentation', 'sti', 'sti', 'OpenOffice.org 1.0 Presentation Template', 'impress_StarOffice_XML_Impress_Template') ### 5 --fmts.add('presentation', 'svg', 'svg', 'Scalable Vector Graphics', 'impress_svg_Export') ### 14 --fmts.add('presentation', 'svm', 'svm', 'StarView Metafile', 'impress_svm_Export') ### 13 --fmts.add('presentation', 'swf', 'swf', 'Macromedia Flash (SWF)', 'impress_flash_Export') ### 34 --fmts.add('presentation', 'sxi', 'sxi', 'OpenOffice.org 1.0 Presentation', 'StarOffice XML (Impress)') ### 41 --fmts.add('presentation', 'tiff', 'tiff', 'Tagged Image File Format', 'impress_tif_Export') ### 12 --fmts.add('presentation', 'uop', 'uop', 'Unified Office Format presentation', 'UOF presentation') ### 4 --fmts.add('presentation', 'vor', 'vor', 'StarImpress 5.0 Template', 'StarImpress 5.0 Vorlage') ### 40 --fmts.add('presentation', 'vor3', 'vor', 'StarDraw 3.0 Template (OpenOffice.org Impress)', 'StarDraw 3.0 Vorlage (StarImpress)') ###1 --fmts.add('presentation', 'vor4', 'vor', 'StarImpress 4.0 Template', 'StarImpress 4.0 Vorlage') ### 39 --fmts.add('presentation', 'vor5', 'vor', 'StarDraw 5.0 Template (OpenOffice.org Impress)', 'StarDraw 5.0 Vorlage (StarImpress)') ### 2 --fmts.add('presentation', 'wmf', 'wmf', 'Windows Metafile', 'impress_wmf_Export') ### 11 --fmts.add('presentation', 'xhtml', 'xml', 'XHTML', 'XHTML Impress File') ### 33 --fmts.add('presentation', 'xpm', 'xpm', 'X PixMap', 'impress_xpm_Export') ### 10 -- --class Options: -- def __init__(self, args): -- self.connection = None -- self.debug = False -- self.doctype = None -- self.exportfilter = [] -- self.exportfilteroptions = "" -- self.filenames = [] -- self.format = None -- self.importfilter = [] -- self.importfilteroptions = "" -- self.listener = False -- self.nolaunch = False -- self.output = None -- self.password = None -- self.pipe = None -- self.port = '2002' -- self.server = '127.0.0.1' -- self.showlist = False -- self.stdout = False -- self.template = None -- self.timeout = 6 -- self.verbose = 0 -- -- ### Get options from the commandline -- try: -- opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', -- ['connection=', 'debug', 'doctype=', 'export=', 'format=', -- 'help', 'import', 'listener', 'no-launch', 'output=', -- 'outputpath', 'password=', 'pipe=', 'port=', 'server=', -- 'timeout=', 'show', 'stdout', 'template', 'verbose', -- 'version'] ) -- except getopt.error, exc: -- print 'unoconv: %s, try unoconv -h for a list of all the options' % str(exc) -- sys.exit(255) -- -- for opt, arg in opts: -- if opt in ['-h', '--help']: -- self.usage() -- print -- self.help() -- sys.exit(1) -- elif opt in ['-c', '--connection']: -- self.connection = arg -- elif opt in ['--debug']: -- self.debug = True -- elif opt in ['-d', '--doctype']: -- self.doctype = arg -- elif opt in ['-e', '--export']: -- l = arg.split('=') -- if len(l) == 2: -- (name, value) = l -- if name in ('FilterOptions'): -- self.exportfilteroptions = value -- elif value in ('True', 'true'): -- self.exportfilter.append( PropertyValue( name, 0, True, 0 ) ) -- elif value in ('False', 'false'): -- self.exportfilter.append( PropertyValue( name, 0, False, 0 ) ) -- else: -- try: -- self.exportfilter.append( PropertyValue( name, 0, int(value), 0 ) ) -- except ValueError: -- self.exportfilter.append( PropertyValue( name, 0, value, 0 ) ) -- else: -- print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg -- elif opt in ['-f', '--format']: -- self.format = arg -- elif opt in ['-i', '--import']: -- l = arg.split('=') -- if len(l) == 2: -- (name, value) = l -- if name in ('FilterOptions'): -- self.importfilteroptions = value -- elif value in ('True', 'true'): -- self.importfilter.append( PropertyValue( name, 0, True, 0 ) ) -- elif value in ('False', 'false'): -- self.importfilter.append( PropertyValue( name, 0, False, 0 ) ) -- else: -- try: -- self.importfilter.append( PropertyValue( name, 0, int(value), 0 ) ) -- except ValueError: -- self.importfilter.append( PropertyValue( name, 0, value, 0 ) ) -- else: -- print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg -- elif opt in ['-l', '--listener']: -- self.listener = True -- elif opt in ['-n', '--no-launch']: -- self.nolaunch = True -- elif opt in ['-o', '--output']: -- self.output = arg -- elif opt in ['--outputpath']: -- print >>sys.stderr, 'Warning: This option is deprecated by --output.' -- self.output = arg -- elif opt in ['--password']: -- self.password = arg -- elif opt in ['--pipe']: -- self.pipe = arg -- elif opt in ['-p', '--port']: -- self.port = arg -- elif opt in ['-s', '--server']: -- self.server = arg -- elif opt in ['--show']: -- self.showlist = True -- elif opt in ['--stdout']: -- self.stdout = True -- elif opt in ['-t', '--template']: -- self.template = arg -- elif opt in ['-T', '--timeout']: -- self.timeout = int(arg) -- elif opt in ['-v', '--verbose']: -- self.verbose = self.verbose + 1 -- elif opt in ['-V', '--version']: -- self.version() -- sys.exit(255) -- -- ### Enable verbosity -- if self.verbose >= 2: -- print >>sys.stderr, 'Verbosity set to level %d' % self.verbose -- -- self.filenames = args -- -- if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: -- print >>sys.stderr, 'unoconv: you have to provide a filename as argument' -- print >>sys.stderr, 'Try `unoconv -h\' for more information.' -- sys.exit(255) -- -- ### Set connection string -- if not self.connection: -- if not self.pipe: -- self.connection = "socket,host=%s,port=%s;urp;StarOffice.ComponentContext" % (self.server, self.port) --# self.connection = "socket,host=%s,port=%s;urp;" % (self.server, self.port) -- else: -- self.connection = "pipe,name=%s;urp;StarOffice.ComponentContext" % (self.pipe) -- -- ### Make it easier for people to use a doctype (first letter is enough) -- if self.doctype: -- for doctype in doctypes: -- if doctype.startswith(self.doctype): -- self.doctype = doctype -- -- ### Check if the user request to see the list of formats -- if self.showlist or self.format == 'list': -- if self.doctype: -- fmts.display(self.doctype) -- else: -- for t in doctypes: -- fmts.display(t) -- sys.exit(0) -- -- ### If no format was specified, probe it or provide it -- if not self.format: -- l = sys.argv[0].split('2') -- if len(l) == 2: -- self.format = l[1] -- else: -- self.format = 'pdf' -- -- def version(self): -- ### Get office product information -- product = uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) -- -- print 'unoconv %s' % VERSION -- print 'Written by Dag Wieers ' -- print 'Homepage at http://dag.wieers.com/home-made/unoconv/' -- print -- print 'platform %s/%s' % (os.name, sys.platform) -- print 'python %s' % sys.version -- print product.ooName, product.ooSetupVersion --# print --# print 'build revision $Rev$' -- -- def usage(self): -- print >>sys.stderr, 'usage: unoconv [options] file [file2 ..]' -- -- def help(self): -- print >>sys.stderr, '''Convert from and to any format supported by LibreOffice -- --unoconv options: -- -c, --connection=string use a custom connection string -- -d, --doctype=type specify document type -- (document, graphics, presentation, spreadsheet) -- -e, --export=name=value set export filter options -- eg. -e PageRange=1-2 -- -f, --format=format specify the output format -- -i, --import=string set import filter option string -- eg. -i utf8 -- -l, --listener start a permanent listener to use by unoconv clients -- -n, --no-launch fail if no listener is found (default: launch one) -- -o, --output=name output basename, filename or directory -- --pipe=name alternative method of connection using a pipe -- -p, --port=port specify the port (default: 2002) -- to be used by client or listener -- --password=string provide a password to decrypt the document -- -s, --server=server specify the server address (default: 127.0.0.1) -- to be used by client or listener -- --show list the available output formats -- --stdout write output to stdout -- -t, --template=file import the styles from template (.ott) -- -T, --timeout=secs timeout after secs if connection to listener fails -- -v, --verbose be more and more verbose (-vvv for debugging) --''' -- --class Convertor: -- def __init__(self): -- global exitcode, ooproc, office, product -- unocontext = None -- -- ### Do the LibreOffice component dance -- self.context = uno.getComponentContext() -- self.svcmgr = self.context.ServiceManager -- resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) -- -- ### Test for an existing connection -- info(3, 'Connection type: %s' % op.connection) -- try: -- unocontext = resolver.resolve("uno:%s" % op.connection) -- except NoConnectException, e: --# info(3, "Existing listener not found.\n%s" % e) -- info(3, "Existing listener not found.") -- -- if op.nolaunch: -- die(113, "Existing listener not found. Unable start listener by parameters. Aborting.") -- -- ### Start our own OpenOffice instance -- info(3, "Launching our own listener using %s." % office.binary) -- try: -- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) -- if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): -- ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) -- else: -- ooproc = subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--accept=%s" % op.connection], env=os.environ) -- info(2, '%s listener successfully started. (pid=%s)' % (product.ooName, ooproc.pid)) -- -- ### Try connection to it for op.timeout seconds (flakky OpenOffice) -- timeout = 0 -- while timeout <= op.timeout: -- ### Is it already/still running ? -- retcode = ooproc.poll() -- if retcode != None: -- info(3, "Process %s (pid=%s) exited with %s." % (office.binary, ooproc.pid, retcode)) -- break -- try: -- unocontext = resolver.resolve("uno:%s" % op.connection) -- break -- except NoConnectException: -- time.sleep(0.5) -- timeout += 0.5 -- except: -- raise -- else: -- error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) -- except Exception, e: -- raise -- error("Launch of %s failed.\n%s" % (office.binary, e)) -- -- if not unocontext: -- die(251, "Unable to connect or start own listener. Aborting.") -- -- ### And some more LibreOffice magic -- unosvcmgr = unocontext.ServiceManager -- self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) -- self.cwd = unohelper.systemPathToFileUrl( os.getcwd() ) -- -- ### List all filters --# self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) --# for filter in self.filters.getElementNames(): --# print filter --# #print dir(filter), dir(filter.format) -- -- def getformat(self, inputfn): -- doctype = None -- -- ### Get the output format from mapping -- if op.doctype: -- outputfmt = fmts.bydoctype(op.doctype, op.format) -- else: -- outputfmt = fmts.byname(op.format) -- -- if not outputfmt: -- outputfmt = fmts.byextension(os.extsep + op.format) -- -- ### If no doctype given, check list of acceptable formats for input file ext doctype -- ### FIXME: This should go into the for-loop to match each individual input filename -- if outputfmt: -- inputext = os.path.splitext(inputfn)[1] -- inputfmt = fmts.byextension(inputext) -- if inputfmt: -- for fmt in outputfmt: -- if inputfmt[0].doctype == fmt.doctype: -- doctype = inputfmt[0].doctype -- outputfmt = fmt -- break -- else: -- outputfmt = outputfmt[0] -- # print >>sys.stderr, 'unoconv: format `%s\' is part of multiple doctypes %s, selecting `%s\'.' % (format, [fmt.doctype for fmt in outputfmt], outputfmt[0].doctype) -- else: -- outputfmt = outputfmt[0] -- -- ### No format found, throw error -- if not outputfmt: -- if doctype: -- print >>sys.stderr, 'unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format) -- else: -- print >>sys.stderr, 'unoconv: format [%s] is not known to unoconv.' % op.format -- die(1) -- -- return outputfmt -- -- def convert(self, inputfn): -- global exitcode -- -- document = None -- outputfmt = self.getformat(inputfn) -- -- if op.verbose > 0: -- print >>sys.stderr, 'Input file:', inputfn -- -- if not os.path.exists(inputfn): -- print >>sys.stderr, 'unoconv: file `%s\' does not exist.' % inputfn -- exitcode = 1 -- -- try: -- ### Import phase -- phase = "import" -- -- ### Load inputfile -- inputprops = UnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=QUIET_UPDATE) -- --# if op.password: --# info = UnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") --# inputprops += UnoProps(ModifyPasswordInfo=info) -- -- ### Cannot use UnoProps for FilterData property -- if op.importfilteroptions: --# print "Import filter options: %s" % op.importfilteroptions -- inputprops += UnoProps(FilterOptions=op.importfilteroptions) -- -- ### Cannot use UnoProps for FilterData property -- if op.importfilter: -- inputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) -- -- inputurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(inputfn)) -- document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) -- -- if not document: -- raise UnoException("The document '%s' could not be opened." % inputurl, None) -- -- ### Import style template -- phase = "import-style" -- if op.template: -- if os.path.exists(op.template): -- info(1, "Template file: %s" % op.template) -- templateprops = UnoProps(OverwriteStyles=True) -- templateurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(op.template)) -- document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) -- else: -- print >>sys.stderr, 'unoconv: template file `%s\' does not exist.' % op.template -- exitcode = 1 -- -- ### Update document links -- phase = "update-links" -- try: -- document.updateLinks() -- except AttributeError: -- # the document doesn't implement the XLinkUpdate interface -- pass -- -- ### Update document indexes -- phase = "update-indexes" -- try: -- document.refresh() -- indexes = document.getDocumentIndexes() -- except AttributeError: -- # the document doesn't implement the XRefreshable and/or -- # XDocumentIndexesSupplier interfaces -- pass -- else: -- for i in range(0, indexes.getCount()): -- indexes.getByIndex(i).update() -- -- info(1, "Selected output format: %s" % outputfmt) -- info(2, "Selected office filter: %s" % outputfmt.filter) -- info(2, "Used doctype: %s" % outputfmt.doctype) -- -- ### Export phase -- phase = "export" -- -- outputprops = UnoProps(FilterName=outputfmt.filter, OutputStream=OutputStream(), Overwrite=True) -- -- ### Set default filter options -- if op.exportfilteroptions: --# print "Export filter options: %s" % op.exportfilteroptions -- outputprops += UnoProps(FilterOptions=op.exportfilteroptions) -- else: -- if outputfmt.filter == 'Text (encoded)': -- outputprops += UnoProps(FilterOptions="76,LF") -- -- elif outputfmt.filter == 'Text': -- outputprops += UnoProps(FilterOptions="76") -- -- elif outputfmt.filter == 'Text - txt - csv (StarCalc)': -- outputprops += UnoProps(FilterOptions="44,34,76") -- -- -- ### Cannot use UnoProps for FilterData property -- if op.exportfilter: -- outputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) -- -- if not op.stdout: -- (outputfn, ext) = os.path.splitext(inputfn) -- if not op.output: -- outputfn = outputfn + os.extsep + outputfmt.extension -- elif os.path.isdir(op.output): -- outputfn = realpath(op.output, os.path.basename(outputfn) + os.extsep + outputfmt.extension) -- elif len(op.filenames) > 1: -- outputfn = op.output + os.extsep + outputfmt.extension -- else: -- outputfn = op.output -- -- outputurl = unohelper.absolutize( self.cwd, unohelper.systemPathToFileUrl(outputfn) ) -- info(1, "Output file: %s" % outputfn) -- else: -- outputurl = "private:stream" -- -- try: -- document.storeToURL(outputurl, tuple(outputprops) ) -- except IOException, e: -- raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) -- -- phase = "dispose" -- document.dispose() -- document.close(True) -- -- except SystemError, e: -- error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) -- exitcode = 1 -- -- except RuntimeException, e: -- error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) -- exitcode = 6 -- -- except DisposedException, e: -- error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) -- exitcode = 7 -- -- except IllegalArgumentException, e: -- error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) -- exitcode = 8 -- -- except IOException, e: --# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) -- error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) -- exitcode = 3 -- -- except CannotConvertException, e: --# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) -- error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) -- exitcode = 4 -- -- except UnoException, e: -- if hasattr(e, 'ErrCode'): -- error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) -- exitcode = e.ErrCode -- pass -- if hasattr(e, 'Message'): -- error("unoconv: UnoException during %s phase:\n%s" % (phase, e.Message)) -- exitcode = 5 -- else: -- error("unoconv: UnoException during %s phase in %s" % (phase, repr(e.__class__))) -- exitcode = 2 -- pass -- --class Listener: -- def __init__(self): -- global product -- -- info(1, "Start listener on %s:%s" % (op.server, op.port)) -- self.context = uno.getComponentContext() -- self.svcmgr = self.context.ServiceManager -- try: -- resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) -- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) -- try: -- unocontext = resolver.resolve("uno:%s" % op.connection) -- except NoConnectException, e: -- pass -- else: -- info(1, "Existing %s listener found, nothing to do." % product.ooName) -- return -- if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): -- subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) -- else: -- subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) -- except Exception, e: -- error("Launch of %s failed.\n%s" % (office.binary, e)) -- else: -- info(1, "Existing %s listener found, nothing to do." % product.ooName) -- --def error(msg): -- "Output error message" -- print >>sys.stderr, msg -- --def info(level, msg): -- "Output info message" -- if 'op' not in globals(): -- pass -- elif op.verbose >= 3 and level >= 3: -- print >>sys.stderr, "DEBUG:", msg -- elif not op.stdout and level <= op.verbose: -- print >>sys.stdout, msg -- elif level <= op.verbose: -- print >>sys.stderr, msg -- --def die(ret, msg=None): -- "Print optional error and exit with errorcode" -- global convertor, ooproc, office -- -- if msg: -- error('Error: %s' % msg) -- -- ### Did we start our own listener instance ? -- if not op.listener and ooproc and convertor: -- -- ### If there is a GUI now attached to the instance, disable listener -- if convertor.desktop.getCurrentFrame(): -- info(2, 'Trying to stop %s GUI listener.' % product.ooName) -- try: -- if product.ooName != "LibreOffice" or product.ooSetupVersion <= 3.3: -- subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-unaccept=%s" % op.connection], env=os.environ) -- else: -- subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) -- ooproc.wait() -- info(2, '%s listener successfully disabled.' % product.ooName) -- except Exception, e: -- error("Terminate using %s failed.\n%s" % (office.binary, e)) -- -- ### If there is no GUI attached to the instance, terminate instance -- else: -- info(3, 'Terminating %s instance.' % product.ooName) -- try: -- convertor.desktop.terminate() -- except DisposedException: -- info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) -- try: -- ooproc.terminate() -- except AttributeError: -- os.kill(ooproc.pid, 15) -- info(3, 'Waiting for %s instance to exit.' % product.ooName) -- ooproc.wait() -- -- ### LibreOffice processes may get stuck and we have to kill them -- ### Is it still running ? -- if ooproc.poll() == None: -- info(1, '%s instance still running, please investigate...' % product.ooName) -- ooproc.wait() -- info(2, '%s instance unsuccessfully terminated, sending KILL signal.' % product.ooName) -- try: -- ooproc.kill() -- except AttributeError: -- os.kill(ooproc.pid, 9) -- info(3, 'Waiting for %s with pid %s to disappear.' % (ooproc.pid, product.ooName)) -- ooproc.wait() -- -- # allow Python GC to garbage collect pyuno object *before* exit call -- # which avoids random segmentation faults --vpa -- convertor = None -- -- sys.exit(ret) -- --def main(): -- global convertor, exitcode -- convertor = None -- -- try: -- if op.listener: -- listener = Listener() -- -- if op.filenames: -- convertor = Convertor() -- for inputfn in op.filenames: -- convertor.convert(inputfn) -- -- except NoConnectException, e: -- error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) -- if op.connection: -- info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) -- else: -- info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"socket,host=%s,port=%s;urp;\"" % (op.server, op.server, op.port, op.server, op.port)) -- info(0, "Please start an soffice instance on server '%s' by doing:\n\n soffice -nologo -nodefault -accept=\"socket,host=127.0.0.1,port=%s;urp;\"" % (op.server, op.port)) -- exitcode = 1 --# except UnboundLocalError: --# die(252, "Failed to connect to remote listener.") -- except OSError: -- error("Warning: failed to launch Office suite. Aborting.") -- --### Main entrance - if __name__ == '__main__': -- exitcode = 0 -- -- info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) -- -- for of in find_offices(): -- if of.python != sys.executable and not sys.executable.startswith(of.basepath): -- python_switch(of) -- office_environ(of) --# debug_office() -- try: -- import uno, unohelper -- office = of -- break -- except: --# debug_office() -- print >>sys.stderr, "unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of -- print >>sys.stderr, "ERROR:", sys.exc_info()[1] -- print >>sys.stderr -+ if sys.version_info < (3,0): -+ from unoconv2 import run - else: --# debug_office() -- print >>sys.stderr, "unoconv: Cannot find a suitable office installation on your system." -- print >>sys.stderr, "ERROR: Please locate your office installation and send your feedback to:" -- print >>sys.stderr, " http://github.com/dagwieers/unoconv/issues" -- sys.exit(1) -- -- ### Now that we have found a working pyuno library, let's import some classes -- from com.sun.star.beans import PropertyValue -- from com.sun.star.connection import NoConnectException -- from com.sun.star.document.UpdateDocMode import QUIET_UPDATE -- from com.sun.star.lang import DisposedException, IllegalArgumentException -- from com.sun.star.io import IOException, XOutputStream -- from com.sun.star.script import CannotConvertException -- from com.sun.star.uno import Exception as UnoException -- from com.sun.star.uno import RuntimeException -- -- ### And now that we have those classes, build on them -- class OutputStream( unohelper.Base, XOutputStream ): -- def __init__( self ): -- self.closed = 0 -- -- def closeOutput(self): -- self.closed = 1 -- -- def writeBytes( self, seq ): -- sys.stdout.write( seq.value ) -- -- def flush( self ): -- pass -- -- def UnoProps(**args): -- props = [] -- for key in args: -- prop = PropertyValue() -- prop.Name = key -- prop.Value = args[key] -- props.append(prop) -- return tuple(props) -- -- op = Options(sys.argv[1:]) -- -- info(2, "Using office base path: %s" % office.basepath) -- info(2, "Using office binary path: %s" % office.unopath) -+ from unoconv3 import run - -- try: -- main() -- except KeyboardInterrupt, e: -- die(6, 'Exiting on user request') -- die(exitcode) -+ run() -diff --git a/unoconv2.py b/unoconv2.py -new file mode 100755 -index 0000000..1aecbb6 ---- /dev/null -+++ b/unoconv2.py -@@ -0,0 +1,1195 @@ -+#!/usr/bin/python -+ -+### 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; version 2 only -+### -+### 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, write to the Free Software -+### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+### Copyright 2007-2010 Dag Wieers -+ -+from distutils.version import LooseVersion -+import getopt -+import glob -+import os -+import subprocess -+import sys -+import time -+ -+__version__ = "$Revision$" -+# $Source$ -+ -+VERSION = '0.6' -+ -+doctypes = ('document', 'graphics', 'presentation', 'spreadsheet') -+ -+global convertor, office, ooproc, product -+ooproc = None -+exitcode = 0 -+ -+class Office: -+ def __init__(self, basepath, urepath, unopath, pyuno, binary, python, pythonhome): -+ self.basepath = basepath -+ self.urepath = urepath -+ self.unopath = unopath -+ self.pyuno = pyuno -+ self.binary = binary -+ self.python = python -+ self.pythonhome = pythonhome -+ -+ def __str__(self): -+ return self.basepath -+ -+ def __repr__(self): -+ return self.basepath -+ -+### Implement a path normalizer in order to make unoconv work on MacOS X -+### (on which 'program' is a symlink to 'MacOSX' which seems to break unoconv) -+def realpath(*args): -+ ''' Implement a combination of os.path.join(), os.path.abspath() and -+ os.path.realpath() in order to normalize path constructions ''' -+ ret = '' -+ for arg in args: -+ ret = os.path.join(ret, arg) -+ return os.path.realpath(os.path.abspath(ret)) -+ -+### The first thing we ought to do is find a suitable Office installation -+### with a compatible pyuno library that we can import. -+### -+### See: http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p=166783 -+ -+def find_offices(): -+ ret = [] -+ extrapaths = [] -+ -+ ### Try using UNO_PATH first (in many incarnations, we'll see what sticks) -+ if 'UNO_PATH' in os.environ: -+ extrapaths += [ os.environ['UNO_PATH'], -+ os.path.dirname(os.environ['UNO_PATH']), -+ os.path.dirname(os.path.dirname(os.environ['UNO_PATH'])) ] -+ -+ else: -+ -+ if os.name in ( 'nt', 'os2' ): -+ if 'PROGRAMFILES' in os.environ.keys(): -+ extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ -+ glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') -+ -+ if 'PROGRAMFILES(X86)' in os.environ.keys(): -+ extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ -+ glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') -+ -+ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): -+ extrapaths += [ '/Applications/LibreOffice.app/Contents', -+ '/Applications/NeoOffice.app/Contents', -+ '/Applications/OpenOffice.org.app/Contents' ] -+ -+ else: -+ extrapaths += glob.glob('/usr/lib*/libreoffice*') + \ -+ glob.glob('/usr/lib*/openoffice*') + \ -+ glob.glob('/usr/lib*/ooo*') + \ -+ glob.glob('/opt/libreoffice*') + \ -+ glob.glob('/opt/openoffice*') + \ -+ glob.glob('/opt/ooo*') + \ -+ glob.glob('/usr/local/libreoffice*') + \ -+ glob.glob('/usr/local/openoffice*') + \ -+ glob.glob('/usr/local/ooo*') + \ -+ glob.glob('/usr/local/lib/libreoffice*') -+ -+ ### Find a working set for python UNO bindings -+ for basepath in extrapaths: -+ if os.name in ( 'nt', 'os2' ): -+ officelibraries = ( 'pyuno.pyd', ) -+ officebinaries = ( 'soffice.exe' ,) -+ pythonbinaries = ( 'python.exe', ) -+ pythonhomes = () -+ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): -+ officelibraries = ( 'pyuno.so', 'libpyuno.dylib' ) -+ officebinaries = ( 'soffice.bin', ) -+ pythonbinaries = ( 'python.bin', 'python' ) -+ pythonhomes = ( 'OOoPython.framework/Versions/*/lib/python*', ) -+ else: -+ officelibraries = ( 'pyuno.so', ) -+ officebinaries = ( 'soffice.bin', ) -+ pythonbinaries = ( 'python.bin', 'python', ) -+ pythonhomes = ( 'python-core-*', ) -+ -+ ### Older LibreOffice/OpenOffice and Windows use basis-link/ or basis/ -+ libpath = 'error' -+ for basis in ( 'basis-link', 'basis', '' ): -+ for lib in officelibraries: -+ if os.path.isfile(realpath(basepath, basis, 'program', lib)): -+ libpath = realpath(basepath, basis, 'program') -+ officelibrary = realpath(libpath, lib) -+ info(3, "Found %s in %s" % (lib, libpath)) -+ # Break the inner loop... -+ break -+ # Continue if the inner loop wasn't broken. -+ else: -+ continue -+ # Inner loop was broken, break the outer. -+ break -+ else: -+ continue -+ -+ ### MacOSX have soffice binaries installed in MacOS subdirectory, not program -+ unopath = 'error' -+ for basis in ( 'basis-link', 'basis', '' ): -+ for bin in officebinaries: -+ if os.path.isfile(realpath(basepath, basis, 'program', bin)): -+ unopath = realpath(basepath, basis, 'program') -+ officebinary = realpath(unopath, bin) -+ info(3, "Found %s in %s" % (bin, unopath)) -+ # Break the inner loop... -+ break -+ # Continue if the inner loop wasn't broken. -+ else: -+ continue -+ # Inner loop was broken, break the outer. -+ break -+ else: -+ continue -+ -+ ### Windows does not provide or need a URE/lib directory ? -+ urepath = '' -+ for basis in ( 'basis-link', 'basis', '' ): -+ for ure in ( 'ure-link', 'ure', 'URE', '' ): -+ if os.path.isfile(realpath(basepath, basis, ure, 'lib', 'unorc')): -+ urepath = realpath(basepath, basis, ure) -+ info(3, "Found %s in %s" % ('unorc', realpath(urepath, 'lib'))) -+ # Break the inner loop... -+ break -+ # Continue if the inner loop wasn't broken. -+ else: -+ continue -+ # Inner loop was broken, break the outer. -+ break -+ -+ pythonhome = None -+ for home in pythonhomes: -+ if glob.glob(realpath(libpath, home)): -+ pythonhome = glob.glob(realpath(libpath, home))[0] -+ info(3, "Found %s in %s" % (home, pythonhome)) -+ break -+ -+# if not os.path.isfile(realpath(basepath, program, officebinary)): -+# continue -+# info(3, "Found %s in %s" % (officebinary, realpath(basepath, program))) -+ -+# if not glob.glob(realpath(basepath, basis, program, 'python-core-*')): -+# continue -+ -+ for pythonbinary in pythonbinaries: -+ if os.path.isfile(realpath(unopath, pythonbinary)): -+ info(3, "Found %s in %s" % (pythonbinary, unopath)) -+ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, -+ realpath(unopath, pythonbinary), pythonhome)) -+ else: -+ info(3, "Considering %s" % basepath) -+ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, -+ sys.executable, None)) -+ return ret -+ -+def office_environ(office): -+ ### Set PATH so that crash_report is found -+ os.environ['PATH'] = realpath(office.basepath, 'program') + os.pathsep + os.environ['PATH'] -+ -+ ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: -+ os.environ['UNO_PATH'] = office.unopath -+ -+ ### Set URE_BOOTSTRAP so that "global_uno.getComponentContext()" bootstraps a complete -+ ### UNO environment -+ if os.name in ( 'nt', 'os2' ): -+ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') -+ else: -+ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamentalrc') -+ -+ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: -+ if 'LD_LIBRARY_PATH' in os.environ: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') + os.pathsep + \ -+ os.environ['LD_LIBRARY_PATH'] -+ else: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') -+ -+ if office.pythonhome: -+ for libpath in ( realpath(office.pythonhome, 'lib'), -+ realpath(office.pythonhome, 'lib', 'lib-dynload'), -+ realpath(office.pythonhome, 'lib', 'lib-tk'), -+ realpath(office.pythonhome, 'lib', 'site-packages'), -+ office.unopath): -+ sys.path.insert(0, libpath) -+ else: -+ ### Still needed for system python using LibreOffice UNO bindings -+ ### Although we prefer to use a system UNO binding in this case -+ sys.path.append(office.unopath) -+ -+def debug_office(): -+ if 'URE_BOOTSTRAP' in os.environ: -+ print >>sys.stderr, 'URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'] -+ if 'UNO_PATH' in os.environ: -+ print >>sys.stderr, 'UNO_PATH=%s' % os.environ['UNO_PATH'] -+ if 'UNO_TYPES' in os.environ: -+ print >>sys.stderr, 'UNO_TYPES=%s' % os.environ['UNO_TYPES'] -+ print 'PATH=%s' % os.environ['PATH'] -+ if 'PYTHONHOME' in os.environ: -+ print >>sys.stderr, 'PYTHONHOME=%s' % os.environ['PYTHONHOME'] -+ if 'PYTHONPATH' in os.environ: -+ print >>sys.stderr, 'PYTHONPATH=%s' % os.environ['PYTHONPATH'] -+ if 'LD_LIBRARY_PATH' in os.environ: -+ print >>sys.stderr, 'LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'] -+ -+def python_switch(office): -+ if office.pythonhome: -+ os.environ['PYTHONHOME'] = office.pythonhome -+ os.environ['PYTHONPATH'] = realpath(office.pythonhome, 'lib') + os.pathsep + \ -+ realpath(office.pythonhome, 'lib', 'lib-dynload') + os.pathsep + \ -+ realpath(office.pythonhome, 'lib', 'lib-tk') + os.pathsep + \ -+ realpath(office.pythonhome, 'lib', 'site-packages') + os.pathsep + \ -+ office.unopath -+ -+ os.environ['UNO_PATH'] = office.unopath -+ -+ info(3, "-> Switching from %s to %s" % (sys.executable, office.python)) -+ if os.name in ('nt', 'os2'): -+ ### os.execv is broken on Windows and can't properly parse command line -+ ### arguments and executable name if they contain whitespaces. subprocess -+ ### fixes that behavior. -+ ret = subprocess.call([office.python] + sys.argv[0:]) -+ sys.exit(ret) -+ else: -+ -+ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: -+ if 'LD_LIBRARY_PATH' in os.environ: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') + os.pathsep + \ -+ os.environ['LD_LIBRARY_PATH'] -+ else: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') -+ -+ try: -+ os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) -+ print(office.python, [office.python, ] + sys.argv[0:], osenviron) -+ except OSError: -+ ### Mac OS X versions prior to 10.6 do not support execv in -+ ### a process that contains multiple threads. Instead of -+ ### re-executing in the current process, start a new one -+ ### and cause the current process to exit. This isn't -+ ### ideal since the new process is detached from the parent -+ ### terminal and thus cannot easily be killed with ctrl-C, -+ ### but it's better than not being able to autoreload at -+ ### all. -+ ### Unfortunately the errno returned in this case does not -+ ### appear to be consistent, so we can't easily check for -+ ### this error specifically. -+ ret = os.spawnvpe(os.P_WAIT, office.python, [office.python, ] + sys.argv[0:], os.environ) -+ sys.exit(ret) -+ -+class Fmt: -+ def __init__(self, doctype, name, extension, summary, filter): -+ self.doctype = doctype -+ self.name = name -+ self.extension = extension -+ self.summary = summary -+ self.filter = filter -+ -+ def __str__(self): -+ return "%s [.%s]" % (self.summary, self.extension) -+ -+ def __repr__(self): -+ return "%s/%s" % (self.name, self.doctype) -+ -+class FmtList: -+ def __init__(self): -+ self.list = [] -+ -+ def add(self, doctype, name, extension, summary, filter): -+ self.list.append(Fmt(doctype, name, extension, summary, filter)) -+ -+ def byname(self, name): -+ ret = [] -+ for fmt in self.list: -+ if fmt.name == name: -+ ret.append(fmt) -+ return ret -+ -+ def byextension(self, extension): -+ ret = [] -+ for fmt in self.list: -+ if os.extsep + fmt.extension == extension: -+ ret.append(fmt) -+ return ret -+ -+ def bydoctype(self, doctype, name): -+ ret = [] -+ for fmt in self.list: -+ if fmt.name == name and fmt.doctype == doctype: -+ ret.append(fmt) -+ return ret -+ -+ def display(self, doctype): -+ print >>sys.stderr, "The following list of %s formats are currently available:\n" % doctype -+ for fmt in self.list: -+ if fmt.doctype == doctype: -+ print >>sys.stderr, " %-8s - %s" % (fmt.name, fmt) -+ print >>sys.stderr -+ -+fmts = FmtList() -+ -+### TextDocument -+fmts.add('document', 'bib', 'bib', 'BibTeX', 'BibTeX_Writer') ### 22 -+fmts.add('document', 'doc', 'doc', 'Microsoft Word 97/2000/XP', 'MS Word 97') ### 29 -+fmts.add('document', 'doc6', 'doc', 'Microsoft Word 6.0', 'MS WinWord 6.0') ### 24 -+fmts.add('document', 'doc95', 'doc', 'Microsoft Word 95', 'MS Word 95') ### 28 -+fmts.add('document', 'docbook', 'xml', 'DocBook', 'DocBook File') ### 39 -+fmts.add('document', 'docx', 'docx', 'Microsoft Office Open XML', 'Office Open XML Text') -+fmts.add('document', 'docx7', 'docx', 'Microsoft Office Open XML', 'MS Word 2007 XML') -+fmts.add('document', 'fodt', 'fodt', 'OpenDocument Text (Flat XML)', 'OpenDocument Text Flat XML') -+fmts.add('document', 'html', 'html', 'HTML Document (OpenOffice.org Writer)', 'HTML (StarWriter)') ### 3 -+fmts.add('document', 'latex', 'ltx', 'LaTeX 2e', 'LaTeX_Writer') ### 31 -+fmts.add('document', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki') -+fmts.add('document', 'odt', 'odt', 'ODF Text Document', 'writer8') ### 10 -+fmts.add('document', 'ooxml', 'xml', 'Microsoft Office Open XML', 'MS Word 2003 XML') ### 11 -+fmts.add('document', 'ott', 'ott', 'Open Document Text', 'writer8_template') ### 21 -+fmts.add('document', 'pdb', 'pdb', 'AportisDoc (Palm)', 'AportisDoc Palm DB') -+fmts.add('document', 'pdf', 'pdf', 'Portable Document Format', 'writer_pdf_Export') ### 18 -+fmts.add('document', 'psw', 'psw', 'Pocket Word', 'PocketWord File') -+fmts.add('document', 'rtf', 'rtf', 'Rich Text Format', 'Rich Text Format') ### 16 -+fmts.add('document', 'sdw', 'sdw', 'StarWriter 5.0', 'StarWriter 5.0') ### 23 -+fmts.add('document', 'sdw4', 'sdw', 'StarWriter 4.0', 'StarWriter 4.0') ### 2 -+fmts.add('document', 'sdw3', 'sdw', 'StarWriter 3.0', 'StarWriter 3.0') ### 20 -+fmts.add('document', 'stw', 'stw', 'Open Office.org 1.0 Text Document Template', 'writer_StarOffice_XML_Writer_Template') ### 9 -+fmts.add('document', 'sxw', 'sxw', 'Open Office.org 1.0 Text Document', 'StarOffice XML (Writer)') ### 1 -+fmts.add('document', 'text', 'txt', 'Text Encoded', 'Text (encoded)') ### 26 -+fmts.add('document', 'txt', 'txt', 'Text', 'Text') ### 34 -+fmts.add('document', 'uot', 'uot', 'Unified Office Format text','UOF text') ### 27 -+fmts.add('document', 'vor', 'vor', 'StarWriter 5.0 Template', 'StarWriter 5.0 Vorlage/Template') ### 6 -+fmts.add('document', 'vor4', 'vor', 'StarWriter 4.0 Template', 'StarWriter 4.0 Vorlage/Template') ### 5 -+fmts.add('document', 'vor3', 'vor', 'StarWriter 3.0 Template', 'StarWriter 3.0 Vorlage/Template') ### 4 -+fmts.add('document', 'xhtml', 'html', 'XHTML Document', 'XHTML Writer File') ### 33 -+ -+### WebDocument -+fmts.add('web', 'etext', 'txt', 'Text Encoded (OpenOffice.org Writer/Web)', 'Text (encoded) (StarWriter/Web)') ### 14 -+fmts.add('web', 'html10', 'html', 'OpenOffice.org 1.0 HTML Template', 'writer_web_StarOffice_XML_Writer_Web_Template') ### 11 -+fmts.add('web', 'html', 'html', 'HTML Document', 'HTML') ### 2 -+fmts.add('web', 'html', 'html', 'HTML Document Template', 'writerweb8_writer_template') ### 13 -+fmts.add('web', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki_Web') ### 9 -+fmts.add('web', 'pdf', 'pdf', 'PDF - Portable Document Format', 'writer_web_pdf_Export') ### 10 -+fmts.add('web', 'sdw3', 'sdw', 'StarWriter 3.0 (OpenOffice.org Writer/Web)', 'StarWriter 3.0 (StarWriter/Web)') ### 3 -+fmts.add('web', 'sdw4', 'sdw', 'StarWriter 4.0 (OpenOffice.org Writer/Web)', 'StarWriter 4.0 (StarWriter/Web)') ### 4 -+fmts.add('web', 'sdw', 'sdw', 'StarWriter 5.0 (OpenOffice.org Writer/Web)', 'StarWriter 5.0 (StarWriter/Web)') ### 5 -+fmts.add('web', 'txt', 'txt', 'OpenOffice.org Text (OpenOffice.org Writer/Web)', 'writerweb8_writer') ### 12 -+fmts.add('web', 'text10', 'txt', 'OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)', 'writer_web_StarOffice_XML_Writer') ### 15 -+fmts.add('web', 'text', 'txt', 'Text (OpenOffice.org Writer/Web)', 'Text (StarWriter/Web)') ### 8 -+fmts.add('web', 'vor4', 'vor', 'StarWriter/Web 4.0 Template', 'StarWriter/Web 4.0 Vorlage/Template') ### 6 -+fmts.add('web', 'vor', 'vor', 'StarWriter/Web 5.0 Template', 'StarWriter/Web 5.0 Vorlage/Template') ### 7 -+ -+### Spreadsheet -+fmts.add('spreadsheet', 'csv', 'csv', 'Text CSV', 'Text - txt - csv (StarCalc)') ### 16 -+fmts.add('spreadsheet', 'dbf', 'dbf', 'dBASE', 'dBase') ### 22 -+fmts.add('spreadsheet', 'dif', 'dif', 'Data Interchange Format', 'DIF') ### 5 -+fmts.add('spreadsheet', 'fods', 'fods', 'OpenDocument Spreadsheet (Flat XML)', 'OpenDocument Spreadsheet Flat XML') -+fmts.add('spreadsheet', 'html', 'html', 'HTML Document (OpenOffice.org Calc)', 'HTML (StarCalc)') ### 7 -+fmts.add('spreadsheet', 'ods', 'ods', 'ODF Spreadsheet', 'calc8') ### 15 -+fmts.add('spreadsheet', 'ooxml', 'xml', 'Microsoft Excel 2003 XML', 'MS Excel 2003 XML') ### 23 -+fmts.add('spreadsheet', 'ots', 'ots', 'ODF Spreadsheet Template', 'calc8_template') ### 14 -+fmts.add('spreadsheet', 'pdf', 'pdf', 'Portable Document Format', 'calc_pdf_Export') ### 34 -+fmts.add('spreadsheet', 'pxl', 'pxl', 'Pocket Excel', 'Pocket Excel') -+fmts.add('spreadsheet', 'sdc', 'sdc', 'StarCalc 5.0', 'StarCalc 5.0') ### 31 -+fmts.add('spreadsheet', 'sdc4', 'sdc', 'StarCalc 4.0', 'StarCalc 4.0') ### 11 -+fmts.add('spreadsheet', 'sdc3', 'sdc', 'StarCalc 3.0', 'StarCalc 3.0') ### 29 -+fmts.add('spreadsheet', 'slk', 'slk', 'SYLK', 'SYLK') ### 35 -+fmts.add('spreadsheet', 'stc', 'stc', 'OpenOffice.org 1.0 Spreadsheet Template', 'calc_StarOffice_XML_Calc_Template') ### 2 -+fmts.add('spreadsheet', 'sxc', 'sxc', 'OpenOffice.org 1.0 Spreadsheet', 'StarOffice XML (Calc)') ### 3 -+fmts.add('spreadsheet', 'uos', 'uos', 'Unified Office Format spreadsheet', 'UOF spreadsheet') ### 9 -+fmts.add('spreadsheet', 'vor3', 'vor', 'StarCalc 3.0 Template', 'StarCalc 3.0 Vorlage/Template') ### 18 -+fmts.add('spreadsheet', 'vor4', 'vor', 'StarCalc 4.0 Template', 'StarCalc 4.0 Vorlage/Template') ### 19 -+fmts.add('spreadsheet', 'vor', 'vor', 'StarCalc 5.0 Template', 'StarCalc 5.0 Vorlage/Template') ### 20 -+fmts.add('spreadsheet', 'xhtml', 'xhtml', 'XHTML', 'XHTML Calc File') ### 26 -+fmts.add('spreadsheet', 'xls', 'xls', 'Microsoft Excel 97/2000/XP', 'MS Excel 97') ### 12 -+fmts.add('spreadsheet', 'xls5', 'xls', 'Microsoft Excel 5.0', 'MS Excel 5.0/95') ### 8 -+fmts.add('spreadsheet', 'xls95', 'xls', 'Microsoft Excel 95', 'MS Excel 95') ### 10 -+fmts.add('spreadsheet', 'xlt', 'xlt', 'Microsoft Excel 97/2000/XP Template', 'MS Excel 97 Vorlage/Template') ### 6 -+fmts.add('spreadsheet', 'xlt5', 'xlt', 'Microsoft Excel 5.0 Template', 'MS Excel 5.0/95 Vorlage/Template') ### 28 -+fmts.add('spreadsheet', 'xlt95', 'xlt', 'Microsoft Excel 95 Template', 'MS Excel 95 Vorlage/Template') ### 21 -+ -+### Graphics -+fmts.add('graphics', 'bmp', 'bmp', 'Windows Bitmap', 'draw_bmp_Export') ### 21 -+fmts.add('graphics', 'emf', 'emf', 'Enhanced Metafile', 'draw_emf_Export') ### 15 -+fmts.add('graphics', 'eps', 'eps', 'Encapsulated PostScript', 'draw_eps_Export') ### 48 -+fmts.add('graphics', 'fodg', 'fodg', 'OpenDocument Drawing (Flat XML)', 'OpenDocument Drawing Flat XML') -+fmts.add('graphics', 'gif', 'gif', 'Graphics Interchange Format', 'draw_gif_Export') ### 30 -+fmts.add('graphics', 'html', 'html', 'HTML Document (OpenOffice.org Draw)', 'draw_html_Export') ### 37 -+fmts.add('graphics', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'draw_jpg_Export') ### 3 -+fmts.add('graphics', 'met', 'met', 'OS/2 Metafile', 'draw_met_Export') ### 43 -+fmts.add('graphics', 'odd', 'odd', 'OpenDocument Drawing', 'draw8') ### 6 -+fmts.add('graphics', 'otg', 'otg', 'OpenDocument Drawing Template', 'draw8_template') ### 20 -+fmts.add('graphics', 'pbm', 'pbm', 'Portable Bitmap', 'draw_pbm_Export') ### 14 -+fmts.add('graphics', 'pct', 'pct', 'Mac Pict', 'draw_pct_Export') ### 41 -+fmts.add('graphics', 'pdf', 'pdf', 'Portable Document Format', 'draw_pdf_Export') ### 28 -+fmts.add('graphics', 'pgm', 'pgm', 'Portable Graymap', 'draw_pgm_Export') ### 11 -+fmts.add('graphics', 'png', 'png', 'Portable Network Graphic', 'draw_png_Export') ### 2 -+fmts.add('graphics', 'ppm', 'ppm', 'Portable Pixelmap', 'draw_ppm_Export') ### 5 -+fmts.add('graphics', 'ras', 'ras', 'Sun Raster Image', 'draw_ras_Export') ## 31 -+fmts.add('graphics', 'std', 'std', 'OpenOffice.org 1.0 Drawing Template', 'draw_StarOffice_XML_Draw_Template') ### 53 -+fmts.add('graphics', 'svg', 'svg', 'Scalable Vector Graphics', 'draw_svg_Export') ### 50 -+fmts.add('graphics', 'svm', 'svm', 'StarView Metafile', 'draw_svm_Export') ### 55 -+fmts.add('graphics', 'swf', 'swf', 'Macromedia Flash (SWF)', 'draw_flash_Export') ### 23 -+fmts.add('graphics', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing', 'StarOffice XML (Draw)') ### 26 -+fmts.add('graphics', 'sxd3', 'sxd', 'StarDraw 3.0', 'StarDraw 3.0') ### 40 -+fmts.add('graphics', 'sxd5', 'sxd', 'StarDraw 5.0', 'StarDraw 5.0') ### 44 -+fmts.add('graphics', 'sxw', 'sxw', 'StarOffice XML (Draw)', 'StarOffice XML (Draw)') -+fmts.add('graphics', 'tiff', 'tiff', 'Tagged Image File Format', 'draw_tif_Export') ### 13 -+fmts.add('graphics', 'vor', 'vor', 'StarDraw 5.0 Template', 'StarDraw 5.0 Vorlage') ### 36 -+fmts.add('graphics', 'vor3', 'vor', 'StarDraw 3.0 Template', 'StarDraw 3.0 Vorlage') ### 35 -+fmts.add('graphics', 'wmf', 'wmf', 'Windows Metafile', 'draw_wmf_Export') ### 8 -+fmts.add('graphics', 'xhtml', 'xhtml', 'XHTML', 'XHTML Draw File') ### 45 -+fmts.add('graphics', 'xpm', 'xpm', 'X PixMap', 'draw_xpm_Export') ### 19 -+ -+### Presentation -+fmts.add('presentation', 'bmp', 'bmp', 'Windows Bitmap', 'impress_bmp_Export') ### 15 -+fmts.add('presentation', 'emf', 'emf', 'Enhanced Metafile', 'impress_emf_Export') ### 16 -+fmts.add('presentation', 'eps', 'eps', 'Encapsulated PostScript', 'impress_eps_Export') ### 17 -+fmts.add('presentation', 'fodp', 'fodp', 'OpenDocument Presentation (Flat XML)', 'OpenDocument Presentation Flat XML') -+fmts.add('presentation', 'gif', 'gif', 'Graphics Interchange Format', 'impress_gif_Export') ### 18 -+fmts.add('presentation', 'html', 'html', 'HTML Document (OpenOffice.org Impress)', 'impress_html_Export') ### 43 -+fmts.add('presentation', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'impress_jpg_Export') ### 19 -+fmts.add('presentation', 'met', 'met', 'OS/2 Metafile', 'impress_met_Export') ### 20 -+fmts.add('presentation', 'odg', 'odg', 'ODF Drawing (Impress)', 'impress8_draw') ### 29 -+fmts.add('presentation', 'odp', 'odp', 'ODF Presentation', 'impress8') ### 9 -+fmts.add('presentation', 'otp', 'otp', 'ODF Presentation Template', 'impress8_template') ### 38 -+fmts.add('presentation', 'pbm', 'pbm', 'Portable Bitmap', 'impress_pbm_Export') ### 21 -+fmts.add('presentation', 'pct', 'pct', 'Mac Pict', 'impress_pct_Export') ### 22 -+fmts.add('presentation', 'pdf', 'pdf', 'Portable Document Format', 'impress_pdf_Export') ### 23 -+fmts.add('presentation', 'pgm', 'pgm', 'Portable Graymap', 'impress_pgm_Export') ### 24 -+fmts.add('presentation', 'png', 'png', 'Portable Network Graphic', 'impress_png_Export') ### 25 -+fmts.add('presentation', 'potm', 'potm', 'Microsoft PowerPoint 2007/2010 XML Template', 'Impress MS PowerPoint 2007 XML Template') -+fmts.add('presentation', 'pot', 'pot', 'Microsoft PowerPoint 97/2000/XP Template', 'MS PowerPoint 97 Vorlage') ### 3 -+fmts.add('presentation', 'ppm', 'ppm', 'Portable Pixelmap', 'impress_ppm_Export') ### 26 -+fmts.add('presentation', 'pptx', 'pptx', 'Microsoft PowerPoint 2007/2010 XML', 'Impress MS PowerPoint 2007 XML') ### 36 -+fmts.add('presentation', 'pps', 'pps', 'Microsoft PowerPoint 97/2000/XP (Autoplay)', 'MS PowerPoint 97 Autoplay') ### 36 -+fmts.add('presentation', 'ppt', 'ppt', 'Microsoft PowerPoint 97/2000/XP', 'MS PowerPoint 97') ### 36 -+fmts.add('presentation', 'pwp', 'pwp', 'PlaceWare', 'placeware_Export') ### 30 -+fmts.add('presentation', 'ras', 'ras', 'Sun Raster Image', 'impress_ras_Export') ### 27 -+fmts.add('presentation', 'sda', 'sda', 'StarDraw 5.0 (OpenOffice.org Impress)', 'StarDraw 5.0 (StarImpress)') ### 8 -+fmts.add('presentation', 'sdd', 'sdd', 'StarImpress 5.0', 'StarImpress 5.0') ### 6 -+fmts.add('presentation', 'sdd3', 'sdd', 'StarDraw 3.0 (OpenOffice.org Impress)', 'StarDraw 3.0 (StarImpress)') ### 42 -+fmts.add('presentation', 'sdd4', 'sdd', 'StarImpress 4.0', 'StarImpress 4.0') ### 37 -+fmts.add('presentation', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)', 'impress_StarOffice_XML_Draw') ### 31 -+fmts.add('presentation', 'sti', 'sti', 'OpenOffice.org 1.0 Presentation Template', 'impress_StarOffice_XML_Impress_Template') ### 5 -+fmts.add('presentation', 'svg', 'svg', 'Scalable Vector Graphics', 'impress_svg_Export') ### 14 -+fmts.add('presentation', 'svm', 'svm', 'StarView Metafile', 'impress_svm_Export') ### 13 -+fmts.add('presentation', 'swf', 'swf', 'Macromedia Flash (SWF)', 'impress_flash_Export') ### 34 -+fmts.add('presentation', 'sxi', 'sxi', 'OpenOffice.org 1.0 Presentation', 'StarOffice XML (Impress)') ### 41 -+fmts.add('presentation', 'tiff', 'tiff', 'Tagged Image File Format', 'impress_tif_Export') ### 12 -+fmts.add('presentation', 'uop', 'uop', 'Unified Office Format presentation', 'UOF presentation') ### 4 -+fmts.add('presentation', 'vor', 'vor', 'StarImpress 5.0 Template', 'StarImpress 5.0 Vorlage') ### 40 -+fmts.add('presentation', 'vor3', 'vor', 'StarDraw 3.0 Template (OpenOffice.org Impress)', 'StarDraw 3.0 Vorlage (StarImpress)') ###1 -+fmts.add('presentation', 'vor4', 'vor', 'StarImpress 4.0 Template', 'StarImpress 4.0 Vorlage') ### 39 -+fmts.add('presentation', 'vor5', 'vor', 'StarDraw 5.0 Template (OpenOffice.org Impress)', 'StarDraw 5.0 Vorlage (StarImpress)') ### 2 -+fmts.add('presentation', 'wmf', 'wmf', 'Windows Metafile', 'impress_wmf_Export') ### 11 -+fmts.add('presentation', 'xhtml', 'xml', 'XHTML', 'XHTML Impress File') ### 33 -+fmts.add('presentation', 'xpm', 'xpm', 'X PixMap', 'impress_xpm_Export') ### 10 -+ -+class Options: -+ def __init__(self, args): -+ self.connection = None -+ self.debug = False -+ self.doctype = None -+ self.exportfilter = [] -+ self.exportfilteroptions = "" -+ self.filenames = [] -+ self.format = None -+ self.importfilter = [] -+ self.importfilteroptions = "" -+ self.listener = False -+ self.nolaunch = False -+ self.output = None -+ self.password = None -+ self.pipe = None -+ self.port = '2002' -+ self.server = '127.0.0.1' -+ self.showlist = False -+ self.stdout = False -+ self.template = None -+ self.timeout = 6 -+ self.verbose = 0 -+ -+ ### Get options from the commandline -+ try: -+ opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', -+ ['connection=', 'debug', 'doctype=', 'export=', 'format=', -+ 'help', 'import', 'listener', 'no-launch', 'output=', -+ 'outputpath', 'password=', 'pipe=', 'port=', 'server=', -+ 'timeout=', 'show', 'stdout', 'template', 'verbose', -+ 'version'] ) -+ except getopt.error, exc: -+ print 'unoconv: %s, try unoconv -h for a list of all the options' % str(exc) -+ sys.exit(255) -+ -+ for opt, arg in opts: -+ if opt in ['-h', '--help']: -+ self.usage() -+ print -+ self.help() -+ sys.exit(1) -+ elif opt in ['-c', '--connection']: -+ self.connection = arg -+ elif opt in ['--debug']: -+ self.debug = True -+ elif opt in ['-d', '--doctype']: -+ self.doctype = arg -+ elif opt in ['-e', '--export']: -+ l = arg.split('=') -+ if len(l) == 2: -+ (name, value) = l -+ if name in ('FilterOptions'): -+ self.exportfilteroptions = value -+ elif value in ('True', 'true'): -+ self.exportfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) -+ elif value in ('False', 'false'): -+ self.exportfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) -+ else: -+ try: -+ self.exportfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) -+ except ValueError: -+ self.exportfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) -+ else: -+ print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg -+ elif opt in ['-f', '--format']: -+ self.format = arg -+ elif opt in ['-i', '--import']: -+ l = arg.split('=') -+ if len(l) == 2: -+ (name, value) = l -+ if name in ('FilterOptions'): -+ self.importfilteroptions = value -+ elif value in ('True', 'true'): -+ self.importfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) -+ elif value in ('False', 'false'): -+ self.importfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) -+ else: -+ try: -+ self.importfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) -+ except ValueError: -+ self.importfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) -+ else: -+ print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg -+ elif opt in ['-l', '--listener']: -+ self.listener = True -+ elif opt in ['-n', '--no-launch']: -+ self.nolaunch = True -+ elif opt in ['-o', '--output']: -+ self.output = arg -+ elif opt in ['--outputpath']: -+ print >>sys.stderr, 'Warning: This option is deprecated by --output.' -+ self.output = arg -+ elif opt in ['--password']: -+ self.password = arg -+ elif opt in ['--pipe']: -+ self.pipe = arg -+ elif opt in ['-p', '--port']: -+ self.port = arg -+ elif opt in ['-s', '--server']: -+ self.server = arg -+ elif opt in ['--show']: -+ self.showlist = True -+ elif opt in ['--stdout']: -+ self.stdout = True -+ elif opt in ['-t', '--template']: -+ self.template = arg -+ elif opt in ['-T', '--timeout']: -+ self.timeout = int(arg) -+ elif opt in ['-v', '--verbose']: -+ self.verbose = self.verbose + 1 -+ elif opt in ['-V', '--version']: -+ self.version() -+ sys.exit(255) -+ -+ ### Enable verbosity -+ if self.verbose >= 2: -+ print >>sys.stderr, 'Verbosity set to level %d' % self.verbose -+ -+ self.filenames = args -+ -+ if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: -+ print >>sys.stderr, 'unoconv: you have to provide a filename as argument' -+ print >>sys.stderr, 'Try `unoconv -h\' for more information.' -+ sys.exit(255) -+ -+ ### Set connection string -+ if not self.connection: -+ if not self.pipe: -+ self.connection = "socket,host=%s,port=%s;urp;StarOffice.ComponentContext" % (self.server, self.port) -+# self.connection = "socket,host=%s,port=%s;urp;" % (self.server, self.port) -+ else: -+ self.connection = "pipe,name=%s;urp;StarOffice.ComponentContext" % (self.pipe) -+ -+ ### Make it easier for people to use a doctype (first letter is enough) -+ if self.doctype: -+ for doctype in doctypes: -+ if doctype.startswith(self.doctype): -+ self.doctype = doctype -+ -+ ### Check if the user request to see the list of formats -+ if self.showlist or self.format == 'list': -+ if self.doctype: -+ fmts.display(self.doctype) -+ else: -+ for t in doctypes: -+ fmts.display(t) -+ sys.exit(0) -+ -+ ### If no format was specified, probe it or provide it -+ if not self.format: -+ l = sys.argv[0].split('2') -+ if len(l) == 2: -+ self.format = l[1] -+ else: -+ self.format = 'pdf' -+ -+ def version(self): -+ ### Get office product information -+ product = global_uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) -+ -+ print 'unoconv %s' % VERSION -+ print 'Written by Dag Wieers ' -+ print 'Homepage at http://dag.wieers.com/home-made/unoconv/' -+ print -+ print 'platform %s/%s' % (os.name, sys.platform) -+ print 'python %s' % sys.version -+ print product.ooName, product.ooSetupVersion -+# print -+# print 'build revision $Rev$' -+ -+ def usage(self): -+ print >>sys.stderr, 'usage: unoconv [options] file [file2 ..]' -+ -+ def help(self): -+ print >>sys.stderr, '''Convert from and to any format supported by LibreOffice -+ -+unoconv options: -+ -c, --connection=string use a custom connection string -+ -d, --doctype=type specify document type -+ (document, graphics, presentation, spreadsheet) -+ -e, --export=name=value set export filter options -+ eg. -e PageRange=1-2 -+ -f, --format=format specify the output format -+ -i, --import=string set import filter option string -+ eg. -i utf8 -+ -l, --listener start a permanent listener to use by unoconv clients -+ -n, --no-launch fail if no listener is found (default: launch one) -+ -o, --output=name output basename, filename or directory -+ --pipe=name alternative method of connection using a pipe -+ -p, --port=port specify the port (default: 2002) -+ to be used by client or listener -+ --password=string provide a password to decrypt the document -+ -s, --server=server specify the server address (default: 127.0.0.1) -+ to be used by client or listener -+ --show list the available output formats -+ --stdout write output to stdout -+ -t, --template=file import the styles from template (.ott) -+ -T, --timeout=secs timeout after secs if connection to listener fails -+ -v, --verbose be more and more verbose (-vvv for debugging) -+''' -+ -+class Convertor: -+ def __init__(self): -+ global exitcode, ooproc, office, product -+ unocontext = None -+ -+ ### Do the LibreOffice component dance -+ self.context = global_uno.getComponentContext() -+ self.svcmgr = self.context.ServiceManager -+ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) -+ -+ ### Test for an existing connection -+ info(3, 'Connection type: %s' % op.connection) -+ try: -+ unocontext = resolver.resolve("uno:%s" % op.connection) -+ except UnoNoConnectException, e: -+# info(3, "Existing listener not found.\n%s" % e) -+ info(3, "Existing listener not found.") -+ -+ if op.nolaunch: -+ die(113, "Existing listener not found. Unable start listener by parameters. Aborting.") -+ -+ ### Start our own OpenOffice instance -+ info(3, "Launching our own listener using %s." % office.binary) -+ try: -+ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) -+ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): -+ ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) -+ else: -+ ooproc = subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--accept=%s" % op.connection], env=os.environ) -+ info(2, '%s listener successfully started. (pid=%s)' % (product.ooName, ooproc.pid)) -+ -+ ### Try connection to it for op.timeout seconds (flakky OpenOffice) -+ timeout = 0 -+ while timeout <= op.timeout: -+ ### Is it already/still running ? -+ retcode = ooproc.poll() -+ if retcode != None: -+ info(3, "Process %s (pid=%s) exited with %s." % (office.binary, ooproc.pid, retcode)) -+ break -+ try: -+ unocontext = resolver.resolve("uno:%s" % op.connection) -+ break -+ except UnoNoConnectException: -+ time.sleep(0.5) -+ timeout += 0.5 -+ except: -+ raise -+ else: -+ error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) -+ except Exception, e: -+ raise -+ error("Launch of %s failed.\n%s" % (office.binary, e)) -+ -+ if not unocontext: -+ die(251, "Unable to connect or start own listener. Aborting.") -+ -+ ### And some more LibreOffice magic -+ unosvcmgr = unocontext.ServiceManager -+ self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) -+ self.cwd = global_unohelper.systemPathToFileUrl( os.getcwd() ) -+ -+ ### List all filters -+# self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) -+# for filter in self.filters.getElementNames(): -+# print filter -+# #print dir(filter), dir(filter.format) -+ -+ def getformat(self, inputfn): -+ doctype = None -+ -+ ### Get the output format from mapping -+ if op.doctype: -+ outputfmt = fmts.bydoctype(op.doctype, op.format) -+ else: -+ outputfmt = fmts.byname(op.format) -+ -+ if not outputfmt: -+ outputfmt = fmts.byextension(os.extsep + op.format) -+ -+ ### If no doctype given, check list of acceptable formats for input file ext doctype -+ ### FIXME: This should go into the for-loop to match each individual input filename -+ if outputfmt: -+ inputext = os.path.splitext(inputfn)[1] -+ inputfmt = fmts.byextension(inputext) -+ if inputfmt: -+ for fmt in outputfmt: -+ if inputfmt[0].doctype == fmt.doctype: -+ doctype = inputfmt[0].doctype -+ outputfmt = fmt -+ break -+ else: -+ outputfmt = outputfmt[0] -+ # print >>sys.stderr, 'unoconv: format `%s\' is part of multiple doctypes %s, selecting `%s\'.' % (format, [fmt.doctype for fmt in outputfmt], outputfmt[0].doctype) -+ else: -+ outputfmt = outputfmt[0] -+ -+ ### No format found, throw error -+ if not outputfmt: -+ if doctype: -+ print >>sys.stderr, 'unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format) -+ else: -+ print >>sys.stderr, 'unoconv: format [%s] is not known to unoconv.' % op.format -+ die(1) -+ -+ return outputfmt -+ -+ def convert(self, inputfn): -+ global exitcode -+ -+ document = None -+ outputfmt = self.getformat(inputfn) -+ -+ if op.verbose > 0: -+ print >>sys.stderr, 'Input file:', inputfn -+ -+ if not os.path.exists(inputfn): -+ print >>sys.stderr, 'unoconv: file `%s\' does not exist.' % inputfn -+ exitcode = 1 -+ -+ try: -+ ### Import phase -+ phase = "import" -+ -+ ### Load inputfile -+ inputprops = GlobalUnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=UNO_QUIET_UPDATE) -+ -+# if op.password: -+# info = GlobalUnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") -+# inputprops += GlobalUnoProps(ModifyPasswordInfo=info) -+ -+ ### Cannot use GlobalUnoProps for FilterData property -+ if op.importfilteroptions: -+# print "Import filter options: %s" % op.importfilteroptions -+ inputprops += GlobalUnoProps(FilterOptions=op.importfilteroptions) -+ -+ ### Cannot use GlobalUnoProps for FilterData property -+ if op.importfilter: -+ inputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) -+ -+ inputurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(inputfn)) -+ document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) -+ -+ if not document: -+ raise UnoException("The document '%s' could not be opened." % inputurl, None) -+ -+ ### Import style template -+ phase = "import-style" -+ if op.template: -+ if os.path.exists(op.template): -+ info(1, "Template file: %s" % op.template) -+ templateprops = GlobalUnoProps(OverwriteStyles=True) -+ templateurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(op.template)) -+ document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) -+ else: -+ print >>sys.stderr, 'unoconv: template file `%s\' does not exist.' % op.template -+ exitcode = 1 -+ -+ ### Update document links -+ phase = "update-links" -+ try: -+ document.updateLinks() -+ except AttributeError: -+ # the document doesn't implement the XLinkUpdate interface -+ pass -+ -+ ### Update document indexes -+ phase = "update-indexes" -+ try: -+ document.refresh() -+ indexes = document.getDocumentIndexes() -+ except AttributeError: -+ # the document doesn't implement the XRefreshable and/or -+ # XDocumentIndexesSupplier interfaces -+ pass -+ else: -+ for i in range(0, indexes.getCount()): -+ indexes.getByIndex(i).update() -+ -+ info(1, "Selected output format: %s" % outputfmt) -+ info(2, "Selected office filter: %s" % outputfmt.filter) -+ info(2, "Used doctype: %s" % outputfmt.doctype) -+ -+ ### Export phase -+ phase = "export" -+ -+ outputprops = GlobalUnoProps(FilterName=outputfmt.filter, OutputStream=GlobalOutputStream(), Overwrite=True) -+ -+ ### Set default filter options -+ if op.exportfilteroptions: -+# print "Export filter options: %s" % op.exportfilteroptions -+ outputprops += GlobalUnoProps(FilterOptions=op.exportfilteroptions) -+ else: -+ if outputfmt.filter == 'Text (encoded)': -+ outputprops += GlobalUnoProps(FilterOptions="76,LF") -+ -+ elif outputfmt.filter == 'Text': -+ outputprops += GlobalUnoProps(FilterOptions="76") -+ -+ elif outputfmt.filter == 'Text - txt - csv (StarCalc)': -+ outputprops += GlobalUnoProps(FilterOptions="44,34,76") -+ -+ -+ ### Cannot use GlobalUnoProps for FilterData property -+ if op.exportfilter: -+ outputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) -+ -+ if not op.stdout: -+ (outputfn, ext) = os.path.splitext(inputfn) -+ if not op.output: -+ outputfn = outputfn + os.extsep + outputfmt.extension -+ elif os.path.isdir(op.output): -+ outputfn = realpath(op.output, os.path.basename(outputfn) + os.extsep + outputfmt.extension) -+ elif len(op.filenames) > 1: -+ outputfn = op.output + os.extsep + outputfmt.extension -+ else: -+ outputfn = op.output -+ -+ outputurl = global_unohelper.absolutize( self.cwd, global_unohelper.systemPathToFileUrl(outputfn) ) -+ info(1, "Output file: %s" % outputfn) -+ else: -+ outputurl = "private:stream" -+ -+ try: -+ document.storeToURL(outputurl, tuple(outputprops) ) -+ except UnoIOException, e: -+ raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) -+ -+ phase = "dispose" -+ document.dispose() -+ document.close(True) -+ -+ except SystemError, e: -+ error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) -+ exitcode = 1 -+ -+ except UnoRuntimeException, e: -+ error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) -+ exitcode = 6 -+ -+ except UnoDisposedException, e: -+ error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) -+ exitcode = 7 -+ -+ except UnoIllegalArgumentException, e: -+ error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) -+ exitcode = 8 -+ -+ except UnoIOException, e: -+# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) -+ error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) -+ exitcode = 3 -+ -+ except UnoCannotConvertException, e: -+# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) -+ error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) -+ exitcode = 4 -+ -+ except UnoException, e: -+ if hasattr(e, 'ErrCode'): -+ error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) -+ exitcode = e.ErrCode -+ pass -+ if hasattr(e, 'Message'): -+ error("unoconv: UnoException during %s phase:\n%s" % (phase, e.Message)) -+ exitcode = 5 -+ else: -+ error("unoconv: UnoException during %s phase in %s" % (phase, repr(e.__class__))) -+ exitcode = 2 -+ pass -+ -+class Listener: -+ def __init__(self): -+ global product -+ -+ info(1, "Start listener on %s:%s" % (op.server, op.port)) -+ self.context = global_uno.getComponentContext() -+ self.svcmgr = self.context.ServiceManager -+ try: -+ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) -+ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) -+ try: -+ unocontext = resolver.resolve("uno:%s" % op.connection) -+ except UnoNoConnectException, e: -+ pass -+ else: -+ info(1, "Existing %s listener found, nothing to do." % product.ooName) -+ return -+ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): -+ subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) -+ else: -+ subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) -+ except Exception, e: -+ error("Launch of %s failed.\n%s" % (office.binary, e)) -+ else: -+ info(1, "Existing %s listener found, nothing to do." % product.ooName) -+ -+def error(msg): -+ "Output error message" -+ print >>sys.stderr, msg -+ -+def info(level, msg): -+ "Output info message" -+ if 'op' not in globals(): -+ pass -+ elif op.verbose >= 3 and level >= 3: -+ print >>sys.stderr, "DEBUG:", msg -+ elif not op.stdout and level <= op.verbose: -+ print >>sys.stdout, msg -+ elif level <= op.verbose: -+ print >>sys.stderr, msg -+ -+def die(ret, msg=None): -+ "Print optional error and exit with errorcode" -+ global convertor, ooproc, office -+ -+ if msg: -+ error('Error: %s' % msg) -+ -+ ### Did we start our own listener instance ? -+ if not op.listener and ooproc and convertor: -+ -+ ### If there is a GUI now attached to the instance, disable listener -+ if convertor.desktop.getCurrentFrame(): -+ info(2, 'Trying to stop %s GUI listener.' % product.ooName) -+ try: -+ if product.ooName != "LibreOffice" or product.ooSetupVersion <= 3.3: -+ subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-unaccept=%s" % op.connection], env=os.environ) -+ else: -+ subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) -+ ooproc.wait() -+ info(2, '%s listener successfully disabled.' % product.ooName) -+ except Exception, e: -+ error("Terminate using %s failed.\n%s" % (office.binary, e)) -+ -+ ### If there is no GUI attached to the instance, terminate instance -+ else: -+ info(3, 'Terminating %s instance.' % product.ooName) -+ try: -+ convertor.desktop.terminate() -+ except UnoDisposedException: -+ info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) -+ try: -+ ooproc.terminate() -+ except AttributeError: -+ os.kill(ooproc.pid, 15) -+ info(3, 'Waiting for %s instance to exit.' % product.ooName) -+ ooproc.wait() -+ -+ ### LibreOffice processes may get stuck and we have to kill them -+ ### Is it still running ? -+ if ooproc.poll() == None: -+ info(1, '%s instance still running, please investigate...' % product.ooName) -+ ooproc.wait() -+ info(2, '%s instance unsuccessfully terminated, sending KILL signal.' % product.ooName) -+ try: -+ ooproc.kill() -+ except AttributeError: -+ os.kill(ooproc.pid, 9) -+ info(3, 'Waiting for %s with pid %s to disappear.' % (ooproc.pid, product.ooName)) -+ ooproc.wait() -+ -+ # allow Python GC to garbage collect pyuno object *before* exit call -+ # which avoids random segmentation faults --vpa -+ convertor = None -+ -+ sys.exit(ret) -+ -+def main(): -+ global convertor, exitcode -+ convertor = None -+ -+ try: -+ if op.listener: -+ listener = Listener() -+ -+ if op.filenames: -+ convertor = Convertor() -+ for inputfn in op.filenames: -+ convertor.convert(inputfn) -+ -+ except UnoNoConnectException, e: -+ error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) -+ if op.connection: -+ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) -+ else: -+ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"socket,host=%s,port=%s;urp;\"" % (op.server, op.server, op.port, op.server, op.port)) -+ info(0, "Please start an soffice instance on server '%s' by doing:\n\n soffice -nologo -nodefault -accept=\"socket,host=127.0.0.1,port=%s;urp;\"" % (op.server, op.port)) -+ exitcode = 1 -+# except UnboundLocalError: -+# die(252, "Failed to connect to remote listener.") -+ except OSError: -+ error("Warning: failed to launch Office suite. Aborting.") -+ -+### Main entrance -+def run(): -+ global exitcode -+ exitcode = 0 -+ -+ info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) -+ -+ for of in find_offices(): -+ if of.python != sys.executable and not sys.executable.startswith(of.basepath): -+ python_switch(of) -+ office_environ(of) -+# debug_office() -+ try: -+ global global_uno -+ global global_unohelper -+ -+ import uno as global_uno -+ import unohelper as global_unohelper -+ global office -+ office = of -+ break -+ except: -+# debug_office() -+ print >>sys.stderr, "unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of -+ print >>sys.stderr, "ERROR:", sys.exc_info()[1] -+ print >>sys.stderr -+ else: -+# debug_office() -+ print >>sys.stderr, "unoconv: Cannot find a suitable office installation on your system." -+ print >>sys.stderr, "ERROR: Please locate your office installation and send your feedback to:" -+ print >>sys.stderr, " http://github.com/dagwieers/unoconv/issues" -+ sys.exit(1) -+ -+ ### Now that we have found a working pyuno library, let's import some classes -+ global UnoPropertyValue -+ global UnoNoConnectException -+ global UNO_QUIET_UPDATE -+ global UnoDisposedException -+ global UnoIllegalArgumentException -+ global UnoIOException -+ global UnoXOutputStream -+ global UnoCannotConvertException -+ global UnoException -+ global UnoRuntimeException -+ -+ from com.sun.star.beans import PropertyValue as UnoPropertyValue -+ from com.sun.star.connection import NoConnectException as UnoNoConnectException -+ from com.sun.star.document.UpdateDocMode import QUIET_UPDATE as UNO_QUIET_UPDATE -+ from com.sun.star.lang import DisposedException as UnoDisposedException -+ from com.sun.star.lang import IllegalArgumentException as UnoIllegalArgumentException -+ from com.sun.star.io import IOException as UnoIOException -+ from com.sun.star.io import XOutputStream as UnoXOutputStream -+ from com.sun.star.script import CannotConvertException as UnoCannotConvertException -+ from com.sun.star.uno import Exception as UnoException -+ from com.sun.star.uno import RuntimeException as UnoRuntimeException -+ -+ ### And now that we have those classes, build on them -+ class OutputStream( global_unohelper.Base, UnoXOutputStream ): -+ def __init__( self ): -+ self.closed = 0 -+ -+ def closeOutput(self): -+ self.closed = 1 -+ -+ def writeBytes( self, seq ): -+ sys.stdout.write( seq.value ) -+ -+ def flush( self ): -+ pass -+ -+ global GlobalOutputStream -+ GlobalOutputStream = OutputStream -+ -+ def UnoProps(**args): -+ props = [] -+ for key in args: -+ prop = UnoPropertyValue() -+ prop.Name = key -+ prop.Value = args[key] -+ props.append(prop) -+ return tuple(props) -+ -+ global GlobalUnoProps -+ GlobalUnoProps = UnoProps -+ -+ global op -+ op = Options(sys.argv[1:]) -+ -+ info(2, "Using office base path: %s" % office.basepath) -+ info(2, "Using office binary path: %s" % office.unopath) -+ -+ try: -+ main() -+ except KeyboardInterrupt, e: -+ die(6, 'Exiting on user request') -+ die(exitcode) -+ -+if __name__ == '__main__': -+ run() -diff --git a/unoconv3.py b/unoconv3.py -new file mode 100755 -index 0000000..09d88c2 ---- /dev/null -+++ b/unoconv3.py -@@ -0,0 +1,1195 @@ -+#!/usr/bin/python3 -+ -+### 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; version 2 only -+### -+### 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, write to the Free Software -+### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+### Copyright 2007-2010 Dag Wieers -+ -+from distutils.version import LooseVersion -+import getopt -+import glob -+import os -+import subprocess -+import sys -+import time -+ -+__version__ = "$Revision$" -+# $Source$ -+ -+VERSION = '0.6' -+ -+doctypes = ('document', 'graphics', 'presentation', 'spreadsheet') -+ -+global convertor, office, ooproc, product -+ooproc = None -+exitcode = 0 -+ -+class Office: -+ def __init__(self, basepath, urepath, unopath, pyuno, binary, python, pythonhome): -+ self.basepath = basepath -+ self.urepath = urepath -+ self.unopath = unopath -+ self.pyuno = pyuno -+ self.binary = binary -+ self.python = python -+ self.pythonhome = pythonhome -+ -+ def __str__(self): -+ return self.basepath -+ -+ def __repr__(self): -+ return self.basepath -+ -+### Implement a path normalizer in order to make unoconv work on MacOS X -+### (on which 'program' is a symlink to 'MacOSX' which seems to break unoconv) -+def realpath(*args): -+ ''' Implement a combination of os.path.join(), os.path.abspath() and -+ os.path.realpath() in order to normalize path constructions ''' -+ ret = '' -+ for arg in args: -+ ret = os.path.join(ret, arg) -+ return os.path.realpath(os.path.abspath(ret)) -+ -+### The first thing we ought to do is find a suitable Office installation -+### with a compatible pyuno library that we can import. -+### -+### See: http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p=166783 -+ -+def find_offices(): -+ ret = [] -+ extrapaths = [] -+ -+ ### Try using UNO_PATH first (in many incarnations, we'll see what sticks) -+ if 'UNO_PATH' in os.environ: -+ extrapaths += [ os.environ['UNO_PATH'], -+ os.path.dirname(os.environ['UNO_PATH']), -+ os.path.dirname(os.path.dirname(os.environ['UNO_PATH'])) ] -+ -+ else: -+ -+ if os.name in ( 'nt', 'os2' ): -+ if 'PROGRAMFILES' in list(os.environ.keys()): -+ extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ -+ glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') -+ -+ if 'PROGRAMFILES(X86)' in list(os.environ.keys()): -+ extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ -+ glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') -+ -+ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): -+ extrapaths += [ '/Applications/LibreOffice.app/Contents', -+ '/Applications/NeoOffice.app/Contents', -+ '/Applications/OpenOffice.org.app/Contents' ] -+ -+ else: -+ extrapaths += glob.glob('/usr/lib*/libreoffice*') + \ -+ glob.glob('/usr/lib*/openoffice*') + \ -+ glob.glob('/usr/lib*/ooo*') + \ -+ glob.glob('/opt/libreoffice*') + \ -+ glob.glob('/opt/openoffice*') + \ -+ glob.glob('/opt/ooo*') + \ -+ glob.glob('/usr/local/libreoffice*') + \ -+ glob.glob('/usr/local/openoffice*') + \ -+ glob.glob('/usr/local/ooo*') + \ -+ glob.glob('/usr/local/lib/libreoffice*') -+ -+ ### Find a working set for python UNO bindings -+ for basepath in extrapaths: -+ if os.name in ( 'nt', 'os2' ): -+ officelibraries = ( 'pyuno.pyd', ) -+ officebinaries = ( 'soffice.exe' ,) -+ pythonbinaries = ( 'python.exe', ) -+ pythonhomes = () -+ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): -+ officelibraries = ( 'pyuno.so', 'libpyuno.dylib' ) -+ officebinaries = ( 'soffice.bin', ) -+ pythonbinaries = ( 'python.bin', 'python' ) -+ pythonhomes = ( 'OOoPython.framework/Versions/*/lib/python*', ) -+ else: -+ officelibraries = ( 'pyuno.so', ) -+ officebinaries = ( 'soffice.bin', ) -+ pythonbinaries = ( 'python.bin', 'python', ) -+ pythonhomes = ( 'python-core-*', ) -+ -+ ### Older LibreOffice/OpenOffice and Windows use basis-link/ or basis/ -+ libpath = 'error' -+ for basis in ( 'basis-link', 'basis', '' ): -+ for lib in officelibraries: -+ if os.path.isfile(realpath(basepath, basis, 'program', lib)): -+ libpath = realpath(basepath, basis, 'program') -+ officelibrary = realpath(libpath, lib) -+ info(3, "Found %s in %s" % (lib, libpath)) -+ # Break the inner loop... -+ break -+ # Continue if the inner loop wasn't broken. -+ else: -+ continue -+ # Inner loop was broken, break the outer. -+ break -+ else: -+ continue -+ -+ ### MacOSX have soffice binaries installed in MacOS subdirectory, not program -+ unopath = 'error' -+ for basis in ( 'basis-link', 'basis', '' ): -+ for bin in officebinaries: -+ if os.path.isfile(realpath(basepath, basis, 'program', bin)): -+ unopath = realpath(basepath, basis, 'program') -+ officebinary = realpath(unopath, bin) -+ info(3, "Found %s in %s" % (bin, unopath)) -+ # Break the inner loop... -+ break -+ # Continue if the inner loop wasn't broken. -+ else: -+ continue -+ # Inner loop was broken, break the outer. -+ break -+ else: -+ continue -+ -+ ### Windows does not provide or need a URE/lib directory ? -+ urepath = '' -+ for basis in ( 'basis-link', 'basis', '' ): -+ for ure in ( 'ure-link', 'ure', 'URE', '' ): -+ if os.path.isfile(realpath(basepath, basis, ure, 'lib', 'unorc')): -+ urepath = realpath(basepath, basis, ure) -+ info(3, "Found %s in %s" % ('unorc', realpath(urepath, 'lib'))) -+ # Break the inner loop... -+ break -+ # Continue if the inner loop wasn't broken. -+ else: -+ continue -+ # Inner loop was broken, break the outer. -+ break -+ -+ pythonhome = None -+ for home in pythonhomes: -+ if glob.glob(realpath(libpath, home)): -+ pythonhome = glob.glob(realpath(libpath, home))[0] -+ info(3, "Found %s in %s" % (home, pythonhome)) -+ break -+ -+# if not os.path.isfile(realpath(basepath, program, officebinary)): -+# continue -+# info(3, "Found %s in %s" % (officebinary, realpath(basepath, program))) -+ -+# if not glob.glob(realpath(basepath, basis, program, 'python-core-*')): -+# continue -+ -+ for pythonbinary in pythonbinaries: -+ if os.path.isfile(realpath(unopath, pythonbinary)): -+ info(3, "Found %s in %s" % (pythonbinary, unopath)) -+ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, -+ realpath(unopath, pythonbinary), pythonhome)) -+ else: -+ info(3, "Considering %s" % basepath) -+ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, -+ sys.executable, None)) -+ return ret -+ -+def office_environ(office): -+ ### Set PATH so that crash_report is found -+ os.environ['PATH'] = realpath(office.basepath, 'program') + os.pathsep + os.environ['PATH'] -+ -+ ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: -+ os.environ['UNO_PATH'] = office.unopath -+ -+ ### Set URE_BOOTSTRAP so that "global_uno.getComponentContext()" bootstraps a complete -+ ### UNO environment -+ if os.name in ( 'nt', 'os2' ): -+ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') -+ else: -+ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamentalrc') -+ -+ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: -+ if 'LD_LIBRARY_PATH' in os.environ: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') + os.pathsep + \ -+ os.environ['LD_LIBRARY_PATH'] -+ else: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') -+ -+ if office.pythonhome: -+ for libpath in ( realpath(office.pythonhome, 'lib'), -+ realpath(office.pythonhome, 'lib', 'lib-dynload'), -+ realpath(office.pythonhome, 'lib', 'lib-tk'), -+ realpath(office.pythonhome, 'lib', 'site-packages'), -+ office.unopath): -+ sys.path.insert(0, libpath) -+ else: -+ ### Still needed for system python using LibreOffice UNO bindings -+ ### Although we prefer to use a system UNO binding in this case -+ sys.path.append(office.unopath) -+ -+def debug_office(): -+ if 'URE_BOOTSTRAP' in os.environ: -+ print('URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'], file=sys.stderr) -+ if 'UNO_PATH' in os.environ: -+ print('UNO_PATH=%s' % os.environ['UNO_PATH'], file=sys.stderr) -+ if 'UNO_TYPES' in os.environ: -+ print('UNO_TYPES=%s' % os.environ['UNO_TYPES'], file=sys.stderr) -+ print('PATH=%s' % os.environ['PATH']) -+ if 'PYTHONHOME' in os.environ: -+ print('PYTHONHOME=%s' % os.environ['PYTHONHOME'], file=sys.stderr) -+ if 'PYTHONPATH' in os.environ: -+ print('PYTHONPATH=%s' % os.environ['PYTHONPATH'], file=sys.stderr) -+ if 'LD_LIBRARY_PATH' in os.environ: -+ print('LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'], file=sys.stderr) -+ -+def python_switch(office): -+ if office.pythonhome: -+ os.environ['PYTHONHOME'] = office.pythonhome -+ os.environ['PYTHONPATH'] = realpath(office.pythonhome, 'lib') + os.pathsep + \ -+ realpath(office.pythonhome, 'lib', 'lib-dynload') + os.pathsep + \ -+ realpath(office.pythonhome, 'lib', 'lib-tk') + os.pathsep + \ -+ realpath(office.pythonhome, 'lib', 'site-packages') + os.pathsep + \ -+ office.unopath -+ -+ os.environ['UNO_PATH'] = office.unopath -+ -+ info(3, "-> Switching from %s to %s" % (sys.executable, office.python)) -+ if os.name in ('nt', 'os2'): -+ ### os.execv is broken on Windows and can't properly parse command line -+ ### arguments and executable name if they contain whitespaces. subprocess -+ ### fixes that behavior. -+ ret = subprocess.call([office.python] + sys.argv[0:]) -+ sys.exit(ret) -+ else: -+ -+ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: -+ if 'LD_LIBRARY_PATH' in os.environ: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') + os.pathsep + \ -+ os.environ['LD_LIBRARY_PATH'] -+ else: -+ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ -+ realpath(office.urepath, 'lib') -+ -+ try: -+ os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) -+ print((office.python, [office.python, ] + sys.argv[0:], osenviron)) -+ except OSError: -+ ### Mac OS X versions prior to 10.6 do not support execv in -+ ### a process that contains multiple threads. Instead of -+ ### re-executing in the current process, start a new one -+ ### and cause the current process to exit. This isn't -+ ### ideal since the new process is detached from the parent -+ ### terminal and thus cannot easily be killed with ctrl-C, -+ ### but it's better than not being able to autoreload at -+ ### all. -+ ### Unfortunately the errno returned in this case does not -+ ### appear to be consistent, so we can't easily check for -+ ### this error specifically. -+ ret = os.spawnvpe(os.P_WAIT, office.python, [office.python, ] + sys.argv[0:], os.environ) -+ sys.exit(ret) -+ -+class Fmt: -+ def __init__(self, doctype, name, extension, summary, filter): -+ self.doctype = doctype -+ self.name = name -+ self.extension = extension -+ self.summary = summary -+ self.filter = filter -+ -+ def __str__(self): -+ return "%s [.%s]" % (self.summary, self.extension) -+ -+ def __repr__(self): -+ return "%s/%s" % (self.name, self.doctype) -+ -+class FmtList: -+ def __init__(self): -+ self.list = [] -+ -+ def add(self, doctype, name, extension, summary, filter): -+ self.list.append(Fmt(doctype, name, extension, summary, filter)) -+ -+ def byname(self, name): -+ ret = [] -+ for fmt in self.list: -+ if fmt.name == name: -+ ret.append(fmt) -+ return ret -+ -+ def byextension(self, extension): -+ ret = [] -+ for fmt in self.list: -+ if os.extsep + fmt.extension == extension: -+ ret.append(fmt) -+ return ret -+ -+ def bydoctype(self, doctype, name): -+ ret = [] -+ for fmt in self.list: -+ if fmt.name == name and fmt.doctype == doctype: -+ ret.append(fmt) -+ return ret -+ -+ def display(self, doctype): -+ print("The following list of %s formats are currently available:\n" % doctype, file=sys.stderr) -+ for fmt in self.list: -+ if fmt.doctype == doctype: -+ print(" %-8s - %s" % (fmt.name, fmt), file=sys.stderr) -+ print(file=sys.stderr) -+ -+fmts = FmtList() -+ -+### TextDocument -+fmts.add('document', 'bib', 'bib', 'BibTeX', 'BibTeX_Writer') ### 22 -+fmts.add('document', 'doc', 'doc', 'Microsoft Word 97/2000/XP', 'MS Word 97') ### 29 -+fmts.add('document', 'doc6', 'doc', 'Microsoft Word 6.0', 'MS WinWord 6.0') ### 24 -+fmts.add('document', 'doc95', 'doc', 'Microsoft Word 95', 'MS Word 95') ### 28 -+fmts.add('document', 'docbook', 'xml', 'DocBook', 'DocBook File') ### 39 -+fmts.add('document', 'docx', 'docx', 'Microsoft Office Open XML', 'Office Open XML Text') -+fmts.add('document', 'docx7', 'docx', 'Microsoft Office Open XML', 'MS Word 2007 XML') -+fmts.add('document', 'fodt', 'fodt', 'OpenDocument Text (Flat XML)', 'OpenDocument Text Flat XML') -+fmts.add('document', 'html', 'html', 'HTML Document (OpenOffice.org Writer)', 'HTML (StarWriter)') ### 3 -+fmts.add('document', 'latex', 'ltx', 'LaTeX 2e', 'LaTeX_Writer') ### 31 -+fmts.add('document', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki') -+fmts.add('document', 'odt', 'odt', 'ODF Text Document', 'writer8') ### 10 -+fmts.add('document', 'ooxml', 'xml', 'Microsoft Office Open XML', 'MS Word 2003 XML') ### 11 -+fmts.add('document', 'ott', 'ott', 'Open Document Text', 'writer8_template') ### 21 -+fmts.add('document', 'pdb', 'pdb', 'AportisDoc (Palm)', 'AportisDoc Palm DB') -+fmts.add('document', 'pdf', 'pdf', 'Portable Document Format', 'writer_pdf_Export') ### 18 -+fmts.add('document', 'psw', 'psw', 'Pocket Word', 'PocketWord File') -+fmts.add('document', 'rtf', 'rtf', 'Rich Text Format', 'Rich Text Format') ### 16 -+fmts.add('document', 'sdw', 'sdw', 'StarWriter 5.0', 'StarWriter 5.0') ### 23 -+fmts.add('document', 'sdw4', 'sdw', 'StarWriter 4.0', 'StarWriter 4.0') ### 2 -+fmts.add('document', 'sdw3', 'sdw', 'StarWriter 3.0', 'StarWriter 3.0') ### 20 -+fmts.add('document', 'stw', 'stw', 'Open Office.org 1.0 Text Document Template', 'writer_StarOffice_XML_Writer_Template') ### 9 -+fmts.add('document', 'sxw', 'sxw', 'Open Office.org 1.0 Text Document', 'StarOffice XML (Writer)') ### 1 -+fmts.add('document', 'text', 'txt', 'Text Encoded', 'Text (encoded)') ### 26 -+fmts.add('document', 'txt', 'txt', 'Text', 'Text') ### 34 -+fmts.add('document', 'uot', 'uot', 'Unified Office Format text','UOF text') ### 27 -+fmts.add('document', 'vor', 'vor', 'StarWriter 5.0 Template', 'StarWriter 5.0 Vorlage/Template') ### 6 -+fmts.add('document', 'vor4', 'vor', 'StarWriter 4.0 Template', 'StarWriter 4.0 Vorlage/Template') ### 5 -+fmts.add('document', 'vor3', 'vor', 'StarWriter 3.0 Template', 'StarWriter 3.0 Vorlage/Template') ### 4 -+fmts.add('document', 'xhtml', 'html', 'XHTML Document', 'XHTML Writer File') ### 33 -+ -+### WebDocument -+fmts.add('web', 'etext', 'txt', 'Text Encoded (OpenOffice.org Writer/Web)', 'Text (encoded) (StarWriter/Web)') ### 14 -+fmts.add('web', 'html10', 'html', 'OpenOffice.org 1.0 HTML Template', 'writer_web_StarOffice_XML_Writer_Web_Template') ### 11 -+fmts.add('web', 'html', 'html', 'HTML Document', 'HTML') ### 2 -+fmts.add('web', 'html', 'html', 'HTML Document Template', 'writerweb8_writer_template') ### 13 -+fmts.add('web', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki_Web') ### 9 -+fmts.add('web', 'pdf', 'pdf', 'PDF - Portable Document Format', 'writer_web_pdf_Export') ### 10 -+fmts.add('web', 'sdw3', 'sdw', 'StarWriter 3.0 (OpenOffice.org Writer/Web)', 'StarWriter 3.0 (StarWriter/Web)') ### 3 -+fmts.add('web', 'sdw4', 'sdw', 'StarWriter 4.0 (OpenOffice.org Writer/Web)', 'StarWriter 4.0 (StarWriter/Web)') ### 4 -+fmts.add('web', 'sdw', 'sdw', 'StarWriter 5.0 (OpenOffice.org Writer/Web)', 'StarWriter 5.0 (StarWriter/Web)') ### 5 -+fmts.add('web', 'txt', 'txt', 'OpenOffice.org Text (OpenOffice.org Writer/Web)', 'writerweb8_writer') ### 12 -+fmts.add('web', 'text10', 'txt', 'OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)', 'writer_web_StarOffice_XML_Writer') ### 15 -+fmts.add('web', 'text', 'txt', 'Text (OpenOffice.org Writer/Web)', 'Text (StarWriter/Web)') ### 8 -+fmts.add('web', 'vor4', 'vor', 'StarWriter/Web 4.0 Template', 'StarWriter/Web 4.0 Vorlage/Template') ### 6 -+fmts.add('web', 'vor', 'vor', 'StarWriter/Web 5.0 Template', 'StarWriter/Web 5.0 Vorlage/Template') ### 7 -+ -+### Spreadsheet -+fmts.add('spreadsheet', 'csv', 'csv', 'Text CSV', 'Text - txt - csv (StarCalc)') ### 16 -+fmts.add('spreadsheet', 'dbf', 'dbf', 'dBASE', 'dBase') ### 22 -+fmts.add('spreadsheet', 'dif', 'dif', 'Data Interchange Format', 'DIF') ### 5 -+fmts.add('spreadsheet', 'fods', 'fods', 'OpenDocument Spreadsheet (Flat XML)', 'OpenDocument Spreadsheet Flat XML') -+fmts.add('spreadsheet', 'html', 'html', 'HTML Document (OpenOffice.org Calc)', 'HTML (StarCalc)') ### 7 -+fmts.add('spreadsheet', 'ods', 'ods', 'ODF Spreadsheet', 'calc8') ### 15 -+fmts.add('spreadsheet', 'ooxml', 'xml', 'Microsoft Excel 2003 XML', 'MS Excel 2003 XML') ### 23 -+fmts.add('spreadsheet', 'ots', 'ots', 'ODF Spreadsheet Template', 'calc8_template') ### 14 -+fmts.add('spreadsheet', 'pdf', 'pdf', 'Portable Document Format', 'calc_pdf_Export') ### 34 -+fmts.add('spreadsheet', 'pxl', 'pxl', 'Pocket Excel', 'Pocket Excel') -+fmts.add('spreadsheet', 'sdc', 'sdc', 'StarCalc 5.0', 'StarCalc 5.0') ### 31 -+fmts.add('spreadsheet', 'sdc4', 'sdc', 'StarCalc 4.0', 'StarCalc 4.0') ### 11 -+fmts.add('spreadsheet', 'sdc3', 'sdc', 'StarCalc 3.0', 'StarCalc 3.0') ### 29 -+fmts.add('spreadsheet', 'slk', 'slk', 'SYLK', 'SYLK') ### 35 -+fmts.add('spreadsheet', 'stc', 'stc', 'OpenOffice.org 1.0 Spreadsheet Template', 'calc_StarOffice_XML_Calc_Template') ### 2 -+fmts.add('spreadsheet', 'sxc', 'sxc', 'OpenOffice.org 1.0 Spreadsheet', 'StarOffice XML (Calc)') ### 3 -+fmts.add('spreadsheet', 'uos', 'uos', 'Unified Office Format spreadsheet', 'UOF spreadsheet') ### 9 -+fmts.add('spreadsheet', 'vor3', 'vor', 'StarCalc 3.0 Template', 'StarCalc 3.0 Vorlage/Template') ### 18 -+fmts.add('spreadsheet', 'vor4', 'vor', 'StarCalc 4.0 Template', 'StarCalc 4.0 Vorlage/Template') ### 19 -+fmts.add('spreadsheet', 'vor', 'vor', 'StarCalc 5.0 Template', 'StarCalc 5.0 Vorlage/Template') ### 20 -+fmts.add('spreadsheet', 'xhtml', 'xhtml', 'XHTML', 'XHTML Calc File') ### 26 -+fmts.add('spreadsheet', 'xls', 'xls', 'Microsoft Excel 97/2000/XP', 'MS Excel 97') ### 12 -+fmts.add('spreadsheet', 'xls5', 'xls', 'Microsoft Excel 5.0', 'MS Excel 5.0/95') ### 8 -+fmts.add('spreadsheet', 'xls95', 'xls', 'Microsoft Excel 95', 'MS Excel 95') ### 10 -+fmts.add('spreadsheet', 'xlt', 'xlt', 'Microsoft Excel 97/2000/XP Template', 'MS Excel 97 Vorlage/Template') ### 6 -+fmts.add('spreadsheet', 'xlt5', 'xlt', 'Microsoft Excel 5.0 Template', 'MS Excel 5.0/95 Vorlage/Template') ### 28 -+fmts.add('spreadsheet', 'xlt95', 'xlt', 'Microsoft Excel 95 Template', 'MS Excel 95 Vorlage/Template') ### 21 -+ -+### Graphics -+fmts.add('graphics', 'bmp', 'bmp', 'Windows Bitmap', 'draw_bmp_Export') ### 21 -+fmts.add('graphics', 'emf', 'emf', 'Enhanced Metafile', 'draw_emf_Export') ### 15 -+fmts.add('graphics', 'eps', 'eps', 'Encapsulated PostScript', 'draw_eps_Export') ### 48 -+fmts.add('graphics', 'fodg', 'fodg', 'OpenDocument Drawing (Flat XML)', 'OpenDocument Drawing Flat XML') -+fmts.add('graphics', 'gif', 'gif', 'Graphics Interchange Format', 'draw_gif_Export') ### 30 -+fmts.add('graphics', 'html', 'html', 'HTML Document (OpenOffice.org Draw)', 'draw_html_Export') ### 37 -+fmts.add('graphics', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'draw_jpg_Export') ### 3 -+fmts.add('graphics', 'met', 'met', 'OS/2 Metafile', 'draw_met_Export') ### 43 -+fmts.add('graphics', 'odd', 'odd', 'OpenDocument Drawing', 'draw8') ### 6 -+fmts.add('graphics', 'otg', 'otg', 'OpenDocument Drawing Template', 'draw8_template') ### 20 -+fmts.add('graphics', 'pbm', 'pbm', 'Portable Bitmap', 'draw_pbm_Export') ### 14 -+fmts.add('graphics', 'pct', 'pct', 'Mac Pict', 'draw_pct_Export') ### 41 -+fmts.add('graphics', 'pdf', 'pdf', 'Portable Document Format', 'draw_pdf_Export') ### 28 -+fmts.add('graphics', 'pgm', 'pgm', 'Portable Graymap', 'draw_pgm_Export') ### 11 -+fmts.add('graphics', 'png', 'png', 'Portable Network Graphic', 'draw_png_Export') ### 2 -+fmts.add('graphics', 'ppm', 'ppm', 'Portable Pixelmap', 'draw_ppm_Export') ### 5 -+fmts.add('graphics', 'ras', 'ras', 'Sun Raster Image', 'draw_ras_Export') ## 31 -+fmts.add('graphics', 'std', 'std', 'OpenOffice.org 1.0 Drawing Template', 'draw_StarOffice_XML_Draw_Template') ### 53 -+fmts.add('graphics', 'svg', 'svg', 'Scalable Vector Graphics', 'draw_svg_Export') ### 50 -+fmts.add('graphics', 'svm', 'svm', 'StarView Metafile', 'draw_svm_Export') ### 55 -+fmts.add('graphics', 'swf', 'swf', 'Macromedia Flash (SWF)', 'draw_flash_Export') ### 23 -+fmts.add('graphics', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing', 'StarOffice XML (Draw)') ### 26 -+fmts.add('graphics', 'sxd3', 'sxd', 'StarDraw 3.0', 'StarDraw 3.0') ### 40 -+fmts.add('graphics', 'sxd5', 'sxd', 'StarDraw 5.0', 'StarDraw 5.0') ### 44 -+fmts.add('graphics', 'sxw', 'sxw', 'StarOffice XML (Draw)', 'StarOffice XML (Draw)') -+fmts.add('graphics', 'tiff', 'tiff', 'Tagged Image File Format', 'draw_tif_Export') ### 13 -+fmts.add('graphics', 'vor', 'vor', 'StarDraw 5.0 Template', 'StarDraw 5.0 Vorlage') ### 36 -+fmts.add('graphics', 'vor3', 'vor', 'StarDraw 3.0 Template', 'StarDraw 3.0 Vorlage') ### 35 -+fmts.add('graphics', 'wmf', 'wmf', 'Windows Metafile', 'draw_wmf_Export') ### 8 -+fmts.add('graphics', 'xhtml', 'xhtml', 'XHTML', 'XHTML Draw File') ### 45 -+fmts.add('graphics', 'xpm', 'xpm', 'X PixMap', 'draw_xpm_Export') ### 19 -+ -+### Presentation -+fmts.add('presentation', 'bmp', 'bmp', 'Windows Bitmap', 'impress_bmp_Export') ### 15 -+fmts.add('presentation', 'emf', 'emf', 'Enhanced Metafile', 'impress_emf_Export') ### 16 -+fmts.add('presentation', 'eps', 'eps', 'Encapsulated PostScript', 'impress_eps_Export') ### 17 -+fmts.add('presentation', 'fodp', 'fodp', 'OpenDocument Presentation (Flat XML)', 'OpenDocument Presentation Flat XML') -+fmts.add('presentation', 'gif', 'gif', 'Graphics Interchange Format', 'impress_gif_Export') ### 18 -+fmts.add('presentation', 'html', 'html', 'HTML Document (OpenOffice.org Impress)', 'impress_html_Export') ### 43 -+fmts.add('presentation', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'impress_jpg_Export') ### 19 -+fmts.add('presentation', 'met', 'met', 'OS/2 Metafile', 'impress_met_Export') ### 20 -+fmts.add('presentation', 'odg', 'odg', 'ODF Drawing (Impress)', 'impress8_draw') ### 29 -+fmts.add('presentation', 'odp', 'odp', 'ODF Presentation', 'impress8') ### 9 -+fmts.add('presentation', 'otp', 'otp', 'ODF Presentation Template', 'impress8_template') ### 38 -+fmts.add('presentation', 'pbm', 'pbm', 'Portable Bitmap', 'impress_pbm_Export') ### 21 -+fmts.add('presentation', 'pct', 'pct', 'Mac Pict', 'impress_pct_Export') ### 22 -+fmts.add('presentation', 'pdf', 'pdf', 'Portable Document Format', 'impress_pdf_Export') ### 23 -+fmts.add('presentation', 'pgm', 'pgm', 'Portable Graymap', 'impress_pgm_Export') ### 24 -+fmts.add('presentation', 'png', 'png', 'Portable Network Graphic', 'impress_png_Export') ### 25 -+fmts.add('presentation', 'potm', 'potm', 'Microsoft PowerPoint 2007/2010 XML Template', 'Impress MS PowerPoint 2007 XML Template') -+fmts.add('presentation', 'pot', 'pot', 'Microsoft PowerPoint 97/2000/XP Template', 'MS PowerPoint 97 Vorlage') ### 3 -+fmts.add('presentation', 'ppm', 'ppm', 'Portable Pixelmap', 'impress_ppm_Export') ### 26 -+fmts.add('presentation', 'pptx', 'pptx', 'Microsoft PowerPoint 2007/2010 XML', 'Impress MS PowerPoint 2007 XML') ### 36 -+fmts.add('presentation', 'pps', 'pps', 'Microsoft PowerPoint 97/2000/XP (Autoplay)', 'MS PowerPoint 97 Autoplay') ### 36 -+fmts.add('presentation', 'ppt', 'ppt', 'Microsoft PowerPoint 97/2000/XP', 'MS PowerPoint 97') ### 36 -+fmts.add('presentation', 'pwp', 'pwp', 'PlaceWare', 'placeware_Export') ### 30 -+fmts.add('presentation', 'ras', 'ras', 'Sun Raster Image', 'impress_ras_Export') ### 27 -+fmts.add('presentation', 'sda', 'sda', 'StarDraw 5.0 (OpenOffice.org Impress)', 'StarDraw 5.0 (StarImpress)') ### 8 -+fmts.add('presentation', 'sdd', 'sdd', 'StarImpress 5.0', 'StarImpress 5.0') ### 6 -+fmts.add('presentation', 'sdd3', 'sdd', 'StarDraw 3.0 (OpenOffice.org Impress)', 'StarDraw 3.0 (StarImpress)') ### 42 -+fmts.add('presentation', 'sdd4', 'sdd', 'StarImpress 4.0', 'StarImpress 4.0') ### 37 -+fmts.add('presentation', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)', 'impress_StarOffice_XML_Draw') ### 31 -+fmts.add('presentation', 'sti', 'sti', 'OpenOffice.org 1.0 Presentation Template', 'impress_StarOffice_XML_Impress_Template') ### 5 -+fmts.add('presentation', 'svg', 'svg', 'Scalable Vector Graphics', 'impress_svg_Export') ### 14 -+fmts.add('presentation', 'svm', 'svm', 'StarView Metafile', 'impress_svm_Export') ### 13 -+fmts.add('presentation', 'swf', 'swf', 'Macromedia Flash (SWF)', 'impress_flash_Export') ### 34 -+fmts.add('presentation', 'sxi', 'sxi', 'OpenOffice.org 1.0 Presentation', 'StarOffice XML (Impress)') ### 41 -+fmts.add('presentation', 'tiff', 'tiff', 'Tagged Image File Format', 'impress_tif_Export') ### 12 -+fmts.add('presentation', 'uop', 'uop', 'Unified Office Format presentation', 'UOF presentation') ### 4 -+fmts.add('presentation', 'vor', 'vor', 'StarImpress 5.0 Template', 'StarImpress 5.0 Vorlage') ### 40 -+fmts.add('presentation', 'vor3', 'vor', 'StarDraw 3.0 Template (OpenOffice.org Impress)', 'StarDraw 3.0 Vorlage (StarImpress)') ###1 -+fmts.add('presentation', 'vor4', 'vor', 'StarImpress 4.0 Template', 'StarImpress 4.0 Vorlage') ### 39 -+fmts.add('presentation', 'vor5', 'vor', 'StarDraw 5.0 Template (OpenOffice.org Impress)', 'StarDraw 5.0 Vorlage (StarImpress)') ### 2 -+fmts.add('presentation', 'wmf', 'wmf', 'Windows Metafile', 'impress_wmf_Export') ### 11 -+fmts.add('presentation', 'xhtml', 'xml', 'XHTML', 'XHTML Impress File') ### 33 -+fmts.add('presentation', 'xpm', 'xpm', 'X PixMap', 'impress_xpm_Export') ### 10 -+ -+class Options: -+ def __init__(self, args): -+ self.connection = None -+ self.debug = False -+ self.doctype = None -+ self.exportfilter = [] -+ self.exportfilteroptions = "" -+ self.filenames = [] -+ self.format = None -+ self.importfilter = [] -+ self.importfilteroptions = "" -+ self.listener = False -+ self.nolaunch = False -+ self.output = None -+ self.password = None -+ self.pipe = None -+ self.port = '2002' -+ self.server = '127.0.0.1' -+ self.showlist = False -+ self.stdout = False -+ self.template = None -+ self.timeout = 6 -+ self.verbose = 0 -+ -+ ### Get options from the commandline -+ try: -+ opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', -+ ['connection=', 'debug', 'doctype=', 'export=', 'format=', -+ 'help', 'import', 'listener', 'no-launch', 'output=', -+ 'outputpath', 'password=', 'pipe=', 'port=', 'server=', -+ 'timeout=', 'show', 'stdout', 'template', 'verbose', -+ 'version'] ) -+ except getopt.error as exc: -+ print('unoconv: %s, try unoconv -h for a list of all the options' % str(exc)) -+ sys.exit(255) -+ -+ for opt, arg in opts: -+ if opt in ['-h', '--help']: -+ self.usage() -+ print() -+ self.help() -+ sys.exit(1) -+ elif opt in ['-c', '--connection']: -+ self.connection = arg -+ elif opt in ['--debug']: -+ self.debug = True -+ elif opt in ['-d', '--doctype']: -+ self.doctype = arg -+ elif opt in ['-e', '--export']: -+ l = arg.split('=') -+ if len(l) == 2: -+ (name, value) = l -+ if name in ('FilterOptions'): -+ self.exportfilteroptions = value -+ elif value in ('True', 'true'): -+ self.exportfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) -+ elif value in ('False', 'false'): -+ self.exportfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) -+ else: -+ try: -+ self.exportfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) -+ except ValueError: -+ self.exportfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) -+ else: -+ print('Warning: Option %s cannot be parsed, ignoring.' % arg, file=sys.stderr) -+ elif opt in ['-f', '--format']: -+ self.format = arg -+ elif opt in ['-i', '--import']: -+ l = arg.split('=') -+ if len(l) == 2: -+ (name, value) = l -+ if name in ('FilterOptions'): -+ self.importfilteroptions = value -+ elif value in ('True', 'true'): -+ self.importfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) -+ elif value in ('False', 'false'): -+ self.importfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) -+ else: -+ try: -+ self.importfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) -+ except ValueError: -+ self.importfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) -+ else: -+ print('Warning: Option %s cannot be parsed, ignoring.' % arg, file=sys.stderr) -+ elif opt in ['-l', '--listener']: -+ self.listener = True -+ elif opt in ['-n', '--no-launch']: -+ self.nolaunch = True -+ elif opt in ['-o', '--output']: -+ self.output = arg -+ elif opt in ['--outputpath']: -+ print('Warning: This option is deprecated by --output.', file=sys.stderr) -+ self.output = arg -+ elif opt in ['--password']: -+ self.password = arg -+ elif opt in ['--pipe']: -+ self.pipe = arg -+ elif opt in ['-p', '--port']: -+ self.port = arg -+ elif opt in ['-s', '--server']: -+ self.server = arg -+ elif opt in ['--show']: -+ self.showlist = True -+ elif opt in ['--stdout']: -+ self.stdout = True -+ elif opt in ['-t', '--template']: -+ self.template = arg -+ elif opt in ['-T', '--timeout']: -+ self.timeout = int(arg) -+ elif opt in ['-v', '--verbose']: -+ self.verbose = self.verbose + 1 -+ elif opt in ['-V', '--version']: -+ self.version() -+ sys.exit(255) -+ -+ ### Enable verbosity -+ if self.verbose >= 2: -+ print('Verbosity set to level %d' % self.verbose, file=sys.stderr) -+ -+ self.filenames = args -+ -+ if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: -+ print('unoconv: you have to provide a filename as argument', file=sys.stderr) -+ print('Try `unoconv -h\' for more information.', file=sys.stderr) -+ sys.exit(255) -+ -+ ### Set connection string -+ if not self.connection: -+ if not self.pipe: -+ self.connection = "socket,host=%s,port=%s;urp;StarOffice.ComponentContext" % (self.server, self.port) -+# self.connection = "socket,host=%s,port=%s;urp;" % (self.server, self.port) -+ else: -+ self.connection = "pipe,name=%s;urp;StarOffice.ComponentContext" % (self.pipe) -+ -+ ### Make it easier for people to use a doctype (first letter is enough) -+ if self.doctype: -+ for doctype in doctypes: -+ if doctype.startswith(self.doctype): -+ self.doctype = doctype -+ -+ ### Check if the user request to see the list of formats -+ if self.showlist or self.format == 'list': -+ if self.doctype: -+ fmts.display(self.doctype) -+ else: -+ for t in doctypes: -+ fmts.display(t) -+ sys.exit(0) -+ -+ ### If no format was specified, probe it or provide it -+ if not self.format: -+ l = sys.argv[0].split('2') -+ if len(l) == 2: -+ self.format = l[1] -+ else: -+ self.format = 'pdf' -+ -+ def version(self): -+ ### Get office product information -+ product = global_uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) -+ -+ print('unoconv %s' % VERSION) -+ print('Written by Dag Wieers ') -+ print('Homepage at http://dag.wieers.com/home-made/unoconv/') -+ print() -+ print('platform %s/%s' % (os.name, sys.platform)) -+ print('python %s' % sys.version) -+ print(product.ooName, product.ooSetupVersion) -+# print -+# print 'build revision $Rev$' -+ -+ def usage(self): -+ print('usage: unoconv [options] file [file2 ..]', file=sys.stderr) -+ -+ def help(self): -+ print('''Convert from and to any format supported by LibreOffice -+ -+unoconv options: -+ -c, --connection=string use a custom connection string -+ -d, --doctype=type specify document type -+ (document, graphics, presentation, spreadsheet) -+ -e, --export=name=value set export filter options -+ eg. -e PageRange=1-2 -+ -f, --format=format specify the output format -+ -i, --import=string set import filter option string -+ eg. -i utf8 -+ -l, --listener start a permanent listener to use by unoconv clients -+ -n, --no-launch fail if no listener is found (default: launch one) -+ -o, --output=name output basename, filename or directory -+ --pipe=name alternative method of connection using a pipe -+ -p, --port=port specify the port (default: 2002) -+ to be used by client or listener -+ --password=string provide a password to decrypt the document -+ -s, --server=server specify the server address (default: 127.0.0.1) -+ to be used by client or listener -+ --show list the available output formats -+ --stdout write output to stdout -+ -t, --template=file import the styles from template (.ott) -+ -T, --timeout=secs timeout after secs if connection to listener fails -+ -v, --verbose be more and more verbose (-vvv for debugging) -+''', file=sys.stderr) -+ -+class Convertor: -+ def __init__(self): -+ global exitcode, ooproc, office, product -+ unocontext = None -+ -+ ### Do the LibreOffice component dance -+ self.context = global_uno.getComponentContext() -+ self.svcmgr = self.context.ServiceManager -+ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) -+ -+ ### Test for an existing connection -+ info(3, 'Connection type: %s' % op.connection) -+ try: -+ unocontext = resolver.resolve("uno:%s" % op.connection) -+ except UnoNoConnectException as e: -+# info(3, "Existing listener not found.\n%s" % e) -+ info(3, "Existing listener not found.") -+ -+ if op.nolaunch: -+ die(113, "Existing listener not found. Unable start listener by parameters. Aborting.") -+ -+ ### Start our own OpenOffice instance -+ info(3, "Launching our own listener using %s." % office.binary) -+ try: -+ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) -+ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): -+ ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) -+ else: -+ ooproc = subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--accept=%s" % op.connection], env=os.environ) -+ info(2, '%s listener successfully started. (pid=%s)' % (product.ooName, ooproc.pid)) -+ -+ ### Try connection to it for op.timeout seconds (flakky OpenOffice) -+ timeout = 0 -+ while timeout <= op.timeout: -+ ### Is it already/still running ? -+ retcode = ooproc.poll() -+ if retcode != None: -+ info(3, "Process %s (pid=%s) exited with %s." % (office.binary, ooproc.pid, retcode)) -+ break -+ try: -+ unocontext = resolver.resolve("uno:%s" % op.connection) -+ break -+ except UnoNoConnectException: -+ time.sleep(0.5) -+ timeout += 0.5 -+ except: -+ raise -+ else: -+ error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) -+ except Exception as e: -+ raise -+ error("Launch of %s failed.\n%s" % (office.binary, e)) -+ -+ if not unocontext: -+ die(251, "Unable to connect or start own listener. Aborting.") -+ -+ ### And some more LibreOffice magic -+ unosvcmgr = unocontext.ServiceManager -+ self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) -+ self.cwd = global_unohelper.systemPathToFileUrl( os.getcwd() ) -+ -+ ### List all filters -+# self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) -+# for filter in self.filters.getElementNames(): -+# print filter -+# #print dir(filter), dir(filter.format) -+ -+ def getformat(self, inputfn): -+ doctype = None -+ -+ ### Get the output format from mapping -+ if op.doctype: -+ outputfmt = fmts.bydoctype(op.doctype, op.format) -+ else: -+ outputfmt = fmts.byname(op.format) -+ -+ if not outputfmt: -+ outputfmt = fmts.byextension(os.extsep + op.format) -+ -+ ### If no doctype given, check list of acceptable formats for input file ext doctype -+ ### FIXME: This should go into the for-loop to match each individual input filename -+ if outputfmt: -+ inputext = os.path.splitext(inputfn)[1] -+ inputfmt = fmts.byextension(inputext) -+ if inputfmt: -+ for fmt in outputfmt: -+ if inputfmt[0].doctype == fmt.doctype: -+ doctype = inputfmt[0].doctype -+ outputfmt = fmt -+ break -+ else: -+ outputfmt = outputfmt[0] -+ # print >>sys.stderr, 'unoconv: format `%s\' is part of multiple doctypes %s, selecting `%s\'.' % (format, [fmt.doctype for fmt in outputfmt], outputfmt[0].doctype) -+ else: -+ outputfmt = outputfmt[0] -+ -+ ### No format found, throw error -+ if not outputfmt: -+ if doctype: -+ print('unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format), file=sys.stderr) -+ else: -+ print('unoconv: format [%s] is not known to unoconv.' % op.format, file=sys.stderr) -+ die(1) -+ -+ return outputfmt -+ -+ def convert(self, inputfn): -+ global exitcode -+ -+ document = None -+ outputfmt = self.getformat(inputfn) -+ -+ if op.verbose > 0: -+ print('Input file:', inputfn, file=sys.stderr) -+ -+ if not os.path.exists(inputfn): -+ print('unoconv: file `%s\' does not exist.' % inputfn, file=sys.stderr) -+ exitcode = 1 -+ -+ try: -+ ### Import phase -+ phase = "import" -+ -+ ### Load inputfile -+ inputprops = GlobalUnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=UNO_QUIET_UPDATE) -+ -+# if op.password: -+# info = GlobalUnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") -+# inputprops += GlobalUnoProps(ModifyPasswordInfo=info) -+ -+ ### Cannot use GlobalUnoProps for FilterData property -+ if op.importfilteroptions: -+# print "Import filter options: %s" % op.importfilteroptions -+ inputprops += GlobalUnoProps(FilterOptions=op.importfilteroptions) -+ -+ ### Cannot use GlobalUnoProps for FilterData property -+ if op.importfilter: -+ inputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) -+ -+ inputurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(inputfn)) -+ document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) -+ -+ if not document: -+ raise UnoException("The document '%s' could not be opened." % inputurl, None) -+ -+ ### Import style template -+ phase = "import-style" -+ if op.template: -+ if os.path.exists(op.template): -+ info(1, "Template file: %s" % op.template) -+ templateprops = GlobalUnoProps(OverwriteStyles=True) -+ templateurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(op.template)) -+ document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) -+ else: -+ print('unoconv: template file `%s\' does not exist.' % op.template, file=sys.stderr) -+ exitcode = 1 -+ -+ ### Update document links -+ phase = "update-links" -+ try: -+ document.updateLinks() -+ except AttributeError: -+ # the document doesn't implement the XLinkUpdate interface -+ pass -+ -+ ### Update document indexes -+ phase = "update-indexes" -+ try: -+ document.refresh() -+ indexes = document.getDocumentIndexes() -+ except AttributeError: -+ # the document doesn't implement the XRefreshable and/or -+ # XDocumentIndexesSupplier interfaces -+ pass -+ else: -+ for i in range(0, indexes.getCount()): -+ indexes.getByIndex(i).update() -+ -+ info(1, "Selected output format: %s" % outputfmt) -+ info(2, "Selected office filter: %s" % outputfmt.filter) -+ info(2, "Used doctype: %s" % outputfmt.doctype) -+ -+ ### Export phase -+ phase = "export" -+ -+ outputprops = GlobalUnoProps(FilterName=outputfmt.filter, OutputStream=GlobalOutputStream(), Overwrite=True) -+ -+ ### Set default filter options -+ if op.exportfilteroptions: -+# print "Export filter options: %s" % op.exportfilteroptions -+ outputprops += GlobalUnoProps(FilterOptions=op.exportfilteroptions) -+ else: -+ if outputfmt.filter == 'Text (encoded)': -+ outputprops += GlobalUnoProps(FilterOptions="76,LF") -+ -+ elif outputfmt.filter == 'Text': -+ outputprops += GlobalUnoProps(FilterOptions="76") -+ -+ elif outputfmt.filter == 'Text - txt - csv (StarCalc)': -+ outputprops += GlobalUnoProps(FilterOptions="44,34,76") -+ -+ -+ ### Cannot use GlobalUnoProps for FilterData property -+ if op.exportfilter: -+ outputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) -+ -+ if not op.stdout: -+ (outputfn, ext) = os.path.splitext(inputfn) -+ if not op.output: -+ outputfn = outputfn + os.extsep + outputfmt.extension -+ elif os.path.isdir(op.output): -+ outputfn = realpath(op.output, os.path.basename(outputfn) + os.extsep + outputfmt.extension) -+ elif len(op.filenames) > 1: -+ outputfn = op.output + os.extsep + outputfmt.extension -+ else: -+ outputfn = op.output -+ -+ outputurl = global_unohelper.absolutize( self.cwd, global_unohelper.systemPathToFileUrl(outputfn) ) -+ info(1, "Output file: %s" % outputfn) -+ else: -+ outputurl = "private:stream" -+ -+ try: -+ document.storeToURL(outputurl, tuple(outputprops) ) -+ except UnoIOException as e: -+ raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) -+ -+ phase = "dispose" -+ document.dispose() -+ document.close(True) -+ -+ except SystemError as e: -+ error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) -+ exitcode = 1 -+ -+ except UnoRuntimeException as e: -+ error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) -+ exitcode = 6 -+ -+ except UnoDisposedException as e: -+ error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) -+ exitcode = 7 -+ -+ except UnoIllegalArgumentException as e: -+ error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) -+ exitcode = 8 -+ -+ except UnoIOException as e: -+# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) -+ error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) -+ exitcode = 3 -+ -+ except UnoCannotConvertException as e: -+# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) -+ error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) -+ exitcode = 4 -+ -+ except UnoException as e: -+ if hasattr(e, 'ErrCode'): -+ error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) -+ exitcode = e.ErrCode -+ pass -+ if hasattr(e, 'Message'): -+ error("unoconv: UnoException during %s phase:\n%s" % (phase, e.Message)) -+ exitcode = 5 -+ else: -+ error("unoconv: UnoException during %s phase in %s" % (phase, repr(e.__class__))) -+ exitcode = 2 -+ pass -+ -+class Listener: -+ def __init__(self): -+ global product -+ -+ info(1, "Start listener on %s:%s" % (op.server, op.port)) -+ self.context = global_uno.getComponentContext() -+ self.svcmgr = self.context.ServiceManager -+ try: -+ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) -+ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) -+ try: -+ unocontext = resolver.resolve("uno:%s" % op.connection) -+ except UnoNoConnectException as e: -+ pass -+ else: -+ info(1, "Existing %s listener found, nothing to do." % product.ooName) -+ return -+ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): -+ subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) -+ else: -+ subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) -+ except Exception as e: -+ error("Launch of %s failed.\n%s" % (office.binary, e)) -+ else: -+ info(1, "Existing %s listener found, nothing to do." % product.ooName) -+ -+def error(msg): -+ "Output error message" -+ print(msg, file=sys.stderr) -+ -+def info(level, msg): -+ "Output info message" -+ if 'op' not in globals(): -+ pass -+ elif op.verbose >= 3 and level >= 3: -+ print("DEBUG:", msg, file=sys.stderr) -+ elif not op.stdout and level <= op.verbose: -+ print(msg, file=sys.stdout) -+ elif level <= op.verbose: -+ print(msg, file=sys.stderr) -+ -+def die(ret, msg=None): -+ "Print optional error and exit with errorcode" -+ global convertor, ooproc, office -+ -+ if msg: -+ error('Error: %s' % msg) -+ -+ ### Did we start our own listener instance ? -+ if not op.listener and ooproc and convertor: -+ -+ ### If there is a GUI now attached to the instance, disable listener -+ if convertor.desktop.getCurrentFrame(): -+ info(2, 'Trying to stop %s GUI listener.' % product.ooName) -+ try: -+ if product.ooName != "LibreOffice" or product.ooSetupVersion <= 3.3: -+ subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-unaccept=%s" % op.connection], env=os.environ) -+ else: -+ subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) -+ ooproc.wait() -+ info(2, '%s listener successfully disabled.' % product.ooName) -+ except Exception as e: -+ error("Terminate using %s failed.\n%s" % (office.binary, e)) -+ -+ ### If there is no GUI attached to the instance, terminate instance -+ else: -+ info(3, 'Terminating %s instance.' % product.ooName) -+ try: -+ convertor.desktop.terminate() -+ except UnoDisposedException: -+ info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) -+ try: -+ ooproc.terminate() -+ except AttributeError: -+ os.kill(ooproc.pid, 15) -+ info(3, 'Waiting for %s instance to exit.' % product.ooName) -+ ooproc.wait() -+ -+ ### LibreOffice processes may get stuck and we have to kill them -+ ### Is it still running ? -+ if ooproc.poll() == None: -+ info(1, '%s instance still running, please investigate...' % product.ooName) -+ ooproc.wait() -+ info(2, '%s instance unsuccessfully terminated, sending KILL signal.' % product.ooName) -+ try: -+ ooproc.kill() -+ except AttributeError: -+ os.kill(ooproc.pid, 9) -+ info(3, 'Waiting for %s with pid %s to disappear.' % (ooproc.pid, product.ooName)) -+ ooproc.wait() -+ -+ # allow Python GC to garbage collect pyuno object *before* exit call -+ # which avoids random segmentation faults --vpa -+ convertor = None -+ -+ sys.exit(ret) -+ -+def main(): -+ global convertor, exitcode -+ convertor = None -+ -+ try: -+ if op.listener: -+ listener = Listener() -+ -+ if op.filenames: -+ convertor = Convertor() -+ for inputfn in op.filenames: -+ convertor.convert(inputfn) -+ -+ except UnoNoConnectException as e: -+ error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) -+ if op.connection: -+ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) -+ else: -+ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"socket,host=%s,port=%s;urp;\"" % (op.server, op.server, op.port, op.server, op.port)) -+ info(0, "Please start an soffice instance on server '%s' by doing:\n\n soffice -nologo -nodefault -accept=\"socket,host=127.0.0.1,port=%s;urp;\"" % (op.server, op.port)) -+ exitcode = 1 -+# except UnboundLocalError: -+# die(252, "Failed to connect to remote listener.") -+ except OSError: -+ error("Warning: failed to launch Office suite. Aborting.") -+ -+### Main entrance -+def run(): -+ global exitcode -+ exitcode = 0 -+ -+ info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) -+ -+ for of in find_offices(): -+ if of.python != sys.executable and not sys.executable.startswith(of.basepath): -+ python_switch(of) -+ office_environ(of) -+# debug_office() -+ try: -+ global global_uno -+ global global_unohelper -+ -+ import uno as global_uno -+ import unohelper as global_unohelper -+ global office -+ office = of -+ break -+ except: -+# debug_office() -+ print("unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of, file=sys.stderr) -+ print("ERROR:", sys.exc_info()[1], file=sys.stderr) -+ print(file=sys.stderr) -+ else: -+# debug_office() -+ print("unoconv: Cannot find a suitable office installation on your system.", file=sys.stderr) -+ print("ERROR: Please locate your office installation and send your feedback to:", file=sys.stderr) -+ print(" http://github.com/dagwieers/unoconv/issues", file=sys.stderr) -+ sys.exit(1) -+ -+ ### Now that we have found a working pyuno library, let's import some classes -+ global UnoPropertyValue -+ global UnoNoConnectException -+ global UNO_QUIET_UPDATE -+ global UnoDisposedException -+ global UnoIllegalArgumentException -+ global UnoIOException -+ global UnoXOutputStream -+ global UnoCannotConvertException -+ global UnoException -+ global UnoRuntimeException -+ -+ from com.sun.star.beans import PropertyValue as UnoPropertyValue -+ from com.sun.star.connection import NoConnectException as UnoNoConnectException -+ from com.sun.star.document.UpdateDocMode import QUIET_UPDATE as UNO_QUIET_UPDATE -+ from com.sun.star.lang import DisposedException as UnoDisposedException -+ from com.sun.star.lang import IllegalArgumentException as UnoIllegalArgumentException -+ from com.sun.star.io import IOException as UnoIOException -+ from com.sun.star.io import XOutputStream as UnoXOutputStream -+ from com.sun.star.script import CannotConvertException as UnoCannotConvertException -+ from com.sun.star.uno import Exception as UnoException -+ from com.sun.star.uno import RuntimeException as UnoRuntimeException -+ -+ ### And now that we have those classes, build on them -+ class OutputStream( global_unohelper.Base, UnoXOutputStream ): -+ def __init__( self ): -+ self.closed = 0 -+ -+ def closeOutput(self): -+ self.closed = 1 -+ -+ def writeBytes( self, seq ): -+ sys.stdout.write( seq.value ) -+ -+ def flush( self ): -+ pass -+ -+ global GlobalOutputStream -+ GlobalOutputStream = OutputStream -+ -+ def UnoProps(**args): -+ props = [] -+ for key in args: -+ prop = UnoPropertyValue() -+ prop.Name = key -+ prop.Value = args[key] -+ props.append(prop) -+ return tuple(props) -+ -+ global GlobalUnoProps -+ GlobalUnoProps = UnoProps -+ -+ global op -+ op = Options(sys.argv[1:]) -+ -+ info(2, "Using office base path: %s" % office.basepath) -+ info(2, "Using office binary path: %s" % office.unopath) -+ -+ try: -+ main() -+ except KeyboardInterrupt as e: -+ die(6, 'Exiting on user request') -+ die(exitcode) -+ -+if __name__ == '__main__': -+ run() --- -1.7.11.7 - diff --git a/0001-update-FSF-address.patch b/0001-update-FSF-address.patch index da5f208..925cf4f 100644 --- a/0001-update-FSF-address.patch +++ b/0001-update-FSF-address.patch @@ -139,34 +139,6 @@ index 30e6706..e4a1ac8 100755 -### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +### Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +### MA 02110-1301 USA. - - import sys - -diff --git a/unoconv2.py b/unoconv2.py -index 30e6706..e4a1ac8 100755 ---- a/unoconv2.py -+++ b/unoconv2.py -@@ -11,7 +11,8 @@ - ### - ### You should have received a copy of the GNU General Public License - ### along with this program; if not, write to the Free Software --### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+### Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, -+### MA 02110-1301 USA. - ### Copyright 2007-2010 Dag Wieers - - from distutils.version import LooseVersion -diff --git a/unoconv3.py b/unoconv3.py -index 30e6706..e4a1ac8 100755 ---- a/unoconv3.py -+++ b/unoconv3.py -@@ -11,7 +11,8 @@ - ### - ### You should have received a copy of the GNU General Public License - ### along with this program; if not, write to the Free Software --### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+### Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, -+### MA 02110-1301 USA. ### Copyright 2007-2010 Dag Wieers from distutils.version import LooseVersion diff --git a/unoconv.spec b/unoconv.spec index 5fe9657..bb314cf 100644 --- a/unoconv.spec +++ b/unoconv.spec @@ -7,7 +7,11 @@ Group: System Environment/Base URL: http://dag.wieers.com/home-made/unoconv/ Source: http://dag.wieers.com/home-made/%{name}/%{name}-%{version}.tar.gz Patch0: 0001-Fix-a-broken-export-option-and-add-V-as-alternative-.patch -Patch1: 0001-python3-added-compatibility.patch +%if 0%{?rhel} +Patch1: 0001-python3-added-compatibility.2.patch +%else +Patch1: 0001-python3-added-compatibility.3.patch +%endif Patch2: 0001-update-FSF-address.patch Patch3: 0001-Resolves-fdo-70309-can-t-write-bytes-direct-to-stdou.patch @@ -32,16 +36,6 @@ RTF, Docbook (.xml), and more. %install make install DESTDIR="%{buildroot}" -pushd %{buildroot}/%{_bindir} -%if 0%{?fedora} >= 19 - mv %{name}3.py %{name} - rm %{name}2.py -%else - mv %{name}2.py %{name} - rm %{name}3.py -%endif -popd - %files %doc AUTHORS ChangeLog COPYING README.asciidoc WISHLIST doc/*.txt tests/