Last active
April 27, 2023 14:39
-
-
Save JannieT/6fee66dc821fd0fe6af68063920149f0 to your computer and use it in GitHub Desktop.
Environment for scripting LibreOffice with Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import uno | |
import sys | |
def createUnoService(id): | |
ctx = getContext() | |
return ctx.ServiceManager.createInstanceWithContext(id, ctx) | |
def getContext(): | |
# get the uno component context from the PyUNO runtime | |
localContext = uno.getComponentContext() | |
# create the UnoUrlResolver | |
resolver = localContext.ServiceManager.createInstanceWithContext( | |
"com.sun.star.bridge.UnoUrlResolver", localContext ) | |
# connect to the running office | |
return resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" ) | |
def getDesktop(): | |
ctx = getContext() | |
# get the central desktop object | |
return ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx) | |
def getFrame(): | |
desktop = getDesktop() | |
return desktop.getCurrentFrame(); | |
def getModel(): | |
desktop = getDesktop() | |
# access the current writer document | |
return desktop.getCurrentComponent() | |
def lastException2String(): | |
(excType,excInstance,excTraceback) = sys.exc_info() | |
ret = str(excType) + ": "+str(excInstance) + "\n" + \ | |
uno._uno_extract_printable_stacktrace( excTraceback ) | |
return ret | |
def printInterfaces(obj): | |
""" | |
Thanks to Jamie Boyle https://documenthacker.wordpress.com | |
""" | |
text = str(obj) | |
interfacesBlock = [z for z in text.split(' ') if z.startswith('supportedInterfaces=')][0] | |
interfaceNames = [] | |
for longName in interfacesBlock[interfacesBlock.find('{')+1:interfacesBlock.find('}')].split(','): | |
interfaceName = longName[longName .rfind('.')+1:] | |
if interfaceName[0]=='X': | |
interfaceName = interfaceName[1:] | |
interfaceNames.append(interfaceName) | |
interfaceNames.sort() #Sort all the names alphabetically | |
for interfaceName in interfaceNames: | |
if interfaceName[0]=='X': | |
print(interfaceName[1:]) | |
else: | |
print(interfaceName) | |
def printObjectProperties(obj): | |
#Get the properties | |
properties = list(obj.getPropertySetInfo().getProperties()) | |
#Sort alphabetically by name | |
properties.sort(key = lambda x:x.Name) | |
longest_len = max([len(z.Name) for z in properties]) | |
for property in properties: | |
print(property.Name.ljust(longest_len)+' -'+str(property.Type)) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from zipfile import ZipFile | |
import shutil | |
import sys | |
import os | |
if len(sys.argv) < 3: | |
print("Usage: {} scriptfile hostdocument".format(sys.argv[0])) | |
exit() | |
MACRO_FILE = sys.argv[1] | |
DOCUMENT_FILE = sys.argv[2] | |
MANIFEST_PATH = 'META-INF/manifest.xml'; | |
EMBED_PATH = 'Scripts/python/' + MACRO_FILE; | |
hasMeta = False | |
with ZipFile(DOCUMENT_FILE) as bundle: | |
# grab the manifest | |
manifest = [] | |
for rawLine in bundle.open('META-INF/manifest.xml'): | |
line = rawLine.decode('utf-8'); | |
if MACRO_FILE in line: | |
hasMeta = True | |
if ('</manifest:manifest>' in line) and (hasMeta == False): | |
for path in ['Scripts/','Scripts/python/', EMBED_PATH]: | |
manifest.append('<manifest:file-entry manifest:media-type="application/binary" manifest:full-path="{}"/>'.format(path)) | |
manifest.append(line) | |
# remove the manifest and script file | |
with ZipFile(DOCUMENT_FILE + '.tmp', 'w') as tmp: | |
for item in bundle.infolist(): | |
buffer = bundle.read(item.filename) | |
if (item.filename not in [MANIFEST_PATH, EMBED_PATH]): | |
tmp.writestr(item, buffer) | |
# os.replace(DOCUMENT_FILE + '.tmp', DOCUMENT_FILE); python 3.3+ | |
os.remove(DOCUMENT_FILE); | |
shutil.move(DOCUMENT_FILE + '.tmp', DOCUMENT_FILE) | |
with ZipFile(DOCUMENT_FILE, 'a') as bundle: | |
bundle.write(MACRO_FILE, EMBED_PATH) | |
bundle.writestr(MANIFEST_PATH, ''.join(manifest)) | |
print("Added the script {} to {}".format(MACRO_FILE, DOCUMENT_FILE)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
PROJECT_FOLDER="/Users/jannie/Workshop/speng" | |
SAMPLE_FOLDER="/Applications/LibreOffice.app/Contents/Resources/Scripts/python" | |
TEMPLATE_FOLDER="~/Library/Application\ Support/LibreOffice/4/user/template" | |
SCRIPT="scriptlight.py" | |
HOSTING_DOCUMENT="se.ott" | |
usage () { | |
echo "Usage: speng (start|run <function>|deploy|open)" | |
} | |
case "$1" in | |
start) | |
/Applications/LibreOffice.app/Contents/MacOS/soffice --writer --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" | |
;; | |
run) | |
/Applications/LibreOffice.app/Contents/MacOS/python -c "import scriptlight; scriptlight.$2()" | |
;; | |
deploy) | |
cd $PROJECT_FOLDER | |
python push_macro.py $SCRIPT $HOSTING_DOCUMENT | |
;; | |
open) | |
edit . $SAMPLE_FOLDER | |
;; | |
*) | |
# test if script is sourced | |
if [[ $0 = ${BASH_SOURCE} ]] ; then | |
usage | |
else | |
cd $PROJECT_FOLDER | |
fi | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment