diff --git a/.unoconv.metadata b/.unoconv.metadata new file mode 100644 index 0000000..b17f7e2 --- /dev/null +++ b/.unoconv.metadata @@ -0,0 +1 @@ +d6c3574639b9ceedcb866b84f18ba7158f25db48 SOURCES/unoconv-0.6.tar.gz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/0001-Fix-a-broken-export-option-and-add-V-as-alternative-.patch b/SOURCES/0001-Fix-a-broken-export-option-and-add-V-as-alternative-.patch new file mode 100644 index 0000000..264a279 --- /dev/null +++ b/SOURCES/0001-Fix-a-broken-export-option-and-add-V-as-alternative-.patch @@ -0,0 +1,38 @@ +From 3c20d6ec49a97c24cfb1fe9fd61ac80944819088 Mon Sep 17 00:00:00 2001 +From: Dag Wieers +Date: Fri, 28 Sep 2012 19:33:01 +0200 +Subject: [PATCH] Fix a broken --export option and add -V as alternative to + --version + +This closes #93. +--- + unoconv | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/unoconv b/unoconv +index 972e962..30e6706 100755 +--- a/unoconv ++++ b/unoconv +@@ -524,8 +524,8 @@ class Options: + + ### Get options from the commandline + try: +- opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:v', +- ['connection=', 'debug', 'doctype=', 'export', 'format=', ++ opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', ++ ['connection=', 'debug', 'doctype=', 'export=', 'format=', + 'help', 'import', 'listener', 'no-launch', 'output=', + 'outputpath', 'password=', 'pipe=', 'port=', 'server=', + 'timeout=', 'show', 'stdout', 'template', 'verbose', +@@ -609,7 +609,7 @@ class Options: + self.timeout = int(arg) + elif opt in ['-v', '--verbose']: + self.verbose = self.verbose + 1 +- elif opt in ['--version']: ++ elif opt in ['-V', '--version']: + self.version() + sys.exit(255) + +-- +1.7.11.7 + diff --git a/SOURCES/0001-python3-added-compatibility.patch b/SOURCES/0001-python3-added-compatibility.patch new file mode 100644 index 0000000..e8d3bca --- /dev/null +++ b/SOURCES/0001-python3-added-compatibility.patch @@ -0,0 +1,3628 @@ +From 6eba87f4654d3f142070c1fe9f272bf787885861 Mon Sep 17 00:00:00 2001 +From: Andres Gomez +Date: Thu, 4 Apr 2013 13:18:06 +0300 +Subject: [PATCH] python3: added compatibility + +Dodgy solution in which we create a python2 and +python3 compatible wrapper that would import the +old script, or a new automatically migrated +version. + +The automatic migration was done with the 2to3 +tool after modifying the original script so we can +invoke it as a module. + +This is needed since LibreOffice is providing its +own python3 bundled package since 4.x series. +--- + Makefile | 2 + + packaging/rpm/unoconv.spec | 2 + + unoconv | 1154 +----------------------------------------- + unoconv2.py | 1195 ++++++++++++++++++++++++++++++++++++++++++++ + unoconv3.py | 1195 ++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 2406 insertions(+), 1142 deletions(-) + create mode 100755 unoconv2.py + create mode 100755 unoconv3.py + +diff --git a/Makefile b/Makefile +index 9bb18f6..b950583 100644 +--- a/Makefile ++++ b/Makefile +@@ -111,6 +111,8 @@ install: + install -d -m0755 $(DESTDIR)$(bindir) + install -d -m0755 $(DESTDIR)$(mandir)/man1/ + install -p -m0755 unoconv $(DESTDIR)$(bindir)/unoconv ++ install -p -m0755 unoconv2.py $(DESTDIR)$(bindir)/unoconv2.py ++ install -p -m0755 unoconv3.py $(DESTDIR)$(bindir)/unoconv3.py + install -p -m0644 doc/unoconv.1 $(DESTDIR)$(mandir)/man1/unoconv.1 + + install-links: $(links) +diff --git a/packaging/rpm/unoconv.spec b/packaging/rpm/unoconv.spec +index 4801dd3..c077fec 100644 +--- a/packaging/rpm/unoconv.spec ++++ b/packaging/rpm/unoconv.spec +@@ -49,6 +49,8 @@ and many more... + %doc AUTHORS ChangeLog COPYING README* WISHLIST doc/ tests/ + %doc %{_mandir}/man1/unoconv.1* + %{_bindir}/unoconv ++%{_bindir}/unoconv2.py ++%{_bindir}/unoconv3.py + + %changelog + * Mon Sep 10 2012 Dag Wieers - 0.6-1 +diff --git a/unoconv b/unoconv +index 30e6706..ed603af 100755 +--- a/unoconv ++++ b/unoconv +@@ -12,1154 +12,24 @@ + ### You should have received a copy of the GNU General Public License + ### along with this program; if not, write to the Free Software + ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-### Copyright 2007-2010 Dag Wieers + +-from distutils.version import LooseVersion +-import getopt +-import glob +-import os +-import subprocess + import sys +-import time + +-__version__ = "$Revision$" +-# $Source$ ++### Extremely dodgy solution for running python2 or python3 versions ++### of the unoconv script + +-VERSION = '0.6' ++### This is needed since LibreOffice is providing its own python3 ++### bundled package since 4.x series + +-doctypes = ('document', 'graphics', 'presentation', 'spreadsheet') ++### A much more proper solution would be to modify the code so it ++### would be compatible with both versions or, if not possible, to ++### create real python modules out of the code and import them in a ++### proper way + +-global convertor, office, ooproc, product +-ooproc = None +-exitcode = 0 +- +-class Office: +- def __init__(self, basepath, urepath, unopath, pyuno, binary, python, pythonhome): +- self.basepath = basepath +- self.urepath = urepath +- self.unopath = unopath +- self.pyuno = pyuno +- self.binary = binary +- self.python = python +- self.pythonhome = pythonhome +- +- def __str__(self): +- return self.basepath +- +- def __repr__(self): +- return self.basepath +- +-### Implement a path normalizer in order to make unoconv work on MacOS X +-### (on which 'program' is a symlink to 'MacOSX' which seems to break unoconv) +-def realpath(*args): +- ''' Implement a combination of os.path.join(), os.path.abspath() and +- os.path.realpath() in order to normalize path constructions ''' +- ret = '' +- for arg in args: +- ret = os.path.join(ret, arg) +- return os.path.realpath(os.path.abspath(ret)) +- +-### The first thing we ought to do is find a suitable Office installation +-### with a compatible pyuno library that we can import. +-### +-### See: http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p=166783 +- +-def find_offices(): +- ret = [] +- extrapaths = [] +- +- ### Try using UNO_PATH first (in many incarnations, we'll see what sticks) +- if 'UNO_PATH' in os.environ: +- extrapaths += [ os.environ['UNO_PATH'], +- os.path.dirname(os.environ['UNO_PATH']), +- os.path.dirname(os.path.dirname(os.environ['UNO_PATH'])) ] +- +- else: +- +- if os.name in ( 'nt', 'os2' ): +- if 'PROGRAMFILES' in os.environ.keys(): +- extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ +- glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') +- +- if 'PROGRAMFILES(X86)' in os.environ.keys(): +- extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ +- glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') +- +- elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): +- extrapaths += [ '/Applications/LibreOffice.app/Contents', +- '/Applications/NeoOffice.app/Contents', +- '/Applications/OpenOffice.org.app/Contents' ] +- +- else: +- extrapaths += glob.glob('/usr/lib*/libreoffice*') + \ +- glob.glob('/usr/lib*/openoffice*') + \ +- glob.glob('/usr/lib*/ooo*') + \ +- glob.glob('/opt/libreoffice*') + \ +- glob.glob('/opt/openoffice*') + \ +- glob.glob('/opt/ooo*') + \ +- glob.glob('/usr/local/libreoffice*') + \ +- glob.glob('/usr/local/openoffice*') + \ +- glob.glob('/usr/local/ooo*') + \ +- glob.glob('/usr/local/lib/libreoffice*') +- +- ### Find a working set for python UNO bindings +- for basepath in extrapaths: +- if os.name in ( 'nt', 'os2' ): +- officelibraries = ( 'pyuno.pyd', ) +- officebinaries = ( 'soffice.exe' ,) +- pythonbinaries = ( 'python.exe', ) +- pythonhomes = () +- elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): +- officelibraries = ( 'pyuno.so', 'libpyuno.dylib' ) +- officebinaries = ( 'soffice.bin', ) +- pythonbinaries = ( 'python.bin', 'python' ) +- pythonhomes = ( 'OOoPython.framework/Versions/*/lib/python*', ) +- else: +- officelibraries = ( 'pyuno.so', ) +- officebinaries = ( 'soffice.bin', ) +- pythonbinaries = ( 'python.bin', 'python', ) +- pythonhomes = ( 'python-core-*', ) +- +- ### Older LibreOffice/OpenOffice and Windows use basis-link/ or basis/ +- libpath = 'error' +- for basis in ( 'basis-link', 'basis', '' ): +- for lib in officelibraries: +- if os.path.isfile(realpath(basepath, basis, 'program', lib)): +- libpath = realpath(basepath, basis, 'program') +- officelibrary = realpath(libpath, lib) +- info(3, "Found %s in %s" % (lib, libpath)) +- # Break the inner loop... +- break +- # Continue if the inner loop wasn't broken. +- else: +- continue +- # Inner loop was broken, break the outer. +- break +- else: +- continue +- +- ### MacOSX have soffice binaries installed in MacOS subdirectory, not program +- unopath = 'error' +- for basis in ( 'basis-link', 'basis', '' ): +- for bin in officebinaries: +- if os.path.isfile(realpath(basepath, basis, 'program', bin)): +- unopath = realpath(basepath, basis, 'program') +- officebinary = realpath(unopath, bin) +- info(3, "Found %s in %s" % (bin, unopath)) +- # Break the inner loop... +- break +- # Continue if the inner loop wasn't broken. +- else: +- continue +- # Inner loop was broken, break the outer. +- break +- else: +- continue +- +- ### Windows does not provide or need a URE/lib directory ? +- urepath = '' +- for basis in ( 'basis-link', 'basis', '' ): +- for ure in ( 'ure-link', 'ure', 'URE', '' ): +- if os.path.isfile(realpath(basepath, basis, ure, 'lib', 'unorc')): +- urepath = realpath(basepath, basis, ure) +- info(3, "Found %s in %s" % ('unorc', realpath(urepath, 'lib'))) +- # Break the inner loop... +- break +- # Continue if the inner loop wasn't broken. +- else: +- continue +- # Inner loop was broken, break the outer. +- break +- +- pythonhome = None +- for home in pythonhomes: +- if glob.glob(realpath(libpath, home)): +- pythonhome = glob.glob(realpath(libpath, home))[0] +- info(3, "Found %s in %s" % (home, pythonhome)) +- break +- +-# if not os.path.isfile(realpath(basepath, program, officebinary)): +-# continue +-# info(3, "Found %s in %s" % (officebinary, realpath(basepath, program))) +- +-# if not glob.glob(realpath(basepath, basis, program, 'python-core-*')): +-# continue +- +- for pythonbinary in pythonbinaries: +- if os.path.isfile(realpath(unopath, pythonbinary)): +- info(3, "Found %s in %s" % (pythonbinary, unopath)) +- ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, +- realpath(unopath, pythonbinary), pythonhome)) +- else: +- info(3, "Considering %s" % basepath) +- ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, +- sys.executable, None)) +- return ret +- +-def office_environ(office): +- ### Set PATH so that crash_report is found +- os.environ['PATH'] = realpath(office.basepath, 'program') + os.pathsep + os.environ['PATH'] +- +- ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: +- os.environ['UNO_PATH'] = office.unopath +- +- ### Set URE_BOOTSTRAP so that "uno.getComponentContext()" bootstraps a complete +- ### UNO environment +- if os.name in ( 'nt', 'os2' ): +- os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') +- else: +- os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamentalrc') +- +- ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: +- if 'LD_LIBRARY_PATH' in os.environ: +- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ +- realpath(office.urepath, 'lib') + os.pathsep + \ +- os.environ['LD_LIBRARY_PATH'] +- else: +- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ +- realpath(office.urepath, 'lib') +- +- if office.pythonhome: +- for libpath in ( realpath(office.pythonhome, 'lib'), +- realpath(office.pythonhome, 'lib', 'lib-dynload'), +- realpath(office.pythonhome, 'lib', 'lib-tk'), +- realpath(office.pythonhome, 'lib', 'site-packages'), +- office.unopath): +- sys.path.insert(0, libpath) +- else: +- ### Still needed for system python using LibreOffice UNO bindings +- ### Although we prefer to use a system UNO binding in this case +- sys.path.append(office.unopath) +- +-def debug_office(): +- if 'URE_BOOTSTRAP' in os.environ: +- print >>sys.stderr, 'URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'] +- if 'UNO_PATH' in os.environ: +- print >>sys.stderr, 'UNO_PATH=%s' % os.environ['UNO_PATH'] +- if 'UNO_TYPES' in os.environ: +- print >>sys.stderr, 'UNO_TYPES=%s' % os.environ['UNO_TYPES'] +- print 'PATH=%s' % os.environ['PATH'] +- if 'PYTHONHOME' in os.environ: +- print >>sys.stderr, 'PYTHONHOME=%s' % os.environ['PYTHONHOME'] +- if 'PYTHONPATH' in os.environ: +- print >>sys.stderr, 'PYTHONPATH=%s' % os.environ['PYTHONPATH'] +- if 'LD_LIBRARY_PATH' in os.environ: +- print >>sys.stderr, 'LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'] +- +-def python_switch(office): +- if office.pythonhome: +- os.environ['PYTHONHOME'] = office.pythonhome +- os.environ['PYTHONPATH'] = realpath(office.pythonhome, 'lib') + os.pathsep + \ +- realpath(office.pythonhome, 'lib', 'lib-dynload') + os.pathsep + \ +- realpath(office.pythonhome, 'lib', 'lib-tk') + os.pathsep + \ +- realpath(office.pythonhome, 'lib', 'site-packages') + os.pathsep + \ +- office.unopath +- +- os.environ['UNO_PATH'] = office.unopath +- +- info(3, "-> Switching from %s to %s" % (sys.executable, office.python)) +- if os.name in ('nt', 'os2'): +- ### os.execv is broken on Windows and can't properly parse command line +- ### arguments and executable name if they contain whitespaces. subprocess +- ### fixes that behavior. +- ret = subprocess.call([office.python] + sys.argv[0:]) +- sys.exit(ret) +- else: +- +- ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: +- if 'LD_LIBRARY_PATH' in os.environ: +- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ +- realpath(office.urepath, 'lib') + os.pathsep + \ +- os.environ['LD_LIBRARY_PATH'] +- else: +- os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ +- realpath(office.urepath, 'lib') +- +- try: +- os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) +- except OSError: +- ### Mac OS X versions prior to 10.6 do not support execv in +- ### a process that contains multiple threads. Instead of +- ### re-executing in the current process, start a new one +- ### and cause the current process to exit. This isn't +- ### ideal since the new process is detached from the parent +- ### terminal and thus cannot easily be killed with ctrl-C, +- ### but it's better than not being able to autoreload at +- ### all. +- ### Unfortunately the errno returned in this case does not +- ### appear to be consistent, so we can't easily check for +- ### this error specifically. +- ret = os.spawnvpe(os.P_WAIT, office.python, [office.python, ] + sys.argv[0:], os.environ) +- sys.exit(ret) +- +-class Fmt: +- def __init__(self, doctype, name, extension, summary, filter): +- self.doctype = doctype +- self.name = name +- self.extension = extension +- self.summary = summary +- self.filter = filter +- +- def __str__(self): +- return "%s [.%s]" % (self.summary, self.extension) +- +- def __repr__(self): +- return "%s/%s" % (self.name, self.doctype) +- +-class FmtList: +- def __init__(self): +- self.list = [] +- +- def add(self, doctype, name, extension, summary, filter): +- self.list.append(Fmt(doctype, name, extension, summary, filter)) +- +- def byname(self, name): +- ret = [] +- for fmt in self.list: +- if fmt.name == name: +- ret.append(fmt) +- return ret +- +- def byextension(self, extension): +- ret = [] +- for fmt in self.list: +- if os.extsep + fmt.extension == extension: +- ret.append(fmt) +- return ret +- +- def bydoctype(self, doctype, name): +- ret = [] +- for fmt in self.list: +- if fmt.name == name and fmt.doctype == doctype: +- ret.append(fmt) +- return ret +- +- def display(self, doctype): +- print >>sys.stderr, "The following list of %s formats are currently available:\n" % doctype +- for fmt in self.list: +- if fmt.doctype == doctype: +- print >>sys.stderr, " %-8s - %s" % (fmt.name, fmt) +- print >>sys.stderr +- +-fmts = FmtList() +- +-### TextDocument +-fmts.add('document', 'bib', 'bib', 'BibTeX', 'BibTeX_Writer') ### 22 +-fmts.add('document', 'doc', 'doc', 'Microsoft Word 97/2000/XP', 'MS Word 97') ### 29 +-fmts.add('document', 'doc6', 'doc', 'Microsoft Word 6.0', 'MS WinWord 6.0') ### 24 +-fmts.add('document', 'doc95', 'doc', 'Microsoft Word 95', 'MS Word 95') ### 28 +-fmts.add('document', 'docbook', 'xml', 'DocBook', 'DocBook File') ### 39 +-fmts.add('document', 'docx', 'docx', 'Microsoft Office Open XML', 'Office Open XML Text') +-fmts.add('document', 'docx7', 'docx', 'Microsoft Office Open XML', 'MS Word 2007 XML') +-fmts.add('document', 'fodt', 'fodt', 'OpenDocument Text (Flat XML)', 'OpenDocument Text Flat XML') +-fmts.add('document', 'html', 'html', 'HTML Document (OpenOffice.org Writer)', 'HTML (StarWriter)') ### 3 +-fmts.add('document', 'latex', 'ltx', 'LaTeX 2e', 'LaTeX_Writer') ### 31 +-fmts.add('document', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki') +-fmts.add('document', 'odt', 'odt', 'ODF Text Document', 'writer8') ### 10 +-fmts.add('document', 'ooxml', 'xml', 'Microsoft Office Open XML', 'MS Word 2003 XML') ### 11 +-fmts.add('document', 'ott', 'ott', 'Open Document Text', 'writer8_template') ### 21 +-fmts.add('document', 'pdb', 'pdb', 'AportisDoc (Palm)', 'AportisDoc Palm DB') +-fmts.add('document', 'pdf', 'pdf', 'Portable Document Format', 'writer_pdf_Export') ### 18 +-fmts.add('document', 'psw', 'psw', 'Pocket Word', 'PocketWord File') +-fmts.add('document', 'rtf', 'rtf', 'Rich Text Format', 'Rich Text Format') ### 16 +-fmts.add('document', 'sdw', 'sdw', 'StarWriter 5.0', 'StarWriter 5.0') ### 23 +-fmts.add('document', 'sdw4', 'sdw', 'StarWriter 4.0', 'StarWriter 4.0') ### 2 +-fmts.add('document', 'sdw3', 'sdw', 'StarWriter 3.0', 'StarWriter 3.0') ### 20 +-fmts.add('document', 'stw', 'stw', 'Open Office.org 1.0 Text Document Template', 'writer_StarOffice_XML_Writer_Template') ### 9 +-fmts.add('document', 'sxw', 'sxw', 'Open Office.org 1.0 Text Document', 'StarOffice XML (Writer)') ### 1 +-fmts.add('document', 'text', 'txt', 'Text Encoded', 'Text (encoded)') ### 26 +-fmts.add('document', 'txt', 'txt', 'Text', 'Text') ### 34 +-fmts.add('document', 'uot', 'uot', 'Unified Office Format text','UOF text') ### 27 +-fmts.add('document', 'vor', 'vor', 'StarWriter 5.0 Template', 'StarWriter 5.0 Vorlage/Template') ### 6 +-fmts.add('document', 'vor4', 'vor', 'StarWriter 4.0 Template', 'StarWriter 4.0 Vorlage/Template') ### 5 +-fmts.add('document', 'vor3', 'vor', 'StarWriter 3.0 Template', 'StarWriter 3.0 Vorlage/Template') ### 4 +-fmts.add('document', 'xhtml', 'html', 'XHTML Document', 'XHTML Writer File') ### 33 +- +-### WebDocument +-fmts.add('web', 'etext', 'txt', 'Text Encoded (OpenOffice.org Writer/Web)', 'Text (encoded) (StarWriter/Web)') ### 14 +-fmts.add('web', 'html10', 'html', 'OpenOffice.org 1.0 HTML Template', 'writer_web_StarOffice_XML_Writer_Web_Template') ### 11 +-fmts.add('web', 'html', 'html', 'HTML Document', 'HTML') ### 2 +-fmts.add('web', 'html', 'html', 'HTML Document Template', 'writerweb8_writer_template') ### 13 +-fmts.add('web', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki_Web') ### 9 +-fmts.add('web', 'pdf', 'pdf', 'PDF - Portable Document Format', 'writer_web_pdf_Export') ### 10 +-fmts.add('web', 'sdw3', 'sdw', 'StarWriter 3.0 (OpenOffice.org Writer/Web)', 'StarWriter 3.0 (StarWriter/Web)') ### 3 +-fmts.add('web', 'sdw4', 'sdw', 'StarWriter 4.0 (OpenOffice.org Writer/Web)', 'StarWriter 4.0 (StarWriter/Web)') ### 4 +-fmts.add('web', 'sdw', 'sdw', 'StarWriter 5.0 (OpenOffice.org Writer/Web)', 'StarWriter 5.0 (StarWriter/Web)') ### 5 +-fmts.add('web', 'txt', 'txt', 'OpenOffice.org Text (OpenOffice.org Writer/Web)', 'writerweb8_writer') ### 12 +-fmts.add('web', 'text10', 'txt', 'OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)', 'writer_web_StarOffice_XML_Writer') ### 15 +-fmts.add('web', 'text', 'txt', 'Text (OpenOffice.org Writer/Web)', 'Text (StarWriter/Web)') ### 8 +-fmts.add('web', 'vor4', 'vor', 'StarWriter/Web 4.0 Template', 'StarWriter/Web 4.0 Vorlage/Template') ### 6 +-fmts.add('web', 'vor', 'vor', 'StarWriter/Web 5.0 Template', 'StarWriter/Web 5.0 Vorlage/Template') ### 7 +- +-### Spreadsheet +-fmts.add('spreadsheet', 'csv', 'csv', 'Text CSV', 'Text - txt - csv (StarCalc)') ### 16 +-fmts.add('spreadsheet', 'dbf', 'dbf', 'dBASE', 'dBase') ### 22 +-fmts.add('spreadsheet', 'dif', 'dif', 'Data Interchange Format', 'DIF') ### 5 +-fmts.add('spreadsheet', 'fods', 'fods', 'OpenDocument Spreadsheet (Flat XML)', 'OpenDocument Spreadsheet Flat XML') +-fmts.add('spreadsheet', 'html', 'html', 'HTML Document (OpenOffice.org Calc)', 'HTML (StarCalc)') ### 7 +-fmts.add('spreadsheet', 'ods', 'ods', 'ODF Spreadsheet', 'calc8') ### 15 +-fmts.add('spreadsheet', 'ooxml', 'xml', 'Microsoft Excel 2003 XML', 'MS Excel 2003 XML') ### 23 +-fmts.add('spreadsheet', 'ots', 'ots', 'ODF Spreadsheet Template', 'calc8_template') ### 14 +-fmts.add('spreadsheet', 'pdf', 'pdf', 'Portable Document Format', 'calc_pdf_Export') ### 34 +-fmts.add('spreadsheet', 'pxl', 'pxl', 'Pocket Excel', 'Pocket Excel') +-fmts.add('spreadsheet', 'sdc', 'sdc', 'StarCalc 5.0', 'StarCalc 5.0') ### 31 +-fmts.add('spreadsheet', 'sdc4', 'sdc', 'StarCalc 4.0', 'StarCalc 4.0') ### 11 +-fmts.add('spreadsheet', 'sdc3', 'sdc', 'StarCalc 3.0', 'StarCalc 3.0') ### 29 +-fmts.add('spreadsheet', 'slk', 'slk', 'SYLK', 'SYLK') ### 35 +-fmts.add('spreadsheet', 'stc', 'stc', 'OpenOffice.org 1.0 Spreadsheet Template', 'calc_StarOffice_XML_Calc_Template') ### 2 +-fmts.add('spreadsheet', 'sxc', 'sxc', 'OpenOffice.org 1.0 Spreadsheet', 'StarOffice XML (Calc)') ### 3 +-fmts.add('spreadsheet', 'uos', 'uos', 'Unified Office Format spreadsheet', 'UOF spreadsheet') ### 9 +-fmts.add('spreadsheet', 'vor3', 'vor', 'StarCalc 3.0 Template', 'StarCalc 3.0 Vorlage/Template') ### 18 +-fmts.add('spreadsheet', 'vor4', 'vor', 'StarCalc 4.0 Template', 'StarCalc 4.0 Vorlage/Template') ### 19 +-fmts.add('spreadsheet', 'vor', 'vor', 'StarCalc 5.0 Template', 'StarCalc 5.0 Vorlage/Template') ### 20 +-fmts.add('spreadsheet', 'xhtml', 'xhtml', 'XHTML', 'XHTML Calc File') ### 26 +-fmts.add('spreadsheet', 'xls', 'xls', 'Microsoft Excel 97/2000/XP', 'MS Excel 97') ### 12 +-fmts.add('spreadsheet', 'xls5', 'xls', 'Microsoft Excel 5.0', 'MS Excel 5.0/95') ### 8 +-fmts.add('spreadsheet', 'xls95', 'xls', 'Microsoft Excel 95', 'MS Excel 95') ### 10 +-fmts.add('spreadsheet', 'xlt', 'xlt', 'Microsoft Excel 97/2000/XP Template', 'MS Excel 97 Vorlage/Template') ### 6 +-fmts.add('spreadsheet', 'xlt5', 'xlt', 'Microsoft Excel 5.0 Template', 'MS Excel 5.0/95 Vorlage/Template') ### 28 +-fmts.add('spreadsheet', 'xlt95', 'xlt', 'Microsoft Excel 95 Template', 'MS Excel 95 Vorlage/Template') ### 21 +- +-### Graphics +-fmts.add('graphics', 'bmp', 'bmp', 'Windows Bitmap', 'draw_bmp_Export') ### 21 +-fmts.add('graphics', 'emf', 'emf', 'Enhanced Metafile', 'draw_emf_Export') ### 15 +-fmts.add('graphics', 'eps', 'eps', 'Encapsulated PostScript', 'draw_eps_Export') ### 48 +-fmts.add('graphics', 'fodg', 'fodg', 'OpenDocument Drawing (Flat XML)', 'OpenDocument Drawing Flat XML') +-fmts.add('graphics', 'gif', 'gif', 'Graphics Interchange Format', 'draw_gif_Export') ### 30 +-fmts.add('graphics', 'html', 'html', 'HTML Document (OpenOffice.org Draw)', 'draw_html_Export') ### 37 +-fmts.add('graphics', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'draw_jpg_Export') ### 3 +-fmts.add('graphics', 'met', 'met', 'OS/2 Metafile', 'draw_met_Export') ### 43 +-fmts.add('graphics', 'odd', 'odd', 'OpenDocument Drawing', 'draw8') ### 6 +-fmts.add('graphics', 'otg', 'otg', 'OpenDocument Drawing Template', 'draw8_template') ### 20 +-fmts.add('graphics', 'pbm', 'pbm', 'Portable Bitmap', 'draw_pbm_Export') ### 14 +-fmts.add('graphics', 'pct', 'pct', 'Mac Pict', 'draw_pct_Export') ### 41 +-fmts.add('graphics', 'pdf', 'pdf', 'Portable Document Format', 'draw_pdf_Export') ### 28 +-fmts.add('graphics', 'pgm', 'pgm', 'Portable Graymap', 'draw_pgm_Export') ### 11 +-fmts.add('graphics', 'png', 'png', 'Portable Network Graphic', 'draw_png_Export') ### 2 +-fmts.add('graphics', 'ppm', 'ppm', 'Portable Pixelmap', 'draw_ppm_Export') ### 5 +-fmts.add('graphics', 'ras', 'ras', 'Sun Raster Image', 'draw_ras_Export') ## 31 +-fmts.add('graphics', 'std', 'std', 'OpenOffice.org 1.0 Drawing Template', 'draw_StarOffice_XML_Draw_Template') ### 53 +-fmts.add('graphics', 'svg', 'svg', 'Scalable Vector Graphics', 'draw_svg_Export') ### 50 +-fmts.add('graphics', 'svm', 'svm', 'StarView Metafile', 'draw_svm_Export') ### 55 +-fmts.add('graphics', 'swf', 'swf', 'Macromedia Flash (SWF)', 'draw_flash_Export') ### 23 +-fmts.add('graphics', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing', 'StarOffice XML (Draw)') ### 26 +-fmts.add('graphics', 'sxd3', 'sxd', 'StarDraw 3.0', 'StarDraw 3.0') ### 40 +-fmts.add('graphics', 'sxd5', 'sxd', 'StarDraw 5.0', 'StarDraw 5.0') ### 44 +-fmts.add('graphics', 'sxw', 'sxw', 'StarOffice XML (Draw)', 'StarOffice XML (Draw)') +-fmts.add('graphics', 'tiff', 'tiff', 'Tagged Image File Format', 'draw_tif_Export') ### 13 +-fmts.add('graphics', 'vor', 'vor', 'StarDraw 5.0 Template', 'StarDraw 5.0 Vorlage') ### 36 +-fmts.add('graphics', 'vor3', 'vor', 'StarDraw 3.0 Template', 'StarDraw 3.0 Vorlage') ### 35 +-fmts.add('graphics', 'wmf', 'wmf', 'Windows Metafile', 'draw_wmf_Export') ### 8 +-fmts.add('graphics', 'xhtml', 'xhtml', 'XHTML', 'XHTML Draw File') ### 45 +-fmts.add('graphics', 'xpm', 'xpm', 'X PixMap', 'draw_xpm_Export') ### 19 +- +-### Presentation +-fmts.add('presentation', 'bmp', 'bmp', 'Windows Bitmap', 'impress_bmp_Export') ### 15 +-fmts.add('presentation', 'emf', 'emf', 'Enhanced Metafile', 'impress_emf_Export') ### 16 +-fmts.add('presentation', 'eps', 'eps', 'Encapsulated PostScript', 'impress_eps_Export') ### 17 +-fmts.add('presentation', 'fodp', 'fodp', 'OpenDocument Presentation (Flat XML)', 'OpenDocument Presentation Flat XML') +-fmts.add('presentation', 'gif', 'gif', 'Graphics Interchange Format', 'impress_gif_Export') ### 18 +-fmts.add('presentation', 'html', 'html', 'HTML Document (OpenOffice.org Impress)', 'impress_html_Export') ### 43 +-fmts.add('presentation', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'impress_jpg_Export') ### 19 +-fmts.add('presentation', 'met', 'met', 'OS/2 Metafile', 'impress_met_Export') ### 20 +-fmts.add('presentation', 'odg', 'odg', 'ODF Drawing (Impress)', 'impress8_draw') ### 29 +-fmts.add('presentation', 'odp', 'odp', 'ODF Presentation', 'impress8') ### 9 +-fmts.add('presentation', 'otp', 'otp', 'ODF Presentation Template', 'impress8_template') ### 38 +-fmts.add('presentation', 'pbm', 'pbm', 'Portable Bitmap', 'impress_pbm_Export') ### 21 +-fmts.add('presentation', 'pct', 'pct', 'Mac Pict', 'impress_pct_Export') ### 22 +-fmts.add('presentation', 'pdf', 'pdf', 'Portable Document Format', 'impress_pdf_Export') ### 23 +-fmts.add('presentation', 'pgm', 'pgm', 'Portable Graymap', 'impress_pgm_Export') ### 24 +-fmts.add('presentation', 'png', 'png', 'Portable Network Graphic', 'impress_png_Export') ### 25 +-fmts.add('presentation', 'potm', 'potm', 'Microsoft PowerPoint 2007/2010 XML Template', 'Impress MS PowerPoint 2007 XML Template') +-fmts.add('presentation', 'pot', 'pot', 'Microsoft PowerPoint 97/2000/XP Template', 'MS PowerPoint 97 Vorlage') ### 3 +-fmts.add('presentation', 'ppm', 'ppm', 'Portable Pixelmap', 'impress_ppm_Export') ### 26 +-fmts.add('presentation', 'pptx', 'pptx', 'Microsoft PowerPoint 2007/2010 XML', 'Impress MS PowerPoint 2007 XML') ### 36 +-fmts.add('presentation', 'pps', 'pps', 'Microsoft PowerPoint 97/2000/XP (Autoplay)', 'MS PowerPoint 97 Autoplay') ### 36 +-fmts.add('presentation', 'ppt', 'ppt', 'Microsoft PowerPoint 97/2000/XP', 'MS PowerPoint 97') ### 36 +-fmts.add('presentation', 'pwp', 'pwp', 'PlaceWare', 'placeware_Export') ### 30 +-fmts.add('presentation', 'ras', 'ras', 'Sun Raster Image', 'impress_ras_Export') ### 27 +-fmts.add('presentation', 'sda', 'sda', 'StarDraw 5.0 (OpenOffice.org Impress)', 'StarDraw 5.0 (StarImpress)') ### 8 +-fmts.add('presentation', 'sdd', 'sdd', 'StarImpress 5.0', 'StarImpress 5.0') ### 6 +-fmts.add('presentation', 'sdd3', 'sdd', 'StarDraw 3.0 (OpenOffice.org Impress)', 'StarDraw 3.0 (StarImpress)') ### 42 +-fmts.add('presentation', 'sdd4', 'sdd', 'StarImpress 4.0', 'StarImpress 4.0') ### 37 +-fmts.add('presentation', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)', 'impress_StarOffice_XML_Draw') ### 31 +-fmts.add('presentation', 'sti', 'sti', 'OpenOffice.org 1.0 Presentation Template', 'impress_StarOffice_XML_Impress_Template') ### 5 +-fmts.add('presentation', 'svg', 'svg', 'Scalable Vector Graphics', 'impress_svg_Export') ### 14 +-fmts.add('presentation', 'svm', 'svm', 'StarView Metafile', 'impress_svm_Export') ### 13 +-fmts.add('presentation', 'swf', 'swf', 'Macromedia Flash (SWF)', 'impress_flash_Export') ### 34 +-fmts.add('presentation', 'sxi', 'sxi', 'OpenOffice.org 1.0 Presentation', 'StarOffice XML (Impress)') ### 41 +-fmts.add('presentation', 'tiff', 'tiff', 'Tagged Image File Format', 'impress_tif_Export') ### 12 +-fmts.add('presentation', 'uop', 'uop', 'Unified Office Format presentation', 'UOF presentation') ### 4 +-fmts.add('presentation', 'vor', 'vor', 'StarImpress 5.0 Template', 'StarImpress 5.0 Vorlage') ### 40 +-fmts.add('presentation', 'vor3', 'vor', 'StarDraw 3.0 Template (OpenOffice.org Impress)', 'StarDraw 3.0 Vorlage (StarImpress)') ###1 +-fmts.add('presentation', 'vor4', 'vor', 'StarImpress 4.0 Template', 'StarImpress 4.0 Vorlage') ### 39 +-fmts.add('presentation', 'vor5', 'vor', 'StarDraw 5.0 Template (OpenOffice.org Impress)', 'StarDraw 5.0 Vorlage (StarImpress)') ### 2 +-fmts.add('presentation', 'wmf', 'wmf', 'Windows Metafile', 'impress_wmf_Export') ### 11 +-fmts.add('presentation', 'xhtml', 'xml', 'XHTML', 'XHTML Impress File') ### 33 +-fmts.add('presentation', 'xpm', 'xpm', 'X PixMap', 'impress_xpm_Export') ### 10 +- +-class Options: +- def __init__(self, args): +- self.connection = None +- self.debug = False +- self.doctype = None +- self.exportfilter = [] +- self.exportfilteroptions = "" +- self.filenames = [] +- self.format = None +- self.importfilter = [] +- self.importfilteroptions = "" +- self.listener = False +- self.nolaunch = False +- self.output = None +- self.password = None +- self.pipe = None +- self.port = '2002' +- self.server = '127.0.0.1' +- self.showlist = False +- self.stdout = False +- self.template = None +- self.timeout = 6 +- self.verbose = 0 +- +- ### Get options from the commandline +- try: +- opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', +- ['connection=', 'debug', 'doctype=', 'export=', 'format=', +- 'help', 'import', 'listener', 'no-launch', 'output=', +- 'outputpath', 'password=', 'pipe=', 'port=', 'server=', +- 'timeout=', 'show', 'stdout', 'template', 'verbose', +- 'version'] ) +- except getopt.error, exc: +- print 'unoconv: %s, try unoconv -h for a list of all the options' % str(exc) +- sys.exit(255) +- +- for opt, arg in opts: +- if opt in ['-h', '--help']: +- self.usage() +- print +- self.help() +- sys.exit(1) +- elif opt in ['-c', '--connection']: +- self.connection = arg +- elif opt in ['--debug']: +- self.debug = True +- elif opt in ['-d', '--doctype']: +- self.doctype = arg +- elif opt in ['-e', '--export']: +- l = arg.split('=') +- if len(l) == 2: +- (name, value) = l +- if name in ('FilterOptions'): +- self.exportfilteroptions = value +- elif value in ('True', 'true'): +- self.exportfilter.append( PropertyValue( name, 0, True, 0 ) ) +- elif value in ('False', 'false'): +- self.exportfilter.append( PropertyValue( name, 0, False, 0 ) ) +- else: +- try: +- self.exportfilter.append( PropertyValue( name, 0, int(value), 0 ) ) +- except ValueError: +- self.exportfilter.append( PropertyValue( name, 0, value, 0 ) ) +- else: +- print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg +- elif opt in ['-f', '--format']: +- self.format = arg +- elif opt in ['-i', '--import']: +- l = arg.split('=') +- if len(l) == 2: +- (name, value) = l +- if name in ('FilterOptions'): +- self.importfilteroptions = value +- elif value in ('True', 'true'): +- self.importfilter.append( PropertyValue( name, 0, True, 0 ) ) +- elif value in ('False', 'false'): +- self.importfilter.append( PropertyValue( name, 0, False, 0 ) ) +- else: +- try: +- self.importfilter.append( PropertyValue( name, 0, int(value), 0 ) ) +- except ValueError: +- self.importfilter.append( PropertyValue( name, 0, value, 0 ) ) +- else: +- print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg +- elif opt in ['-l', '--listener']: +- self.listener = True +- elif opt in ['-n', '--no-launch']: +- self.nolaunch = True +- elif opt in ['-o', '--output']: +- self.output = arg +- elif opt in ['--outputpath']: +- print >>sys.stderr, 'Warning: This option is deprecated by --output.' +- self.output = arg +- elif opt in ['--password']: +- self.password = arg +- elif opt in ['--pipe']: +- self.pipe = arg +- elif opt in ['-p', '--port']: +- self.port = arg +- elif opt in ['-s', '--server']: +- self.server = arg +- elif opt in ['--show']: +- self.showlist = True +- elif opt in ['--stdout']: +- self.stdout = True +- elif opt in ['-t', '--template']: +- self.template = arg +- elif opt in ['-T', '--timeout']: +- self.timeout = int(arg) +- elif opt in ['-v', '--verbose']: +- self.verbose = self.verbose + 1 +- elif opt in ['-V', '--version']: +- self.version() +- sys.exit(255) +- +- ### Enable verbosity +- if self.verbose >= 2: +- print >>sys.stderr, 'Verbosity set to level %d' % self.verbose +- +- self.filenames = args +- +- if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: +- print >>sys.stderr, 'unoconv: you have to provide a filename as argument' +- print >>sys.stderr, 'Try `unoconv -h\' for more information.' +- sys.exit(255) +- +- ### Set connection string +- if not self.connection: +- if not self.pipe: +- self.connection = "socket,host=%s,port=%s;urp;StarOffice.ComponentContext" % (self.server, self.port) +-# self.connection = "socket,host=%s,port=%s;urp;" % (self.server, self.port) +- else: +- self.connection = "pipe,name=%s;urp;StarOffice.ComponentContext" % (self.pipe) +- +- ### Make it easier for people to use a doctype (first letter is enough) +- if self.doctype: +- for doctype in doctypes: +- if doctype.startswith(self.doctype): +- self.doctype = doctype +- +- ### Check if the user request to see the list of formats +- if self.showlist or self.format == 'list': +- if self.doctype: +- fmts.display(self.doctype) +- else: +- for t in doctypes: +- fmts.display(t) +- sys.exit(0) +- +- ### If no format was specified, probe it or provide it +- if not self.format: +- l = sys.argv[0].split('2') +- if len(l) == 2: +- self.format = l[1] +- else: +- self.format = 'pdf' +- +- def version(self): +- ### Get office product information +- product = uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) +- +- print 'unoconv %s' % VERSION +- print 'Written by Dag Wieers ' +- print 'Homepage at http://dag.wieers.com/home-made/unoconv/' +- print +- print 'platform %s/%s' % (os.name, sys.platform) +- print 'python %s' % sys.version +- print product.ooName, product.ooSetupVersion +-# print +-# print 'build revision $Rev$' +- +- def usage(self): +- print >>sys.stderr, 'usage: unoconv [options] file [file2 ..]' +- +- def help(self): +- print >>sys.stderr, '''Convert from and to any format supported by LibreOffice +- +-unoconv options: +- -c, --connection=string use a custom connection string +- -d, --doctype=type specify document type +- (document, graphics, presentation, spreadsheet) +- -e, --export=name=value set export filter options +- eg. -e PageRange=1-2 +- -f, --format=format specify the output format +- -i, --import=string set import filter option string +- eg. -i utf8 +- -l, --listener start a permanent listener to use by unoconv clients +- -n, --no-launch fail if no listener is found (default: launch one) +- -o, --output=name output basename, filename or directory +- --pipe=name alternative method of connection using a pipe +- -p, --port=port specify the port (default: 2002) +- to be used by client or listener +- --password=string provide a password to decrypt the document +- -s, --server=server specify the server address (default: 127.0.0.1) +- to be used by client or listener +- --show list the available output formats +- --stdout write output to stdout +- -t, --template=file import the styles from template (.ott) +- -T, --timeout=secs timeout after secs if connection to listener fails +- -v, --verbose be more and more verbose (-vvv for debugging) +-''' +- +-class Convertor: +- def __init__(self): +- global exitcode, ooproc, office, product +- unocontext = None +- +- ### Do the LibreOffice component dance +- self.context = uno.getComponentContext() +- self.svcmgr = self.context.ServiceManager +- resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) +- +- ### Test for an existing connection +- info(3, 'Connection type: %s' % op.connection) +- try: +- unocontext = resolver.resolve("uno:%s" % op.connection) +- except NoConnectException, e: +-# info(3, "Existing listener not found.\n%s" % e) +- info(3, "Existing listener not found.") +- +- if op.nolaunch: +- die(113, "Existing listener not found. Unable start listener by parameters. Aborting.") +- +- ### Start our own OpenOffice instance +- info(3, "Launching our own listener using %s." % office.binary) +- try: +- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) +- if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): +- ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) +- else: +- ooproc = subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--accept=%s" % op.connection], env=os.environ) +- info(2, '%s listener successfully started. (pid=%s)' % (product.ooName, ooproc.pid)) +- +- ### Try connection to it for op.timeout seconds (flakky OpenOffice) +- timeout = 0 +- while timeout <= op.timeout: +- ### Is it already/still running ? +- retcode = ooproc.poll() +- if retcode != None: +- info(3, "Process %s (pid=%s) exited with %s." % (office.binary, ooproc.pid, retcode)) +- break +- try: +- unocontext = resolver.resolve("uno:%s" % op.connection) +- break +- except NoConnectException: +- time.sleep(0.5) +- timeout += 0.5 +- except: +- raise +- else: +- error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) +- except Exception, e: +- raise +- error("Launch of %s failed.\n%s" % (office.binary, e)) +- +- if not unocontext: +- die(251, "Unable to connect or start own listener. Aborting.") +- +- ### And some more LibreOffice magic +- unosvcmgr = unocontext.ServiceManager +- self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) +- self.cwd = unohelper.systemPathToFileUrl( os.getcwd() ) +- +- ### List all filters +-# self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) +-# for filter in self.filters.getElementNames(): +-# print filter +-# #print dir(filter), dir(filter.format) +- +- def getformat(self, inputfn): +- doctype = None +- +- ### Get the output format from mapping +- if op.doctype: +- outputfmt = fmts.bydoctype(op.doctype, op.format) +- else: +- outputfmt = fmts.byname(op.format) +- +- if not outputfmt: +- outputfmt = fmts.byextension(os.extsep + op.format) +- +- ### If no doctype given, check list of acceptable formats for input file ext doctype +- ### FIXME: This should go into the for-loop to match each individual input filename +- if outputfmt: +- inputext = os.path.splitext(inputfn)[1] +- inputfmt = fmts.byextension(inputext) +- if inputfmt: +- for fmt in outputfmt: +- if inputfmt[0].doctype == fmt.doctype: +- doctype = inputfmt[0].doctype +- outputfmt = fmt +- break +- else: +- outputfmt = outputfmt[0] +- # print >>sys.stderr, 'unoconv: format `%s\' is part of multiple doctypes %s, selecting `%s\'.' % (format, [fmt.doctype for fmt in outputfmt], outputfmt[0].doctype) +- else: +- outputfmt = outputfmt[0] +- +- ### No format found, throw error +- if not outputfmt: +- if doctype: +- print >>sys.stderr, 'unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format) +- else: +- print >>sys.stderr, 'unoconv: format [%s] is not known to unoconv.' % op.format +- die(1) +- +- return outputfmt +- +- def convert(self, inputfn): +- global exitcode +- +- document = None +- outputfmt = self.getformat(inputfn) +- +- if op.verbose > 0: +- print >>sys.stderr, 'Input file:', inputfn +- +- if not os.path.exists(inputfn): +- print >>sys.stderr, 'unoconv: file `%s\' does not exist.' % inputfn +- exitcode = 1 +- +- try: +- ### Import phase +- phase = "import" +- +- ### Load inputfile +- inputprops = UnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=QUIET_UPDATE) +- +-# if op.password: +-# info = UnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") +-# inputprops += UnoProps(ModifyPasswordInfo=info) +- +- ### Cannot use UnoProps for FilterData property +- if op.importfilteroptions: +-# print "Import filter options: %s" % op.importfilteroptions +- inputprops += UnoProps(FilterOptions=op.importfilteroptions) +- +- ### Cannot use UnoProps for FilterData property +- if op.importfilter: +- inputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) +- +- inputurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(inputfn)) +- document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) +- +- if not document: +- raise UnoException("The document '%s' could not be opened." % inputurl, None) +- +- ### Import style template +- phase = "import-style" +- if op.template: +- if os.path.exists(op.template): +- info(1, "Template file: %s" % op.template) +- templateprops = UnoProps(OverwriteStyles=True) +- templateurl = unohelper.absolutize(self.cwd, unohelper.systemPathToFileUrl(op.template)) +- document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) +- else: +- print >>sys.stderr, 'unoconv: template file `%s\' does not exist.' % op.template +- exitcode = 1 +- +- ### Update document links +- phase = "update-links" +- try: +- document.updateLinks() +- except AttributeError: +- # the document doesn't implement the XLinkUpdate interface +- pass +- +- ### Update document indexes +- phase = "update-indexes" +- try: +- document.refresh() +- indexes = document.getDocumentIndexes() +- except AttributeError: +- # the document doesn't implement the XRefreshable and/or +- # XDocumentIndexesSupplier interfaces +- pass +- else: +- for i in range(0, indexes.getCount()): +- indexes.getByIndex(i).update() +- +- info(1, "Selected output format: %s" % outputfmt) +- info(2, "Selected office filter: %s" % outputfmt.filter) +- info(2, "Used doctype: %s" % outputfmt.doctype) +- +- ### Export phase +- phase = "export" +- +- outputprops = UnoProps(FilterName=outputfmt.filter, OutputStream=OutputStream(), Overwrite=True) +- +- ### Set default filter options +- if op.exportfilteroptions: +-# print "Export filter options: %s" % op.exportfilteroptions +- outputprops += UnoProps(FilterOptions=op.exportfilteroptions) +- else: +- if outputfmt.filter == 'Text (encoded)': +- outputprops += UnoProps(FilterOptions="76,LF") +- +- elif outputfmt.filter == 'Text': +- outputprops += UnoProps(FilterOptions="76") +- +- elif outputfmt.filter == 'Text - txt - csv (StarCalc)': +- outputprops += UnoProps(FilterOptions="44,34,76") +- +- +- ### Cannot use UnoProps for FilterData property +- if op.exportfilter: +- outputprops += ( PropertyValue( "FilterData", 0, uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) +- +- if not op.stdout: +- (outputfn, ext) = os.path.splitext(inputfn) +- if not op.output: +- outputfn = outputfn + os.extsep + outputfmt.extension +- elif os.path.isdir(op.output): +- outputfn = realpath(op.output, os.path.basename(outputfn) + os.extsep + outputfmt.extension) +- elif len(op.filenames) > 1: +- outputfn = op.output + os.extsep + outputfmt.extension +- else: +- outputfn = op.output +- +- outputurl = unohelper.absolutize( self.cwd, unohelper.systemPathToFileUrl(outputfn) ) +- info(1, "Output file: %s" % outputfn) +- else: +- outputurl = "private:stream" +- +- try: +- document.storeToURL(outputurl, tuple(outputprops) ) +- except IOException, e: +- raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) +- +- phase = "dispose" +- document.dispose() +- document.close(True) +- +- except SystemError, e: +- error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) +- exitcode = 1 +- +- except RuntimeException, e: +- error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) +- exitcode = 6 +- +- except DisposedException, e: +- error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) +- exitcode = 7 +- +- except IllegalArgumentException, e: +- error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) +- exitcode = 8 +- +- except IOException, e: +-# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) +- error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) +- exitcode = 3 +- +- except CannotConvertException, e: +-# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) +- error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) +- exitcode = 4 +- +- except UnoException, e: +- if hasattr(e, 'ErrCode'): +- error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) +- exitcode = e.ErrCode +- pass +- if hasattr(e, 'Message'): +- error("unoconv: UnoException during %s phase:\n%s" % (phase, e.Message)) +- exitcode = 5 +- else: +- error("unoconv: UnoException during %s phase in %s" % (phase, repr(e.__class__))) +- exitcode = 2 +- pass +- +-class Listener: +- def __init__(self): +- global product +- +- info(1, "Start listener on %s:%s" % (op.server, op.port)) +- self.context = uno.getComponentContext() +- self.svcmgr = self.context.ServiceManager +- try: +- resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) +- product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", UnoProps(nodepath="/org.openoffice.Setup/Product")) +- try: +- unocontext = resolver.resolve("uno:%s" % op.connection) +- except NoConnectException, e: +- pass +- else: +- info(1, "Existing %s listener found, nothing to do." % product.ooName) +- return +- if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): +- subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) +- else: +- subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) +- except Exception, e: +- error("Launch of %s failed.\n%s" % (office.binary, e)) +- else: +- info(1, "Existing %s listener found, nothing to do." % product.ooName) +- +-def error(msg): +- "Output error message" +- print >>sys.stderr, msg +- +-def info(level, msg): +- "Output info message" +- if 'op' not in globals(): +- pass +- elif op.verbose >= 3 and level >= 3: +- print >>sys.stderr, "DEBUG:", msg +- elif not op.stdout and level <= op.verbose: +- print >>sys.stdout, msg +- elif level <= op.verbose: +- print >>sys.stderr, msg +- +-def die(ret, msg=None): +- "Print optional error and exit with errorcode" +- global convertor, ooproc, office +- +- if msg: +- error('Error: %s' % msg) +- +- ### Did we start our own listener instance ? +- if not op.listener and ooproc and convertor: +- +- ### If there is a GUI now attached to the instance, disable listener +- if convertor.desktop.getCurrentFrame(): +- info(2, 'Trying to stop %s GUI listener.' % product.ooName) +- try: +- if product.ooName != "LibreOffice" or product.ooSetupVersion <= 3.3: +- subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-unaccept=%s" % op.connection], env=os.environ) +- else: +- subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) +- ooproc.wait() +- info(2, '%s listener successfully disabled.' % product.ooName) +- except Exception, e: +- error("Terminate using %s failed.\n%s" % (office.binary, e)) +- +- ### If there is no GUI attached to the instance, terminate instance +- else: +- info(3, 'Terminating %s instance.' % product.ooName) +- try: +- convertor.desktop.terminate() +- except DisposedException: +- info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) +- try: +- ooproc.terminate() +- except AttributeError: +- os.kill(ooproc.pid, 15) +- info(3, 'Waiting for %s instance to exit.' % product.ooName) +- ooproc.wait() +- +- ### LibreOffice processes may get stuck and we have to kill them +- ### Is it still running ? +- if ooproc.poll() == None: +- info(1, '%s instance still running, please investigate...' % product.ooName) +- ooproc.wait() +- info(2, '%s instance unsuccessfully terminated, sending KILL signal.' % product.ooName) +- try: +- ooproc.kill() +- except AttributeError: +- os.kill(ooproc.pid, 9) +- info(3, 'Waiting for %s with pid %s to disappear.' % (ooproc.pid, product.ooName)) +- ooproc.wait() +- +- # allow Python GC to garbage collect pyuno object *before* exit call +- # which avoids random segmentation faults --vpa +- convertor = None +- +- sys.exit(ret) +- +-def main(): +- global convertor, exitcode +- convertor = None +- +- try: +- if op.listener: +- listener = Listener() +- +- if op.filenames: +- convertor = Convertor() +- for inputfn in op.filenames: +- convertor.convert(inputfn) +- +- except NoConnectException, e: +- error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) +- if op.connection: +- info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) +- else: +- info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"socket,host=%s,port=%s;urp;\"" % (op.server, op.server, op.port, op.server, op.port)) +- info(0, "Please start an soffice instance on server '%s' by doing:\n\n soffice -nologo -nodefault -accept=\"socket,host=127.0.0.1,port=%s;urp;\"" % (op.server, op.port)) +- exitcode = 1 +-# except UnboundLocalError: +-# die(252, "Failed to connect to remote listener.") +- except OSError: +- error("Warning: failed to launch Office suite. Aborting.") +- +-### Main entrance + if __name__ == '__main__': +- exitcode = 0 +- +- info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) +- +- for of in find_offices(): +- if of.python != sys.executable and not sys.executable.startswith(of.basepath): +- python_switch(of) +- office_environ(of) +-# debug_office() +- try: +- import uno, unohelper +- office = of +- break +- except: +-# debug_office() +- print >>sys.stderr, "unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of +- print >>sys.stderr, "ERROR:", sys.exc_info()[1] +- print >>sys.stderr ++ if sys.version_info < (3,0): ++ from unoconv2 import run + else: +-# debug_office() +- print >>sys.stderr, "unoconv: Cannot find a suitable office installation on your system." +- print >>sys.stderr, "ERROR: Please locate your office installation and send your feedback to:" +- print >>sys.stderr, " http://github.com/dagwieers/unoconv/issues" +- sys.exit(1) +- +- ### Now that we have found a working pyuno library, let's import some classes +- from com.sun.star.beans import PropertyValue +- from com.sun.star.connection import NoConnectException +- from com.sun.star.document.UpdateDocMode import QUIET_UPDATE +- from com.sun.star.lang import DisposedException, IllegalArgumentException +- from com.sun.star.io import IOException, XOutputStream +- from com.sun.star.script import CannotConvertException +- from com.sun.star.uno import Exception as UnoException +- from com.sun.star.uno import RuntimeException +- +- ### And now that we have those classes, build on them +- class OutputStream( unohelper.Base, XOutputStream ): +- def __init__( self ): +- self.closed = 0 +- +- def closeOutput(self): +- self.closed = 1 +- +- def writeBytes( self, seq ): +- sys.stdout.write( seq.value ) +- +- def flush( self ): +- pass +- +- def UnoProps(**args): +- props = [] +- for key in args: +- prop = PropertyValue() +- prop.Name = key +- prop.Value = args[key] +- props.append(prop) +- return tuple(props) +- +- op = Options(sys.argv[1:]) +- +- info(2, "Using office base path: %s" % office.basepath) +- info(2, "Using office binary path: %s" % office.unopath) ++ from unoconv3 import run + +- try: +- main() +- except KeyboardInterrupt, e: +- die(6, 'Exiting on user request') +- die(exitcode) ++ run() +diff --git a/unoconv2.py b/unoconv2.py +new file mode 100755 +index 0000000..1aecbb6 +--- /dev/null ++++ b/unoconv2.py +@@ -0,0 +1,1195 @@ ++#!/usr/bin/python ++ ++### This program is free software; you can redistribute it and/or modify ++### it under the terms of the GNU General Public License as published by ++### the Free Software Foundation; version 2 only ++### ++### This program is distributed in the hope that it will be useful, ++### but WITHOUT ANY WARRANTY; without even the implied warranty of ++### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++### GNU General Public License for more details. ++### ++### You should have received a copy of the GNU General Public License ++### along with this program; if not, write to the Free Software ++### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++### Copyright 2007-2010 Dag Wieers ++ ++from distutils.version import LooseVersion ++import getopt ++import glob ++import os ++import subprocess ++import sys ++import time ++ ++__version__ = "$Revision$" ++# $Source$ ++ ++VERSION = '0.6' ++ ++doctypes = ('document', 'graphics', 'presentation', 'spreadsheet') ++ ++global convertor, office, ooproc, product ++ooproc = None ++exitcode = 0 ++ ++class Office: ++ def __init__(self, basepath, urepath, unopath, pyuno, binary, python, pythonhome): ++ self.basepath = basepath ++ self.urepath = urepath ++ self.unopath = unopath ++ self.pyuno = pyuno ++ self.binary = binary ++ self.python = python ++ self.pythonhome = pythonhome ++ ++ def __str__(self): ++ return self.basepath ++ ++ def __repr__(self): ++ return self.basepath ++ ++### Implement a path normalizer in order to make unoconv work on MacOS X ++### (on which 'program' is a symlink to 'MacOSX' which seems to break unoconv) ++def realpath(*args): ++ ''' Implement a combination of os.path.join(), os.path.abspath() and ++ os.path.realpath() in order to normalize path constructions ''' ++ ret = '' ++ for arg in args: ++ ret = os.path.join(ret, arg) ++ return os.path.realpath(os.path.abspath(ret)) ++ ++### The first thing we ought to do is find a suitable Office installation ++### with a compatible pyuno library that we can import. ++### ++### See: http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p=166783 ++ ++def find_offices(): ++ ret = [] ++ extrapaths = [] ++ ++ ### Try using UNO_PATH first (in many incarnations, we'll see what sticks) ++ if 'UNO_PATH' in os.environ: ++ extrapaths += [ os.environ['UNO_PATH'], ++ os.path.dirname(os.environ['UNO_PATH']), ++ os.path.dirname(os.path.dirname(os.environ['UNO_PATH'])) ] ++ ++ else: ++ ++ if os.name in ( 'nt', 'os2' ): ++ if 'PROGRAMFILES' in os.environ.keys(): ++ extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ ++ glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') ++ ++ if 'PROGRAMFILES(X86)' in os.environ.keys(): ++ extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ ++ glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') ++ ++ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): ++ extrapaths += [ '/Applications/LibreOffice.app/Contents', ++ '/Applications/NeoOffice.app/Contents', ++ '/Applications/OpenOffice.org.app/Contents' ] ++ ++ else: ++ extrapaths += glob.glob('/usr/lib*/libreoffice*') + \ ++ glob.glob('/usr/lib*/openoffice*') + \ ++ glob.glob('/usr/lib*/ooo*') + \ ++ glob.glob('/opt/libreoffice*') + \ ++ glob.glob('/opt/openoffice*') + \ ++ glob.glob('/opt/ooo*') + \ ++ glob.glob('/usr/local/libreoffice*') + \ ++ glob.glob('/usr/local/openoffice*') + \ ++ glob.glob('/usr/local/ooo*') + \ ++ glob.glob('/usr/local/lib/libreoffice*') ++ ++ ### Find a working set for python UNO bindings ++ for basepath in extrapaths: ++ if os.name in ( 'nt', 'os2' ): ++ officelibraries = ( 'pyuno.pyd', ) ++ officebinaries = ( 'soffice.exe' ,) ++ pythonbinaries = ( 'python.exe', ) ++ pythonhomes = () ++ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): ++ officelibraries = ( 'pyuno.so', 'libpyuno.dylib' ) ++ officebinaries = ( 'soffice.bin', ) ++ pythonbinaries = ( 'python.bin', 'python' ) ++ pythonhomes = ( 'OOoPython.framework/Versions/*/lib/python*', ) ++ else: ++ officelibraries = ( 'pyuno.so', ) ++ officebinaries = ( 'soffice.bin', ) ++ pythonbinaries = ( 'python.bin', 'python', ) ++ pythonhomes = ( 'python-core-*', ) ++ ++ ### Older LibreOffice/OpenOffice and Windows use basis-link/ or basis/ ++ libpath = 'error' ++ for basis in ( 'basis-link', 'basis', '' ): ++ for lib in officelibraries: ++ if os.path.isfile(realpath(basepath, basis, 'program', lib)): ++ libpath = realpath(basepath, basis, 'program') ++ officelibrary = realpath(libpath, lib) ++ info(3, "Found %s in %s" % (lib, libpath)) ++ # Break the inner loop... ++ break ++ # Continue if the inner loop wasn't broken. ++ else: ++ continue ++ # Inner loop was broken, break the outer. ++ break ++ else: ++ continue ++ ++ ### MacOSX have soffice binaries installed in MacOS subdirectory, not program ++ unopath = 'error' ++ for basis in ( 'basis-link', 'basis', '' ): ++ for bin in officebinaries: ++ if os.path.isfile(realpath(basepath, basis, 'program', bin)): ++ unopath = realpath(basepath, basis, 'program') ++ officebinary = realpath(unopath, bin) ++ info(3, "Found %s in %s" % (bin, unopath)) ++ # Break the inner loop... ++ break ++ # Continue if the inner loop wasn't broken. ++ else: ++ continue ++ # Inner loop was broken, break the outer. ++ break ++ else: ++ continue ++ ++ ### Windows does not provide or need a URE/lib directory ? ++ urepath = '' ++ for basis in ( 'basis-link', 'basis', '' ): ++ for ure in ( 'ure-link', 'ure', 'URE', '' ): ++ if os.path.isfile(realpath(basepath, basis, ure, 'lib', 'unorc')): ++ urepath = realpath(basepath, basis, ure) ++ info(3, "Found %s in %s" % ('unorc', realpath(urepath, 'lib'))) ++ # Break the inner loop... ++ break ++ # Continue if the inner loop wasn't broken. ++ else: ++ continue ++ # Inner loop was broken, break the outer. ++ break ++ ++ pythonhome = None ++ for home in pythonhomes: ++ if glob.glob(realpath(libpath, home)): ++ pythonhome = glob.glob(realpath(libpath, home))[0] ++ info(3, "Found %s in %s" % (home, pythonhome)) ++ break ++ ++# if not os.path.isfile(realpath(basepath, program, officebinary)): ++# continue ++# info(3, "Found %s in %s" % (officebinary, realpath(basepath, program))) ++ ++# if not glob.glob(realpath(basepath, basis, program, 'python-core-*')): ++# continue ++ ++ for pythonbinary in pythonbinaries: ++ if os.path.isfile(realpath(unopath, pythonbinary)): ++ info(3, "Found %s in %s" % (pythonbinary, unopath)) ++ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, ++ realpath(unopath, pythonbinary), pythonhome)) ++ else: ++ info(3, "Considering %s" % basepath) ++ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, ++ sys.executable, None)) ++ return ret ++ ++def office_environ(office): ++ ### Set PATH so that crash_report is found ++ os.environ['PATH'] = realpath(office.basepath, 'program') + os.pathsep + os.environ['PATH'] ++ ++ ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: ++ os.environ['UNO_PATH'] = office.unopath ++ ++ ### Set URE_BOOTSTRAP so that "global_uno.getComponentContext()" bootstraps a complete ++ ### UNO environment ++ if os.name in ( 'nt', 'os2' ): ++ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') ++ else: ++ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamentalrc') ++ ++ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: ++ if 'LD_LIBRARY_PATH' in os.environ: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') + os.pathsep + \ ++ os.environ['LD_LIBRARY_PATH'] ++ else: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') ++ ++ if office.pythonhome: ++ for libpath in ( realpath(office.pythonhome, 'lib'), ++ realpath(office.pythonhome, 'lib', 'lib-dynload'), ++ realpath(office.pythonhome, 'lib', 'lib-tk'), ++ realpath(office.pythonhome, 'lib', 'site-packages'), ++ office.unopath): ++ sys.path.insert(0, libpath) ++ else: ++ ### Still needed for system python using LibreOffice UNO bindings ++ ### Although we prefer to use a system UNO binding in this case ++ sys.path.append(office.unopath) ++ ++def debug_office(): ++ if 'URE_BOOTSTRAP' in os.environ: ++ print >>sys.stderr, 'URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'] ++ if 'UNO_PATH' in os.environ: ++ print >>sys.stderr, 'UNO_PATH=%s' % os.environ['UNO_PATH'] ++ if 'UNO_TYPES' in os.environ: ++ print >>sys.stderr, 'UNO_TYPES=%s' % os.environ['UNO_TYPES'] ++ print 'PATH=%s' % os.environ['PATH'] ++ if 'PYTHONHOME' in os.environ: ++ print >>sys.stderr, 'PYTHONHOME=%s' % os.environ['PYTHONHOME'] ++ if 'PYTHONPATH' in os.environ: ++ print >>sys.stderr, 'PYTHONPATH=%s' % os.environ['PYTHONPATH'] ++ if 'LD_LIBRARY_PATH' in os.environ: ++ print >>sys.stderr, 'LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'] ++ ++def python_switch(office): ++ if office.pythonhome: ++ os.environ['PYTHONHOME'] = office.pythonhome ++ os.environ['PYTHONPATH'] = realpath(office.pythonhome, 'lib') + os.pathsep + \ ++ realpath(office.pythonhome, 'lib', 'lib-dynload') + os.pathsep + \ ++ realpath(office.pythonhome, 'lib', 'lib-tk') + os.pathsep + \ ++ realpath(office.pythonhome, 'lib', 'site-packages') + os.pathsep + \ ++ office.unopath ++ ++ os.environ['UNO_PATH'] = office.unopath ++ ++ info(3, "-> Switching from %s to %s" % (sys.executable, office.python)) ++ if os.name in ('nt', 'os2'): ++ ### os.execv is broken on Windows and can't properly parse command line ++ ### arguments and executable name if they contain whitespaces. subprocess ++ ### fixes that behavior. ++ ret = subprocess.call([office.python] + sys.argv[0:]) ++ sys.exit(ret) ++ else: ++ ++ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: ++ if 'LD_LIBRARY_PATH' in os.environ: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') + os.pathsep + \ ++ os.environ['LD_LIBRARY_PATH'] ++ else: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') ++ ++ try: ++ os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) ++ print(office.python, [office.python, ] + sys.argv[0:], osenviron) ++ except OSError: ++ ### Mac OS X versions prior to 10.6 do not support execv in ++ ### a process that contains multiple threads. Instead of ++ ### re-executing in the current process, start a new one ++ ### and cause the current process to exit. This isn't ++ ### ideal since the new process is detached from the parent ++ ### terminal and thus cannot easily be killed with ctrl-C, ++ ### but it's better than not being able to autoreload at ++ ### all. ++ ### Unfortunately the errno returned in this case does not ++ ### appear to be consistent, so we can't easily check for ++ ### this error specifically. ++ ret = os.spawnvpe(os.P_WAIT, office.python, [office.python, ] + sys.argv[0:], os.environ) ++ sys.exit(ret) ++ ++class Fmt: ++ def __init__(self, doctype, name, extension, summary, filter): ++ self.doctype = doctype ++ self.name = name ++ self.extension = extension ++ self.summary = summary ++ self.filter = filter ++ ++ def __str__(self): ++ return "%s [.%s]" % (self.summary, self.extension) ++ ++ def __repr__(self): ++ return "%s/%s" % (self.name, self.doctype) ++ ++class FmtList: ++ def __init__(self): ++ self.list = [] ++ ++ def add(self, doctype, name, extension, summary, filter): ++ self.list.append(Fmt(doctype, name, extension, summary, filter)) ++ ++ def byname(self, name): ++ ret = [] ++ for fmt in self.list: ++ if fmt.name == name: ++ ret.append(fmt) ++ return ret ++ ++ def byextension(self, extension): ++ ret = [] ++ for fmt in self.list: ++ if os.extsep + fmt.extension == extension: ++ ret.append(fmt) ++ return ret ++ ++ def bydoctype(self, doctype, name): ++ ret = [] ++ for fmt in self.list: ++ if fmt.name == name and fmt.doctype == doctype: ++ ret.append(fmt) ++ return ret ++ ++ def display(self, doctype): ++ print >>sys.stderr, "The following list of %s formats are currently available:\n" % doctype ++ for fmt in self.list: ++ if fmt.doctype == doctype: ++ print >>sys.stderr, " %-8s - %s" % (fmt.name, fmt) ++ print >>sys.stderr ++ ++fmts = FmtList() ++ ++### TextDocument ++fmts.add('document', 'bib', 'bib', 'BibTeX', 'BibTeX_Writer') ### 22 ++fmts.add('document', 'doc', 'doc', 'Microsoft Word 97/2000/XP', 'MS Word 97') ### 29 ++fmts.add('document', 'doc6', 'doc', 'Microsoft Word 6.0', 'MS WinWord 6.0') ### 24 ++fmts.add('document', 'doc95', 'doc', 'Microsoft Word 95', 'MS Word 95') ### 28 ++fmts.add('document', 'docbook', 'xml', 'DocBook', 'DocBook File') ### 39 ++fmts.add('document', 'docx', 'docx', 'Microsoft Office Open XML', 'Office Open XML Text') ++fmts.add('document', 'docx7', 'docx', 'Microsoft Office Open XML', 'MS Word 2007 XML') ++fmts.add('document', 'fodt', 'fodt', 'OpenDocument Text (Flat XML)', 'OpenDocument Text Flat XML') ++fmts.add('document', 'html', 'html', 'HTML Document (OpenOffice.org Writer)', 'HTML (StarWriter)') ### 3 ++fmts.add('document', 'latex', 'ltx', 'LaTeX 2e', 'LaTeX_Writer') ### 31 ++fmts.add('document', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki') ++fmts.add('document', 'odt', 'odt', 'ODF Text Document', 'writer8') ### 10 ++fmts.add('document', 'ooxml', 'xml', 'Microsoft Office Open XML', 'MS Word 2003 XML') ### 11 ++fmts.add('document', 'ott', 'ott', 'Open Document Text', 'writer8_template') ### 21 ++fmts.add('document', 'pdb', 'pdb', 'AportisDoc (Palm)', 'AportisDoc Palm DB') ++fmts.add('document', 'pdf', 'pdf', 'Portable Document Format', 'writer_pdf_Export') ### 18 ++fmts.add('document', 'psw', 'psw', 'Pocket Word', 'PocketWord File') ++fmts.add('document', 'rtf', 'rtf', 'Rich Text Format', 'Rich Text Format') ### 16 ++fmts.add('document', 'sdw', 'sdw', 'StarWriter 5.0', 'StarWriter 5.0') ### 23 ++fmts.add('document', 'sdw4', 'sdw', 'StarWriter 4.0', 'StarWriter 4.0') ### 2 ++fmts.add('document', 'sdw3', 'sdw', 'StarWriter 3.0', 'StarWriter 3.0') ### 20 ++fmts.add('document', 'stw', 'stw', 'Open Office.org 1.0 Text Document Template', 'writer_StarOffice_XML_Writer_Template') ### 9 ++fmts.add('document', 'sxw', 'sxw', 'Open Office.org 1.0 Text Document', 'StarOffice XML (Writer)') ### 1 ++fmts.add('document', 'text', 'txt', 'Text Encoded', 'Text (encoded)') ### 26 ++fmts.add('document', 'txt', 'txt', 'Text', 'Text') ### 34 ++fmts.add('document', 'uot', 'uot', 'Unified Office Format text','UOF text') ### 27 ++fmts.add('document', 'vor', 'vor', 'StarWriter 5.0 Template', 'StarWriter 5.0 Vorlage/Template') ### 6 ++fmts.add('document', 'vor4', 'vor', 'StarWriter 4.0 Template', 'StarWriter 4.0 Vorlage/Template') ### 5 ++fmts.add('document', 'vor3', 'vor', 'StarWriter 3.0 Template', 'StarWriter 3.0 Vorlage/Template') ### 4 ++fmts.add('document', 'xhtml', 'html', 'XHTML Document', 'XHTML Writer File') ### 33 ++ ++### WebDocument ++fmts.add('web', 'etext', 'txt', 'Text Encoded (OpenOffice.org Writer/Web)', 'Text (encoded) (StarWriter/Web)') ### 14 ++fmts.add('web', 'html10', 'html', 'OpenOffice.org 1.0 HTML Template', 'writer_web_StarOffice_XML_Writer_Web_Template') ### 11 ++fmts.add('web', 'html', 'html', 'HTML Document', 'HTML') ### 2 ++fmts.add('web', 'html', 'html', 'HTML Document Template', 'writerweb8_writer_template') ### 13 ++fmts.add('web', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki_Web') ### 9 ++fmts.add('web', 'pdf', 'pdf', 'PDF - Portable Document Format', 'writer_web_pdf_Export') ### 10 ++fmts.add('web', 'sdw3', 'sdw', 'StarWriter 3.0 (OpenOffice.org Writer/Web)', 'StarWriter 3.0 (StarWriter/Web)') ### 3 ++fmts.add('web', 'sdw4', 'sdw', 'StarWriter 4.0 (OpenOffice.org Writer/Web)', 'StarWriter 4.0 (StarWriter/Web)') ### 4 ++fmts.add('web', 'sdw', 'sdw', 'StarWriter 5.0 (OpenOffice.org Writer/Web)', 'StarWriter 5.0 (StarWriter/Web)') ### 5 ++fmts.add('web', 'txt', 'txt', 'OpenOffice.org Text (OpenOffice.org Writer/Web)', 'writerweb8_writer') ### 12 ++fmts.add('web', 'text10', 'txt', 'OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)', 'writer_web_StarOffice_XML_Writer') ### 15 ++fmts.add('web', 'text', 'txt', 'Text (OpenOffice.org Writer/Web)', 'Text (StarWriter/Web)') ### 8 ++fmts.add('web', 'vor4', 'vor', 'StarWriter/Web 4.0 Template', 'StarWriter/Web 4.0 Vorlage/Template') ### 6 ++fmts.add('web', 'vor', 'vor', 'StarWriter/Web 5.0 Template', 'StarWriter/Web 5.0 Vorlage/Template') ### 7 ++ ++### Spreadsheet ++fmts.add('spreadsheet', 'csv', 'csv', 'Text CSV', 'Text - txt - csv (StarCalc)') ### 16 ++fmts.add('spreadsheet', 'dbf', 'dbf', 'dBASE', 'dBase') ### 22 ++fmts.add('spreadsheet', 'dif', 'dif', 'Data Interchange Format', 'DIF') ### 5 ++fmts.add('spreadsheet', 'fods', 'fods', 'OpenDocument Spreadsheet (Flat XML)', 'OpenDocument Spreadsheet Flat XML') ++fmts.add('spreadsheet', 'html', 'html', 'HTML Document (OpenOffice.org Calc)', 'HTML (StarCalc)') ### 7 ++fmts.add('spreadsheet', 'ods', 'ods', 'ODF Spreadsheet', 'calc8') ### 15 ++fmts.add('spreadsheet', 'ooxml', 'xml', 'Microsoft Excel 2003 XML', 'MS Excel 2003 XML') ### 23 ++fmts.add('spreadsheet', 'ots', 'ots', 'ODF Spreadsheet Template', 'calc8_template') ### 14 ++fmts.add('spreadsheet', 'pdf', 'pdf', 'Portable Document Format', 'calc_pdf_Export') ### 34 ++fmts.add('spreadsheet', 'pxl', 'pxl', 'Pocket Excel', 'Pocket Excel') ++fmts.add('spreadsheet', 'sdc', 'sdc', 'StarCalc 5.0', 'StarCalc 5.0') ### 31 ++fmts.add('spreadsheet', 'sdc4', 'sdc', 'StarCalc 4.0', 'StarCalc 4.0') ### 11 ++fmts.add('spreadsheet', 'sdc3', 'sdc', 'StarCalc 3.0', 'StarCalc 3.0') ### 29 ++fmts.add('spreadsheet', 'slk', 'slk', 'SYLK', 'SYLK') ### 35 ++fmts.add('spreadsheet', 'stc', 'stc', 'OpenOffice.org 1.0 Spreadsheet Template', 'calc_StarOffice_XML_Calc_Template') ### 2 ++fmts.add('spreadsheet', 'sxc', 'sxc', 'OpenOffice.org 1.0 Spreadsheet', 'StarOffice XML (Calc)') ### 3 ++fmts.add('spreadsheet', 'uos', 'uos', 'Unified Office Format spreadsheet', 'UOF spreadsheet') ### 9 ++fmts.add('spreadsheet', 'vor3', 'vor', 'StarCalc 3.0 Template', 'StarCalc 3.0 Vorlage/Template') ### 18 ++fmts.add('spreadsheet', 'vor4', 'vor', 'StarCalc 4.0 Template', 'StarCalc 4.0 Vorlage/Template') ### 19 ++fmts.add('spreadsheet', 'vor', 'vor', 'StarCalc 5.0 Template', 'StarCalc 5.0 Vorlage/Template') ### 20 ++fmts.add('spreadsheet', 'xhtml', 'xhtml', 'XHTML', 'XHTML Calc File') ### 26 ++fmts.add('spreadsheet', 'xls', 'xls', 'Microsoft Excel 97/2000/XP', 'MS Excel 97') ### 12 ++fmts.add('spreadsheet', 'xls5', 'xls', 'Microsoft Excel 5.0', 'MS Excel 5.0/95') ### 8 ++fmts.add('spreadsheet', 'xls95', 'xls', 'Microsoft Excel 95', 'MS Excel 95') ### 10 ++fmts.add('spreadsheet', 'xlt', 'xlt', 'Microsoft Excel 97/2000/XP Template', 'MS Excel 97 Vorlage/Template') ### 6 ++fmts.add('spreadsheet', 'xlt5', 'xlt', 'Microsoft Excel 5.0 Template', 'MS Excel 5.0/95 Vorlage/Template') ### 28 ++fmts.add('spreadsheet', 'xlt95', 'xlt', 'Microsoft Excel 95 Template', 'MS Excel 95 Vorlage/Template') ### 21 ++ ++### Graphics ++fmts.add('graphics', 'bmp', 'bmp', 'Windows Bitmap', 'draw_bmp_Export') ### 21 ++fmts.add('graphics', 'emf', 'emf', 'Enhanced Metafile', 'draw_emf_Export') ### 15 ++fmts.add('graphics', 'eps', 'eps', 'Encapsulated PostScript', 'draw_eps_Export') ### 48 ++fmts.add('graphics', 'fodg', 'fodg', 'OpenDocument Drawing (Flat XML)', 'OpenDocument Drawing Flat XML') ++fmts.add('graphics', 'gif', 'gif', 'Graphics Interchange Format', 'draw_gif_Export') ### 30 ++fmts.add('graphics', 'html', 'html', 'HTML Document (OpenOffice.org Draw)', 'draw_html_Export') ### 37 ++fmts.add('graphics', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'draw_jpg_Export') ### 3 ++fmts.add('graphics', 'met', 'met', 'OS/2 Metafile', 'draw_met_Export') ### 43 ++fmts.add('graphics', 'odd', 'odd', 'OpenDocument Drawing', 'draw8') ### 6 ++fmts.add('graphics', 'otg', 'otg', 'OpenDocument Drawing Template', 'draw8_template') ### 20 ++fmts.add('graphics', 'pbm', 'pbm', 'Portable Bitmap', 'draw_pbm_Export') ### 14 ++fmts.add('graphics', 'pct', 'pct', 'Mac Pict', 'draw_pct_Export') ### 41 ++fmts.add('graphics', 'pdf', 'pdf', 'Portable Document Format', 'draw_pdf_Export') ### 28 ++fmts.add('graphics', 'pgm', 'pgm', 'Portable Graymap', 'draw_pgm_Export') ### 11 ++fmts.add('graphics', 'png', 'png', 'Portable Network Graphic', 'draw_png_Export') ### 2 ++fmts.add('graphics', 'ppm', 'ppm', 'Portable Pixelmap', 'draw_ppm_Export') ### 5 ++fmts.add('graphics', 'ras', 'ras', 'Sun Raster Image', 'draw_ras_Export') ## 31 ++fmts.add('graphics', 'std', 'std', 'OpenOffice.org 1.0 Drawing Template', 'draw_StarOffice_XML_Draw_Template') ### 53 ++fmts.add('graphics', 'svg', 'svg', 'Scalable Vector Graphics', 'draw_svg_Export') ### 50 ++fmts.add('graphics', 'svm', 'svm', 'StarView Metafile', 'draw_svm_Export') ### 55 ++fmts.add('graphics', 'swf', 'swf', 'Macromedia Flash (SWF)', 'draw_flash_Export') ### 23 ++fmts.add('graphics', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing', 'StarOffice XML (Draw)') ### 26 ++fmts.add('graphics', 'sxd3', 'sxd', 'StarDraw 3.0', 'StarDraw 3.0') ### 40 ++fmts.add('graphics', 'sxd5', 'sxd', 'StarDraw 5.0', 'StarDraw 5.0') ### 44 ++fmts.add('graphics', 'sxw', 'sxw', 'StarOffice XML (Draw)', 'StarOffice XML (Draw)') ++fmts.add('graphics', 'tiff', 'tiff', 'Tagged Image File Format', 'draw_tif_Export') ### 13 ++fmts.add('graphics', 'vor', 'vor', 'StarDraw 5.0 Template', 'StarDraw 5.0 Vorlage') ### 36 ++fmts.add('graphics', 'vor3', 'vor', 'StarDraw 3.0 Template', 'StarDraw 3.0 Vorlage') ### 35 ++fmts.add('graphics', 'wmf', 'wmf', 'Windows Metafile', 'draw_wmf_Export') ### 8 ++fmts.add('graphics', 'xhtml', 'xhtml', 'XHTML', 'XHTML Draw File') ### 45 ++fmts.add('graphics', 'xpm', 'xpm', 'X PixMap', 'draw_xpm_Export') ### 19 ++ ++### Presentation ++fmts.add('presentation', 'bmp', 'bmp', 'Windows Bitmap', 'impress_bmp_Export') ### 15 ++fmts.add('presentation', 'emf', 'emf', 'Enhanced Metafile', 'impress_emf_Export') ### 16 ++fmts.add('presentation', 'eps', 'eps', 'Encapsulated PostScript', 'impress_eps_Export') ### 17 ++fmts.add('presentation', 'fodp', 'fodp', 'OpenDocument Presentation (Flat XML)', 'OpenDocument Presentation Flat XML') ++fmts.add('presentation', 'gif', 'gif', 'Graphics Interchange Format', 'impress_gif_Export') ### 18 ++fmts.add('presentation', 'html', 'html', 'HTML Document (OpenOffice.org Impress)', 'impress_html_Export') ### 43 ++fmts.add('presentation', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'impress_jpg_Export') ### 19 ++fmts.add('presentation', 'met', 'met', 'OS/2 Metafile', 'impress_met_Export') ### 20 ++fmts.add('presentation', 'odg', 'odg', 'ODF Drawing (Impress)', 'impress8_draw') ### 29 ++fmts.add('presentation', 'odp', 'odp', 'ODF Presentation', 'impress8') ### 9 ++fmts.add('presentation', 'otp', 'otp', 'ODF Presentation Template', 'impress8_template') ### 38 ++fmts.add('presentation', 'pbm', 'pbm', 'Portable Bitmap', 'impress_pbm_Export') ### 21 ++fmts.add('presentation', 'pct', 'pct', 'Mac Pict', 'impress_pct_Export') ### 22 ++fmts.add('presentation', 'pdf', 'pdf', 'Portable Document Format', 'impress_pdf_Export') ### 23 ++fmts.add('presentation', 'pgm', 'pgm', 'Portable Graymap', 'impress_pgm_Export') ### 24 ++fmts.add('presentation', 'png', 'png', 'Portable Network Graphic', 'impress_png_Export') ### 25 ++fmts.add('presentation', 'potm', 'potm', 'Microsoft PowerPoint 2007/2010 XML Template', 'Impress MS PowerPoint 2007 XML Template') ++fmts.add('presentation', 'pot', 'pot', 'Microsoft PowerPoint 97/2000/XP Template', 'MS PowerPoint 97 Vorlage') ### 3 ++fmts.add('presentation', 'ppm', 'ppm', 'Portable Pixelmap', 'impress_ppm_Export') ### 26 ++fmts.add('presentation', 'pptx', 'pptx', 'Microsoft PowerPoint 2007/2010 XML', 'Impress MS PowerPoint 2007 XML') ### 36 ++fmts.add('presentation', 'pps', 'pps', 'Microsoft PowerPoint 97/2000/XP (Autoplay)', 'MS PowerPoint 97 Autoplay') ### 36 ++fmts.add('presentation', 'ppt', 'ppt', 'Microsoft PowerPoint 97/2000/XP', 'MS PowerPoint 97') ### 36 ++fmts.add('presentation', 'pwp', 'pwp', 'PlaceWare', 'placeware_Export') ### 30 ++fmts.add('presentation', 'ras', 'ras', 'Sun Raster Image', 'impress_ras_Export') ### 27 ++fmts.add('presentation', 'sda', 'sda', 'StarDraw 5.0 (OpenOffice.org Impress)', 'StarDraw 5.0 (StarImpress)') ### 8 ++fmts.add('presentation', 'sdd', 'sdd', 'StarImpress 5.0', 'StarImpress 5.0') ### 6 ++fmts.add('presentation', 'sdd3', 'sdd', 'StarDraw 3.0 (OpenOffice.org Impress)', 'StarDraw 3.0 (StarImpress)') ### 42 ++fmts.add('presentation', 'sdd4', 'sdd', 'StarImpress 4.0', 'StarImpress 4.0') ### 37 ++fmts.add('presentation', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)', 'impress_StarOffice_XML_Draw') ### 31 ++fmts.add('presentation', 'sti', 'sti', 'OpenOffice.org 1.0 Presentation Template', 'impress_StarOffice_XML_Impress_Template') ### 5 ++fmts.add('presentation', 'svg', 'svg', 'Scalable Vector Graphics', 'impress_svg_Export') ### 14 ++fmts.add('presentation', 'svm', 'svm', 'StarView Metafile', 'impress_svm_Export') ### 13 ++fmts.add('presentation', 'swf', 'swf', 'Macromedia Flash (SWF)', 'impress_flash_Export') ### 34 ++fmts.add('presentation', 'sxi', 'sxi', 'OpenOffice.org 1.0 Presentation', 'StarOffice XML (Impress)') ### 41 ++fmts.add('presentation', 'tiff', 'tiff', 'Tagged Image File Format', 'impress_tif_Export') ### 12 ++fmts.add('presentation', 'uop', 'uop', 'Unified Office Format presentation', 'UOF presentation') ### 4 ++fmts.add('presentation', 'vor', 'vor', 'StarImpress 5.0 Template', 'StarImpress 5.0 Vorlage') ### 40 ++fmts.add('presentation', 'vor3', 'vor', 'StarDraw 3.0 Template (OpenOffice.org Impress)', 'StarDraw 3.0 Vorlage (StarImpress)') ###1 ++fmts.add('presentation', 'vor4', 'vor', 'StarImpress 4.0 Template', 'StarImpress 4.0 Vorlage') ### 39 ++fmts.add('presentation', 'vor5', 'vor', 'StarDraw 5.0 Template (OpenOffice.org Impress)', 'StarDraw 5.0 Vorlage (StarImpress)') ### 2 ++fmts.add('presentation', 'wmf', 'wmf', 'Windows Metafile', 'impress_wmf_Export') ### 11 ++fmts.add('presentation', 'xhtml', 'xml', 'XHTML', 'XHTML Impress File') ### 33 ++fmts.add('presentation', 'xpm', 'xpm', 'X PixMap', 'impress_xpm_Export') ### 10 ++ ++class Options: ++ def __init__(self, args): ++ self.connection = None ++ self.debug = False ++ self.doctype = None ++ self.exportfilter = [] ++ self.exportfilteroptions = "" ++ self.filenames = [] ++ self.format = None ++ self.importfilter = [] ++ self.importfilteroptions = "" ++ self.listener = False ++ self.nolaunch = False ++ self.output = None ++ self.password = None ++ self.pipe = None ++ self.port = '2002' ++ self.server = '127.0.0.1' ++ self.showlist = False ++ self.stdout = False ++ self.template = None ++ self.timeout = 6 ++ self.verbose = 0 ++ ++ ### Get options from the commandline ++ try: ++ opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', ++ ['connection=', 'debug', 'doctype=', 'export=', 'format=', ++ 'help', 'import', 'listener', 'no-launch', 'output=', ++ 'outputpath', 'password=', 'pipe=', 'port=', 'server=', ++ 'timeout=', 'show', 'stdout', 'template', 'verbose', ++ 'version'] ) ++ except getopt.error, exc: ++ print 'unoconv: %s, try unoconv -h for a list of all the options' % str(exc) ++ sys.exit(255) ++ ++ for opt, arg in opts: ++ if opt in ['-h', '--help']: ++ self.usage() ++ print ++ self.help() ++ sys.exit(1) ++ elif opt in ['-c', '--connection']: ++ self.connection = arg ++ elif opt in ['--debug']: ++ self.debug = True ++ elif opt in ['-d', '--doctype']: ++ self.doctype = arg ++ elif opt in ['-e', '--export']: ++ l = arg.split('=') ++ if len(l) == 2: ++ (name, value) = l ++ if name in ('FilterOptions'): ++ self.exportfilteroptions = value ++ elif value in ('True', 'true'): ++ self.exportfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) ++ elif value in ('False', 'false'): ++ self.exportfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) ++ else: ++ try: ++ self.exportfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) ++ except ValueError: ++ self.exportfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) ++ else: ++ print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg ++ elif opt in ['-f', '--format']: ++ self.format = arg ++ elif opt in ['-i', '--import']: ++ l = arg.split('=') ++ if len(l) == 2: ++ (name, value) = l ++ if name in ('FilterOptions'): ++ self.importfilteroptions = value ++ elif value in ('True', 'true'): ++ self.importfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) ++ elif value in ('False', 'false'): ++ self.importfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) ++ else: ++ try: ++ self.importfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) ++ except ValueError: ++ self.importfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) ++ else: ++ print >>sys.stderr, 'Warning: Option %s cannot be parsed, ignoring.' % arg ++ elif opt in ['-l', '--listener']: ++ self.listener = True ++ elif opt in ['-n', '--no-launch']: ++ self.nolaunch = True ++ elif opt in ['-o', '--output']: ++ self.output = arg ++ elif opt in ['--outputpath']: ++ print >>sys.stderr, 'Warning: This option is deprecated by --output.' ++ self.output = arg ++ elif opt in ['--password']: ++ self.password = arg ++ elif opt in ['--pipe']: ++ self.pipe = arg ++ elif opt in ['-p', '--port']: ++ self.port = arg ++ elif opt in ['-s', '--server']: ++ self.server = arg ++ elif opt in ['--show']: ++ self.showlist = True ++ elif opt in ['--stdout']: ++ self.stdout = True ++ elif opt in ['-t', '--template']: ++ self.template = arg ++ elif opt in ['-T', '--timeout']: ++ self.timeout = int(arg) ++ elif opt in ['-v', '--verbose']: ++ self.verbose = self.verbose + 1 ++ elif opt in ['-V', '--version']: ++ self.version() ++ sys.exit(255) ++ ++ ### Enable verbosity ++ if self.verbose >= 2: ++ print >>sys.stderr, 'Verbosity set to level %d' % self.verbose ++ ++ self.filenames = args ++ ++ if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: ++ print >>sys.stderr, 'unoconv: you have to provide a filename as argument' ++ print >>sys.stderr, 'Try `unoconv -h\' for more information.' ++ sys.exit(255) ++ ++ ### Set connection string ++ if not self.connection: ++ if not self.pipe: ++ self.connection = "socket,host=%s,port=%s;urp;StarOffice.ComponentContext" % (self.server, self.port) ++# self.connection = "socket,host=%s,port=%s;urp;" % (self.server, self.port) ++ else: ++ self.connection = "pipe,name=%s;urp;StarOffice.ComponentContext" % (self.pipe) ++ ++ ### Make it easier for people to use a doctype (first letter is enough) ++ if self.doctype: ++ for doctype in doctypes: ++ if doctype.startswith(self.doctype): ++ self.doctype = doctype ++ ++ ### Check if the user request to see the list of formats ++ if self.showlist or self.format == 'list': ++ if self.doctype: ++ fmts.display(self.doctype) ++ else: ++ for t in doctypes: ++ fmts.display(t) ++ sys.exit(0) ++ ++ ### If no format was specified, probe it or provide it ++ if not self.format: ++ l = sys.argv[0].split('2') ++ if len(l) == 2: ++ self.format = l[1] ++ else: ++ self.format = 'pdf' ++ ++ def version(self): ++ ### Get office product information ++ product = global_uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ ++ print 'unoconv %s' % VERSION ++ print 'Written by Dag Wieers ' ++ print 'Homepage at http://dag.wieers.com/home-made/unoconv/' ++ print ++ print 'platform %s/%s' % (os.name, sys.platform) ++ print 'python %s' % sys.version ++ print product.ooName, product.ooSetupVersion ++# print ++# print 'build revision $Rev$' ++ ++ def usage(self): ++ print >>sys.stderr, 'usage: unoconv [options] file [file2 ..]' ++ ++ def help(self): ++ print >>sys.stderr, '''Convert from and to any format supported by LibreOffice ++ ++unoconv options: ++ -c, --connection=string use a custom connection string ++ -d, --doctype=type specify document type ++ (document, graphics, presentation, spreadsheet) ++ -e, --export=name=value set export filter options ++ eg. -e PageRange=1-2 ++ -f, --format=format specify the output format ++ -i, --import=string set import filter option string ++ eg. -i utf8 ++ -l, --listener start a permanent listener to use by unoconv clients ++ -n, --no-launch fail if no listener is found (default: launch one) ++ -o, --output=name output basename, filename or directory ++ --pipe=name alternative method of connection using a pipe ++ -p, --port=port specify the port (default: 2002) ++ to be used by client or listener ++ --password=string provide a password to decrypt the document ++ -s, --server=server specify the server address (default: 127.0.0.1) ++ to be used by client or listener ++ --show list the available output formats ++ --stdout write output to stdout ++ -t, --template=file import the styles from template (.ott) ++ -T, --timeout=secs timeout after secs if connection to listener fails ++ -v, --verbose be more and more verbose (-vvv for debugging) ++''' ++ ++class Convertor: ++ def __init__(self): ++ global exitcode, ooproc, office, product ++ unocontext = None ++ ++ ### Do the LibreOffice component dance ++ self.context = global_uno.getComponentContext() ++ self.svcmgr = self.context.ServiceManager ++ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) ++ ++ ### Test for an existing connection ++ info(3, 'Connection type: %s' % op.connection) ++ try: ++ unocontext = resolver.resolve("uno:%s" % op.connection) ++ except UnoNoConnectException, e: ++# info(3, "Existing listener not found.\n%s" % e) ++ info(3, "Existing listener not found.") ++ ++ if op.nolaunch: ++ die(113, "Existing listener not found. Unable start listener by parameters. Aborting.") ++ ++ ### Start our own OpenOffice instance ++ info(3, "Launching our own listener using %s." % office.binary) ++ try: ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): ++ ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) ++ else: ++ ooproc = subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--accept=%s" % op.connection], env=os.environ) ++ info(2, '%s listener successfully started. (pid=%s)' % (product.ooName, ooproc.pid)) ++ ++ ### Try connection to it for op.timeout seconds (flakky OpenOffice) ++ timeout = 0 ++ while timeout <= op.timeout: ++ ### Is it already/still running ? ++ retcode = ooproc.poll() ++ if retcode != None: ++ info(3, "Process %s (pid=%s) exited with %s." % (office.binary, ooproc.pid, retcode)) ++ break ++ try: ++ unocontext = resolver.resolve("uno:%s" % op.connection) ++ break ++ except UnoNoConnectException: ++ time.sleep(0.5) ++ timeout += 0.5 ++ except: ++ raise ++ else: ++ error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) ++ except Exception, e: ++ raise ++ error("Launch of %s failed.\n%s" % (office.binary, e)) ++ ++ if not unocontext: ++ die(251, "Unable to connect or start own listener. Aborting.") ++ ++ ### And some more LibreOffice magic ++ unosvcmgr = unocontext.ServiceManager ++ self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) ++ self.cwd = global_unohelper.systemPathToFileUrl( os.getcwd() ) ++ ++ ### List all filters ++# self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) ++# for filter in self.filters.getElementNames(): ++# print filter ++# #print dir(filter), dir(filter.format) ++ ++ def getformat(self, inputfn): ++ doctype = None ++ ++ ### Get the output format from mapping ++ if op.doctype: ++ outputfmt = fmts.bydoctype(op.doctype, op.format) ++ else: ++ outputfmt = fmts.byname(op.format) ++ ++ if not outputfmt: ++ outputfmt = fmts.byextension(os.extsep + op.format) ++ ++ ### If no doctype given, check list of acceptable formats for input file ext doctype ++ ### FIXME: This should go into the for-loop to match each individual input filename ++ if outputfmt: ++ inputext = os.path.splitext(inputfn)[1] ++ inputfmt = fmts.byextension(inputext) ++ if inputfmt: ++ for fmt in outputfmt: ++ if inputfmt[0].doctype == fmt.doctype: ++ doctype = inputfmt[0].doctype ++ outputfmt = fmt ++ break ++ else: ++ outputfmt = outputfmt[0] ++ # print >>sys.stderr, 'unoconv: format `%s\' is part of multiple doctypes %s, selecting `%s\'.' % (format, [fmt.doctype for fmt in outputfmt], outputfmt[0].doctype) ++ else: ++ outputfmt = outputfmt[0] ++ ++ ### No format found, throw error ++ if not outputfmt: ++ if doctype: ++ print >>sys.stderr, 'unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format) ++ else: ++ print >>sys.stderr, 'unoconv: format [%s] is not known to unoconv.' % op.format ++ die(1) ++ ++ return outputfmt ++ ++ def convert(self, inputfn): ++ global exitcode ++ ++ document = None ++ outputfmt = self.getformat(inputfn) ++ ++ if op.verbose > 0: ++ print >>sys.stderr, 'Input file:', inputfn ++ ++ if not os.path.exists(inputfn): ++ print >>sys.stderr, 'unoconv: file `%s\' does not exist.' % inputfn ++ exitcode = 1 ++ ++ try: ++ ### Import phase ++ phase = "import" ++ ++ ### Load inputfile ++ inputprops = GlobalUnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=UNO_QUIET_UPDATE) ++ ++# if op.password: ++# info = GlobalUnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") ++# inputprops += GlobalUnoProps(ModifyPasswordInfo=info) ++ ++ ### Cannot use GlobalUnoProps for FilterData property ++ if op.importfilteroptions: ++# print "Import filter options: %s" % op.importfilteroptions ++ inputprops += GlobalUnoProps(FilterOptions=op.importfilteroptions) ++ ++ ### Cannot use GlobalUnoProps for FilterData property ++ if op.importfilter: ++ inputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) ++ ++ inputurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(inputfn)) ++ document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) ++ ++ if not document: ++ raise UnoException("The document '%s' could not be opened." % inputurl, None) ++ ++ ### Import style template ++ phase = "import-style" ++ if op.template: ++ if os.path.exists(op.template): ++ info(1, "Template file: %s" % op.template) ++ templateprops = GlobalUnoProps(OverwriteStyles=True) ++ templateurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(op.template)) ++ document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) ++ else: ++ print >>sys.stderr, 'unoconv: template file `%s\' does not exist.' % op.template ++ exitcode = 1 ++ ++ ### Update document links ++ phase = "update-links" ++ try: ++ document.updateLinks() ++ except AttributeError: ++ # the document doesn't implement the XLinkUpdate interface ++ pass ++ ++ ### Update document indexes ++ phase = "update-indexes" ++ try: ++ document.refresh() ++ indexes = document.getDocumentIndexes() ++ except AttributeError: ++ # the document doesn't implement the XRefreshable and/or ++ # XDocumentIndexesSupplier interfaces ++ pass ++ else: ++ for i in range(0, indexes.getCount()): ++ indexes.getByIndex(i).update() ++ ++ info(1, "Selected output format: %s" % outputfmt) ++ info(2, "Selected office filter: %s" % outputfmt.filter) ++ info(2, "Used doctype: %s" % outputfmt.doctype) ++ ++ ### Export phase ++ phase = "export" ++ ++ outputprops = GlobalUnoProps(FilterName=outputfmt.filter, OutputStream=GlobalOutputStream(), Overwrite=True) ++ ++ ### Set default filter options ++ if op.exportfilteroptions: ++# print "Export filter options: %s" % op.exportfilteroptions ++ outputprops += GlobalUnoProps(FilterOptions=op.exportfilteroptions) ++ else: ++ if outputfmt.filter == 'Text (encoded)': ++ outputprops += GlobalUnoProps(FilterOptions="76,LF") ++ ++ elif outputfmt.filter == 'Text': ++ outputprops += GlobalUnoProps(FilterOptions="76") ++ ++ elif outputfmt.filter == 'Text - txt - csv (StarCalc)': ++ outputprops += GlobalUnoProps(FilterOptions="44,34,76") ++ ++ ++ ### Cannot use GlobalUnoProps for FilterData property ++ if op.exportfilter: ++ outputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) ++ ++ if not op.stdout: ++ (outputfn, ext) = os.path.splitext(inputfn) ++ if not op.output: ++ outputfn = outputfn + os.extsep + outputfmt.extension ++ elif os.path.isdir(op.output): ++ outputfn = realpath(op.output, os.path.basename(outputfn) + os.extsep + outputfmt.extension) ++ elif len(op.filenames) > 1: ++ outputfn = op.output + os.extsep + outputfmt.extension ++ else: ++ outputfn = op.output ++ ++ outputurl = global_unohelper.absolutize( self.cwd, global_unohelper.systemPathToFileUrl(outputfn) ) ++ info(1, "Output file: %s" % outputfn) ++ else: ++ outputurl = "private:stream" ++ ++ try: ++ document.storeToURL(outputurl, tuple(outputprops) ) ++ except UnoIOException, e: ++ raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) ++ ++ phase = "dispose" ++ document.dispose() ++ document.close(True) ++ ++ except SystemError, e: ++ error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) ++ exitcode = 1 ++ ++ except UnoRuntimeException, e: ++ error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) ++ exitcode = 6 ++ ++ except UnoDisposedException, e: ++ error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) ++ exitcode = 7 ++ ++ except UnoIllegalArgumentException, e: ++ error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) ++ exitcode = 8 ++ ++ except UnoIOException, e: ++# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) ++ error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) ++ exitcode = 3 ++ ++ except UnoCannotConvertException, e: ++# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) ++ error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) ++ exitcode = 4 ++ ++ except UnoException, e: ++ if hasattr(e, 'ErrCode'): ++ error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) ++ exitcode = e.ErrCode ++ pass ++ if hasattr(e, 'Message'): ++ error("unoconv: UnoException during %s phase:\n%s" % (phase, e.Message)) ++ exitcode = 5 ++ else: ++ error("unoconv: UnoException during %s phase in %s" % (phase, repr(e.__class__))) ++ exitcode = 2 ++ pass ++ ++class Listener: ++ def __init__(self): ++ global product ++ ++ info(1, "Start listener on %s:%s" % (op.server, op.port)) ++ self.context = global_uno.getComponentContext() ++ self.svcmgr = self.context.ServiceManager ++ try: ++ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ try: ++ unocontext = resolver.resolve("uno:%s" % op.connection) ++ except UnoNoConnectException, e: ++ pass ++ else: ++ info(1, "Existing %s listener found, nothing to do." % product.ooName) ++ return ++ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): ++ subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) ++ else: ++ subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) ++ except Exception, e: ++ error("Launch of %s failed.\n%s" % (office.binary, e)) ++ else: ++ info(1, "Existing %s listener found, nothing to do." % product.ooName) ++ ++def error(msg): ++ "Output error message" ++ print >>sys.stderr, msg ++ ++def info(level, msg): ++ "Output info message" ++ if 'op' not in globals(): ++ pass ++ elif op.verbose >= 3 and level >= 3: ++ print >>sys.stderr, "DEBUG:", msg ++ elif not op.stdout and level <= op.verbose: ++ print >>sys.stdout, msg ++ elif level <= op.verbose: ++ print >>sys.stderr, msg ++ ++def die(ret, msg=None): ++ "Print optional error and exit with errorcode" ++ global convertor, ooproc, office ++ ++ if msg: ++ error('Error: %s' % msg) ++ ++ ### Did we start our own listener instance ? ++ if not op.listener and ooproc and convertor: ++ ++ ### If there is a GUI now attached to the instance, disable listener ++ if convertor.desktop.getCurrentFrame(): ++ info(2, 'Trying to stop %s GUI listener.' % product.ooName) ++ try: ++ if product.ooName != "LibreOffice" or product.ooSetupVersion <= 3.3: ++ subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-unaccept=%s" % op.connection], env=os.environ) ++ else: ++ subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) ++ ooproc.wait() ++ info(2, '%s listener successfully disabled.' % product.ooName) ++ except Exception, e: ++ error("Terminate using %s failed.\n%s" % (office.binary, e)) ++ ++ ### If there is no GUI attached to the instance, terminate instance ++ else: ++ info(3, 'Terminating %s instance.' % product.ooName) ++ try: ++ convertor.desktop.terminate() ++ except UnoDisposedException: ++ info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) ++ try: ++ ooproc.terminate() ++ except AttributeError: ++ os.kill(ooproc.pid, 15) ++ info(3, 'Waiting for %s instance to exit.' % product.ooName) ++ ooproc.wait() ++ ++ ### LibreOffice processes may get stuck and we have to kill them ++ ### Is it still running ? ++ if ooproc.poll() == None: ++ info(1, '%s instance still running, please investigate...' % product.ooName) ++ ooproc.wait() ++ info(2, '%s instance unsuccessfully terminated, sending KILL signal.' % product.ooName) ++ try: ++ ooproc.kill() ++ except AttributeError: ++ os.kill(ooproc.pid, 9) ++ info(3, 'Waiting for %s with pid %s to disappear.' % (ooproc.pid, product.ooName)) ++ ooproc.wait() ++ ++ # allow Python GC to garbage collect pyuno object *before* exit call ++ # which avoids random segmentation faults --vpa ++ convertor = None ++ ++ sys.exit(ret) ++ ++def main(): ++ global convertor, exitcode ++ convertor = None ++ ++ try: ++ if op.listener: ++ listener = Listener() ++ ++ if op.filenames: ++ convertor = Convertor() ++ for inputfn in op.filenames: ++ convertor.convert(inputfn) ++ ++ except UnoNoConnectException, e: ++ error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) ++ if op.connection: ++ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) ++ else: ++ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"socket,host=%s,port=%s;urp;\"" % (op.server, op.server, op.port, op.server, op.port)) ++ info(0, "Please start an soffice instance on server '%s' by doing:\n\n soffice -nologo -nodefault -accept=\"socket,host=127.0.0.1,port=%s;urp;\"" % (op.server, op.port)) ++ exitcode = 1 ++# except UnboundLocalError: ++# die(252, "Failed to connect to remote listener.") ++ except OSError: ++ error("Warning: failed to launch Office suite. Aborting.") ++ ++### Main entrance ++def run(): ++ global exitcode ++ exitcode = 0 ++ ++ info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) ++ ++ for of in find_offices(): ++ if of.python != sys.executable and not sys.executable.startswith(of.basepath): ++ python_switch(of) ++ office_environ(of) ++# debug_office() ++ try: ++ global global_uno ++ global global_unohelper ++ ++ import uno as global_uno ++ import unohelper as global_unohelper ++ global office ++ office = of ++ break ++ except: ++# debug_office() ++ print >>sys.stderr, "unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of ++ print >>sys.stderr, "ERROR:", sys.exc_info()[1] ++ print >>sys.stderr ++ else: ++# debug_office() ++ print >>sys.stderr, "unoconv: Cannot find a suitable office installation on your system." ++ print >>sys.stderr, "ERROR: Please locate your office installation and send your feedback to:" ++ print >>sys.stderr, " http://github.com/dagwieers/unoconv/issues" ++ sys.exit(1) ++ ++ ### Now that we have found a working pyuno library, let's import some classes ++ global UnoPropertyValue ++ global UnoNoConnectException ++ global UNO_QUIET_UPDATE ++ global UnoDisposedException ++ global UnoIllegalArgumentException ++ global UnoIOException ++ global UnoXOutputStream ++ global UnoCannotConvertException ++ global UnoException ++ global UnoRuntimeException ++ ++ from com.sun.star.beans import PropertyValue as UnoPropertyValue ++ from com.sun.star.connection import NoConnectException as UnoNoConnectException ++ from com.sun.star.document.UpdateDocMode import QUIET_UPDATE as UNO_QUIET_UPDATE ++ from com.sun.star.lang import DisposedException as UnoDisposedException ++ from com.sun.star.lang import IllegalArgumentException as UnoIllegalArgumentException ++ from com.sun.star.io import IOException as UnoIOException ++ from com.sun.star.io import XOutputStream as UnoXOutputStream ++ from com.sun.star.script import CannotConvertException as UnoCannotConvertException ++ from com.sun.star.uno import Exception as UnoException ++ from com.sun.star.uno import RuntimeException as UnoRuntimeException ++ ++ ### And now that we have those classes, build on them ++ class OutputStream( global_unohelper.Base, UnoXOutputStream ): ++ def __init__( self ): ++ self.closed = 0 ++ ++ def closeOutput(self): ++ self.closed = 1 ++ ++ def writeBytes( self, seq ): ++ sys.stdout.write( seq.value ) ++ ++ def flush( self ): ++ pass ++ ++ global GlobalOutputStream ++ GlobalOutputStream = OutputStream ++ ++ def UnoProps(**args): ++ props = [] ++ for key in args: ++ prop = UnoPropertyValue() ++ prop.Name = key ++ prop.Value = args[key] ++ props.append(prop) ++ return tuple(props) ++ ++ global GlobalUnoProps ++ GlobalUnoProps = UnoProps ++ ++ global op ++ op = Options(sys.argv[1:]) ++ ++ info(2, "Using office base path: %s" % office.basepath) ++ info(2, "Using office binary path: %s" % office.unopath) ++ ++ try: ++ main() ++ except KeyboardInterrupt, e: ++ die(6, 'Exiting on user request') ++ die(exitcode) ++ ++if __name__ == '__main__': ++ run() +diff --git a/unoconv3.py b/unoconv3.py +new file mode 100755 +index 0000000..09d88c2 +--- /dev/null ++++ b/unoconv3.py +@@ -0,0 +1,1195 @@ ++#!/usr/bin/python3 ++ ++### This program is free software; you can redistribute it and/or modify ++### it under the terms of the GNU General Public License as published by ++### the Free Software Foundation; version 2 only ++### ++### This program is distributed in the hope that it will be useful, ++### but WITHOUT ANY WARRANTY; without even the implied warranty of ++### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++### GNU General Public License for more details. ++### ++### You should have received a copy of the GNU General Public License ++### along with this program; if not, write to the Free Software ++### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++### Copyright 2007-2010 Dag Wieers ++ ++from distutils.version import LooseVersion ++import getopt ++import glob ++import os ++import subprocess ++import sys ++import time ++ ++__version__ = "$Revision$" ++# $Source$ ++ ++VERSION = '0.6' ++ ++doctypes = ('document', 'graphics', 'presentation', 'spreadsheet') ++ ++global convertor, office, ooproc, product ++ooproc = None ++exitcode = 0 ++ ++class Office: ++ def __init__(self, basepath, urepath, unopath, pyuno, binary, python, pythonhome): ++ self.basepath = basepath ++ self.urepath = urepath ++ self.unopath = unopath ++ self.pyuno = pyuno ++ self.binary = binary ++ self.python = python ++ self.pythonhome = pythonhome ++ ++ def __str__(self): ++ return self.basepath ++ ++ def __repr__(self): ++ return self.basepath ++ ++### Implement a path normalizer in order to make unoconv work on MacOS X ++### (on which 'program' is a symlink to 'MacOSX' which seems to break unoconv) ++def realpath(*args): ++ ''' Implement a combination of os.path.join(), os.path.abspath() and ++ os.path.realpath() in order to normalize path constructions ''' ++ ret = '' ++ for arg in args: ++ ret = os.path.join(ret, arg) ++ return os.path.realpath(os.path.abspath(ret)) ++ ++### The first thing we ought to do is find a suitable Office installation ++### with a compatible pyuno library that we can import. ++### ++### See: http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=36370&p=166783 ++ ++def find_offices(): ++ ret = [] ++ extrapaths = [] ++ ++ ### Try using UNO_PATH first (in many incarnations, we'll see what sticks) ++ if 'UNO_PATH' in os.environ: ++ extrapaths += [ os.environ['UNO_PATH'], ++ os.path.dirname(os.environ['UNO_PATH']), ++ os.path.dirname(os.path.dirname(os.environ['UNO_PATH'])) ] ++ ++ else: ++ ++ if os.name in ( 'nt', 'os2' ): ++ if 'PROGRAMFILES' in list(os.environ.keys()): ++ extrapaths += glob.glob(os.environ['PROGRAMFILES']+'\\LibreOffice*') + \ ++ glob.glob(os.environ['PROGRAMFILES']+'\\OpenOffice.org*') ++ ++ if 'PROGRAMFILES(X86)' in list(os.environ.keys()): ++ extrapaths += glob.glob(os.environ['PROGRAMFILES(X86)']+'\\LibreOffice*') + \ ++ glob.glob(os.environ['PROGRAMFILES(X86)']+'\\OpenOffice.org*') ++ ++ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): ++ extrapaths += [ '/Applications/LibreOffice.app/Contents', ++ '/Applications/NeoOffice.app/Contents', ++ '/Applications/OpenOffice.org.app/Contents' ] ++ ++ else: ++ extrapaths += glob.glob('/usr/lib*/libreoffice*') + \ ++ glob.glob('/usr/lib*/openoffice*') + \ ++ glob.glob('/usr/lib*/ooo*') + \ ++ glob.glob('/opt/libreoffice*') + \ ++ glob.glob('/opt/openoffice*') + \ ++ glob.glob('/opt/ooo*') + \ ++ glob.glob('/usr/local/libreoffice*') + \ ++ glob.glob('/usr/local/openoffice*') + \ ++ glob.glob('/usr/local/ooo*') + \ ++ glob.glob('/usr/local/lib/libreoffice*') ++ ++ ### Find a working set for python UNO bindings ++ for basepath in extrapaths: ++ if os.name in ( 'nt', 'os2' ): ++ officelibraries = ( 'pyuno.pyd', ) ++ officebinaries = ( 'soffice.exe' ,) ++ pythonbinaries = ( 'python.exe', ) ++ pythonhomes = () ++ elif os.name in ( 'mac', ) or sys.platform in ( 'darwin', ): ++ officelibraries = ( 'pyuno.so', 'libpyuno.dylib' ) ++ officebinaries = ( 'soffice.bin', ) ++ pythonbinaries = ( 'python.bin', 'python' ) ++ pythonhomes = ( 'OOoPython.framework/Versions/*/lib/python*', ) ++ else: ++ officelibraries = ( 'pyuno.so', ) ++ officebinaries = ( 'soffice.bin', ) ++ pythonbinaries = ( 'python.bin', 'python', ) ++ pythonhomes = ( 'python-core-*', ) ++ ++ ### Older LibreOffice/OpenOffice and Windows use basis-link/ or basis/ ++ libpath = 'error' ++ for basis in ( 'basis-link', 'basis', '' ): ++ for lib in officelibraries: ++ if os.path.isfile(realpath(basepath, basis, 'program', lib)): ++ libpath = realpath(basepath, basis, 'program') ++ officelibrary = realpath(libpath, lib) ++ info(3, "Found %s in %s" % (lib, libpath)) ++ # Break the inner loop... ++ break ++ # Continue if the inner loop wasn't broken. ++ else: ++ continue ++ # Inner loop was broken, break the outer. ++ break ++ else: ++ continue ++ ++ ### MacOSX have soffice binaries installed in MacOS subdirectory, not program ++ unopath = 'error' ++ for basis in ( 'basis-link', 'basis', '' ): ++ for bin in officebinaries: ++ if os.path.isfile(realpath(basepath, basis, 'program', bin)): ++ unopath = realpath(basepath, basis, 'program') ++ officebinary = realpath(unopath, bin) ++ info(3, "Found %s in %s" % (bin, unopath)) ++ # Break the inner loop... ++ break ++ # Continue if the inner loop wasn't broken. ++ else: ++ continue ++ # Inner loop was broken, break the outer. ++ break ++ else: ++ continue ++ ++ ### Windows does not provide or need a URE/lib directory ? ++ urepath = '' ++ for basis in ( 'basis-link', 'basis', '' ): ++ for ure in ( 'ure-link', 'ure', 'URE', '' ): ++ if os.path.isfile(realpath(basepath, basis, ure, 'lib', 'unorc')): ++ urepath = realpath(basepath, basis, ure) ++ info(3, "Found %s in %s" % ('unorc', realpath(urepath, 'lib'))) ++ # Break the inner loop... ++ break ++ # Continue if the inner loop wasn't broken. ++ else: ++ continue ++ # Inner loop was broken, break the outer. ++ break ++ ++ pythonhome = None ++ for home in pythonhomes: ++ if glob.glob(realpath(libpath, home)): ++ pythonhome = glob.glob(realpath(libpath, home))[0] ++ info(3, "Found %s in %s" % (home, pythonhome)) ++ break ++ ++# if not os.path.isfile(realpath(basepath, program, officebinary)): ++# continue ++# info(3, "Found %s in %s" % (officebinary, realpath(basepath, program))) ++ ++# if not glob.glob(realpath(basepath, basis, program, 'python-core-*')): ++# continue ++ ++ for pythonbinary in pythonbinaries: ++ if os.path.isfile(realpath(unopath, pythonbinary)): ++ info(3, "Found %s in %s" % (pythonbinary, unopath)) ++ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, ++ realpath(unopath, pythonbinary), pythonhome)) ++ else: ++ info(3, "Considering %s" % basepath) ++ ret.append(Office(basepath, urepath, unopath, officelibrary, officebinary, ++ sys.executable, None)) ++ return ret ++ ++def office_environ(office): ++ ### Set PATH so that crash_report is found ++ os.environ['PATH'] = realpath(office.basepath, 'program') + os.pathsep + os.environ['PATH'] ++ ++ ### Set UNO_PATH so that "officehelper.bootstrap()" can find soffice executable: ++ os.environ['UNO_PATH'] = office.unopath ++ ++ ### Set URE_BOOTSTRAP so that "global_uno.getComponentContext()" bootstraps a complete ++ ### UNO environment ++ if os.name in ( 'nt', 'os2' ): ++ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamental.ini') ++ else: ++ os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:' + realpath(office.basepath, 'program', 'fundamentalrc') ++ ++ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: ++ if 'LD_LIBRARY_PATH' in os.environ: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') + os.pathsep + \ ++ os.environ['LD_LIBRARY_PATH'] ++ else: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') ++ ++ if office.pythonhome: ++ for libpath in ( realpath(office.pythonhome, 'lib'), ++ realpath(office.pythonhome, 'lib', 'lib-dynload'), ++ realpath(office.pythonhome, 'lib', 'lib-tk'), ++ realpath(office.pythonhome, 'lib', 'site-packages'), ++ office.unopath): ++ sys.path.insert(0, libpath) ++ else: ++ ### Still needed for system python using LibreOffice UNO bindings ++ ### Although we prefer to use a system UNO binding in this case ++ sys.path.append(office.unopath) ++ ++def debug_office(): ++ if 'URE_BOOTSTRAP' in os.environ: ++ print('URE_BOOTSTRAP=%s' % os.environ['URE_BOOTSTRAP'], file=sys.stderr) ++ if 'UNO_PATH' in os.environ: ++ print('UNO_PATH=%s' % os.environ['UNO_PATH'], file=sys.stderr) ++ if 'UNO_TYPES' in os.environ: ++ print('UNO_TYPES=%s' % os.environ['UNO_TYPES'], file=sys.stderr) ++ print('PATH=%s' % os.environ['PATH']) ++ if 'PYTHONHOME' in os.environ: ++ print('PYTHONHOME=%s' % os.environ['PYTHONHOME'], file=sys.stderr) ++ if 'PYTHONPATH' in os.environ: ++ print('PYTHONPATH=%s' % os.environ['PYTHONPATH'], file=sys.stderr) ++ if 'LD_LIBRARY_PATH' in os.environ: ++ print('LD_LIBRARY_PATH=%s' % os.environ['LD_LIBRARY_PATH'], file=sys.stderr) ++ ++def python_switch(office): ++ if office.pythonhome: ++ os.environ['PYTHONHOME'] = office.pythonhome ++ os.environ['PYTHONPATH'] = realpath(office.pythonhome, 'lib') + os.pathsep + \ ++ realpath(office.pythonhome, 'lib', 'lib-dynload') + os.pathsep + \ ++ realpath(office.pythonhome, 'lib', 'lib-tk') + os.pathsep + \ ++ realpath(office.pythonhome, 'lib', 'site-packages') + os.pathsep + \ ++ office.unopath ++ ++ os.environ['UNO_PATH'] = office.unopath ++ ++ info(3, "-> Switching from %s to %s" % (sys.executable, office.python)) ++ if os.name in ('nt', 'os2'): ++ ### os.execv is broken on Windows and can't properly parse command line ++ ### arguments and executable name if they contain whitespaces. subprocess ++ ### fixes that behavior. ++ ret = subprocess.call([office.python] + sys.argv[0:]) ++ sys.exit(ret) ++ else: ++ ++ ### Set LD_LIBRARY_PATH so that "import pyuno" finds libpyuno.so: ++ if 'LD_LIBRARY_PATH' in os.environ: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') + os.pathsep + \ ++ os.environ['LD_LIBRARY_PATH'] ++ else: ++ os.environ['LD_LIBRARY_PATH'] = office.unopath + os.pathsep + \ ++ realpath(office.urepath, 'lib') ++ ++ try: ++ os.execvpe(office.python, [office.python, ] + sys.argv[0:], os.environ) ++ print((office.python, [office.python, ] + sys.argv[0:], osenviron)) ++ except OSError: ++ ### Mac OS X versions prior to 10.6 do not support execv in ++ ### a process that contains multiple threads. Instead of ++ ### re-executing in the current process, start a new one ++ ### and cause the current process to exit. This isn't ++ ### ideal since the new process is detached from the parent ++ ### terminal and thus cannot easily be killed with ctrl-C, ++ ### but it's better than not being able to autoreload at ++ ### all. ++ ### Unfortunately the errno returned in this case does not ++ ### appear to be consistent, so we can't easily check for ++ ### this error specifically. ++ ret = os.spawnvpe(os.P_WAIT, office.python, [office.python, ] + sys.argv[0:], os.environ) ++ sys.exit(ret) ++ ++class Fmt: ++ def __init__(self, doctype, name, extension, summary, filter): ++ self.doctype = doctype ++ self.name = name ++ self.extension = extension ++ self.summary = summary ++ self.filter = filter ++ ++ def __str__(self): ++ return "%s [.%s]" % (self.summary, self.extension) ++ ++ def __repr__(self): ++ return "%s/%s" % (self.name, self.doctype) ++ ++class FmtList: ++ def __init__(self): ++ self.list = [] ++ ++ def add(self, doctype, name, extension, summary, filter): ++ self.list.append(Fmt(doctype, name, extension, summary, filter)) ++ ++ def byname(self, name): ++ ret = [] ++ for fmt in self.list: ++ if fmt.name == name: ++ ret.append(fmt) ++ return ret ++ ++ def byextension(self, extension): ++ ret = [] ++ for fmt in self.list: ++ if os.extsep + fmt.extension == extension: ++ ret.append(fmt) ++ return ret ++ ++ def bydoctype(self, doctype, name): ++ ret = [] ++ for fmt in self.list: ++ if fmt.name == name and fmt.doctype == doctype: ++ ret.append(fmt) ++ return ret ++ ++ def display(self, doctype): ++ print("The following list of %s formats are currently available:\n" % doctype, file=sys.stderr) ++ for fmt in self.list: ++ if fmt.doctype == doctype: ++ print(" %-8s - %s" % (fmt.name, fmt), file=sys.stderr) ++ print(file=sys.stderr) ++ ++fmts = FmtList() ++ ++### TextDocument ++fmts.add('document', 'bib', 'bib', 'BibTeX', 'BibTeX_Writer') ### 22 ++fmts.add('document', 'doc', 'doc', 'Microsoft Word 97/2000/XP', 'MS Word 97') ### 29 ++fmts.add('document', 'doc6', 'doc', 'Microsoft Word 6.0', 'MS WinWord 6.0') ### 24 ++fmts.add('document', 'doc95', 'doc', 'Microsoft Word 95', 'MS Word 95') ### 28 ++fmts.add('document', 'docbook', 'xml', 'DocBook', 'DocBook File') ### 39 ++fmts.add('document', 'docx', 'docx', 'Microsoft Office Open XML', 'Office Open XML Text') ++fmts.add('document', 'docx7', 'docx', 'Microsoft Office Open XML', 'MS Word 2007 XML') ++fmts.add('document', 'fodt', 'fodt', 'OpenDocument Text (Flat XML)', 'OpenDocument Text Flat XML') ++fmts.add('document', 'html', 'html', 'HTML Document (OpenOffice.org Writer)', 'HTML (StarWriter)') ### 3 ++fmts.add('document', 'latex', 'ltx', 'LaTeX 2e', 'LaTeX_Writer') ### 31 ++fmts.add('document', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki') ++fmts.add('document', 'odt', 'odt', 'ODF Text Document', 'writer8') ### 10 ++fmts.add('document', 'ooxml', 'xml', 'Microsoft Office Open XML', 'MS Word 2003 XML') ### 11 ++fmts.add('document', 'ott', 'ott', 'Open Document Text', 'writer8_template') ### 21 ++fmts.add('document', 'pdb', 'pdb', 'AportisDoc (Palm)', 'AportisDoc Palm DB') ++fmts.add('document', 'pdf', 'pdf', 'Portable Document Format', 'writer_pdf_Export') ### 18 ++fmts.add('document', 'psw', 'psw', 'Pocket Word', 'PocketWord File') ++fmts.add('document', 'rtf', 'rtf', 'Rich Text Format', 'Rich Text Format') ### 16 ++fmts.add('document', 'sdw', 'sdw', 'StarWriter 5.0', 'StarWriter 5.0') ### 23 ++fmts.add('document', 'sdw4', 'sdw', 'StarWriter 4.0', 'StarWriter 4.0') ### 2 ++fmts.add('document', 'sdw3', 'sdw', 'StarWriter 3.0', 'StarWriter 3.0') ### 20 ++fmts.add('document', 'stw', 'stw', 'Open Office.org 1.0 Text Document Template', 'writer_StarOffice_XML_Writer_Template') ### 9 ++fmts.add('document', 'sxw', 'sxw', 'Open Office.org 1.0 Text Document', 'StarOffice XML (Writer)') ### 1 ++fmts.add('document', 'text', 'txt', 'Text Encoded', 'Text (encoded)') ### 26 ++fmts.add('document', 'txt', 'txt', 'Text', 'Text') ### 34 ++fmts.add('document', 'uot', 'uot', 'Unified Office Format text','UOF text') ### 27 ++fmts.add('document', 'vor', 'vor', 'StarWriter 5.0 Template', 'StarWriter 5.0 Vorlage/Template') ### 6 ++fmts.add('document', 'vor4', 'vor', 'StarWriter 4.0 Template', 'StarWriter 4.0 Vorlage/Template') ### 5 ++fmts.add('document', 'vor3', 'vor', 'StarWriter 3.0 Template', 'StarWriter 3.0 Vorlage/Template') ### 4 ++fmts.add('document', 'xhtml', 'html', 'XHTML Document', 'XHTML Writer File') ### 33 ++ ++### WebDocument ++fmts.add('web', 'etext', 'txt', 'Text Encoded (OpenOffice.org Writer/Web)', 'Text (encoded) (StarWriter/Web)') ### 14 ++fmts.add('web', 'html10', 'html', 'OpenOffice.org 1.0 HTML Template', 'writer_web_StarOffice_XML_Writer_Web_Template') ### 11 ++fmts.add('web', 'html', 'html', 'HTML Document', 'HTML') ### 2 ++fmts.add('web', 'html', 'html', 'HTML Document Template', 'writerweb8_writer_template') ### 13 ++fmts.add('web', 'mediawiki', 'txt', 'MediaWiki', 'MediaWiki_Web') ### 9 ++fmts.add('web', 'pdf', 'pdf', 'PDF - Portable Document Format', 'writer_web_pdf_Export') ### 10 ++fmts.add('web', 'sdw3', 'sdw', 'StarWriter 3.0 (OpenOffice.org Writer/Web)', 'StarWriter 3.0 (StarWriter/Web)') ### 3 ++fmts.add('web', 'sdw4', 'sdw', 'StarWriter 4.0 (OpenOffice.org Writer/Web)', 'StarWriter 4.0 (StarWriter/Web)') ### 4 ++fmts.add('web', 'sdw', 'sdw', 'StarWriter 5.0 (OpenOffice.org Writer/Web)', 'StarWriter 5.0 (StarWriter/Web)') ### 5 ++fmts.add('web', 'txt', 'txt', 'OpenOffice.org Text (OpenOffice.org Writer/Web)', 'writerweb8_writer') ### 12 ++fmts.add('web', 'text10', 'txt', 'OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)', 'writer_web_StarOffice_XML_Writer') ### 15 ++fmts.add('web', 'text', 'txt', 'Text (OpenOffice.org Writer/Web)', 'Text (StarWriter/Web)') ### 8 ++fmts.add('web', 'vor4', 'vor', 'StarWriter/Web 4.0 Template', 'StarWriter/Web 4.0 Vorlage/Template') ### 6 ++fmts.add('web', 'vor', 'vor', 'StarWriter/Web 5.0 Template', 'StarWriter/Web 5.0 Vorlage/Template') ### 7 ++ ++### Spreadsheet ++fmts.add('spreadsheet', 'csv', 'csv', 'Text CSV', 'Text - txt - csv (StarCalc)') ### 16 ++fmts.add('spreadsheet', 'dbf', 'dbf', 'dBASE', 'dBase') ### 22 ++fmts.add('spreadsheet', 'dif', 'dif', 'Data Interchange Format', 'DIF') ### 5 ++fmts.add('spreadsheet', 'fods', 'fods', 'OpenDocument Spreadsheet (Flat XML)', 'OpenDocument Spreadsheet Flat XML') ++fmts.add('spreadsheet', 'html', 'html', 'HTML Document (OpenOffice.org Calc)', 'HTML (StarCalc)') ### 7 ++fmts.add('spreadsheet', 'ods', 'ods', 'ODF Spreadsheet', 'calc8') ### 15 ++fmts.add('spreadsheet', 'ooxml', 'xml', 'Microsoft Excel 2003 XML', 'MS Excel 2003 XML') ### 23 ++fmts.add('spreadsheet', 'ots', 'ots', 'ODF Spreadsheet Template', 'calc8_template') ### 14 ++fmts.add('spreadsheet', 'pdf', 'pdf', 'Portable Document Format', 'calc_pdf_Export') ### 34 ++fmts.add('spreadsheet', 'pxl', 'pxl', 'Pocket Excel', 'Pocket Excel') ++fmts.add('spreadsheet', 'sdc', 'sdc', 'StarCalc 5.0', 'StarCalc 5.0') ### 31 ++fmts.add('spreadsheet', 'sdc4', 'sdc', 'StarCalc 4.0', 'StarCalc 4.0') ### 11 ++fmts.add('spreadsheet', 'sdc3', 'sdc', 'StarCalc 3.0', 'StarCalc 3.0') ### 29 ++fmts.add('spreadsheet', 'slk', 'slk', 'SYLK', 'SYLK') ### 35 ++fmts.add('spreadsheet', 'stc', 'stc', 'OpenOffice.org 1.0 Spreadsheet Template', 'calc_StarOffice_XML_Calc_Template') ### 2 ++fmts.add('spreadsheet', 'sxc', 'sxc', 'OpenOffice.org 1.0 Spreadsheet', 'StarOffice XML (Calc)') ### 3 ++fmts.add('spreadsheet', 'uos', 'uos', 'Unified Office Format spreadsheet', 'UOF spreadsheet') ### 9 ++fmts.add('spreadsheet', 'vor3', 'vor', 'StarCalc 3.0 Template', 'StarCalc 3.0 Vorlage/Template') ### 18 ++fmts.add('spreadsheet', 'vor4', 'vor', 'StarCalc 4.0 Template', 'StarCalc 4.0 Vorlage/Template') ### 19 ++fmts.add('spreadsheet', 'vor', 'vor', 'StarCalc 5.0 Template', 'StarCalc 5.0 Vorlage/Template') ### 20 ++fmts.add('spreadsheet', 'xhtml', 'xhtml', 'XHTML', 'XHTML Calc File') ### 26 ++fmts.add('spreadsheet', 'xls', 'xls', 'Microsoft Excel 97/2000/XP', 'MS Excel 97') ### 12 ++fmts.add('spreadsheet', 'xls5', 'xls', 'Microsoft Excel 5.0', 'MS Excel 5.0/95') ### 8 ++fmts.add('spreadsheet', 'xls95', 'xls', 'Microsoft Excel 95', 'MS Excel 95') ### 10 ++fmts.add('spreadsheet', 'xlt', 'xlt', 'Microsoft Excel 97/2000/XP Template', 'MS Excel 97 Vorlage/Template') ### 6 ++fmts.add('spreadsheet', 'xlt5', 'xlt', 'Microsoft Excel 5.0 Template', 'MS Excel 5.0/95 Vorlage/Template') ### 28 ++fmts.add('spreadsheet', 'xlt95', 'xlt', 'Microsoft Excel 95 Template', 'MS Excel 95 Vorlage/Template') ### 21 ++ ++### Graphics ++fmts.add('graphics', 'bmp', 'bmp', 'Windows Bitmap', 'draw_bmp_Export') ### 21 ++fmts.add('graphics', 'emf', 'emf', 'Enhanced Metafile', 'draw_emf_Export') ### 15 ++fmts.add('graphics', 'eps', 'eps', 'Encapsulated PostScript', 'draw_eps_Export') ### 48 ++fmts.add('graphics', 'fodg', 'fodg', 'OpenDocument Drawing (Flat XML)', 'OpenDocument Drawing Flat XML') ++fmts.add('graphics', 'gif', 'gif', 'Graphics Interchange Format', 'draw_gif_Export') ### 30 ++fmts.add('graphics', 'html', 'html', 'HTML Document (OpenOffice.org Draw)', 'draw_html_Export') ### 37 ++fmts.add('graphics', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'draw_jpg_Export') ### 3 ++fmts.add('graphics', 'met', 'met', 'OS/2 Metafile', 'draw_met_Export') ### 43 ++fmts.add('graphics', 'odd', 'odd', 'OpenDocument Drawing', 'draw8') ### 6 ++fmts.add('graphics', 'otg', 'otg', 'OpenDocument Drawing Template', 'draw8_template') ### 20 ++fmts.add('graphics', 'pbm', 'pbm', 'Portable Bitmap', 'draw_pbm_Export') ### 14 ++fmts.add('graphics', 'pct', 'pct', 'Mac Pict', 'draw_pct_Export') ### 41 ++fmts.add('graphics', 'pdf', 'pdf', 'Portable Document Format', 'draw_pdf_Export') ### 28 ++fmts.add('graphics', 'pgm', 'pgm', 'Portable Graymap', 'draw_pgm_Export') ### 11 ++fmts.add('graphics', 'png', 'png', 'Portable Network Graphic', 'draw_png_Export') ### 2 ++fmts.add('graphics', 'ppm', 'ppm', 'Portable Pixelmap', 'draw_ppm_Export') ### 5 ++fmts.add('graphics', 'ras', 'ras', 'Sun Raster Image', 'draw_ras_Export') ## 31 ++fmts.add('graphics', 'std', 'std', 'OpenOffice.org 1.0 Drawing Template', 'draw_StarOffice_XML_Draw_Template') ### 53 ++fmts.add('graphics', 'svg', 'svg', 'Scalable Vector Graphics', 'draw_svg_Export') ### 50 ++fmts.add('graphics', 'svm', 'svm', 'StarView Metafile', 'draw_svm_Export') ### 55 ++fmts.add('graphics', 'swf', 'swf', 'Macromedia Flash (SWF)', 'draw_flash_Export') ### 23 ++fmts.add('graphics', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing', 'StarOffice XML (Draw)') ### 26 ++fmts.add('graphics', 'sxd3', 'sxd', 'StarDraw 3.0', 'StarDraw 3.0') ### 40 ++fmts.add('graphics', 'sxd5', 'sxd', 'StarDraw 5.0', 'StarDraw 5.0') ### 44 ++fmts.add('graphics', 'sxw', 'sxw', 'StarOffice XML (Draw)', 'StarOffice XML (Draw)') ++fmts.add('graphics', 'tiff', 'tiff', 'Tagged Image File Format', 'draw_tif_Export') ### 13 ++fmts.add('graphics', 'vor', 'vor', 'StarDraw 5.0 Template', 'StarDraw 5.0 Vorlage') ### 36 ++fmts.add('graphics', 'vor3', 'vor', 'StarDraw 3.0 Template', 'StarDraw 3.0 Vorlage') ### 35 ++fmts.add('graphics', 'wmf', 'wmf', 'Windows Metafile', 'draw_wmf_Export') ### 8 ++fmts.add('graphics', 'xhtml', 'xhtml', 'XHTML', 'XHTML Draw File') ### 45 ++fmts.add('graphics', 'xpm', 'xpm', 'X PixMap', 'draw_xpm_Export') ### 19 ++ ++### Presentation ++fmts.add('presentation', 'bmp', 'bmp', 'Windows Bitmap', 'impress_bmp_Export') ### 15 ++fmts.add('presentation', 'emf', 'emf', 'Enhanced Metafile', 'impress_emf_Export') ### 16 ++fmts.add('presentation', 'eps', 'eps', 'Encapsulated PostScript', 'impress_eps_Export') ### 17 ++fmts.add('presentation', 'fodp', 'fodp', 'OpenDocument Presentation (Flat XML)', 'OpenDocument Presentation Flat XML') ++fmts.add('presentation', 'gif', 'gif', 'Graphics Interchange Format', 'impress_gif_Export') ### 18 ++fmts.add('presentation', 'html', 'html', 'HTML Document (OpenOffice.org Impress)', 'impress_html_Export') ### 43 ++fmts.add('presentation', 'jpg', 'jpg', 'Joint Photographic Experts Group', 'impress_jpg_Export') ### 19 ++fmts.add('presentation', 'met', 'met', 'OS/2 Metafile', 'impress_met_Export') ### 20 ++fmts.add('presentation', 'odg', 'odg', 'ODF Drawing (Impress)', 'impress8_draw') ### 29 ++fmts.add('presentation', 'odp', 'odp', 'ODF Presentation', 'impress8') ### 9 ++fmts.add('presentation', 'otp', 'otp', 'ODF Presentation Template', 'impress8_template') ### 38 ++fmts.add('presentation', 'pbm', 'pbm', 'Portable Bitmap', 'impress_pbm_Export') ### 21 ++fmts.add('presentation', 'pct', 'pct', 'Mac Pict', 'impress_pct_Export') ### 22 ++fmts.add('presentation', 'pdf', 'pdf', 'Portable Document Format', 'impress_pdf_Export') ### 23 ++fmts.add('presentation', 'pgm', 'pgm', 'Portable Graymap', 'impress_pgm_Export') ### 24 ++fmts.add('presentation', 'png', 'png', 'Portable Network Graphic', 'impress_png_Export') ### 25 ++fmts.add('presentation', 'potm', 'potm', 'Microsoft PowerPoint 2007/2010 XML Template', 'Impress MS PowerPoint 2007 XML Template') ++fmts.add('presentation', 'pot', 'pot', 'Microsoft PowerPoint 97/2000/XP Template', 'MS PowerPoint 97 Vorlage') ### 3 ++fmts.add('presentation', 'ppm', 'ppm', 'Portable Pixelmap', 'impress_ppm_Export') ### 26 ++fmts.add('presentation', 'pptx', 'pptx', 'Microsoft PowerPoint 2007/2010 XML', 'Impress MS PowerPoint 2007 XML') ### 36 ++fmts.add('presentation', 'pps', 'pps', 'Microsoft PowerPoint 97/2000/XP (Autoplay)', 'MS PowerPoint 97 Autoplay') ### 36 ++fmts.add('presentation', 'ppt', 'ppt', 'Microsoft PowerPoint 97/2000/XP', 'MS PowerPoint 97') ### 36 ++fmts.add('presentation', 'pwp', 'pwp', 'PlaceWare', 'placeware_Export') ### 30 ++fmts.add('presentation', 'ras', 'ras', 'Sun Raster Image', 'impress_ras_Export') ### 27 ++fmts.add('presentation', 'sda', 'sda', 'StarDraw 5.0 (OpenOffice.org Impress)', 'StarDraw 5.0 (StarImpress)') ### 8 ++fmts.add('presentation', 'sdd', 'sdd', 'StarImpress 5.0', 'StarImpress 5.0') ### 6 ++fmts.add('presentation', 'sdd3', 'sdd', 'StarDraw 3.0 (OpenOffice.org Impress)', 'StarDraw 3.0 (StarImpress)') ### 42 ++fmts.add('presentation', 'sdd4', 'sdd', 'StarImpress 4.0', 'StarImpress 4.0') ### 37 ++fmts.add('presentation', 'sxd', 'sxd', 'OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)', 'impress_StarOffice_XML_Draw') ### 31 ++fmts.add('presentation', 'sti', 'sti', 'OpenOffice.org 1.0 Presentation Template', 'impress_StarOffice_XML_Impress_Template') ### 5 ++fmts.add('presentation', 'svg', 'svg', 'Scalable Vector Graphics', 'impress_svg_Export') ### 14 ++fmts.add('presentation', 'svm', 'svm', 'StarView Metafile', 'impress_svm_Export') ### 13 ++fmts.add('presentation', 'swf', 'swf', 'Macromedia Flash (SWF)', 'impress_flash_Export') ### 34 ++fmts.add('presentation', 'sxi', 'sxi', 'OpenOffice.org 1.0 Presentation', 'StarOffice XML (Impress)') ### 41 ++fmts.add('presentation', 'tiff', 'tiff', 'Tagged Image File Format', 'impress_tif_Export') ### 12 ++fmts.add('presentation', 'uop', 'uop', 'Unified Office Format presentation', 'UOF presentation') ### 4 ++fmts.add('presentation', 'vor', 'vor', 'StarImpress 5.0 Template', 'StarImpress 5.0 Vorlage') ### 40 ++fmts.add('presentation', 'vor3', 'vor', 'StarDraw 3.0 Template (OpenOffice.org Impress)', 'StarDraw 3.0 Vorlage (StarImpress)') ###1 ++fmts.add('presentation', 'vor4', 'vor', 'StarImpress 4.0 Template', 'StarImpress 4.0 Vorlage') ### 39 ++fmts.add('presentation', 'vor5', 'vor', 'StarDraw 5.0 Template (OpenOffice.org Impress)', 'StarDraw 5.0 Vorlage (StarImpress)') ### 2 ++fmts.add('presentation', 'wmf', 'wmf', 'Windows Metafile', 'impress_wmf_Export') ### 11 ++fmts.add('presentation', 'xhtml', 'xml', 'XHTML', 'XHTML Impress File') ### 33 ++fmts.add('presentation', 'xpm', 'xpm', 'X PixMap', 'impress_xpm_Export') ### 10 ++ ++class Options: ++ def __init__(self, args): ++ self.connection = None ++ self.debug = False ++ self.doctype = None ++ self.exportfilter = [] ++ self.exportfilteroptions = "" ++ self.filenames = [] ++ self.format = None ++ self.importfilter = [] ++ self.importfilteroptions = "" ++ self.listener = False ++ self.nolaunch = False ++ self.output = None ++ self.password = None ++ self.pipe = None ++ self.port = '2002' ++ self.server = '127.0.0.1' ++ self.showlist = False ++ self.stdout = False ++ self.template = None ++ self.timeout = 6 ++ self.verbose = 0 ++ ++ ### Get options from the commandline ++ try: ++ opts, args = getopt.getopt (args, 'c:Dd:e:f:hi:Llo:np:s:T:t:vV', ++ ['connection=', 'debug', 'doctype=', 'export=', 'format=', ++ 'help', 'import', 'listener', 'no-launch', 'output=', ++ 'outputpath', 'password=', 'pipe=', 'port=', 'server=', ++ 'timeout=', 'show', 'stdout', 'template', 'verbose', ++ 'version'] ) ++ except getopt.error as exc: ++ print('unoconv: %s, try unoconv -h for a list of all the options' % str(exc)) ++ sys.exit(255) ++ ++ for opt, arg in opts: ++ if opt in ['-h', '--help']: ++ self.usage() ++ print() ++ self.help() ++ sys.exit(1) ++ elif opt in ['-c', '--connection']: ++ self.connection = arg ++ elif opt in ['--debug']: ++ self.debug = True ++ elif opt in ['-d', '--doctype']: ++ self.doctype = arg ++ elif opt in ['-e', '--export']: ++ l = arg.split('=') ++ if len(l) == 2: ++ (name, value) = l ++ if name in ('FilterOptions'): ++ self.exportfilteroptions = value ++ elif value in ('True', 'true'): ++ self.exportfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) ++ elif value in ('False', 'false'): ++ self.exportfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) ++ else: ++ try: ++ self.exportfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) ++ except ValueError: ++ self.exportfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) ++ else: ++ print('Warning: Option %s cannot be parsed, ignoring.' % arg, file=sys.stderr) ++ elif opt in ['-f', '--format']: ++ self.format = arg ++ elif opt in ['-i', '--import']: ++ l = arg.split('=') ++ if len(l) == 2: ++ (name, value) = l ++ if name in ('FilterOptions'): ++ self.importfilteroptions = value ++ elif value in ('True', 'true'): ++ self.importfilter.append( UnoPropertyValue( name, 0, True, 0 ) ) ++ elif value in ('False', 'false'): ++ self.importfilter.append( UnoPropertyValue( name, 0, False, 0 ) ) ++ else: ++ try: ++ self.importfilter.append( UnoPropertyValue( name, 0, int(value), 0 ) ) ++ except ValueError: ++ self.importfilter.append( UnoPropertyValue( name, 0, value, 0 ) ) ++ else: ++ print('Warning: Option %s cannot be parsed, ignoring.' % arg, file=sys.stderr) ++ elif opt in ['-l', '--listener']: ++ self.listener = True ++ elif opt in ['-n', '--no-launch']: ++ self.nolaunch = True ++ elif opt in ['-o', '--output']: ++ self.output = arg ++ elif opt in ['--outputpath']: ++ print('Warning: This option is deprecated by --output.', file=sys.stderr) ++ self.output = arg ++ elif opt in ['--password']: ++ self.password = arg ++ elif opt in ['--pipe']: ++ self.pipe = arg ++ elif opt in ['-p', '--port']: ++ self.port = arg ++ elif opt in ['-s', '--server']: ++ self.server = arg ++ elif opt in ['--show']: ++ self.showlist = True ++ elif opt in ['--stdout']: ++ self.stdout = True ++ elif opt in ['-t', '--template']: ++ self.template = arg ++ elif opt in ['-T', '--timeout']: ++ self.timeout = int(arg) ++ elif opt in ['-v', '--verbose']: ++ self.verbose = self.verbose + 1 ++ elif opt in ['-V', '--version']: ++ self.version() ++ sys.exit(255) ++ ++ ### Enable verbosity ++ if self.verbose >= 2: ++ print('Verbosity set to level %d' % self.verbose, file=sys.stderr) ++ ++ self.filenames = args ++ ++ if not self.listener and not self.showlist and self.doctype != 'list' and not self.filenames: ++ print('unoconv: you have to provide a filename as argument', file=sys.stderr) ++ print('Try `unoconv -h\' for more information.', file=sys.stderr) ++ sys.exit(255) ++ ++ ### Set connection string ++ if not self.connection: ++ if not self.pipe: ++ self.connection = "socket,host=%s,port=%s;urp;StarOffice.ComponentContext" % (self.server, self.port) ++# self.connection = "socket,host=%s,port=%s;urp;" % (self.server, self.port) ++ else: ++ self.connection = "pipe,name=%s;urp;StarOffice.ComponentContext" % (self.pipe) ++ ++ ### Make it easier for people to use a doctype (first letter is enough) ++ if self.doctype: ++ for doctype in doctypes: ++ if doctype.startswith(self.doctype): ++ self.doctype = doctype ++ ++ ### Check if the user request to see the list of formats ++ if self.showlist or self.format == 'list': ++ if self.doctype: ++ fmts.display(self.doctype) ++ else: ++ for t in doctypes: ++ fmts.display(t) ++ sys.exit(0) ++ ++ ### If no format was specified, probe it or provide it ++ if not self.format: ++ l = sys.argv[0].split('2') ++ if len(l) == 2: ++ self.format = l[1] ++ else: ++ self.format = 'pdf' ++ ++ def version(self): ++ ### Get office product information ++ product = global_uno.getComponentContext().ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ ++ print('unoconv %s' % VERSION) ++ print('Written by Dag Wieers ') ++ print('Homepage at http://dag.wieers.com/home-made/unoconv/') ++ print() ++ print('platform %s/%s' % (os.name, sys.platform)) ++ print('python %s' % sys.version) ++ print(product.ooName, product.ooSetupVersion) ++# print ++# print 'build revision $Rev$' ++ ++ def usage(self): ++ print('usage: unoconv [options] file [file2 ..]', file=sys.stderr) ++ ++ def help(self): ++ print('''Convert from and to any format supported by LibreOffice ++ ++unoconv options: ++ -c, --connection=string use a custom connection string ++ -d, --doctype=type specify document type ++ (document, graphics, presentation, spreadsheet) ++ -e, --export=name=value set export filter options ++ eg. -e PageRange=1-2 ++ -f, --format=format specify the output format ++ -i, --import=string set import filter option string ++ eg. -i utf8 ++ -l, --listener start a permanent listener to use by unoconv clients ++ -n, --no-launch fail if no listener is found (default: launch one) ++ -o, --output=name output basename, filename or directory ++ --pipe=name alternative method of connection using a pipe ++ -p, --port=port specify the port (default: 2002) ++ to be used by client or listener ++ --password=string provide a password to decrypt the document ++ -s, --server=server specify the server address (default: 127.0.0.1) ++ to be used by client or listener ++ --show list the available output formats ++ --stdout write output to stdout ++ -t, --template=file import the styles from template (.ott) ++ -T, --timeout=secs timeout after secs if connection to listener fails ++ -v, --verbose be more and more verbose (-vvv for debugging) ++''', file=sys.stderr) ++ ++class Convertor: ++ def __init__(self): ++ global exitcode, ooproc, office, product ++ unocontext = None ++ ++ ### Do the LibreOffice component dance ++ self.context = global_uno.getComponentContext() ++ self.svcmgr = self.context.ServiceManager ++ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) ++ ++ ### Test for an existing connection ++ info(3, 'Connection type: %s' % op.connection) ++ try: ++ unocontext = resolver.resolve("uno:%s" % op.connection) ++ except UnoNoConnectException as e: ++# info(3, "Existing listener not found.\n%s" % e) ++ info(3, "Existing listener not found.") ++ ++ if op.nolaunch: ++ die(113, "Existing listener not found. Unable start listener by parameters. Aborting.") ++ ++ ### Start our own OpenOffice instance ++ info(3, "Launching our own listener using %s." % office.binary) ++ try: ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): ++ ooproc = subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-accept=%s" % op.connection], env=os.environ) ++ else: ++ ooproc = subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--accept=%s" % op.connection], env=os.environ) ++ info(2, '%s listener successfully started. (pid=%s)' % (product.ooName, ooproc.pid)) ++ ++ ### Try connection to it for op.timeout seconds (flakky OpenOffice) ++ timeout = 0 ++ while timeout <= op.timeout: ++ ### Is it already/still running ? ++ retcode = ooproc.poll() ++ if retcode != None: ++ info(3, "Process %s (pid=%s) exited with %s." % (office.binary, ooproc.pid, retcode)) ++ break ++ try: ++ unocontext = resolver.resolve("uno:%s" % op.connection) ++ break ++ except UnoNoConnectException: ++ time.sleep(0.5) ++ timeout += 0.5 ++ except: ++ raise ++ else: ++ error("Failed to connect to %s (pid=%s) in %d seconds.\n%s" % (office.binary, ooproc.pid, op.timeout, e)) ++ except Exception as e: ++ raise ++ error("Launch of %s failed.\n%s" % (office.binary, e)) ++ ++ if not unocontext: ++ die(251, "Unable to connect or start own listener. Aborting.") ++ ++ ### And some more LibreOffice magic ++ unosvcmgr = unocontext.ServiceManager ++ self.desktop = unosvcmgr.createInstanceWithContext("com.sun.star.frame.Desktop", unocontext) ++ self.cwd = global_unohelper.systemPathToFileUrl( os.getcwd() ) ++ ++ ### List all filters ++# self.filters = unosvcmgr.createInstanceWithContext( "com.sun.star.document.FilterFactory", unocontext) ++# for filter in self.filters.getElementNames(): ++# print filter ++# #print dir(filter), dir(filter.format) ++ ++ def getformat(self, inputfn): ++ doctype = None ++ ++ ### Get the output format from mapping ++ if op.doctype: ++ outputfmt = fmts.bydoctype(op.doctype, op.format) ++ else: ++ outputfmt = fmts.byname(op.format) ++ ++ if not outputfmt: ++ outputfmt = fmts.byextension(os.extsep + op.format) ++ ++ ### If no doctype given, check list of acceptable formats for input file ext doctype ++ ### FIXME: This should go into the for-loop to match each individual input filename ++ if outputfmt: ++ inputext = os.path.splitext(inputfn)[1] ++ inputfmt = fmts.byextension(inputext) ++ if inputfmt: ++ for fmt in outputfmt: ++ if inputfmt[0].doctype == fmt.doctype: ++ doctype = inputfmt[0].doctype ++ outputfmt = fmt ++ break ++ else: ++ outputfmt = outputfmt[0] ++ # print >>sys.stderr, 'unoconv: format `%s\' is part of multiple doctypes %s, selecting `%s\'.' % (format, [fmt.doctype for fmt in outputfmt], outputfmt[0].doctype) ++ else: ++ outputfmt = outputfmt[0] ++ ++ ### No format found, throw error ++ if not outputfmt: ++ if doctype: ++ print('unoconv: format [%s/%s] is not known to unoconv.' % (op.doctype, op.format), file=sys.stderr) ++ else: ++ print('unoconv: format [%s] is not known to unoconv.' % op.format, file=sys.stderr) ++ die(1) ++ ++ return outputfmt ++ ++ def convert(self, inputfn): ++ global exitcode ++ ++ document = None ++ outputfmt = self.getformat(inputfn) ++ ++ if op.verbose > 0: ++ print('Input file:', inputfn, file=sys.stderr) ++ ++ if not os.path.exists(inputfn): ++ print('unoconv: file `%s\' does not exist.' % inputfn, file=sys.stderr) ++ exitcode = 1 ++ ++ try: ++ ### Import phase ++ phase = "import" ++ ++ ### Load inputfile ++ inputprops = GlobalUnoProps(Hidden=True, ReadOnly=True, UpdateDocMode=UNO_QUIET_UPDATE) ++ ++# if op.password: ++# info = GlobalUnoProps(algorithm-name="PBKDF2", salt="salt", iteration-count=1024, hash="hash") ++# inputprops += GlobalUnoProps(ModifyPasswordInfo=info) ++ ++ ### Cannot use GlobalUnoProps for FilterData property ++ if op.importfilteroptions: ++# print "Import filter options: %s" % op.importfilteroptions ++ inputprops += GlobalUnoProps(FilterOptions=op.importfilteroptions) ++ ++ ### Cannot use GlobalUnoProps for FilterData property ++ if op.importfilter: ++ inputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.importfilter ), ), 0 ), ) ++ ++ inputurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(inputfn)) ++ document = self.desktop.loadComponentFromURL( inputurl , "_blank", 0, inputprops ) ++ ++ if not document: ++ raise UnoException("The document '%s' could not be opened." % inputurl, None) ++ ++ ### Import style template ++ phase = "import-style" ++ if op.template: ++ if os.path.exists(op.template): ++ info(1, "Template file: %s" % op.template) ++ templateprops = GlobalUnoProps(OverwriteStyles=True) ++ templateurl = global_unohelper.absolutize(self.cwd, global_unohelper.systemPathToFileUrl(op.template)) ++ document.StyleFamilies.loadStylesFromURL(templateurl, templateprops) ++ else: ++ print('unoconv: template file `%s\' does not exist.' % op.template, file=sys.stderr) ++ exitcode = 1 ++ ++ ### Update document links ++ phase = "update-links" ++ try: ++ document.updateLinks() ++ except AttributeError: ++ # the document doesn't implement the XLinkUpdate interface ++ pass ++ ++ ### Update document indexes ++ phase = "update-indexes" ++ try: ++ document.refresh() ++ indexes = document.getDocumentIndexes() ++ except AttributeError: ++ # the document doesn't implement the XRefreshable and/or ++ # XDocumentIndexesSupplier interfaces ++ pass ++ else: ++ for i in range(0, indexes.getCount()): ++ indexes.getByIndex(i).update() ++ ++ info(1, "Selected output format: %s" % outputfmt) ++ info(2, "Selected office filter: %s" % outputfmt.filter) ++ info(2, "Used doctype: %s" % outputfmt.doctype) ++ ++ ### Export phase ++ phase = "export" ++ ++ outputprops = GlobalUnoProps(FilterName=outputfmt.filter, OutputStream=GlobalOutputStream(), Overwrite=True) ++ ++ ### Set default filter options ++ if op.exportfilteroptions: ++# print "Export filter options: %s" % op.exportfilteroptions ++ outputprops += GlobalUnoProps(FilterOptions=op.exportfilteroptions) ++ else: ++ if outputfmt.filter == 'Text (encoded)': ++ outputprops += GlobalUnoProps(FilterOptions="76,LF") ++ ++ elif outputfmt.filter == 'Text': ++ outputprops += GlobalUnoProps(FilterOptions="76") ++ ++ elif outputfmt.filter == 'Text - txt - csv (StarCalc)': ++ outputprops += GlobalUnoProps(FilterOptions="44,34,76") ++ ++ ++ ### Cannot use GlobalUnoProps for FilterData property ++ if op.exportfilter: ++ outputprops += ( UnoPropertyValue( "FilterData", 0, global_uno.Any("[]com.sun.star.beans.PropertyValue", tuple( op.exportfilter ), ), 0 ), ) ++ ++ if not op.stdout: ++ (outputfn, ext) = os.path.splitext(inputfn) ++ if not op.output: ++ outputfn = outputfn + os.extsep + outputfmt.extension ++ elif os.path.isdir(op.output): ++ outputfn = realpath(op.output, os.path.basename(outputfn) + os.extsep + outputfmt.extension) ++ elif len(op.filenames) > 1: ++ outputfn = op.output + os.extsep + outputfmt.extension ++ else: ++ outputfn = op.output ++ ++ outputurl = global_unohelper.absolutize( self.cwd, global_unohelper.systemPathToFileUrl(outputfn) ) ++ info(1, "Output file: %s" % outputfn) ++ else: ++ outputurl = "private:stream" ++ ++ try: ++ document.storeToURL(outputurl, tuple(outputprops) ) ++ except UnoIOException as e: ++ raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None) ++ ++ phase = "dispose" ++ document.dispose() ++ document.close(True) ++ ++ except SystemError as e: ++ error("unoconv: SystemError during %s phase:\n%s" % (phase, e)) ++ exitcode = 1 ++ ++ except UnoRuntimeException as e: ++ error("unoconv: RuntimeException during %s phase:\nOffice probably died. %s" % (phase, e)) ++ exitcode = 6 ++ ++ except UnoDisposedException as e: ++ error("unoconv: DisposedException during %s phase:\nOffice probably died. %s" % (phase, e)) ++ exitcode = 7 ++ ++ except UnoIllegalArgumentException as e: ++ error("UNO IllegalArgument during %s phase:\nSource file cannot be read. %s" % (phase, e)) ++ exitcode = 8 ++ ++ except UnoIOException as e: ++# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) ++ error("unoconv: IOException during %s phase:\n%s" % (phase, e.Message)) ++ exitcode = 3 ++ ++ except UnoCannotConvertException as e: ++# for attr in dir(e): print '%s: %s', (attr, getattr(e, attr)) ++ error("unoconv: CannotConvertException during %s phase:\n%s" % (phase, e.Message)) ++ exitcode = 4 ++ ++ except UnoException as e: ++ if hasattr(e, 'ErrCode'): ++ error("unoconv: UnoException during %s phase in %s (ErrCode %d)" % (phase, repr(e.__class__), e.ErrCode)) ++ exitcode = e.ErrCode ++ pass ++ if hasattr(e, 'Message'): ++ error("unoconv: UnoException during %s phase:\n%s" % (phase, e.Message)) ++ exitcode = 5 ++ else: ++ error("unoconv: UnoException during %s phase in %s" % (phase, repr(e.__class__))) ++ exitcode = 2 ++ pass ++ ++class Listener: ++ def __init__(self): ++ global product ++ ++ info(1, "Start listener on %s:%s" % (op.server, op.port)) ++ self.context = global_uno.getComponentContext() ++ self.svcmgr = self.context.ServiceManager ++ try: ++ resolver = self.svcmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", self.context) ++ product = self.svcmgr.createInstance("com.sun.star.configuration.ConfigurationProvider").createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", GlobalUnoProps(nodepath="/org.openoffice.Setup/Product")) ++ try: ++ unocontext = resolver.resolve("uno:%s" % op.connection) ++ except UnoNoConnectException as e: ++ pass ++ else: ++ info(1, "Existing %s listener found, nothing to do." % product.ooName) ++ return ++ if product.ooName != "LibreOffice" or LooseVersion(product.ooSetupVersion) <= LooseVersion('3.3'): ++ subprocess.call([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nologo", "-nofirststartwizard", "-norestore", "-accept=%s" % op.connection], env=os.environ) ++ else: ++ subprocess.call([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nologo", "--nofirststartwizard", "--norestore", "--accept=%s" % op.connection], env=os.environ) ++ except Exception as e: ++ error("Launch of %s failed.\n%s" % (office.binary, e)) ++ else: ++ info(1, "Existing %s listener found, nothing to do." % product.ooName) ++ ++def error(msg): ++ "Output error message" ++ print(msg, file=sys.stderr) ++ ++def info(level, msg): ++ "Output info message" ++ if 'op' not in globals(): ++ pass ++ elif op.verbose >= 3 and level >= 3: ++ print("DEBUG:", msg, file=sys.stderr) ++ elif not op.stdout and level <= op.verbose: ++ print(msg, file=sys.stdout) ++ elif level <= op.verbose: ++ print(msg, file=sys.stderr) ++ ++def die(ret, msg=None): ++ "Print optional error and exit with errorcode" ++ global convertor, ooproc, office ++ ++ if msg: ++ error('Error: %s' % msg) ++ ++ ### Did we start our own listener instance ? ++ if not op.listener and ooproc and convertor: ++ ++ ### If there is a GUI now attached to the instance, disable listener ++ if convertor.desktop.getCurrentFrame(): ++ info(2, 'Trying to stop %s GUI listener.' % product.ooName) ++ try: ++ if product.ooName != "LibreOffice" or product.ooSetupVersion <= 3.3: ++ subprocess.Popen([office.binary, "-headless", "-invisible", "-nocrashreport", "-nodefault", "-nofirststartwizard", "-nologo", "-norestore", "-unaccept=%s" % op.connection], env=os.environ) ++ else: ++ subprocess.Popen([office.binary, "--headless", "--invisible", "--nocrashreport", "--nodefault", "--nofirststartwizard", "--nologo", "--norestore", "--unaccept=%s" % op.connection], env=os.environ) ++ ooproc.wait() ++ info(2, '%s listener successfully disabled.' % product.ooName) ++ except Exception as e: ++ error("Terminate using %s failed.\n%s" % (office.binary, e)) ++ ++ ### If there is no GUI attached to the instance, terminate instance ++ else: ++ info(3, 'Terminating %s instance.' % product.ooName) ++ try: ++ convertor.desktop.terminate() ++ except UnoDisposedException: ++ info(2, '%s instance unsuccessfully closed, sending TERM signal.' % product.ooName) ++ try: ++ ooproc.terminate() ++ except AttributeError: ++ os.kill(ooproc.pid, 15) ++ info(3, 'Waiting for %s instance to exit.' % product.ooName) ++ ooproc.wait() ++ ++ ### LibreOffice processes may get stuck and we have to kill them ++ ### Is it still running ? ++ if ooproc.poll() == None: ++ info(1, '%s instance still running, please investigate...' % product.ooName) ++ ooproc.wait() ++ info(2, '%s instance unsuccessfully terminated, sending KILL signal.' % product.ooName) ++ try: ++ ooproc.kill() ++ except AttributeError: ++ os.kill(ooproc.pid, 9) ++ info(3, 'Waiting for %s with pid %s to disappear.' % (ooproc.pid, product.ooName)) ++ ooproc.wait() ++ ++ # allow Python GC to garbage collect pyuno object *before* exit call ++ # which avoids random segmentation faults --vpa ++ convertor = None ++ ++ sys.exit(ret) ++ ++def main(): ++ global convertor, exitcode ++ convertor = None ++ ++ try: ++ if op.listener: ++ listener = Listener() ++ ++ if op.filenames: ++ convertor = Convertor() ++ for inputfn in op.filenames: ++ convertor.convert(inputfn) ++ ++ except UnoNoConnectException as e: ++ error("unoconv: could not find an existing connection to LibreOffice at %s:%s." % (op.server, op.port)) ++ if op.connection: ++ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"%s\"" % (op.server, op.server, op.port, op.connection)) ++ else: ++ info(0, "Please start an LibreOffice instance on server '%s' by doing:\n\n unoconv --listener --server %s --port %s\n\nor alternatively:\n\n soffice -nologo -nodefault -accept=\"socket,host=%s,port=%s;urp;\"" % (op.server, op.server, op.port, op.server, op.port)) ++ info(0, "Please start an soffice instance on server '%s' by doing:\n\n soffice -nologo -nodefault -accept=\"socket,host=127.0.0.1,port=%s;urp;\"" % (op.server, op.port)) ++ exitcode = 1 ++# except UnboundLocalError: ++# die(252, "Failed to connect to remote listener.") ++ except OSError: ++ error("Warning: failed to launch Office suite. Aborting.") ++ ++### Main entrance ++def run(): ++ global exitcode ++ exitcode = 0 ++ ++ info(3, 'sysname=%s, platform=%s, python=%s, python-version=%s' % (os.name, sys.platform, sys.executable, sys.version)) ++ ++ for of in find_offices(): ++ if of.python != sys.executable and not sys.executable.startswith(of.basepath): ++ python_switch(of) ++ office_environ(of) ++# debug_office() ++ try: ++ global global_uno ++ global global_unohelper ++ ++ import uno as global_uno ++ import unohelper as global_unohelper ++ global office ++ office = of ++ break ++ except: ++# debug_office() ++ print("unoconv: Cannot find a suitable pyuno library and python binary combination in %s" % of, file=sys.stderr) ++ print("ERROR:", sys.exc_info()[1], file=sys.stderr) ++ print(file=sys.stderr) ++ else: ++# debug_office() ++ print("unoconv: Cannot find a suitable office installation on your system.", file=sys.stderr) ++ print("ERROR: Please locate your office installation and send your feedback to:", file=sys.stderr) ++ print(" http://github.com/dagwieers/unoconv/issues", file=sys.stderr) ++ sys.exit(1) ++ ++ ### Now that we have found a working pyuno library, let's import some classes ++ global UnoPropertyValue ++ global UnoNoConnectException ++ global UNO_QUIET_UPDATE ++ global UnoDisposedException ++ global UnoIllegalArgumentException ++ global UnoIOException ++ global UnoXOutputStream ++ global UnoCannotConvertException ++ global UnoException ++ global UnoRuntimeException ++ ++ from com.sun.star.beans import PropertyValue as UnoPropertyValue ++ from com.sun.star.connection import NoConnectException as UnoNoConnectException ++ from com.sun.star.document.UpdateDocMode import QUIET_UPDATE as UNO_QUIET_UPDATE ++ from com.sun.star.lang import DisposedException as UnoDisposedException ++ from com.sun.star.lang import IllegalArgumentException as UnoIllegalArgumentException ++ from com.sun.star.io import IOException as UnoIOException ++ from com.sun.star.io import XOutputStream as UnoXOutputStream ++ from com.sun.star.script import CannotConvertException as UnoCannotConvertException ++ from com.sun.star.uno import Exception as UnoException ++ from com.sun.star.uno import RuntimeException as UnoRuntimeException ++ ++ ### And now that we have those classes, build on them ++ class OutputStream( global_unohelper.Base, UnoXOutputStream ): ++ def __init__( self ): ++ self.closed = 0 ++ ++ def closeOutput(self): ++ self.closed = 1 ++ ++ def writeBytes( self, seq ): ++ sys.stdout.write( seq.value ) ++ ++ def flush( self ): ++ pass ++ ++ global GlobalOutputStream ++ GlobalOutputStream = OutputStream ++ ++ def UnoProps(**args): ++ props = [] ++ for key in args: ++ prop = UnoPropertyValue() ++ prop.Name = key ++ prop.Value = args[key] ++ props.append(prop) ++ return tuple(props) ++ ++ global GlobalUnoProps ++ GlobalUnoProps = UnoProps ++ ++ global op ++ op = Options(sys.argv[1:]) ++ ++ info(2, "Using office base path: %s" % office.basepath) ++ info(2, "Using office binary path: %s" % office.unopath) ++ ++ try: ++ main() ++ except KeyboardInterrupt as e: ++ die(6, 'Exiting on user request') ++ die(exitcode) ++ ++if __name__ == '__main__': ++ run() +-- +1.7.11.7 + diff --git a/SOURCES/0001-update-FSF-address.patch b/SOURCES/0001-update-FSF-address.patch new file mode 100644 index 0000000..da5f208 --- /dev/null +++ b/SOURCES/0001-update-FSF-address.patch @@ -0,0 +1,175 @@ +From 4be0b90f1935120e4f9196b6fc126248079cbf11 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 5 Nov 2012 15:08:24 +0100 +Subject: [PATCH] update FSF address + +--- + COPYING | 41 ++++++++++++++++++++--------------------- + unoconv | 3 ++- + 2 files changed, 22 insertions(+), 22 deletions(-) + +diff --git a/COPYING b/COPYING +index d60c31a..d159169 100644 +--- a/COPYING ++++ b/COPYING +@@ -1,12 +1,12 @@ +- GNU GENERAL PUBLIC LICENSE +- Version 2, June 1991 ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 + +- Copyright (C) 1989, 1991 Free Software Foundation, Inc. +- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +- Preamble ++ Preamble + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public +@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This + General Public License applies to most of the Free Software + Foundation's software and to any other program whose authors commit to + using it. (Some other Free Software Foundation software is covered by +-the GNU Library General Public License instead.) You can apply it to ++the GNU Lesser General Public License instead.) You can apply it to + your programs, too. + + When we speak of free software, we are referring to freedom, not +@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and + modification follow. +- +- GNU GENERAL PUBLIC LICENSE ++ ++ GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) +- ++ + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in +@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. +- ++ + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program is +@@ -225,7 +225,7 @@ impose that choice. + + This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License. +- ++ + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License +@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals + of preserving the free status of all derivatives of our free software and + of promoting the sharing and reuse of software generally. + +- NO WARRANTY ++ NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + +- END OF TERMS AND CONDITIONS +- +- How to Apply These Terms to Your New Programs ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest + possible use to the public, the best way to achieve this is to make it +@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +- You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +- ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Also add information on how to contact you by electronic and paper mail. + + If the program is interactive, make it output a short notice like this + when it starts in an interactive mode: + +- Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. +@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names: + This General Public License does not permit incorporating your program into + proprietary programs. If your program is a subroutine library, you may + consider it more useful to permit linking proprietary applications with the +-library. If this is what you want to do, use the GNU Library General ++library. If this is what you want to do, use the GNU Lesser General + Public License instead of this License. +diff --git a/unoconv b/unoconv +index 30e6706..e4a1ac8 100755 +--- a/unoconv ++++ b/unoconv +@@ -11,7 +11,8 @@ + ### + ### You should have received a copy of the GNU General Public License + ### along with this program; if not, write to the Free Software +-### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++### Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++### MA 02110-1301 USA. + + import sys + +diff --git a/unoconv2.py b/unoconv2.py +index 30e6706..e4a1ac8 100755 +--- a/unoconv2.py ++++ b/unoconv2.py +@@ -11,7 +11,8 @@ + ### + ### You should have received a copy of the GNU General Public License + ### along with this program; if not, write to the Free Software +-### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++### Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++### MA 02110-1301 USA. + ### Copyright 2007-2010 Dag Wieers + + from distutils.version import LooseVersion +diff --git a/unoconv3.py b/unoconv3.py +index 30e6706..e4a1ac8 100755 +--- a/unoconv3.py ++++ b/unoconv3.py +@@ -11,7 +11,8 @@ + ### + ### You should have received a copy of the GNU General Public License + ### along with this program; if not, write to the Free Software +-### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++### Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++### MA 02110-1301 USA. + ### Copyright 2007-2010 Dag Wieers + + from distutils.version import LooseVersion +-- +1.7.11.7 + diff --git a/SPECS/unoconv.spec b/SPECS/unoconv.spec new file mode 100644 index 0000000..5f34c62 --- /dev/null +++ b/SPECS/unoconv.spec @@ -0,0 +1,115 @@ +Summary: Tool to convert between any document format supported by LibreOffice +Name: unoconv +Version: 0.6 +Release: 5%{?dist} +License: GPLv2 +Group: System Environment/Base +URL: http://dag.wieers.com/home-made/unoconv/ +Source: http://dag.wieers.com/home-made/%{name}/%{name}-%{version}.tar.gz +Patch0: 0001-Fix-a-broken-export-option-and-add-V-as-alternative-.patch +Patch1: 0001-python3-added-compatibility.patch +Patch2: 0001-update-FSF-address.patch + +BuildArch: noarch +Requires: libreoffice-core +Requires: libreoffice-pyuno + +%description +unoconv converts between any document format that LibreOffice understands. +It uses LibreOffice's UNO bindings for non-interactive conversion of +documents. + +Supported document formats include Open Document Format (.odf), MS Word (.doc), +MS Office Open/MS OOXML (.xml), Portable Document Format (.pdf), HTML, XHTML, +RTF, Docbook (.xml), and more. + +%prep +%setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 + +%build + +%install +make install DESTDIR="%{buildroot}" +pushd %{buildroot}/%{_bindir} +%if 0%{?fedora} >= 19 + mv %{name}3.py %{name} + rm %{name}2.py +%else + mv %{name}2.py %{name} + rm %{name}3.py +%endif +popd + + +%files +%doc AUTHORS ChangeLog COPYING README.asciidoc WISHLIST doc/*.txt tests/ +%{_mandir}/man1/%{name}.1* +%{_bindir}/%{name} + +%changelog +* Tue Jul 23 2013 David Tardon - 0.6-5 +- Resolves: rhbz#987046 drop env from shebang + +* Wed May 29 2013 David Tardon - 0.6-4 +- rhbz#957776 cannot open office documents + +* Mon Apr 08 2013 David Tardon - 0.6-3 +- Resolves: rhbz#947096 unoconv doesn't work with Libreoffice 4.0 + +* Fri Feb 15 2013 Fedora Release Engineering - 0.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Nov 05 2012 David Tardon - 0.6-1 +- new upstream release + +* Sun Jul 22 2012 Fedora Release Engineering - 0.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Mar 26 2012 David Tardon - 0.5-1 +- new upstream release + +* Mon Mar 26 2012 David Tardon - 0.4-6 + +* Sat Jan 14 2012 Fedora Release Engineering - 0.4-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Feb 07 2011 Fedora Release Engineering - 0.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Nov 30 2010 Orcan Ogetbil - 0.4-3 +- Add missing Requires on openoffice.org-brand/libreoffice-core. RHBZ#658576 + +* Sat Nov 13 2010 Orcan Ogetbil - 0.4-2 +- Backport some upstream fixes (LD_LIBRARY_PATH issue and -o flag issue) + +* Fri Nov 12 2010 Orcan Ogetbil - 0.4-1 +- Update to 0.4 + +* Sat Oct 30 2010 Caolán McNamara - 0.3-5 +- rebuild for LibreOffice + +* Sun Jul 26 2009 Fedora Release Engineering - 0.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu May 07 2009 Orcan Ogetbil - 0.3-3 +- Fix rpmlints +- Prepare package for Fedora review + +* Sun Feb 22 2009 Peter Hanecak 0.3-2 +- used %%{?dist} in release number +- license GPLv2 + +* Wed Dec 19 2007 Dag Wieers - 0.3-2 - 5993+/dag +- Fixed openoffice.org2 dependency on RHEL4. + +* Sat Sep 01 2007 Dag Wieers - 0.3-1 +- Updated to release 0.3. + +* Sun May 20 2007 Dag Wieers - 0.2-1 +- Updated to release 0.2. + +* Sat May 19 2007 Dag Wieers - 0.1-1 +- Initial package. (using DAR)