diff --git a/bin/mtag/README.md b/bin/mtag/README.md index 2adda0ba..43dfbc8e 100644 --- a/bin/mtag/README.md +++ b/bin/mtag/README.md @@ -6,6 +6,7 @@ some of these rely on libraries which are not MIT-compatible * [audio-bpm.py](./audio-bpm.py) detects the BPM of music using the BeatRoot Vamp Plugin; imports GPL2 * [audio-key.py](./audio-key.py) detects the melodic key of music using the Mixxx fork of keyfinder; imports GPL3 +* [image-noexif.py](./image-noexif.py) removes exif tags from images; is GPLv1 or artistic-license * [media-hash.py](./media-hash.py) generates checksums for audio and video streams; uses FFmpeg (LGPL or GPL) these do not have any problematic dependencies: diff --git a/bin/mtag/image-noexif.py b/bin/mtag/image-noexif.py new file mode 100644 index 00000000..d5392b00 --- /dev/null +++ b/bin/mtag/image-noexif.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 + +""" +remove exif tags from uploaded images + +dependencies: + exiftool + +about: + creates a "noexif" subfolder and puts exif-stripped copies of each image there, + the reason for the subfolder is to avoid issues with the up2k.db / deduplication: + + if the original image is modified in-place, then copyparty will keep the original + hash in up2k.db for a while (until the next volume rescan), so if the image is + reuploaded after a rescan then the upload will be renamed and kept as a dupe + + alternatively you could switch the logic around, making a copy of the original + image into a subfolder named "exif" and modify the original in-place, but then + up2k.db will be out of sync until the next rescan, so any additional uploads + of the same image will get symlinked (deduplicated) to the modified copy + instead of the original in "exif" + + or maybe delete the original image after processing, that would kinda work too + +example copyparty config to use this: + -v/mnt/nas/pics:pics:rwmd,ed:c,e2ts,mte=+noexif:c,mtp=noexif=ejpg,ejpeg,ad,bin/mtag/image-noexif.py + +explained: + for realpath /mnt/nas/pics (served at /pics) with read-write-modify-delete for ed, + enable file analysis on upload (e2ts), + append "noexif" to the list of known tags (mtp), + and use mtp plugin "bin/mtag/image-noexif.py" to provide that tag, + do this on all uploads with the file extension "jpg" or "jpeg", + ad = parse file regardless if FFmpeg thinks it is audio or not + +PS: this requires e2ts to be functional, + meaning you need to do at least one of these: + * apt install ffmpeg + * pip3 install mutagen + and your python must have sqlite3 support compiled in +""" + + +import os +import sys +import time +import filecmp +import subprocess as sp + +try: + from copyparty.util import fsenc +except: + + def fsenc(p): + return p.encode("utf-8") + + +def main(): + cwd, fn = os.path.split(sys.argv[1]) + if os.path.basename(cwd) == "noexif": + return + + os.chdir(cwd) + f1 = fsenc(fn) + f2 = os.path.join(b"noexif", f1) + cmd = [ + b"exiftool", + b"-exif:all=", + b"-iptc:all=", + b"-xmp:all=", + b"-P", + b"-o", + b"noexif/", + b"--", + f1, + ] + sp.check_output(cmd) + if not os.path.exists(f2): + print("failed") + return + + if filecmp.cmp(f1, f2, shallow=False): + print("clean") + else: + print("exif") + + # lastmod = os.path.getmtime(f1) + # times = (int(time.time()), int(lastmod)) + # os.utime(f2, times) + + +if __name__ == "__main__": + main()