173 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/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:
 | |
|             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:
 | |
|             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)
 | |
|         except Exception as e:
 | |
|             raise Exception("Failed to start OpenOffice on port %d: %s" % (self.port, e.message))
 | |
| 
 | |
|         if pid <= 0:
 | |
|             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]
 | |
|         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()
 | |
|         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()
 | |
|     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)
 | 
