sylikc / pyexiftool

PyExifTool (active PyPI project) - A Python library to communicate with an instance of Phil Harvey's ExifTool command-line application. Runs one process with special -stay_open flag, and pipes data to/from. Much more efficient than running a subprocess for each command!
Other
144 stars 17 forks source link

variable inside exiftoolhelper.execute() #80

Open ArthurHuyghe opened 8 months ago

ArthurHuyghe commented 8 months ago

Hi, if have written a small program to test some functionality. I can't seem to figure out how to pass a variable as an argument for .execute(). this is my prgram:

from exiftool import ExifToolHelper
import logging
logging.basicConfig(level=logging.DEBUG)

# Define a list of file paths for which you want to retrieve metadata
path = "C:\Users\Arthu\Pictures"

# Create an ExifToolHelper instance
with ExifToolHelper(logger=logging.getLogger(__name__)) as et:
    # Execute the ExifTool command
    result = et.execute('-Directory<CreateDate',  '-d "%Y/%m"',  '-r',  f'{path}')

# 'result' contains the output of the ExifTool command
print(result)

I would like to pass a path from a file or directory to the exiftool command, wich should basicly comme down to exiftool "-Directory<CreateDate" -d "%Y/%m" -r "C:\Users\Arthu\Pictures\test exif tool".

Could you please teach me how to do this propperly?

ArthurHuyghe commented 7 months ago

@sylikc, I debugged my previous code a bit and fixed some obvious mistakes.

from exiftool import ExifToolHelper
import logging
logging.basicConfig(level=logging.DEBUG)

# Define a list with al the parameters needed for exiftool
path = 'C:/Users/Arthu/Pictures/test_exif_tool'
dateformat = '-d "C:/Users/Arthu/Pictures/test_exif_tool/%Y/%m"'
recursive = '-r'
sorting = '-Directory<DateTimeOriginal'
parameters = sorting + ', ' + dateformat + ', ' + recursive + ', ' + path
parameters = str(parameters)
#print(parametersRaw)
print(parameters)

# Create an ExifToolHelper instance
with ExifToolHelper(logger=logging.getLogger(__name__)) as et:
    # Execute the ExifTool command
    result = et.execute(parameters)
    et.terminate()

# 'result' contains the output of the ExifTool command
print(result)

However, i still get an error about the variable inside the execute command, this is the output I get:

