small-hacks/ooutils.py

174 lines
4.8 KiB
Python
Raw Normal View History

2015-12-21 23:57:18 -08:00
#!/usr/bin/python3
# ooutils.py
# from http://www.linuxjournal.com/node/1007788
# OpenOffice utils.
#
# Based on code from:
# PyODConverter (Python OpenDocument Converter) v1.0.0 - 2008-05-05
# Copyright (C) 2008 Mirko Nasato <mirko@artofsolving.com>
# Licensed under the GNU LGPL v2.1 - or any later version.
# http://www.gnu.org/licenses/lgpl-2.1.html
#
import sys
import os
import time
import atexit
OPENOFFICE_PORT = 8100
# Find OpenOffice.
_oopaths=(
('/usr/lib/libreoffice/program', '/usr/lib/libreoffice/program'),
('/usr/lib64/ooo-2.0/program', '/usr/lib64/ooo-2.0/program'),
('/opt/openoffice.org3/program', '/opt/openoffice.org/basis3.0/program'),
)
for p in _oopaths:
if os.path.exists(p[0]):
OPENOFFICE_PATH = p[0]
OPENOFFICE_BIN = os.path.join(OPENOFFICE_PATH, 'soffice')
OPENOFFICE_LIBPATH = p[1]
# Add to path so we can find uno.
if sys.path.count(OPENOFFICE_LIBPATH) == 0:
sys.path.insert(0, OPENOFFICE_LIBPATH)
break
import uno
from com.sun.star.beans import PropertyValue
from com.sun.star.connection import NoConnectException
class OORunner:
"""
Start, stop, and connect to OpenOffice.
"""
def __init__(self, port=OPENOFFICE_PORT):
""" Create OORunner that connects on the specified port. """
self.port = port
def connect(self, no_startup=False):
"""
Connect to OpenOffice.
If a connection cannot be established try to start OpenOffice.
"""
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
context = None
did_start = False
n = 0
while n < 6:
try:
context = resolver.resolve("uno:socket,host=localhost,port=%d;urp;StarOffice.ComponentContext" % self.port)
break
except NoConnectException:
pass
# If first connect failed then try starting OpenOffice.
if n == 0:
# Exit loop if startup not desired.
if no_startup:
break
self.startup()
did_start = True
# Pause and try again to connect
time.sleep(1)
n += 1
if not context:
2015-12-21 23:57:18 -08:00
raise Exception("Failed to connect to OpenOffice on port %d" % self.port)
desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
if not desktop:
2015-12-21 23:57:18 -08:00
raise Exception("Failed to create OpenOffice desktop on port %d" % self.port)
if did_start:
_started_desktops[self.port] = desktop
return desktop
def startup(self):
"""
Start a headless instance of OpenOffice.
"""
args = [OPENOFFICE_BIN,
'-accept=socket,host=localhost,port=%d;urp;StarOffice.ServiceManager' % self.port,
'-norestore',
'-nofirststartwizard',
'-nologo',
'-headless',
]
env = {'PATH' : '/bin:/usr/bin:%s' % OPENOFFICE_PATH,
'PYTHONPATH' : OPENOFFICE_LIBPATH,
}
try:
pid = os.spawnve(os.P_NOWAIT, args[0], args, env)
2015-12-21 23:57:18 -08:00
except Exception as e:
raise Exception("Failed to start OpenOffice on port %d: %s" % (self.port, e.message))
if pid <= 0:
2015-12-21 23:57:18 -08:00
raise Exception("Failed to start OpenOffice on port %d" % self.port)
def shutdown(self):
"""
Shutdown OpenOffice.
"""
try:
if _started_desktops.get(self.port):
_started_desktops[self.port].terminate()
del _started_desktops[self.port]
2015-12-21 23:57:18 -08:00
except Exception as e:
pass
# Keep track of started desktops and shut them down on exit.
_started_desktops = {}
def _shutdown_desktops():
""" Shutdown all OpenOffice desktops that were started by the program. """
for port, desktop in _started_desktops.items():
try:
if desktop:
desktop.terminate()
2015-12-21 23:57:18 -08:00
except Exception as e:
pass
atexit.register(_shutdown_desktops)
def oo_shutdown_if_running(port=OPENOFFICE_PORT):
""" Shutdown OpenOffice if it's running on the specified port. """
oorunner = OORunner(port)
try:
desktop = oorunner.connect(no_startup=True)
desktop.terminate()
2015-12-21 23:57:18 -08:00
except Exception as e:
pass
def oo_properties(**args):
"""
Convert args to OpenOffice property values.
"""
props = []
for key in args:
prop = PropertyValue()
prop.Name = key
prop.Value = args[key]
props.append(prop)
return tuple(props)