SctiptForge Python scripts and default pipe
Python scripts may run either
(1) inside the LO process, the usual mode
(2) as a client of a LO server
using a pipe or a socket.
The LO command is started with
an "--accept" argument.
The benefit of (2) is the freedom to
choose his/her preferred IDE to edit
and debug the script. The drawback is the
reference to the pipe/socket in the
script source code.
APSO is the best (only ?) choice for debugging (1).
With this commit, when no reference is given
to a pipe or a socket in the user script,
ScriptForge tries a connection through the
default pipe 'PIPE2LIBREOFFICE'.
If the connection fails, mode (1) is assumed.
The benefit is that the same source code
can run without change in both (1) and (2)
modes.
The command to run LO must refer explicitly
to the default pipe when (2) is wanted.
The change has no effect on existing Python
scripts.
Change-Id: I3176f4744ffea5b387280e9364b3563483fd14f0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205228
Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
Tested-by: Jenkins
This commit is contained in:
@@ -49,14 +49,23 @@
|
||||
from scriptforge import CreateScriptService
|
||||
|
||||
When Python and LibreOffice are started in separate processes,
|
||||
LibreOffice being started from console ... (example for Linux with port = 2024)
|
||||
./soffice --accept='socket,host=localhost,port=2024;urp;'
|
||||
then use next statements:
|
||||
LibreOffice being started from console ... (examples for Linux with port = 2026 or pipe = 'MYPIPE')
|
||||
Either:
|
||||
./soffice --accept='socket,host=localhost,port=2026;urp;'
|
||||
or:
|
||||
./soffice --accept='pipe,name=MYPIPE;urp;'
|
||||
then use next statements: either
|
||||
from scriptforge import CreateScriptService, ScriptForge
|
||||
ScriptForge(hostname = 'localhost', port = 2024)
|
||||
ScriptForge(hostname = 'localhost', port = 2026)
|
||||
or
|
||||
from scriptforge import CreateScriptService, ScriptForge
|
||||
ScriptForge(pipe = 'MYPIPE')
|
||||
|
||||
When the user uses an IDE like PyCharm or VSCode, (s)he might benefit from the typing
|
||||
hints provided by them thanks to the twin scriptforge.pyi module.
|
||||
To edit and debug a user script in a specialized Python IDE, and afterwards, when ready,
|
||||
run it in the usual interactive mode without code change, write:
|
||||
from scriptforge import CreateScriptService
|
||||
and start LibreOffice with a dedicated pipe:
|
||||
./soffice --accept='pipe,name=PIPE2LIBREOFFICE;urp;'
|
||||
|
||||
Specific documentation about the use of ScriptForge from Python scripts:
|
||||
https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_intro.html?DbPAR=BASIC
|
||||
@@ -96,9 +105,10 @@ class ScriptForge(object, metaclass = _Singleton):
|
||||
- Dispatching of services
|
||||
- Coexistence with UNO
|
||||
|
||||
The class may be instantiated several times. Only the first instance will be retained ("Singleton").
|
||||
The class has the singleton pattern. It creates an instance only if it does not exist.
|
||||
Otherwise, it returns the already created instance.
|
||||
|
||||
All its properties and methods are for INTERNAL / DEBUGGING use only.
|
||||
All the properties and methods of the actual class are for INTERNAL / DEBUGGING use only.
|
||||
"""
|
||||
|
||||
# #########################################################################
|
||||
@@ -148,6 +158,8 @@ class ScriptForge(object, metaclass = _Singleton):
|
||||
('ScriptForge.SharedMemory', 7),
|
||||
('ScriptForge.String', 8),
|
||||
('ScriptForge.UI', 9)])
|
||||
# The default pipe name to connect to when debugging user scripts from external IDE's
|
||||
defaultpipe = 'PIPE2LIBREOFFICE'
|
||||
|
||||
def __init__(self, hostname = '', port = 0, pipe = ''):
|
||||
"""
|
||||
@@ -189,11 +201,12 @@ class ScriptForge(object, metaclass = _Singleton):
|
||||
:param pipe: pipe name or ''
|
||||
:return: the derived component context
|
||||
"""
|
||||
ctx = uno.getComponentContext() # com.sun.star.uno.XComponentContext
|
||||
resolver = ctx.ServiceManager.createInstanceWithContext(
|
||||
'com.sun.star.bridge.UnoUrlResolver', ctx) # com.sun.star.comp.bridge.UnoUrlResolver
|
||||
|
||||
if (len(hostname) > 0 and port > 0 and len(pipe) == 0) \
|
||||
or (len(hostname) == 0 and port == 0 and len(pipe) > 0): # Explicit connection via socket or pipe
|
||||
ctx = uno.getComponentContext() # com.sun.star.uno.XComponentContext
|
||||
resolver = ctx.ServiceManager.createInstanceWithContext(
|
||||
'com.sun.star.bridge.UnoUrlResolver', ctx) # com.sun.star.comp.bridge.UnoUrlResolver
|
||||
try:
|
||||
if len(pipe) == 0:
|
||||
conn = 'socket,host=%s,port=%d' % (hostname, port)
|
||||
@@ -206,7 +219,15 @@ class ScriptForge(object, metaclass = _Singleton):
|
||||
"Connection to LibreOffice failed (%s)" % conn)
|
||||
return ctx
|
||||
elif len(hostname) == 0 and port == 0 and len(pipe) == 0: # Usual interactive mode
|
||||
return uno.getComponentContext()
|
||||
# Try a connection through the default pipe first
|
||||
try:
|
||||
conn = 'pipe,name=%s' % ScriptForge.defaultpipe
|
||||
url = 'uno:%s;urp;StarOffice.ComponentContext' % conn
|
||||
ctx = resolver.resolve(url)
|
||||
except Exception: # thrown when LibreOffice specified instance isn't started
|
||||
print("Connection to LibreOffice failed (%s). Assuming interactive mode." % conn)
|
||||
finally: # Ignore exception
|
||||
return ctx
|
||||
else:
|
||||
raise SystemExit('The creation of the ScriptForge() instance got invalid arguments: '
|
||||
+ "(host = '" + hostname + "', port = " + str(port) + ", pipe = '" + pipe + "')")
|
||||
|
||||
@@ -236,7 +236,14 @@ class ScriptForge(object, metaclass = ...):
|
||||
- Dispatching of services
|
||||
- Coexistence with UNO
|
||||
|
||||
The class may be instantiated several times. Only the first instance will be retained ("Singleton").
|
||||
The class has the singleton pattern. It creates an instance only if it does not exist.
|
||||
Otherwise, it returns the already created instance.
|
||||
|
||||
The instance may be created explicitly in a user script. This must be done before any
|
||||
invocation of CreateScriptService().
|
||||
If not done yet, the CreateScriptService() will create it with the default arguments.
|
||||
However, a connection with the default pipe will be tried in the first place. If successful,
|
||||
the default pipe will be used. If failed, the usual interactive mode is selected.
|
||||
"""
|
||||
|
||||
def __init__(self, hostname: str = ..., port: int = ..., pipe: str = ...):
|
||||
@@ -248,10 +255,12 @@ class ScriptForge(object, metaclass = ...):
|
||||
- Dispatching of services
|
||||
- Coexistence with UNO
|
||||
|
||||
The class may be instantiated several times. Only the first instance will be retained ("Singleton").
|
||||
he class has the singleton pattern. It creates an instance only if it does not exist.
|
||||
Otherwise, it returns the already created instance.
|
||||
|
||||
Both arguments are mandatory when Python and LibreOffice run in separate processes.
|
||||
Otherwise, do not call this routine or leave both arguments out.
|
||||
Either the first two arguments are mandatory when Python and LibreOffice run in separate processes,
|
||||
or the the third one is required.
|
||||
Otherwise, do not call this routine or leave all arguments out.
|
||||
To execute at most once by LibreOffice session.
|
||||
Args
|
||||
``hostname``: probably 'localhost'
|
||||
|
||||
Reference in New Issue
Block a user