-Directory<DateTimeOriginal, -d "C:/Users/Arthu/Pictures/test_exif_tool/%Y/%m", -r, C:/Users/Arthu/Pictures/test_exif_tool
INFO:__main__:Property 'executable': set to "C:\WINDOWS\exiftool.exe"
INFO:__main__:Property 'common_args': set to "['-G', '-n']"
INFO:__main__:Property 'config_file': set to "None"
INFO:__main__:Method 'execute': Command sent = [b'-ver', b'-echo4', b'=${status}=post509863']
DEBUG:__main__:ExifToolHelper.execute: IN  params = ('-ver',)
DEBUG:__main__:ExifToolHelper.execute: OUT stdout = "12.69
"
DEBUG:__main__:ExifToolHelper.execute: OUT stderr = ""
DEBUG:__main__:ExifToolHelper.execute: OUT status = 0
INFO:__main__:Method 'run': Exiftool version '12.69' (pid 23232) launched with args '['C:\\WINDOWS\\exiftool.exe', '-stay_open', 'True', '-@', '-', '-common_args', '-G', '-n']'
INFO:__main__:Method 'execute': Command sent = [b'-Directory<DateTimeOriginal, -d "C:/Users/Arthu/Pictures/test_exif_tool/%Y/%m", -r, C:/Users/Arthu/Pictures/test_exif_tool', b'-echo4', b'=${status}=post445699']
DEBUG:__main__:ExifToolHelper.execute: IN  params = ('-Directory<DateTimeOriginal, -d "C:/Users/Arthu/Pictures/test_exif_tool/%Y/%m", -r, C:/Users/Arthu/Pictures/test_exif_tool',)
DEBUG:__main__:ExifToolHelper.execute: OUT stdout = ""
DEBUG:__main__:ExifToolHelper.execute: OUT stderr = "No file specified
"
DEBUG:__main__:ExifToolHelper.execute: OUT status = 1
INFO:__main__:Method 'terminate': Exiftool terminated successfully.
Traceback (most recent call last):
  File "C:\Users\Arthu\AppData\Local\Programs\Python\Python311\Lib\runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Arthu\AppData\Local\Programs\Python\Python311\Lib\runpy.py", line 88, in _run_code
    exec(code, run_globals)
  File "c:\Users\Arthu\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher/../..\debugpy\__main__.py", line 39, in <module>
    cli.main()
  File "c:\Users\Arthu\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 430, in main
    run()
  File "c:\Users\Arthu\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 284, in run_file
    runpy.run_path(target, run_name="__main__")
  File "c:\Users\Arthu\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 321, in run_path
    return _run_module_code(code, init_globals, run_name,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\Arthu\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 135, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "c:\Users\Arthu\.vscode\extensions\ms-python.python-2023.20.0\pythonFiles\lib\python\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 124, in _run_code
    exec(code, run_globals)
  File "c:\Users\Arthu\Documents\GitHub\PhotoOrganizer\PhotoOrganizer_v3\PhotoOrganizer_v3.py", line 18, in <module>
    result = et.execute(parameters)
             ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Arthu\AppData\Local\Programs\Python\Python311\Lib\site-packages\exiftool\helper.py", line 135, in execute
    raise ExifToolExecuteError(self._last_status, self._last_stdout, self._last_stderr, str_bytes_params)
exiftool.exceptions.ExifToolExecuteError: execute returned a non-zero exit status: 1

Could you help me find the correct way to do this?

sylikc commented 7 months ago

@ArthurHuyghe Have you checked out the Quick Start / Examples guide?

https://sylikc.github.io/pyexiftool/examples.html#input-parameters

let me know if it's unclear and I'll update it, but there's a note that addresses just the problem you're having.

ArthurHuyghe commented 7 months ago

@sylikc, I am not sure if I understood the note in the documentation. Should result = et.execute(*[parameters]) be the correct execution command? In this expression parameters is a variable I defined earlier containing all the commands I want to pass to exiftool.

sylikc commented 7 months ago

@ArthurHuyghe I just updated the FAQ to try to help with this. See if it helps: https://sylikc.github.io/pyexiftool/faq.html#shlex-split

sylikc commented 7 months ago

Also, in your code above, you don't need to call terminate(), as when it exits the with block, terminate() is called automatically

 with ExifToolHelper(logger=logging.getLogger(__name__)) as et:
     result = et.execute(parameters)
     et.terminate()  # don't need to do this, it's done automatically after "with" ends
ArthurHuyghe commented 6 months ago

@sylikc, Sorry for the late response. The additions to the FAQ do help massively. However, if I run my code, it hangs after the execution call without doing anything. I suspect this has something to do with #73 as I try to run my program on Windows. In this issue, you say CPython 3.12 fixes this problem. I installed the latest version, 3.12.1, and tried again, but nothing changed.

This is my code:

from exiftool import ExifToolHelper
import logging, shlex
logging.basicConfig(level=logging.DEBUG)

# Create an ExifToolHelper instance
with ExifToolHelper(logger=logging.getLogger(__name__)) as et:
    parameters = shlex.split(r'"-Directory<mediacreatedate" -d "C:\Users\Arthu\Pictures\test_exif_tool/%Y/%m/%d" "C:\Users\Arthu\Pictures\test_exif_tool"')
    print(parameters)
    # Execute the ExifTool command
    result = et.execute(*parameters)

# 'result' contains the output of the ExifTool command
print(result)

And here is the output until it hangs: image

Thanks for all the help you already provided!

sylikc commented 1 week ago

that's a really odd hang. when running on the command line the command doesn't hang?