add timeouts for mtp calls

This commit is contained in:
ed 2021-03-19 21:22:56 +01:00
parent 6599c3eced
commit c0e31851da
3 changed files with 33 additions and 11 deletions

View file

@ -129,11 +129,11 @@ see the beautiful mess of a dictionary in [mtag.py](https://github.com/9001/copy
## file parser plugins
copyparty can invoke external programs to collect additional metadata for files using `mtp` (as argument or volume flag)
copyparty can invoke external programs to collect additional metadata for files using `mtp` (as argument or volume flag), there is a default timeout of 30sec
* `-mtp key=~/bin/audio-key.py` will execute `~/bin/audio-key.py` with filename as argument 1 to provide the `key` tag if that does not exist in the audio metadata
* `-mtp .bpm=f,~/bin/audio-bpm.py` replaces (`f,`) any existing `.bpm` tag using the `~/bin/audio-bpm.py` program
* `-v ~/music::r:cmtp=key=~/bin/audio-key.py:cmtp=.bpm=f,~/bin/audio-bpm.py` both as a per-volume config wow this is getting ugly
* `-mtp .bpm=~/bin/audio-bpm.py` will execute `~/bin/audio-bpm.py` with the audio file as argument 1 to provide the `.bpm` tag, if that does not exist in the audio metadata
* `-mtp key=f,t5,~/bin/audio-key.py` uses `~/bin/audio-key.py` to get the `key` tag, replacing any existing metadata tag (`f,`), aborting if it takes longer than 5sec (`t5,`)
* `-v ~/music::r:cmtp=.bpm=~/bin/audio-bpm.py:cmtp=key=f,t5,~/bin/audio-key.py` both as a per-volume config wow this is getting ugly
# client examples

View file

@ -321,12 +321,11 @@ class MTag(object):
env["PYTHONPATH"] = pypath
ret = {}
for tagname, binpath in parsers.items():
for tagname, (binpath, timeout) in parsers.items():
try:
binpath = os.path.expanduser(binpath)
cmd = [sys.executable, binpath, abspath]
cmd = [fsenc(x) for x in cmd]
v = sp.check_output(cmd, env=env).strip()
v = sp.check_output(cmd, env=env, timeout=timeout).strip()
if v:
ret[tagname] = v.decode("utf-8")
except:

View file

@ -506,14 +506,37 @@ class Up2k(object):
sz0 = os.path.getsize(db_path)
force = {}
timeout = {}
parsers = {}
for parser in self.flags[ptop]["mtp"]:
orig = parser
tag, parser = parser.split("=", 1)
if parser.lower().startswith("f,"):
parser = parser[2:]
force[tag] = True
while True:
try:
bp = os.path.expanduser(parser)
if os.path.exists(bp):
parsers[tag] = [bp, timeout.get(tag, 30)]
break
except:
pass
parsers[tag] = parser
try:
arg, parser = parser.split(",", 1)
arg = arg.lower()
if arg == "f":
force[tag] = True
continue
if arg.startswith("t"):
timeout[tag] = int(arg[1:])
continue
raise Exception()
except:
self.log("invalid argument: " + orig, 1)
return
q = "select count(w) from mt where k = 't:mtp'"
with self.mutex: