[Solved] External python script to monitor OnSave event

Creating a macro - Writing a Script - Using the API

[Solved] External python script to monitor OnSave event

Postby GaryDyr » Sat Apr 05, 2014 4:56 pm

I am trying to run OpenOffice calc from an external python script. A user can start the script, which opens up a single specific spreadsheet. The user then manually updates the sheet, saves the document, and exits calc. The python script then would resume to further process the spreadsheet data. My problem is how to add listeners using the python script to trap the OpenOffice OnSave and/or OnUnLoad events, so the python script can either quit or process the modified file. I can use the python subprocess function to open OpenOffice. along with an embedded macro to add a time stamp coupled to the OnSave event, but I was hoping to avoid that path for simplicity. However, all attempts to figure out how to recognize the OnSave event from a python scipt have failed. I have searched extensively for examples, and found several questions related to this problem, but no answers, especially with current versions of python and OpenOffice. I have tried a lot of variations, but all fail. Essentially, I am unable to figure out how to use or translate the CreateUnoListener function to an external python script. I would appreciate it if someone could provide a working example of how to trap such events, especially using python from an external script. The following script is one version I have tried, but fails as indicated.

I am using OpenOffice 4.01 and python 3.4 running on Windows 8.1.
Code: Select all   Expand viewCollapse view
import os
import win32com.client

drives = ['%s:' % d for d in dl if os.path.exists('%s:' % d)]
for d in drives:
   if os.path.isdir(d+'\\Scheduler'):
      DriveOption = d
default_drivepath =DriveOption+"\\Scheduler\\"
norm_drivepath = DriveOption+'/Scheduler/'
outfile = 'o_f_ScheduledEvents.csv'
OF_file = 'schedule.ods'

URLout = 'file:///'+norm_drivepath+outfile
sURL = 'file:///'+norm_drivepath+OF_file
sPath = default_drivepath+OF_file

manager = win32com.client.Dispatch("com.sun.star.ServiceManager")
desktop = manager.createInstance("com.sun.star.frame.Desktop")
manager._FlagAsMethod("Bridge_GetStruct") #used later to set propertyValues
args = []

doc1 = desktop.loadComponentFromURL(sURL,"Scheduler",0,args)
sheets1 = doc1.getSheets()
ws = sheets1.getByName('Schedule')
we = sheets1.getByName('EventStream')

#next two lines do not work as they do in a macro
#oListener = CreateUnoListener( "docListener_","com.sun.star.document.XDocumentEventListener" )
#above line produces error: not defined

# The below does not work either
docListener = manager.createInstance("com.sun.star.document.XDocumentEventListener")
#above line fails with this error:
#Traceback (most recent call last):...
#  File "<COMObject <unknown>>", line 2, in addDocumentEventListener
#pywintypes.com_error: (-2147352567, 'Exception occurred.', (1001, '[automation bridge] ', 'InterfaceOleWrapper_Impl::Invoke : \n[automation #bridge]UnoConversionUtilities<T>::createOleObjectWrapper \nThe VARIANT does not contain an object type! ', None, 0, 0), None)

#same type error as above with this variation

while docListener_documentEventOccured(o):
    if obe[0] == "OnSave":
        print('Doc registered save')

Last edited by GaryDyr on Fri Apr 11, 2014 6:28 pm, edited 1 time in total.
OpenOffice 4.01; Windows 8.1
Posts: 2
Joined: Sat Apr 05, 2014 4:39 pm

Re: External python script to monitor OnSave event

Postby FJCC » Sat Apr 05, 2014 7:44 pm

I don't have time to work up a complete example but what I think you want to do is define a class in Python that inherits from the listener interface. There is an example of a ModifyListener here.
Windows 10 and Linux Mint, since 2017
If your question is answered, please go to your first post, select the Edit button, and add [Solved] to the beginning of the title.
Posts: 7487
Joined: Sat Nov 08, 2008 8:08 pm
Location: Colorado, USA

Re: External python script to monitor OnSave event

Postby Charlie Young » Mon Apr 07, 2014 1:28 am

I decided to play around with this. My example is run from MyMacros, but there should be no difficulty using the listener in an external script. This just writes the event name, such as OnSave, OnSaveDone, OnFocus, etc. into Sheet1.A1.

One amusing, if also irritating, item to notice, is that "Occurred" is misspelled in "documentEventOccured," and I made the mistake of spelling it correctly at first. It took awhile to find that. :?

Code: Select all   Expand viewCollapse view
import uno
import unohelper

from com.sun.star.document import XDocumentEventListener, DocumentEvent


class MyDocumentEventListener( unohelper.Base, XDocumentEventListener ):
    def __init__(self):
        self.doc = None
    def setDocument(self,doc):
        self.doc = doc
        self.sheet = self.doc.getSheets().getByIndex(0)
        self.cell = self.sheet.getCellByPosition(0,0)
    def documentEventOccured(self, DocEvent):
    def disposing(self, DocEvent):

def testEventListener(*dummy):
    global docEventListener
    oDoc = context.getDocument()
    docEventListener = MyDocumentEventListener()
def removeEventListener(*dummy):
    oDoc = context.getDocument()
g_exportedScripts = testEventListener, removeEventListener,

 Edit: Fixed oversight; added function to remove the listener if it is no longer wanted. 
Apache OpenOffice 4.1.1
Windows XP
User avatar
Charlie Young
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: External python script to monitor OnSave event

Postby GaryDyr » Fri Apr 11, 2014 6:27 pm

Charlie, I appreciate you taking the time to look at this in more detail and updating the older information. The code module works on my system as anticipated when installed in the ../Scripts/python folder.
I am still missing something, probably a great deal, with my original idea of starting AOO from my currently installed python 3.4 version, and trying to add the script you generated to a python module that is either run from a folder external to the OpenOffice folder, or from the OO /Scripts/python folder. In the latter case, I get an error indicating python can't import win32com. In the former case, the module errors out indicating it can't import uno, or errors out trying to load pyuno in the uno module. I have tried the example suggested in the PyUno-Bridge document by starting AOO in listening mode, but I can't seem to make that work either. After much reading and fumbling with code, and getting hopelessly confused, I have come to the conclusion that I am asking to do something that is way past my meager understanding of python and AOO and the interplay between the two. Your code works and it does help me do what I want, but exclusively from the AOO side. I will close this as [Solved] because your efforts did help address the latest code to add a listener. My current problems are only peripherally related to the listener issue, and essentially are a whole different topic.
OpenOffice 4.01; Windows 8.1
Posts: 2
Joined: Sat Apr 05, 2014 4:39 pm

Re: [Solved] External python script to monitor OnSave event

Postby Charlie Young » Fri Apr 11, 2014 9:12 pm

See my posts in This thread for a discussion of running an external Python script using AOO's Python 2.7.5. i haven't tried really to do any UNO programming with Python 3.x, I just use it to learn Python specific things.

I'll be happy if those posts prove useful, since they provided a second-rate solution to the problem discussed in the thread.
Apache OpenOffice 4.1.1
Windows XP
User avatar
Charlie Young
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Return to Macros and UNO API

Who is online

Users browsing this forum: No registered users and 3 guests