mirror of
https://github.com/9001/copyparty.git
synced 2026-03-31 12:33:05 +10:00
view .cbz in browser (#916)
adds functionality to allow browsing .cbz directly in the browser, without downloading them and using a separate program. meant for quickly inspecting the contents, less so for reading. adds two new api calls, ?zls and ?zget, which return a file listing of a zip file and a specific file in the archive, respectively. uses the zipfile module, so no support for .cbr etc
This commit is contained in:
@@ -1521,6 +1521,63 @@ class HttpCli(object):
|
||||
self.log("rss: %d hits, %d bytes" % (len(hits), len(bret)))
|
||||
return True
|
||||
|
||||
def tx_zls(self, abspath) -> bool:
|
||||
if self.do_log:
|
||||
self.log("zls %s @%s" % (self.req, self.uname))
|
||||
if self.args.no_zls:
|
||||
raise Pebkac(405, "zip browsing is disabled in server config")
|
||||
|
||||
import zipfile
|
||||
|
||||
try:
|
||||
with zipfile.ZipFile(abspath, "r") as zf:
|
||||
filelist = [{"fn": f.filename} for f in zf.infolist()]
|
||||
ret = json.dumps(filelist).encode("utf-8", "replace")
|
||||
self.reply(ret, mime="application/json")
|
||||
return True
|
||||
except (zipfile.BadZipfile, RuntimeError):
|
||||
raise Pebkac(404, "requested file is not a valid zip file")
|
||||
|
||||
def tx_zget(self, abspath) -> bool:
|
||||
maxsz = 1024 * 1024 * 64
|
||||
|
||||
inner_path = self.uparam.get("zget")
|
||||
if not inner_path:
|
||||
raise Pebkac(405, "inner path is required")
|
||||
if self.do_log:
|
||||
self.log(
|
||||
"zget %s \033[35m%s\033[0m @%s" % (self.req, inner_path, self.uname)
|
||||
)
|
||||
if self.args.no_zls:
|
||||
raise Pebkac(405, "zip browsing is disabled in server config")
|
||||
|
||||
import zipfile
|
||||
|
||||
try:
|
||||
with zipfile.ZipFile(abspath, "r") as zf:
|
||||
zi = zf.getinfo(inner_path)
|
||||
if zi.file_size >= maxsz:
|
||||
raise Pebkac(404, "zip bomb defused")
|
||||
with zf.open(zi, "r") as fi:
|
||||
self.send_headers(length=zi.file_size, mime=guess_mime(inner_path))
|
||||
|
||||
sendfile_py(
|
||||
self.log,
|
||||
0,
|
||||
zi.file_size,
|
||||
fi,
|
||||
self.s,
|
||||
self.args.s_wr_sz,
|
||||
self.args.s_wr_slp,
|
||||
not self.args.no_poll,
|
||||
{},
|
||||
"",
|
||||
)
|
||||
except KeyError:
|
||||
raise Pebkac(404, "no such file in archive")
|
||||
except (zipfile.BadZipfile, RuntimeError):
|
||||
raise Pebkac(404, "requested file is not a valid zip file")
|
||||
|
||||
def handle_propfind(self) -> bool:
|
||||
if self.do_log:
|
||||
self.log("PFIND %s @%s" % (self.req, self.uname))
|
||||
@@ -6480,6 +6537,11 @@ class HttpCli(object):
|
||||
):
|
||||
return self.tx_md(vn, abspath)
|
||||
|
||||
if "zls" in self.uparam:
|
||||
return self.tx_zls(abspath)
|
||||
if "zget" in self.uparam:
|
||||
return self.tx_zget(abspath)
|
||||
|
||||
if not add_og or not og_fn:
|
||||
return self.tx_file(
|
||||
abspath, None if st.st_size or "nopipe" in vn.flags else vn.realpath
|
||||
@@ -6569,6 +6631,7 @@ class HttpCli(object):
|
||||
"acct": self.uname,
|
||||
"perms": perms,
|
||||
}
|
||||
# also see `js_htm` in authsrv.py
|
||||
j2a = {
|
||||
"cgv1": vn.js_htm,
|
||||
"cgv": cgv,
|
||||
|
||||
Reference in New Issue
Block a user