Python Macro: how to get the path of the current Draw-document(.odg) and open an existing Calc document(.ods) to transfer spezific data

Working with Linux (Ubuntu20.04) I’ve got a P&ID made with Libreoffice Draw (file mydraw.odg). I want to transfer some specific text-infos (Name, Title, Description) in an existing file named mycalc.ods. The .ods and .odg files are in the same directory.
my macro till now looks like shown in :

My questions:
How to ask if the XSCRIPTCONTEXT.getDocument() is a .odg Document ??
How to get full pathname of actual open document ??
How to open the existing mycalc.ods file ??
How to close the changed mycalc.ods file ??

Please, help us to help you by not uploading a picture of the code but copy&paste the code.
To keep the formatting, start on a new line with: ```python and close the Codeblock with ```
thanks

sorry, I didn’t check how to insert code; here’s my code as text

def transfer_object_list_info( ):
    def get_named_objects_info(mydraw):
    	...  # thanks the answer of jimk I know how to get and set objects name, title and description
    	return named_objects
    #####################
    def insert_info_to(mycalc, object_list):
    	...	
    ##################
    import os
    mydraw = XSCRIPTCONTEXT.getDocument()
    if not hasattr(mydraw, "Draw"):  # doesn't function; How to ask if it's a .odg Document ??
       return   
    filename = mydraw.get_my_filename()  # doesn't function; How to get full pathname of mydraw.odg ??
    filename = filename.replace('mydraw.odg', 'mycalc.ods')
    uno_url = uno.systemPathToFileUrl(filename)
    mycalc = XSCRIPTCONTEXT.getDocument(uno_url) # doesn't function; How to open the existing .ods file ??
    object_list = get_named_objects_info(mydraw)
    insert_info_to(mycalc, object_list)
    mycalc.storeToURL(uno_url)
    mycalc.terminate()	# doesn't function; How to close the .ods file ??

edit by @karolus Backtics ``` instead singlequotes ‘’'

Hello
may be some help for you:

import uno
from pathlib import Path

#ctx = uno.getComponentContext()
#createUnoService = ctx.ServiceManager.createInstance
#desktop = createUnoService("com.sun.star.frame.Desktop")
# here actually no need for the 3 lines above, better:
desktop = XSCRIPTCONTEXT.getDesktop()

this_doc = XSCRIPTCONTEXT.getDocument()
this_doc_url = this_doc.URL
this_doc_path = uno.fileUrlToSystemPath(this_doc_url)
this_p = Path(this_doc_path)

other_path = Path(this_p.parent / 'other-file_name.ods')
other_doc = desktop.loadComponentFromURL(other_path.as_uri(), "_blanc",0,(),)

Update:
the Example above more straight:

import uno
from pathlib import Path

desktop = XSCRIPTCONTEXT.getDesktop()

this_doc = XSCRIPTCONTEXT.getDocument()
this_doc_url = this_doc.URL
this_doc_path = uno.fileUrlToSystemPath(this_doc_url)
this_p = Path(this_doc_path)

#use ´.with_name´ method from path-object
other_path = this_p.with_name( 'other-file_name.ods' ) 
other_doc = desktop.loadComponentFromURL(other_path.as_uri(), "_blanc",0,(),)
1 Like

Thanks very much for your help. With that my macro now runs perfect.

in very conventional programming without uno path functions and type=draw functions
use suggestions of karolus below (and or above) to improve text manipulation (or circumvent it)
(edited and added on request of @karolus)

import uno
ctx = uno.getComponentContext() 
smgr = ctx.ServiceManager
StarDeskTop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)

#these variables are useful in many defs, for convenience: the dispatcher functionality

dispatcher = smgr.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx)
def transfer():

    oDoc = XSCRIPTCONTEXT.getDocument()
    
    if not oDoc.hasLocation() :  # new document without a name/location
        return
  
    sText = oDoc.URL
    
    i = sText.rfind("/")
    sPath = sText[:i+1]
    i = sText.rfind(".")
    if sText[i+1:] != "odg":
        return
    
    sText = sPath + "mycalc.ods"
    args = dictToProperty({"Hidden":True})
    mycalc = StarDeskTop.loadComponentFromURL(sText, '_default', 0, args)
    # add data to mycalc

    mycalc.storeAsURL( sText , () )
    mycalc.dispose()


def dictToProperty(values):
    # call: arg as { 'FilterName': 'writer_pdf_Export' , "Hidden" : False , ...}
    ps = tuple([PropertyValue(Name=n, Value=v) for n, v in values.items()])
    return ps

edit by @karolus repared codeblock

1 Like

@parsely I dont know about GLOBAL StarDeskTop ???

if you need it by Textmanipulation:

fileurl = "file:///home/pi/2017_1/Pivottabelle.ods"
parenturl, filename = fileurl.rsplit('/',1)
_, suffix = filename.rsplit('.',1)

In LibO Basic StarDesktop is a predefined variable supplying an object which supports the one service com.sun.star.frame.Desktop. By definition of this service it can be instantiated only once. If you try to create a second instance, what you get will be identical to the first instance.
See LibreOffice: Desktop Service Reference.

Of course I know in Basic but @parsely show python-code and I miss the part where ‘StarDeskTop’ is defined

Yes. I know, but above I commented on the answer by @parsley and…
This is software, and it’s misleading (therefore?). I tried to disambiguate the addressee by formatting “In LibO Basic” bold. Next time, in a similar case, I will emphasize the main addresse by naming… OK?

sorry, developed this def in a larger file that has these general lines before all the defs

    import uno
    ctx = uno.getComponentContext()  
    smgr = ctx.ServiceManager
    StarDeskTop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)

Sorry to split hairs, but the name ‘StarDeskTop’ is oddly chosen, why not at least ‘StarDesktop’ or just ‘desktop’ ?
In Basic it wouldn’t matter at all because you can reference it elsewhere in arbitrary UPpeR- | lowercase, but that’s not possible in python (thanks god).