| 
									
										
										
										
											2015-12-21 23:57:18 -08:00
										 |  |  | #!/usr/bin/python3 | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  | # 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) | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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) | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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)) | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if pid <= 0: | 
					
						
							| 
									
										
										
										
											2015-12-21 23:57:18 -08:00
										 |  |  |             raise Exception("Failed to start OpenOffice on port %d" % self.port) | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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: | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  |             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: | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  |             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: | 
					
						
							| 
									
										
										
										
											2013-01-03 18:57:19 -06:00
										 |  |  |         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) |