mirror of
https://github.com/9001/copyparty.git
synced 2026-04-12 23:32:32 -06:00
thumbs: fix th=x on non-jxl-capable servers;
if FFmpeg was compiled without jxl support, then every request for a jxl thumbnail would result in a placeholder svg detect this and switch to webp as fallback; the initial request will still fail but successive ones are fine closes #1333, closes #1372
This commit is contained in:
parent
bbe58105e7
commit
1afe48b85d
|
|
@ -146,21 +146,17 @@ class BrokerMp(object):
|
||||||
returns a Queue object which eventually contains the response if want_retval
|
returns a Queue object which eventually contains the response if want_retval
|
||||||
(not-impl here since nothing uses it yet)
|
(not-impl here since nothing uses it yet)
|
||||||
"""
|
"""
|
||||||
|
if dest.startswith("httpsrv."):
|
||||||
if dest == "httpsrv.listen":
|
if dest == "httpsrv.listen":
|
||||||
for p in self.procs:
|
for p in self.procs:
|
||||||
p.q_pend.put((0, dest, [args[0], len(self.procs)]))
|
p.q_pend.put((0, dest, [args[0], len(self.procs)]))
|
||||||
|
else:
|
||||||
elif dest == "httpsrv.set_netdevs":
|
|
||||||
for p in self.procs:
|
for p in self.procs:
|
||||||
p.q_pend.put((0, dest, list(args)))
|
p.q_pend.put((0, dest, list(args)))
|
||||||
|
|
||||||
elif dest == "cb_httpsrv_up":
|
elif dest == "cb_httpsrv_up":
|
||||||
self.hub.cb_httpsrv_up()
|
self.hub.cb_httpsrv_up()
|
||||||
|
|
||||||
elif dest == "httpsrv.set_bad_ver":
|
|
||||||
for p in self.procs:
|
|
||||||
p.q_pend.put((0, dest, list(args)))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("what is " + str(dest))
|
raise Exception("what is " + str(dest))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,12 +58,7 @@ class BrokerThr(BrokerCli):
|
||||||
self.httpsrv.listen(args[0], 1)
|
self.httpsrv.listen(args[0], 1)
|
||||||
return
|
return
|
||||||
|
|
||||||
if dest == "httpsrv.set_netdevs":
|
getattr(self.httpsrv, dest[8:])(*args)
|
||||||
self.httpsrv.set_netdevs(args[0])
|
|
||||||
return
|
|
||||||
|
|
||||||
if dest == "httpsrv.set_bad_ver":
|
|
||||||
self.httpsrv.set_bad_ver()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# new ipc invoking managed service in hub
|
# new ipc invoking managed service in hub
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ class HttpCli(object):
|
||||||
self.E: EnvParams = self.args.E
|
self.E: EnvParams = self.args.E
|
||||||
self.asrv = conn.asrv # mypy404
|
self.asrv = conn.asrv # mypy404
|
||||||
self.ico = conn.ico # mypy404
|
self.ico = conn.ico # mypy404
|
||||||
self.thumbcli = conn.thumbcli # mypy404
|
self.thumbcli = conn.hsrv.thumbcli
|
||||||
self.u2fh = conn.u2fh # mypy404
|
self.u2fh = conn.u2fh # mypy404
|
||||||
self.pipes = conn.pipes # mypy404
|
self.pipes = conn.pipes # mypy404
|
||||||
self.log_func = conn.log_func # mypy404
|
self.log_func = conn.log_func # mypy404
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,6 @@ class HttpConn(object):
|
||||||
self.bans: dict[str, int] = hsrv.bans
|
self.bans: dict[str, int] = hsrv.bans
|
||||||
self.aclose: dict[str, int] = hsrv.aclose
|
self.aclose: dict[str, int] = hsrv.aclose
|
||||||
|
|
||||||
enth = (HAVE_PIL or HAVE_VIPS or HAVE_FFMPEG) and not self.args.no_thumb
|
|
||||||
self.thumbcli: Optional[ThumbCli] = ThumbCli(hsrv) if enth else None # mypy404
|
|
||||||
self.ico: Ico = Ico(self.args) # mypy404
|
self.ico: Ico = Ico(self.args) # mypy404
|
||||||
|
|
||||||
self.t0: float = time.time() # mypy404
|
self.t0: float = time.time() # mypy404
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,9 @@ except SyntaxError:
|
||||||
|
|
||||||
from .httpconn import HttpConn
|
from .httpconn import HttpConn
|
||||||
from .metrics import Metrics
|
from .metrics import Metrics
|
||||||
|
from .mtag import HAVE_FFMPEG
|
||||||
|
from .th_cli import ThumbCli
|
||||||
|
from .th_srv import HAVE_PIL, HAVE_VIPS
|
||||||
from .u2idx import U2idx
|
from .u2idx import U2idx
|
||||||
from .util import (
|
from .util import (
|
||||||
E_SCK,
|
E_SCK,
|
||||||
|
|
@ -133,6 +136,8 @@ class HttpSrv(object):
|
||||||
self.bans: dict[str, int] = {}
|
self.bans: dict[str, int] = {}
|
||||||
self.aclose: dict[str, int] = {}
|
self.aclose: dict[str, int] = {}
|
||||||
|
|
||||||
|
self.thumbcli: Optional[ThumbCli] = None
|
||||||
|
|
||||||
dli: dict[str, tuple[float, int, "VFS", str, str]] = {} # info
|
dli: dict[str, tuple[float, int, "VFS", str, str]] = {} # info
|
||||||
dls: dict[str, tuple[float, int]] = {} # state
|
dls: dict[str, tuple[float, int]] = {} # state
|
||||||
self.dli = self.tdli = dli
|
self.dli = self.tdli = dli
|
||||||
|
|
@ -230,16 +235,20 @@ class HttpSrv(object):
|
||||||
if self.args.log_thrs:
|
if self.args.log_thrs:
|
||||||
start_log_thrs(self.log, self.args.log_thrs, nid)
|
start_log_thrs(self.log, self.args.log_thrs, nid)
|
||||||
|
|
||||||
self.th_cfg: dict[str, set[str]] = {}
|
if (HAVE_PIL or HAVE_VIPS or HAVE_FFMPEG) and not self.args.no_thumb:
|
||||||
Daemon(self.post_init, "hsrv-init2")
|
Daemon(self.post_init, "hsrv-init2")
|
||||||
|
|
||||||
def post_init(self) -> None:
|
def post_init(self) -> None:
|
||||||
try:
|
try:
|
||||||
x = self.broker.ask("thumbsrv.getcfg")
|
x = self.broker.ask("thumbsrv.getcfg")
|
||||||
self.th_cfg = x.get()
|
self.thumbcli = ThumbCli(self, x.get())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def set_th_cfg(self, c: dict[str, set[str]], opts: tuple[bool]) -> None:
|
||||||
|
self.args.th_no_jxl = opts[0]
|
||||||
|
self.thumbcli = ThumbCli(self, c)
|
||||||
|
|
||||||
def set_bad_ver(self) -> None:
|
def set_bad_ver(self) -> None:
|
||||||
self.bad_ver = True
|
self.bad_ver = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ IMG_EXTS = set(["webp", "jpg", "png", "jxl"])
|
||||||
|
|
||||||
|
|
||||||
class ThumbCli(object):
|
class ThumbCli(object):
|
||||||
def __init__(self, hsrv: "HttpSrv") -> None:
|
def __init__(self, hsrv: "HttpSrv", c: dict[str, set[str]]) -> None:
|
||||||
self.broker = hsrv.broker
|
self.broker = hsrv.broker
|
||||||
self.log_func = hsrv.log
|
self.log_func = hsrv.log
|
||||||
self.args = hsrv.args
|
self.args = hsrv.args
|
||||||
|
|
@ -33,16 +33,6 @@ class ThumbCli(object):
|
||||||
# cache on both sides for less broker spam
|
# cache on both sides for less broker spam
|
||||||
self.cooldown = Cooldown(self.args.th_poke)
|
self.cooldown = Cooldown(self.args.th_poke)
|
||||||
|
|
||||||
try:
|
|
||||||
c = hsrv.th_cfg
|
|
||||||
if not c:
|
|
||||||
raise Exception()
|
|
||||||
except:
|
|
||||||
c = {
|
|
||||||
k: set()
|
|
||||||
for k in ["thumbable", "pil", "vips", "raw", "ffi", "ffv", "ffa"]
|
|
||||||
}
|
|
||||||
|
|
||||||
self.thumbable = c["thumbable"]
|
self.thumbable = c["thumbable"]
|
||||||
self.fmt_pil = c["pil"]
|
self.fmt_pil = c["pil"]
|
||||||
self.fmt_vips = c["vips"]
|
self.fmt_vips = c["vips"]
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,10 @@ class ThumbSrv(object):
|
||||||
self.fmt_pil.discard(f)
|
self.fmt_pil.discard(f)
|
||||||
|
|
||||||
self.thumbable: set[str] = set()
|
self.thumbable: set[str] = set()
|
||||||
|
self._build_thumbable()
|
||||||
|
|
||||||
|
def _build_thumbable(self) -> None:
|
||||||
|
self.thumbable.clear()
|
||||||
|
|
||||||
if "pil" in self.args.th_dec:
|
if "pil" in self.args.th_dec:
|
||||||
self.thumbable |= self.fmt_pil
|
self.thumbable |= self.fmt_pil
|
||||||
|
|
@ -417,6 +421,10 @@ class ThumbSrv(object):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _rebuild_thumbable(self) -> None:
|
||||||
|
self._build_thumbable()
|
||||||
|
self.hub.broker.say("httpsrv.set_th_cfg", self.getcfg(), (self.args.th_no_jxl,))
|
||||||
|
|
||||||
def getcfg(self) -> dict[str, set[str]]:
|
def getcfg(self) -> dict[str, set[str]]:
|
||||||
return {
|
return {
|
||||||
"thumbable": self.thumbable,
|
"thumbable": self.thumbable,
|
||||||
|
|
@ -834,6 +842,21 @@ class ThumbSrv(object):
|
||||||
ret = 321
|
ret = 321
|
||||||
c = 3
|
c = 3
|
||||||
|
|
||||||
|
elif cmd[-1].lower().endswith(b".jxl") and (
|
||||||
|
"Error selecting an encoder" in serr
|
||||||
|
or "Automatic encoder selection failed" in serr
|
||||||
|
or "Default encoder for format webp" in serr
|
||||||
|
or "Unrecognized option 'effort:v" in serr
|
||||||
|
or "Please choose an encoder manually" in serr
|
||||||
|
):
|
||||||
|
self.args.th_no_jxl = True
|
||||||
|
self.fmt_ffi.discard("jxl")
|
||||||
|
self.fmt_ffv.discard("jxl")
|
||||||
|
self._rebuild_thumbable()
|
||||||
|
t = "FFmpeg failed because it was compiled without jpegxl; enabling --th-no-jxl to force webp output:\n"
|
||||||
|
ret = 321
|
||||||
|
c = 1
|
||||||
|
|
||||||
elif (
|
elif (
|
||||||
(not self.args.th_ff_jpg or time.time() - int(self.args.th_ff_jpg) < 60)
|
(not self.args.th_ff_jpg or time.time() - int(self.args.th_ff_jpg) < 60)
|
||||||
and cmd[-1].lower().endswith(b".webp")
|
and cmd[-1].lower().endswith(b".webp")
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,7 @@ class VHttpSrv(object):
|
||||||
self.g403 = Garda("")
|
self.g403 = Garda("")
|
||||||
self.gurl = Garda("")
|
self.gurl = Garda("")
|
||||||
|
|
||||||
|
self.thumbcli = None
|
||||||
self.u2idx = None
|
self.u2idx = None
|
||||||
|
|
||||||
def cachebuster(self):
|
def cachebuster(self):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue