Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python-Fu - os.path not working
#1
Hi all,

I'm trying to set up a Python-Fu script that will get the file path of the current file, save the file, and then return the folder and file name of the file. For some reason, though, the os.path operations that I'm including don't appear to be working. Here's the code:

Code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from gimpfu import*

def getPathSave(image, layer):
    pdb.gimp_message("Test")
    filePath = pdb.gimp_image_get_filename(image)  
    pdb.gimp_message("filePath = " + str(filePath))  
    pdb.gimp_file_save(image, layer, filePath, filePath)
    pathCheck = os.path.exists(filePath)  # sanity check to make sure that it's actually giving me a path
    pdb.gimp_message("pathCheck = " + str(pathCheck))    
    folderName = os.path.dirName(filePath)
    pdb.gimp_message("folderName = " + str(folderName))
    fileName = os.path.basename(filePath)
    pdb.gimp_message("fileName = " + str(fileName))
    #return folderName, fileName

register(
    "python_fu_marvelmods_basic_get_path_save",
    "Saves the file and collects file path information. Returns the folder that the file is in, as well as its name (without the extension).",
    "Saves the file and collects file path information. Returns the folder that the file is in, as well as its name (without the extension).",
    "BaconWizard17",
    "BaconWizard17",
    "January 2024",
    "Get File Path and Save",
    "*",
    [
        (PF_IMAGE, "image", "Input image", None),
        (PF_DRAWABLE, "drawable", "Layer, mask, or channel", None)
    ],
    [
        #(PF_STRING, "folderName", "The folder that the file is in"),
        #(PF_STRING, "fileName", "The file name")
    ],
    getPathSave,
    menu='<Image>/Marvel Mods/Basic Procedures'
)

main()

