ChatGPT made me a watchdog script that automates adding metadata to files, but..

Started by ww408, March 07, 2025, 12:08:29 PM

Previous topic - Next topic

ww408

One thing I don't like about ExifTool is that using it to tag files with each and every desired tag is too time-consuming, so I've started to just dump everything into xmp-dc:description, but even that is too time-consuming, in my opinion, so I had ChatGPT make me a script that automatically runs exiftool "-xmp-dc:description<=input" . every time the file, input, is modified, i.e., I move target files into the folder that contains input (input is a text file) and add my text to input and save, which triggers the watchdog script. And it works perfectly, except for the fact that the result always has a trailing period because whether I edit the text file with FeatherPad or nano, an empty line is forcibly created; even if I run one of ChatGPT's corrective wrapper scripts that is supposed to reject this empty line, an empty line is still created.

StarGeek

The only thing I can offer is how to strip any trailing whitespaces after the fact.

exiftool -API "Filter=s/\s+$//" -if "$Description# ne $Description" "-Description<Description" /path/to/files/
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

ww408

The result still has a trailing period.

This is the wrapper that ChatGPT made from your command:

import time
import subprocess
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

WATCHED_FILE = "/home/green/Desktop/ExifTool/input"
WATCHED_DIR = "/home/green/Desktop/ExifTool"
COMMAND_TO_RUN = [
    "exiftool",
    "-API", "Filter=s/\\s+$//",
    "-if", "$Description# ne $Description",
    "-Description<Description",
    "."
]

class FileChangeHandler(FileSystemEventHandler):
    def on_modified(self, event):
        if event.src_path == WATCHED_FILE:
            print(f"{WATCHED_FILE} modified, running ExifTool command...")

            # Run exiftool command to clean up trailing whitespace
            subprocess.run(COMMAND_TO_RUN, cwd=WATCHED_DIR)

def watch_file():
    event_handler = FileChangeHandler()
    observer = Observer()
    observer.schedule(event_handler, WATCHED_DIR, recursive=False)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

if __name__ == "__main__":
    watch_file()

And this is the base script it gave me:

import time
import subprocess
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

WATCHED_FILE = "/home/green/Desktop/ExifTool/input"
WATCHED_DIR = "/home/green/Desktop/ExifTool"
COMMAND_TO_RUN = ["exiftool", "-xmp-dc:description<=input", "."]

class FileChangeHandler(FileSystemEventHandler):
    def on_modified(self, event):
        if event.src_path == WATCHED_FILE:
            print(f"{WATCHED_FILE} modified, running command...")
            subprocess.run(COMMAND_TO_RUN, cwd=WATCHED_DIR)

def watch_file():
    event_handler = FileChangeHandler()
    observer = Observer()
    observer.schedule(event_handler, WATCHED_DIR, recursive=False)
    observer.start()
   
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

if __name__ == "__main__":
    watch_file()

And you'll notice that while the base script clearly specifies description<=input, the wrapper script doesn't even contain input in the "COMMAND_TO_RUN" section...and yet it works. I asked ChatGPT how it works and it told me that it implicitly knows to read the file named input, but its explanation of how just made my head spin.

StarGeek

By default, when exiftool the contents of a tag, non-printable characters appear as dots. It sounds like your workflow is adding a trailing Line Feed. My command strips away any trailing white spaces such as these.

You can add the -j (-json) option when listing the output, and it will show you any non-printable characters. For example, this output shows that there are multiple Carriage Returns (\r)/New Lines (\n), as are standard in Windows text files.
C:\>exiftool -G1 -a -s -j -Description y:\!temp\Test4.jpg
[{
  "SourceFile": "y:/!temp/Test4.jpg",
  "XMP-dc:Description": "test\r\n\r\n\r\n"
}]

Running my command afterwards strips away those trailing characters
C:\>exiftool -P -overwrite_original -api "filter=s/\s+$//" -if "$Description# ne $Description" "-Description<description" y:\!temp\Test4.jpg
    1 image files updated

C:\>exiftool -G1 -a -s -j -Description y:\!temp\Test4.jpg
[{
  "SourceFile": "y:/!temp/Test4.jpg",
  "XMP-dc:Description": "test"
}]

I can't help with your script, just the exiftool command. Your other option would be to preprocess your input text file to remove the trailing white spaces. This is easy enough on Mac/Linux using the sed command, but it's a bit more complicated on Windows.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype