1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
18 print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables")
19 print("PYTHONPATH=/installation/opt/program")
20 print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc")
24 class OfficeConnection
:
25 def __init__(self
, args
):
31 """ Create a new connection to a LibreOffice process
33 If the connection method is path the instance will be created as a
34 new subprocess. If the connection method is connect the instance tries
35 to connect to an existing instance with the specified socket string """
36 (method
, sep
, rest
) = self
.args
["--soffice"].partition(":")
38 raise Exception("soffice parameter does not specify method")
40 socket
= "pipe,name=pytest" + str(uuid
.uuid1())
42 userdir
= self
.args
["--userdir"]
44 raise Exception("'path' method requires --userdir")
45 if not(userdir
.startswith("file://")):
46 raise Exception("--userdir must be file URL")
47 self
.soffice
= self
.bootstrap(rest
, userdir
, socket
)
48 elif method
== "connect":
51 raise Exception("unsupported connection method: " + method
)
53 # connect to the soffice instance
56 self
.xContext
= self
.connect(socket
)
59 if not success
and self
.soffice
:
60 self
.soffice
.terminate()
64 def bootstrap(self
, soffice
, userdir
, socket
):
65 """ Creates a new LibreOffice process
67 @param soffice Path to the soffice installation
68 @param userdir Directory of the user profile, only one process per user
70 @param socket The socket string used for the PyUNO connection """
72 argv
= [soffice
, "--accept=" + socket
+ ";urp",
73 "-env:UserInstallation=" + userdir
,
74 "--quickstart=no", "--nofirststartwizard",
75 "--norestore", "--nologo"]
76 if "--valgrind" in self
.args
:
77 argv
.append("--valgrind")
79 if "--gdb" in self
.args
:
83 argv
.insert(3, "--args")
84 argv
[4] = argv
[4].replace("soffice", "soffice.bin")
87 environ
= dict(os
.environ
)
88 if 'LIBO_LANG' in environ
:
90 env
['LC_ALL'] = environ
['LIBO_LANG']
92 return subprocess
.Popen(argv
, env
=env
)
94 def connect(self
, socket
):
95 """ Tries to connect to the LibreOffice instance through the specified socket"""
96 xLocalContext
= uno
.getComponentContext()
97 xUnoResolver
= xLocalContext
.ServiceManager
.createInstanceWithContext(
98 "com.sun.star.bridge.UnoUrlResolver", xLocalContext
)
99 url
= "uno:" + socket
+ ";urp;StarOffice.ComponentContext"
100 print("OfficeConnection: connecting to: " + url
)
102 if self
.soffice
and self
.soffice
.poll() is not None:
103 raise Exception("soffice has stopped.")
106 xContext
= xUnoResolver
.resolve(url
)
108 except pyuno
.getClass("com.sun.star.connection.NoConnectException"):
109 print("NoConnectException: sleeping...")
113 """Terminate a LibreOffice instance created with the path connection method.
115 Tries to terminate the soffice instance through the normal
116 XDesktop::terminate method and waits indefinitely for the subprocess
122 print("tearDown: calling terminate()...")
123 xMgr
= self
.xContext
.ServiceManager
124 xDesktop
= xMgr
.createInstanceWithContext(
125 "com.sun.star.frame.Desktop", self
.xContext
)
128 except pyuno
.getClass("com.sun.star.beans.UnknownPropertyException"):
129 print("caught while TearDown:\n", traceback
.format_exc())
130 pass # ignore, also means disposed
131 except pyuno
.getClass("com.sun.star.lang.DisposedException"):
132 print("caught while TearDown:\n", traceback
.format_exc())
135 self
.soffice
.terminate()
137 ret
= self
.soffice
.wait()
141 raise Exception("Exit status indicates failure: " + str(ret
))
144 def getHelpText(cls
):
146 --soffice=method:location
147 specify soffice instance to connect to
148 supported methods: 'path', 'connect'
149 --userdir=URL specify user installation directory for 'path' method
150 --valgrind pass --valgrind to soffice for 'path' method
152 'location' is a pathname, not a URL. 'userdir' is a URL.
157 class PersistentConnection
:
158 def __init__(self
, args
):
160 self
.connection
= None
162 def getContext(self
):
163 """ Returns the XContext corresponding to the LibreOffice instance
165 This is the starting point for any PyUNO access to the LibreOffice
167 return self
.connection
.xContext
170 # don't create two connections
174 conn
= OfficeConnection(self
.args
)
176 self
.connection
= conn
181 self
.connection
.tearDown()
183 self
.connection
= None
186 """ Kills the LibreOffice instance if it was created through the connection
188 Only works with the connection method path"""
189 if self
.connection
and self
.connection
.soffice
:
190 self
.connection
.soffice
.kill()
192 # vim: set shiftwidth=4 softtabstop=4 expandtab: