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

Newline in field causes execute error #91

Open umbra3275 opened 1 week ago

umbra3275 commented 1 week ago

The following command on command line:

exiftool -comment="post contents:
 new line" images-saved/temp-file.jpg

gives the following output:

    1 image files updated

However, when I try to use pyexiftool to do the same, even using shlex to parse the exact same string:

>>> import shlex, exiftool
>>> with exiftool.ExifToolHelper() as et:
...     params = shlex.split("""-comment="post contents:
...  new line" images-saved/temp-file.jpg""")
...     et.execute(*params)
... 

I get this output

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "/home/pi/.local/lib/python3.11/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

Given that using shlex to determine the correct parsing is the only thing I have found to do if pyexiftool's output doesn't match exiftool's, I'm not sure what else I can do here.

sylikc commented 4 days ago

It would be good programming if you added print(params) to see if what params are actually passed

I'm unable to replicate this issue on Windows, and I'm not even sure how multiline comments are supposed to be stored. Can you use the debugging steps, enable logging and see what's happening in your env?

umbra3275 commented 4 days ago

assuming this is what you mean by debugging steps and enabling logging, yeah. here's the updated script:

import logging
import shlex, exiftool
logging.basicConfig(level=logging.DEBUG)
with exiftool.ExifToolHelper(logger=logging.getLogger(__name__)) as et: 
    params = shlex.split("""-comment="post contents:
 new line" temp-file.jpg""")
    print(params)
    try:
        et.execute(*params)
    except exiftool.exceptions.ExifToolExecuteError as e:
        print(e.stderr)

which gives the following output

INFO:__main__:Property 'executable': set to "/usr/bin/exiftool"
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}=post131387']
DEBUG:__main__:ExifToolHelper.execute: IN  params = ('-ver',)
DEBUG:__main__:ExifToolHelper.execute: OUT stdout = "12.57
"
DEBUG:__main__:ExifToolHelper.execute: OUT stderr = ""
DEBUG:__main__:ExifToolHelper.execute: OUT status = 0
INFO:__main__:Method 'run': Exiftool version '12.57' (pid 7005) launched with args '['/usr/bin/exiftool', '-stay_open', 'True', '-@', '-', '-common_args', '-G', '-n']'
['-comment=post contents:\n new line', 'temp-file.jpg']
INFO:__main__:Method 'execute': Command sent = [b'-comment=post contents:\n new line', b'temp-file.jpg', b'-echo4', b'=${status}=post753851']
DEBUG:__main__:ExifToolHelper.execute: IN  params = ('-comment=post contents:\n new line', 'temp-file.jpg')
DEBUG:__main__:ExifToolHelper.execute: OUT stdout = "1 image files updated
    1 files weren't updated due to errors
"
DEBUG:__main__:ExifToolHelper.execute: OUT stderr = "Error: File not found - new line
"
DEBUG:__main__:ExifToolHelper.execute: OUT status = 1
Error: File not found - new line

INFO:__main__:Method 'terminate': Exiftool terminated successfully.

From what I can tell, shlex is parsing things correctly. I'm not sure how exactly the shell passes that to exiftool, so I can't confirm that it matches, but nothing jumps out.

I'm not sure why it's not reproducible on windows, though that's possibly because windows is pretty restrictive about what characters you can and can't use in various things. I can produce it on both my debian desktop, and my raspbian pi, so it might just be a linux thing? I'm more than happy to run tests and get further info about my environment, but I'll need to know what would actually help.

temp-file Here's the jpg that base exiftool creates when asked to update the comment to a string containing a newline. idk if that's how a newline is supposed to be stored, but that's how it's doing it. Looking at the hex dump of the image file , it's just using the ascii newline character.

sylikc commented 3 days ago

Looks like your issue is already on ExifTool's FAQ Q21 ...

i added -ec flag and replaced newlines with "\\n" and it worked... please refer to the FAQ