Environment for scripting LibreOffice with Python
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)) | |
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)) |
#!/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