dave-howard / vsdx

vsdx - A python library for processing .vsdx files
BSD 3-Clause "New" or "Revised" License
67 stars 25 forks source link

Can not save vsdx #51

Open Kranfield opened 1 year ago

Kranfield commented 1 year ago

Hello,

When I try to save a vsdx (with vis.save_vsdx("vsdx_file_name_here") I edited with a python script, I have this error :

Traceback (most recent call last):

  File "C:\Spyder\Python\Python310\lib\xml\etree\ElementTree.py", line 762, in _get_writer
    write = file_or_filename.write

AttributeError: 'str' object has no attribute 'write'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "C:\Users\qbernard\Desktop\PythonTestsScripts\VisioUpdater\script\main.py", line 357, in <module>
    vis.save_vsdx('vsdxfile.vsdx')

  File "C:\Spyder\Python\Python310\lib\site-packages\vsdx\vsdxfile.py", line 1015, in save_vsdx
    xml_to_file(self.pages_xml_rels, f'{self.directory}/visio/pages/_rels/pages.xml.rels')

  File "C:\Spyder\Python\Python310\lib\site-packages\vsdx\vsdxfile.py", line 49, in xml_to_file
    xml.write(filename, xml_declaration=True, method='xml', encoding='UTF-8')

  File "C:\Spyder\Python\Python310\lib\xml\etree\ElementTree.py", line 732, in write
    with _get_writer(file_or_filename, enc_lower) as write:

  File "C:\Spyder\Python\Python310\lib\contextlib.py", line 135, in __enter__
    return next(self.gen)

  File "C:\Spyder\Python\Python310\lib\xml\etree\ElementTree.py", line 768, in _get_writer
    file = open(file_or_filename, "w", encoding=encoding,

FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\qbernard\\Desktop\\PythonTestsScripts\\VisioUpdater\\script\\MVS_BASELINE20220927/visio/pages/_rels/pages.xml.rels'

Right now I am not sure why the "file is not found", since when I open my vsdx as a zip, in /MVS_BASELINE20220927/vision/pages/_rels, i find the pages.xml.rels. I was guessing it is because of the \ and / in the path, but I prefer to ask here (maybe I did a stupid error and I did not see it...)

my main section of code :

if __name__ == '__main__' :
    """

    """

    pathVis = 'C:/Users/qbernard/Desktop/PythonTestsScripts/VisioUpdater/script/MVS_BASELINE20220927.vsdx'
    vis,pathVis = openVis(pathVis = pathVis)
    extractToDatabase(vis = vis, pathVis = pathVis)

    dataset = restruct(database)
    dataset = keySave(dataset)
    dataset_001 = AdvQuery(dataset, "ID", ["VAR"])
    dataset_001 = AdvQuery(dataset_001, "Nom ADL1", ["Nom ADL1"]) # Testing Purposes
    batchRewrite(dataset_001, "Nom ADL1", "Nom_ADL1") # Testing Purposes
    print("DEBUG : Importing to Visio")
    importDatabaseToVis(database, vis = vis, pathVis = pathVis)
    pathVis02 = vsdxSaveAs() # this open a save as window, we overwrite the vsdx file.
    vis.save_vsdx('pathVis02')

Any guess where this error can come from ?

Yours,

Quentin

Kranfield commented 1 year ago

Ok so after a week, I found why it was not working. It seems that the saving process is not opening the file so you have to open it before and keep it open. Maybe it would be great to add a functionnality that detect whether the file is open or not, and will open it in write mode if it is not the case.

dave-howard commented 1 year ago

Hi @Kranfield - I guess in your OpenVis() method you are either processing the vsdx file in a with block or explicitly closing it, so the vis object has all the data from the vsdx file but after it's closed the folder structure is removed so we get this error.

I hadn't considered this use case before - but I can see it being really useful. Ideally the original vsdx file contents will be incorporated into the VisioFile object so it can still reconstruct the file structure in save_vsdx() whether still open or not.

Let me have a look into that and feedback here