Ask Your Question
0

How do I run python macro from the command line? [closed]

asked 2014-08-26 02:41:20 +0100

sup gravatar image

This concerns Basic macros. How can I launch python macros from the command line? Libreoffice launches, does not run the macro and does not throw any errors, which is mostly unhelpful.

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by Alex Kemp
close date 2016-03-02 23:50:02.292266

2 Answers

Sort by » oldest newest most voted
0

answered 2014-08-26 12:17:55 +0100

sup gravatar image

updated 2014-08-26 14:27:45 +0100

It seems hackish, but based on this , the following works:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""In Libreoffice 4, python3 is default, so this script needs to be python3 too
Unicode is just good practise
I guess this line is different on Windows."""

import uno
from pythonscript import ScriptContext
import sys

def connect_to_office():
     """We connect to libreoffice only when run externally.
     If that is the case, XSCRIPTCONTEXT is not in global scope."""
    if not 'XSCRIPTCONTEXT' in globals():
        localContext = uno.getComponentContext()
        resolver = localContext.ServiceManager.createInstanceWithContext(
                         'com.sun.star.bridge.UnoUrlResolver', localContext )
        """It is assumed libreoffice is run like this from a shell:
        libreoffice "--accept=pipe,name=some_name;urp;StarOffice.Servicemanager ~/test.ods"
        """
        client = resolver.resolve("uno:pipe,"
                        "name=some_name;" 
                        "urp;"
                        "StarOffice.ComponentContext")
        global XSCRIPTCONTEXT
        XSCRIPTCONTEXT = ScriptContext(client, None, None)

"""this is the macro that would be run firectly from libreoffice"""
def run_all():
    connect_to_office()
    oDoc = XSCRIPTCONTEXT.getDocument()
    """I assume a calc file here, this prints Hello world to cell A1"""
    oSheet = oDoc.CurrentController.ActiveSheet
    oCell = oSheet.getCellRangeByName("A1")
    oCell.String = 'Hello world!'

    """Libreoffice allows to run functions as macros, but in a script
executed from a shell, any function needs to be run, but we must
make sure it is not run twice in case it is run directly
from libreoffice."""
if __name__ == "__main__":
    run_all()
"""Make only this macro visible to libreoffice UI.
I.e., it hides connecto_to_office macro.
The comma at the end is important."""
g_exportedScripts = run_all,

This scipt can be run both directly from inside Libreoffice and from the command line (in that case, libreoffice needs to be already running). Something like this works for me:

#!/bin/bash
libreoffice "--accept=pipe,name=some_name;urp;StarOffice.Servicemanager" ~/Desktop/test.ods &
sleep 3 # we need to wait till libreoffice starts, 3 seconds is more than enough for my computer but it YMMV
~/.config/libreoffice/4/user/Scripts/python/your_macro.py

Do not forget to make this file executable.

edit flag offensive delete link more
1

answered 2014-08-26 03:13:56 +0100

karolus gravatar image

updated 2014-08-26 13:22:33 +0100

The answer is rather simple, make them executable and execute them, if it works depends only on their content -- you do not need to involve soffice -blah -spam whatever in any way

Karolus

edit:

the common pattern in python-Scripts to distinguish between "run the Script as itself" and "import only some functionality" is at last in the Scriptfile:
...

other stuff

if __name__ == "__main__":
     this()
     that()

in this Case if the script is executed directly it runs only the stuff on module-level and at last the functions this() and that()

And - sorry - but i have to announce:
If you become familiar with ipython notebook you'll dont need all that boilerplate in every script!!

Edit 2:

Another pattern designed in pythonscript.py for Libreoffice is:

g_exportedScripts = this, that

this pattern make exclusive only the Functions this and that visible and executable over Libre-GUI

edit flag offensive delete link more

Comments

Alright, I figured it out, but this seems to be insanely complex (see my answer bellow)!

sup gravatar imagesup ( 2014-08-26 12:18:48 +0100 )edit

Ah, good, thanksI updated the answer. How would ipython notebooks help? By reusing some of the code? I could do that with pythons files as well, if I needed to, or not? anyway, I am writing only this macro and the code must reside somewhere anyway. Or what am I missing?

sup gravatar imagesup ( 2014-08-26 13:49:17 +0100 )edit
1

You'll need run the boilerplate only once in the notebook, and after develop some useful parts you put this into Function or Classes ..whatever into one "Cell" and put at the Topline of that "Cell" :

%%writefile  path/to/your/LO/Scripts/python/yourfilname.py
the Rest ....

(ctrl+enter) writes the Cellcontent without 1.Line to the given Path

karolus gravatar imagekarolus ( 2014-08-26 14:04:49 +0100 )edit

Question Tools

1 follower

Stats

Asked: 2014-08-26 02:41:20 +0100

Seen: 2,050 times

Last updated: Aug 26 '14