From 5e3775c1afc9438f9930080a9b8542a063ba1765 Mon Sep 17 00:00:00 2001 From: ed Date: Sun, 21 Feb 2021 02:07:34 +0000 Subject: [PATCH] fuse.py prefers ?ls if available --- bin/copyparty-fuse.py | 39 ++++++++++++++++++++++++++++++++++----- copyparty/httpcli.py | 4 ++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/bin/copyparty-fuse.py b/bin/copyparty-fuse.py index 2eb9b9fd..9967881f 100755 --- a/bin/copyparty-fuse.py +++ b/bin/copyparty-fuse.py @@ -33,6 +33,7 @@ import re import os import sys import time +import json import stat import errno import struct @@ -323,7 +324,7 @@ class Gateway(object): if bad_good: path = dewin(path) - web_path = self.quotep("/" + "/".join([self.web_root, path])) + "?dots" + web_path = self.quotep("/" + "/".join([self.web_root, path])) + "?dots&ls" r = self.sendreq("GET", web_path) if r.status != 200: self.closeconn() @@ -334,12 +335,17 @@ class Gateway(object): ) raise FuseOSError(errno.ENOENT) - if not r.getheader("Content-Type", "").startswith("text/html"): + ctype = r.getheader("Content-Type", "") + if ctype == "application/json": + parser = self.parse_jls + elif ctype.startswith("text/html"): + parser = self.parse_html + else: log("listdir on file: {}".format(path)) raise FuseOSError(errno.ENOENT) try: - return self.parse_html(r) + return parser(r) except: info(repr(path) + "\n" + traceback.format_exc()) raise @@ -367,6 +373,29 @@ class Gateway(object): return r.read() + def parse_jls(self, datasrc): + rsp = b"" + while True: + buf = datasrc.read(1024 * 32) + if not buf: + break + + rsp += buf + + rsp = json.loads(rsp.decode("utf-8")) + ret = [] + for is_dir, nodes in [[True, rsp["dirs"]], [False, rsp["files"]]]: + for n in nodes: + fname = unquote(n["href"]).rstrip(b"/") + fname = fname.decode("wtf-8") + if bad_good: + fname = enwin(fname) + + fun = self.stat_dir if is_dir else self.stat_file + ret.append([fname, fun(n["ts"], n["sz"]), 0]) + + return ret + def parse_html(self, datasrc): ret = [] remainder = b"" @@ -818,9 +847,9 @@ class CPPF(Operations): return cache_stat fun = info - if MACOS and path.split('/')[-1].startswith('._'): + if MACOS and path.split("/")[-1].startswith("._"): fun = dbg - + fun("=ENOENT ({})".format(hexler(path))) raise FuseOSError(errno.ENOENT) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 0f0b0d09..6fe2376a 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -1084,7 +1084,7 @@ class HttpCli(object): ret = self.gen_tree(top, dst) ret = json.dumps(ret) - self.reply(ret.encode("utf-8")) + self.reply(ret.encode("utf-8"), mime="application/json") return True def gen_tree(self, top, target): @@ -1270,7 +1270,7 @@ class HttpCli(object): if is_ls: [x.pop("name") for y in [dirs, files] for x in y] ret = json.dumps({"dirs": dirs, "files": files, "srvinf": srv_info}) - self.reply(ret.encode("utf-8", "replace")) + self.reply(ret.encode("utf-8", "replace"), mime="application/json") return True logues = [None, None]