I took this code from a finished script that already works. It's a process that I use in a lot of other scripts, so I'm trying to consolidate it into one and just call this instead of copying the same code every time. But I can't get it to work on its own for whatever reason. I haven't even gotten to the point of returning the values (you can see that they're commented out). The first three pdb.gimp_message scripts work and will show something in the error console, but the last two don't show anything. It seems that the values aren't getting collected, so there's nothing to return. But I have no clue why it's not working.

I've tried using this method to debug the script, but it just crashes the Python-Fu console for some reason, so I haven't gotten any luck there.

I'm on Windows 10 and using GIMP 2.10.36. Any help would be seriously appreciated!
Modder/Skinner at MarvelMods.com using GIMP to create, edit, and export textures and previews more efficiently.

My GIMP scripts hosted on GitHub
Reply
#2
The function is dirname and not dirName (no camelcase N, done too much Java lately?)

If you had copy-pasted the code in the python-fu console, you would have found this very quickly:


➤> folderName = os.path.dirName(filePath)
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'module' object has no attribute 'dirName'


The method you point to in the Tutorials section to is not to be used in the python-fu console but in your code (it reroutes the stdOut and obviously the python-fu console needs it too...)
Reply
#3
(01-11-2024, 08:47 AM)Ofnuts Wrote: The function is dirname and not dirName (no camelcase N, done too much Java lately?)

If you had copy-pasted the code in the python-fu console, you would have found this very quickly:


➤> folderName = os.path.dirName(filePath)
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'module' object has no attribute 'dirName'


The method you point to in the Tutorials section to is not to be used in the python-fu console but in your code (it reroutes the stdOut and obviously the python-fu console needs it too...)

Man, I figured it was something silly, but I didn’t realize it was that silly. Thanks for the help!
Modder/Skinner at MarvelMods.com using GIMP to create, edit, and export textures and previews more efficiently.

My GIMP scripts hosted on GitHub
Reply
#4
I was able to get the script to work, but now I have another issue: how do I properly return two variables from a script? I've been able to have one return variable work successfully in the past, but I'm having trouble with two. Here's the revised code:
Code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from gimpfu import*

def getPathSave(image, layer):
    filePath = pdb.gimp_image_get_filename(image)  
    pdb.gimp_file_save(image, layer, filePath, filePath)
    folderName = os.path.dirname(filePath)
    fileName = os.path.basename(filePath)
    pdb.gimp_message("folderName = " + str(folderName))
    pdb.gimp_message("fileName = " + str(fileName))
    return folderName, fileName

register(
    "python_fu_marvelmods_basic_get_path_save",
    "Saves the file and collects file path information. Returns the folder that the file is in, as well as its name (without the extension).",
    "Saves the file and collects file path information. Returns the folder that the file is in, as well as its name (without the extension).",
    "BaconWizard17",
    "BaconWizard17",
    "January 2024",
    "Get File Path and Save",
    "*",
    [
        (PF_IMAGE, "image", "Input image", None),
        (PF_DRAWABLE, "drawable", "Layer, mask, or channel", None)
    ],
    [
        (PF_STRING, "folderName", "The folder that the file is in"),
        (PF_STRING, "fileName", "The file name")
    ],
    getPathSave,
    menu='<Image>/Marvel Mods/Basic Procedures'
)

main()

The code works fine on its own, with no errors and the messages displaying appropriately in the error console. But when I call it from another script like so:
Code:
folderName, fileName = pdb.python_fu_marvelmods_basic_get_path_save(image, layer)

I get a "RuntimeError: execution error" from Gimp. The second script so far only contains that line of code within its main function.

I have also tried putting the variables into a list within both scripts:
Code:
[folderName, fileName]
which got me the same results. I've also tried running it with only one return variable, and it worked fine with returning either variable on its own. So I would assume that the issue is however I'm setting up the two return variables. The documentation doesn't cover this, so I'm at a loss.
Modder/Skinner at MarvelMods.com using GIMP to create, edit, and export textures and previews more efficiently.

My GIMP scripts hosted on GitHub
Reply
#5
(01-15-2024, 04:15 PM)BaconWizard17 Wrote: I was able to get the script to work, but now I have another issue: how do I properly return two variables from a script? I've been able to have one return variable work successfully in the past, but I'm having trouble with two. Here's the revised code:
Code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from gimpfu import*

def getPathSave(image, layer):
   filePath = pdb.gimp_image_get_filename(image)  
   pdb.gimp_file_save(image, layer, filePath, filePath)
   folderName = os.path.dirname(filePath)
   fileName = os.path.basename(filePath)
   pdb.gimp_message("folderName = " + str(folderName))
   pdb.gimp_message("fileName = " + str(fileName))
   return folderName, fileName

register(
   "python_fu_marvelmods_basic_get_path_save",
   "Saves the file and collects file path information. Returns the folder that the file is in, as well as its name (without the extension).",
   "Saves the file and collects file path information. Returns the folder that the file is in, as well as its name (without the extension).",
   "BaconWizard17",
   "BaconWizard17",
   "January 2024",
   "Get File Path and Save",
   "*",
   [
       (PF_IMAGE, "image", "Input image", None),
       (PF_DRAWABLE, "drawable", "Layer, mask, or channel", None)
   ],
   [
       (PF_STRING, "folderName", "The folder that the file is in"),
       (PF_STRING, "fileName", "The file name")
   ],
   getPathSave,
   menu='<Image>/Marvel Mods/Basic Procedures'
)

main()

The code works fine on its own, with no errors and the messages displaying appropriately in the error console. But when I call it from another script like so:
Code:
folderName, fileName = pdb.python_fu_marvelmods_basic_get_path_save(image, layer)

I get a "RuntimeError: execution error" from Gimp. The second script so far only contains that line of code within its main function.

I have also tried putting the variables into a list within both scripts:
Code:
[folderName, fileName]
which got me the same results. I've also tried running it with only one return variable, and it worked fine with returning either variable on its own. So I would assume that the issue is however I'm setting up the two return variables. The documentation doesn't cover this, so I'm at a loss.

Your code works:


➤> image=gimp.image_list()[0]
➤> pdb.python_fu_marvelmods_basic_get_path_save(image,image.active_layer)
('/tmp/screenshots', 'MapToSphere2.png')


You may be passing a bad image or layer argument, or working with an image that has no filename yet...

You can improve you code a bit by catching exceptions:

Code:
# -*- coding: utf-8 -*-

import os, traceback
from gimpfu import*

def getPathSave(image,layer):
    try:
        filePath = pdb.gimp_image_get_filename(image)  
        folderName = os.path.dirname(filePath)
        fileName = os.path.basename(filePath)
        pdb.gimp_message('folderName: "%s", filename: "%s"' % (folderName,fileName))
    except Exception as e:
        print e.args[0]
        gimp.message(e.args[0]+'\n'+traceback.format_exc())
        return None
    return folderName, fileName

desc="Image file info"
register(
    "python_fu_marvelmods_basic_get_path_save",
    desc,desc,
    "BaconWizard17",
    "BaconWizard17",
    "January 2024",
    desc,
    "*",
    [
        (PF_IMAGE, "image", "Input image", None),
        (PF_DRAWABLE, "drawable", "Layer, mask, or channel", None)
    ],
    [
        (PF_STRING, "folderName", "The folder that the file is in"),
        (PF_STRING, "fileName", "The file name")
    ],
    getPathSave,
    menu='<Image>/Test'
)

main()

Then when you call your script on a new image:


Image file info Warning
'NoneType' object has no attribute 'rfind'
Traceback (most recent call last):
  File "/home/me/Code/Gimp/Foreign/Activated/return2.py", line 10, in getPathSave
    folderName = os.path.dirname(filePath)
  File "/usr/lib/python2.7/posixpath.py", line 122, in dirname
    i = p.rfind('/') + 1
AttributeError: 'NoneType' object has no attribute 'rfind'

and since the only object of type NoneType is None itself this means that you got a None where you thought you had an object.

Btw, since your description states "as well as its name (without the extension)" you may want to use an os.path.splitext() somewhere.
Reply
#6
Thank you for the advice! The debugging didn't fix my code, but it did end up being a useful addition. After some more experimentation, I found that it would work if I coded it like this:
Code:
(folderName, fileName) = pdb.python_fu_marvelmods_basic_get_path_save(image, layer)
instead of like this:
Code:
folderName, fileName = pdb.python_fu_marvelmods_basic_get_path_save(image, layer)
Modder/Skinner at MarvelMods.com using GIMP to create, edit, and export textures and previews more efficiently.

My GIMP scripts hosted on GitHub
Reply


Forum Jump: