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