mirror of
https://github.com/9001/copyparty.git
synced 2025-11-24 07:23:22 -07:00
WIP cbz browsing
This commit is contained in:
parent
2ce32e4fb6
commit
076bf52c13
|
|
@ -1516,6 +1516,7 @@ def add_optouts(ap):
|
|||
ap2.add_argument("--no-pipe", action="store_true", help="disable race-the-beam (lockstep download of files which are currently being uploaded) (volflag=nopipe)")
|
||||
ap2.add_argument("--no-tail", action="store_true", help="disable streaming a growing files with ?tail (volflag=notail)")
|
||||
ap2.add_argument("--no-db-ip", action="store_true", help="do not write uploader-IP into the database; will also disable unpost, you may want \033[32m--forget-ip\033[0m instead (volflag=no_db_ip)")
|
||||
ap2.add_argument("--no-zls", action="store_true", help="disable browsing the contents of zip/cbz files, does not affect thumbnails")
|
||||
|
||||
|
||||
def add_safety(ap):
|
||||
|
|
|
|||
|
|
@ -1519,6 +1519,74 @@ 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 = [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)
|
||||
with zf.open(zi, "r") as fi:
|
||||
self.send_headers(length=zi.file_size, mime=guess_mime(inner_path))
|
||||
|
||||
remains = 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,
|
||||
{},
|
||||
"",
|
||||
)
|
||||
# fd, ret = tempfile.mkstemp("." + inner_path.rsplit(".", 1)[0])
|
||||
# fsz = 0
|
||||
# with os.fdopen(fd, "wb") as fo:
|
||||
#
|
||||
# while True:
|
||||
# buf = fi.read(32768)
|
||||
# if not buf:
|
||||
# break
|
||||
#
|
||||
# fsz += len(buf)
|
||||
# if fsz > maxsz:
|
||||
# raise Exception("zipbomb defused")
|
||||
#
|
||||
# fo.write(buf)
|
||||
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))
|
||||
|
|
@ -6478,6 +6546,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
|
||||
|
|
@ -6576,6 +6649,7 @@ class HttpCli(object):
|
|||
"taglist": [],
|
||||
"have_tags_idx": int(e2t),
|
||||
"have_b_u": (self.can_write and self.uparam.get("b") == "u"),
|
||||
"have_zls": int(not self.args.no_zls),
|
||||
"sb_lg": vn.js_ls["sb_lg"],
|
||||
"url_suf": url_suf,
|
||||
"title": html_escape("%s %s" % (self.args.bname, self.vpath), crlf=True),
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ window.baguetteBox = (function () {
|
|||
scrollTimer = 0,
|
||||
re_i = /^[^?]+\.(a?png|avif|bmp|gif|heif|jpe?g|jfif|svg|webp)(\?|$)/i,
|
||||
re_v = /^[^?]+\.(webm|mkv|mp4|m4v|mov)(\?|$)/i,
|
||||
re_cbz = /^[^?]+\.(cbz)(\?|$)/i,
|
||||
cbz_pics = ["png", "jpg", "jpeg", "gif", "bmp", "tga", "tif", "tiff", "webp", "avif"],
|
||||
anims = ['slideIn', 'fadeIn', 'none'],
|
||||
data = {}, // all galleries
|
||||
imagesElements = [],
|
||||
|
|
@ -147,6 +149,8 @@ window.baguetteBox = (function () {
|
|||
tagsNodeList = [galleryElement];
|
||||
else
|
||||
tagsNodeList = galleryElement.getElementsByTagName('a');
|
||||
if (have_zls)
|
||||
bindCbzClickListeners(tagsNodeList, userOptions);
|
||||
|
||||
tagsNodeList = [].filter.call(tagsNodeList, function (element) {
|
||||
if (element.className.indexOf(userOptions && userOptions.ignoreClass) === -1)
|
||||
|
|
@ -178,6 +182,62 @@ window.baguetteBox = (function () {
|
|||
return [selectorData.galleries, options];
|
||||
}
|
||||
|
||||
function bindCbzClickListeners(tagsNodeList, userOptions) {
|
||||
var cbzNodes = [].filter.call(tagsNodeList, function (element) {
|
||||
return re_cbz.test(element.href);
|
||||
});
|
||||
if (!tagsNodeList.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
[].forEach.call(cbzNodes, function (cbzElement, index) {
|
||||
var gallery = [];
|
||||
var eventHandler = function (e) {
|
||||
if (ctrl(e) || e && e.shiftKey)
|
||||
return true;
|
||||
|
||||
e.preventDefault ? e.preventDefault() : e.returnValue = false;
|
||||
fillCbzGallery(gallery, cbzElement, eventHandler).then(() => {
|
||||
console.log("starting prepare")
|
||||
prepareOverlay(gallery, userOptions);
|
||||
console.log("prepare done, starting show")
|
||||
showOverlay(0);
|
||||
});
|
||||
}
|
||||
|
||||
bind(cbzElement, "click", eventHandler);
|
||||
})
|
||||
}
|
||||
|
||||
function fillCbzGallery(gallery, cbzElement, eventHandler) {
|
||||
var href = cbzElement.href
|
||||
var zlsHref = href + (href.indexOf("?") === -1 ? "?" : "&") + "zls";
|
||||
console.log("pre-fetch")
|
||||
return fetch(zlsHref).then(response => response.json())
|
||||
.then((fileList) => {
|
||||
console.log("fetched")
|
||||
var imagesList = fileList.filter((name) =>
|
||||
name.indexOf(".") !== -1
|
||||
&& cbz_pics.indexOf(name.split(".").pop()) !== -1
|
||||
).sort();
|
||||
|
||||
imagesList.forEach((imageName) => {
|
||||
var imageHref = href
|
||||
+ (href.indexOf("?") === -1 ? "?" : "&")
|
||||
+ "zget="
|
||||
+ encodeURIComponent(imageName);
|
||||
|
||||
var galleryItem = {
|
||||
href: imageHref,
|
||||
imageElement: cbzElement,
|
||||
eventHandler: eventHandler,
|
||||
};
|
||||
gallery.push(galleryItem);
|
||||
});
|
||||
console.log(gallery);
|
||||
});
|
||||
}
|
||||
|
||||
function clearCachedData() {
|
||||
for (var selector in data)
|
||||
if (data.hasOwnProperty(selector))
|
||||
|
|
@ -786,7 +846,7 @@ window.baguetteBox = (function () {
|
|||
imageContainer.removeChild(imageContainer.firstChild);
|
||||
|
||||
var imageElement = galleryItem.imageElement,
|
||||
imageSrc = imageElement.href,
|
||||
imageSrc = galleryItem.href || imageElement.href,
|
||||
is_vid = re_v.test(imageSrc),
|
||||
thumbnailElement = imageElement.querySelector('img, video'),
|
||||
imageCaption = typeof options.captions === 'function' ?
|
||||
|
|
|
|||
|
|
@ -139,7 +139,8 @@
|
|||
have_tags_idx = {{ have_tags_idx }},
|
||||
sb_lg = "{{ sb_lg }}",
|
||||
logues = {{ logues|tojson if sb_lg else "[]" }},
|
||||
ls0 = {{ ls0|tojson }};
|
||||
ls0 = {{ ls0|tojson }},
|
||||
have_zls = {{ have_zls }};
|
||||
|
||||
var STG = window.localStorage;
|
||||
document.documentElement.className = (STG && STG.cpp_thm) || dtheme;
|
||||
|
|
|
|||
|
|
@ -17565,7 +17565,9 @@ var thegrid = (function () {
|
|||
esc(uricom_dec(h.split('/').pop())) + '</a>';
|
||||
},
|
||||
onChange: function (i) {
|
||||
sethash('g' + r.bbox[i].imageElement.getAttribute('ref') + getsort());
|
||||
if (r.bbox[i]) {
|
||||
sethash('g' + r.bbox[i].imageElement.getAttribute('ref') + getsort());
|
||||
}
|
||||
}
|
||||
});
|
||||
r.bbox = br[0][0];
|
||||
|
|
|
|||
Loading…
Reference in a new issue