diff --git a/bin/mtag/rclone-upload.py b/bin/mtag/rclone-upload.py new file mode 100644 index 00000000..3b2c7cae --- /dev/null +++ b/bin/mtag/rclone-upload.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python + +import json +import os +import subprocess as sp +import sys +import time + +try: + from copyparty.util import fsenc +except: + + def fsenc(p): + return p.encode("utf-8") + + +_ = r""" +first checks the tag "vidchk" which must be "ok" to continue, +then uploads all files to some cloud storage (RCLONE_REMOTE) +and DELETES THE ORIGINAL FILES if rclone returns 0 ("success") + +deps: + rclone + +usage: + -mtp x2=t43200,ay,p2,bin/mtag/rclone-upload.py + +explained: +t43200: timeout 12h + ay: only process files which contain audio (including video with audio) + p2: set priority 2 (after vidchk's suggested priority of 1), + so the output of vidchk will be passed in here + +complete usage example as vflags along with vidchk: + -vsrv/vidchk:vidchk:r:rw,ed:c,e2dsa,e2ts,mtp=vidchk=t600,p,bin/mtag/vidchk.py:c,mtp=rupload=t43200,ay,p2,bin/mtag/rclone-upload.py:c,mte=+vidchk,rupload + +setup: see https://rclone.org/drive/ + +if you wanna use this script standalone / separately from copyparty, +either set CONDITIONAL_UPLOAD False or provide the following stdin: + {"vidchk":"ok"} +""" + + +RCLONE_REMOTE = "notmybox" +CONDITIONAL_UPLOAD = True + + +def main(): + if CONDITIONAL_UPLOAD: + fp = sys.argv[1] + zb = sys.stdin.buffer.read() + zs = zb.decode("utf-8", "replace") + md = json.loads(zs) + + chk = md.get("vidchk", None) + if chk != "ok": + print(f"vidchk={chk}", file=sys.stderr) + sys.exit(1) + + dst = f"{RCLONE_REMOTE}:".encode("utf-8") + cmd = [b"rclone", b"copy", b"--", fsenc(fp), dst] + + t0 = time.time() + try: + sp.check_call(cmd) + except: + print("rclone failed", file=sys.stderr) + sys.exit(1) + + print(f"{time.time() - t0:.1f} sec") + os.unlink(fsenc(fp)) + + +if __name__ == "__main__": + main() diff --git a/bin/mtag/vidchk.py b/bin/mtag/vidchk.py index 5a5390c8..24b57933 100755 --- a/bin/mtag/vidchk.py +++ b/bin/mtag/vidchk.py @@ -4,16 +4,28 @@ import json import sys import subprocess as sp -from copyparty.util import fsenc +try: + from copyparty.util import fsenc +except: + + def fsenc(p): + return p.encode("utf-8") + _ = r""" inspects video files for errors and such -usage: -mtp vidchk=t600,ay,p,bin/mtag/vidchk.py +usage: + -mtp vidchk=t600,ay,p,bin/mtag/vidchk.py + +explained: t600: timeout 10min ay: only process files which contain audio (including video with audio) p: set priority 1 (lowest priority after initial ffprobe/mutagen for base tags), makes copyparty feed base tags into this script as json + +if you wanna use this script standalone / separately from copyparty, +provide the video resolution on stdin as json: {"res":"1920x1080"} """ diff --git a/copyparty/mtag.py b/copyparty/mtag.py index 92477bab..0f09b1db 100644 --- a/copyparty/mtag.py +++ b/copyparty/mtag.py @@ -504,7 +504,7 @@ class MTag(object): env = os.environ.copy() env["PYTHONPATH"] = pypath - ret = {} + ret: dict[str, Any] = {} for tagname, parser in sorted(parsers.items(), key=lambda x: (x[1].pri, x[0])): try: cmd = [parser.bin, abspath] @@ -514,7 +514,9 @@ class MTag(object): args = {"env": env, "timeout": parser.timeout, "kill": parser.kill} if parser.pri: - args["sin"] = json.dumps(oth_tags).encode("utf-8", "replace") + zd = oth_tags.copy() + zd.update(ret) + args["sin"] = json.dumps(zd).encode("utf-8", "replace") if WINDOWS: args["creationflags"] = 0x4000