Starting, Stopping, and Connecting to OpenOffice with Python

Using pyuno you
can script OpenOffice with Python.
Pyuno allows you to create macros inside OpenOffice and it also allows you to create
external Python scripts that talk to a running copy of OpenOffice.
If you want to get started with pyuno be prepared for an often
frustrating experience: the documentation is sketchy
and often just plain hard to locate, and
the version of Python that's embedded in OpenOffice has been
stuck at version 2.3 for quite a while now.

Pyuno is the Python layer that implements OpenOffice's UNO interface.
UNO is an application programming language independent interface to OpenOffice.
UNO is specified in IDL and often the only documentation for pyuno is the
IDL documentation for UNO.

The code presented here runs outside of OpenOffice and shows
how to start, stop, and connect to OpenOffice in "headless" mode.
Running OpenOffice in "headless" mode means that OpenOffice
doesn't display a window it just waits for UNO operations (via a TCP/IP port).
The code presented here was tested with version 2.5 of Python
and version 2.4 of OpenOffice.
I also tested it with version 3.0 of OpenOffice but it only
runs if you use the version of Python that comes with OpenOffice.

The code consists mainly of the Python class OORunner which
has methods for connecting to OpenOffice, for starting it, and
for shutting it down.
The code also keeps track of all the copies of OpenOffice that it's
started and shuts them all down on exit.
This code is based on some code that I found
here,
I refactored the connecting and added the ability to start
and and stop OpenOffice from Python.
The file name is ooutils.py.

# 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#importsysimportosimporttimeimportatexitOPENOFFICE_PORT=8100# Find OpenOffice._oopaths=(('/usr/lib64/ooo-2.0/program','/usr/lib64/ooo-2.0/program'),('/opt/openoffice.org3/program','/opt/openoffice.org/basis3.0/program'),)forpin_oopaths:ifos.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.ifsys.path.count(OPENOFFICE_LIBPATH)==0:sys.path.insert(0,OPENOFFICE_LIBPATH)breakimportunofromcom.sun.star.beansimportPropertyValuefromcom.sun.star.connectionimportNoConnectExceptionclassOORunner:""" Start, stop, and connect to OpenOffice. """def__init__(self,port=OPENOFFICE_PORT):""" Create OORunner that connects on the specified port. """self.port=portdefconnect(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=Nonedid_start=Falsen=0whilen<6:try:context=resolver.resolve("uno:socket,host=localhost,port=%d;urp;StarOffice.ComponentContext"%self.port)breakexceptNoConnectException:pass# If first connect failed then try starting OpenOffice.ifn==0:# Exit loop if startup not desired.ifno_startup:breakself.startup()did_start=True# Pause and try again to connecttime.sleep(1)n+=1ifnotcontext:raiseException,"Failed to connect to OpenOffice on port %d"%self.portdesktop=context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop",context)ifnotdesktop:raiseException,"Failed to create OpenOffice desktop on port %d"%self.portifdid_start:_started_desktops[self.port]=desktopreturndesktopdefstartup(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)exceptException,e:raiseException,"Failed to start OpenOffice on port %d: %s"%(self.port,e.message)ifpid<=0:raiseException,"Failed to start OpenOffice on port %d"%self.portdefshutdown(self):""" Shutdown OpenOffice. """try:if_started_desktops.get(self.port):_started_desktops[self.port].terminate()del_started_desktops[self.port]exceptException,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. """forport,desktopin_started_desktops.items():try:ifdesktop:desktop.terminate()exceptException,e:passatexit.register(_shutdown_desktops)defoo_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()exceptException,e:passdefoo_properties(**args):""" Convert args to OpenOffice property values. """props=[]forkeyinargs:prop=PropertyValue()prop.Name=keyprop.Value=args[key]props.append(prop)returntuple(props)

Using the class is straightforward: you simply create an instance
of it and call connect() on that instance.
Connect returns the OpenOffice desktop object.
This is the object that you use for most interactions with OpenOffice.

As I mentioned there are also startup and shutdown methods,
but you don't really need to call them: the connect method
will call the startup method if it's unable to connect
and the atexit code will shutdown all started copies of OpenOffice on exit.
There's also a function oo_shutdown_if_running() that
can be called to shutdown a desktop if it's running.

Next week I'll show you how to use the code presented here to
write a Python program to convert spreadsheets to CSV files.

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.