mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
option to show upload timestamps in directory listing;
enable with -mte +.ip_at or volflag mte=+.ip_at worst-case performance impact: 18%
This commit is contained in:
parent
2048b7538e
commit
4b5a0787ab
|
@ -27,6 +27,8 @@ from .authsrv import expand_config_file, re_vol, split_cfg_ln, upgrade_cfg_fmt
|
|||
from .cfg import flagcats, onedash
|
||||
from .svchub import SvcHub
|
||||
from .util import (
|
||||
DEF_MTE,
|
||||
DEF_MTH,
|
||||
IMPLICATIONS,
|
||||
JINJA_VER,
|
||||
PYFTPD_VER,
|
||||
|
@ -1132,10 +1134,8 @@ def add_db_metadata(ap):
|
|||
ap2.add_argument("--mtag-v", action="store_true", help="verbose tag scanning; print errors from mtp subprocesses and such")
|
||||
ap2.add_argument("--mtag-vv", action="store_true", help="debug mtp settings and mutagen/ffprobe parsers")
|
||||
ap2.add_argument("-mtm", metavar="M=t,t,t", type=u, action="append", help="add/replace metadata mapping")
|
||||
ap2.add_argument("-mte", metavar="M,M,M", type=u, help="tags to index/display (comma-sep.)",
|
||||
default="circle,album,.tn,artist,title,.bpm,key,.dur,.q,.vq,.aq,vc,ac,fmt,res,.fps,ahash,vhash,up_ip,.up_at")
|
||||
ap2.add_argument("-mth", metavar="M,M,M", type=u, help="tags to hide by default (comma-sep.)",
|
||||
default=".vq,.aq,vc,ac,fmt,res,.fps")
|
||||
ap2.add_argument("-mte", metavar="M,M,M", type=u, help="tags to index/display (comma-sep.); either an entire replacement list, or add/remove stuff on the default-list with +foo or /bar", default=DEF_MTE)
|
||||
ap2.add_argument("-mth", metavar="M,M,M", type=u, help="tags to hide by default (comma-sep.); assign/add/remove same as -mte", default=DEF_MTH)
|
||||
ap2.add_argument("-mtp", metavar="M=[f,]BIN", type=u, action="append", help="read tag M using program BIN to parse the file")
|
||||
|
||||
|
||||
|
|
|
@ -21,11 +21,13 @@ from .util import (
|
|||
META_NOBOTS,
|
||||
SQLITE_VER,
|
||||
UNPLICATIONS,
|
||||
ODict,
|
||||
Pebkac,
|
||||
absreal,
|
||||
afsenc,
|
||||
get_df,
|
||||
humansize,
|
||||
odfusion,
|
||||
relchk,
|
||||
statdir,
|
||||
uncyg,
|
||||
|
@ -1477,13 +1479,14 @@ class AuthSrv(object):
|
|||
|
||||
# default tag cfgs if unset
|
||||
if "mte" not in vol.flags:
|
||||
vol.flags["mte"] = self.args.mte
|
||||
elif vol.flags["mte"].startswith("+"):
|
||||
vol.flags["mte"] = ",".join(
|
||||
x for x in [self.args.mte, vol.flags["mte"][1:]] if x
|
||||
)
|
||||
vol.flags["mte"] = self.args.mte.copy()
|
||||
else:
|
||||
vol.flags["mte"] = odfusion(self.args.mte, vol.flags["mte"])
|
||||
|
||||
if "mth" not in vol.flags:
|
||||
vol.flags["mth"] = self.args.mth
|
||||
vol.flags["mth"] = self.args.mth.copy()
|
||||
else:
|
||||
vol.flags["mth"] = odfusion(self.args.mth, vol.flags["mth"])
|
||||
|
||||
# append additive args from argv to volflags
|
||||
hooks = "xbu xau xiu xbr xar xbd xad xm xban".split()
|
||||
|
@ -1584,12 +1587,12 @@ class AuthSrv(object):
|
|||
if local:
|
||||
local_only_mtp[a] = True
|
||||
|
||||
local_mte = {}
|
||||
for a in vol.flags.get("mte", "").split(","):
|
||||
local_mte = ODict()
|
||||
for a in vol.flags.get("mte", {}).keys():
|
||||
local = True
|
||||
all_mte[a] = True
|
||||
local_mte[a] = True
|
||||
for b in self.args.mte.split(","):
|
||||
for b in self.args.mte.keys():
|
||||
if not a or not b:
|
||||
continue
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ from .util import (
|
|||
HTTPCODE,
|
||||
META_NOBOTS,
|
||||
MultipartParser,
|
||||
ODict,
|
||||
Pebkac,
|
||||
UnrecvEOF,
|
||||
absreal,
|
||||
|
@ -1971,8 +1972,7 @@ class HttpCli(object):
|
|||
self.log("q#: {} ({:.2f}s)".format(msg, idx.p_dur))
|
||||
|
||||
order = []
|
||||
cfg = self.args.mte.split(",")
|
||||
for t in cfg:
|
||||
for t in self.args.mte:
|
||||
if t in taglist:
|
||||
order.append(t)
|
||||
for t in taglist:
|
||||
|
@ -4051,6 +4051,9 @@ class HttpCli(object):
|
|||
ap = vn.canonical(rem)
|
||||
return self.tx_file(ap) # is no-cache
|
||||
|
||||
mte = vn.flags.get("mte", {})
|
||||
add_up_at = ".up_at" in mte
|
||||
is_admin = self.can_admin
|
||||
tagset: set[str] = set()
|
||||
for fe in files:
|
||||
fn = fe["name"]
|
||||
|
@ -4078,24 +4081,38 @@ class HttpCli(object):
|
|||
self.log(t.format(rd, fn, min_ex()))
|
||||
break
|
||||
|
||||
fe["tags"] = {k: v for k, v in r}
|
||||
tags = {k: v for k, v in r}
|
||||
|
||||
if self.can_admin:
|
||||
if is_admin:
|
||||
q = "select ip, at from up where rd=? and fn=?"
|
||||
try:
|
||||
zs1, zs2 = icur.execute(q, erd_efn).fetchone()
|
||||
fe["tags"]["up_ip"] = zs1
|
||||
fe["tags"][".up_at"] = zs2
|
||||
if zs1:
|
||||
tags["up_ip"] = zs1
|
||||
if zs2:
|
||||
tags[".up_at"] = zs2
|
||||
except:
|
||||
pass
|
||||
elif add_up_at:
|
||||
q = "select at from up where rd=? and fn=?"
|
||||
try:
|
||||
(zs1,) = icur.execute(q, erd_efn).fetchone()
|
||||
if zs1:
|
||||
tags[".up_at"] = zs1
|
||||
except:
|
||||
pass
|
||||
|
||||
_ = [tagset.add(k) for k in fe["tags"]]
|
||||
_ = [tagset.add(k) for k in tags]
|
||||
fe["tags"] = tags
|
||||
|
||||
if icur:
|
||||
mte = vn.flags.get("mte") or "up_ip,.up_at"
|
||||
taglist = [k for k in mte.split(",") if k in tagset]
|
||||
lmte = list(mte)
|
||||
if self.can_admin:
|
||||
lmte += ["up_ip", ".up_at"]
|
||||
|
||||
taglist = [k for k in lmte if k in tagset]
|
||||
for fe in dirs:
|
||||
fe["tags"] = {}
|
||||
fe["tags"] = ODict()
|
||||
else:
|
||||
taglist = list(tagset)
|
||||
|
||||
|
@ -4142,7 +4159,7 @@ class HttpCli(object):
|
|||
j2a["txt_ext"] = self.args.textfiles.replace(",", " ")
|
||||
|
||||
if "mth" in vn.flags:
|
||||
j2a["def_hcols"] = vn.flags["mth"].split(",")
|
||||
j2a["def_hcols"] = list(vn.flags["mth"])
|
||||
|
||||
html = self.j2s(tpl, **j2a)
|
||||
self.reply(html.encode("utf-8", "replace"))
|
||||
|
|
|
@ -39,13 +39,17 @@ from .util import (
|
|||
FFMPEG_URL,
|
||||
VERSIONS,
|
||||
Daemon,
|
||||
DEF_MTE,
|
||||
DEF_MTH,
|
||||
Garda,
|
||||
HLog,
|
||||
HMaccas,
|
||||
ODict,
|
||||
alltrace,
|
||||
ansi_re,
|
||||
min_ex,
|
||||
mp,
|
||||
odfusion,
|
||||
pybin,
|
||||
start_log_thrs,
|
||||
start_stackmon,
|
||||
|
@ -433,6 +437,12 @@ class SvcHub(object):
|
|||
zs = al.xff_src.replace(" ", "").replace(".", "\\.").replace(",", "|")
|
||||
al.xff_re = re.compile("^(?:" + zs + ")")
|
||||
|
||||
mte = ODict.fromkeys(DEF_MTE.split(","), True)
|
||||
al.mte = odfusion(mte, al.mte)
|
||||
|
||||
mth = ODict.fromkeys(DEF_MTH.split(","), True)
|
||||
al.mth = odfusion(mth, al.mth)
|
||||
|
||||
return True
|
||||
|
||||
def _setlimits(self) -> None:
|
||||
|
|
|
@ -642,10 +642,7 @@ class Up2k(object):
|
|||
if self.stop:
|
||||
break
|
||||
|
||||
en: set[str] = set()
|
||||
if "mte" in vol.flags:
|
||||
en = set(vol.flags["mte"].split(","))
|
||||
|
||||
en = set(vol.flags.get("mte", {}))
|
||||
self.entags[vol.realpath] = en
|
||||
|
||||
if "e2d" in vol.flags:
|
||||
|
|
|
@ -36,6 +36,14 @@ from .__version__ import S_BUILD_DT, S_VERSION
|
|||
from .stolen import surrogateescape
|
||||
|
||||
|
||||
if sys.version_info >= (3, 7) or (
|
||||
sys.version_info >= (3, 6) and platform.python_implementation() == "CPython"
|
||||
):
|
||||
ODict = dict
|
||||
else:
|
||||
from collections import OrderedDict as ODict
|
||||
|
||||
|
||||
def _ens(want: str) -> tuple[int, ...]:
|
||||
ret: list[int] = []
|
||||
for v in want.split():
|
||||
|
@ -261,6 +269,11 @@ EXTS["vnd.mozilla.apng"] = "png"
|
|||
MAGIC_MAP = {"jpeg": "jpg"}
|
||||
|
||||
|
||||
DEF_MTE = "circle,album,.tn,artist,title,.bpm,key,.dur,.q,.vq,.aq,vc,ac,fmt,res,.fps,ahash,vhash"
|
||||
|
||||
DEF_MTH = ".vq,.aq,vc,ac,fmt,res,.fps"
|
||||
|
||||
|
||||
REKOBO_KEY = {
|
||||
v: ln.split(" ", 1)[0]
|
||||
for ln in """
|
||||
|
@ -1774,6 +1787,21 @@ def exclude_dotfiles(filepaths: list[str]) -> list[str]:
|
|||
return [x for x in filepaths if not x.split("/")[-1].startswith(".")]
|
||||
|
||||
|
||||
def odfusion(base: ODict[str, bool], oth: str) -> ODict[str, bool]:
|
||||
# merge an "ordered set" (just a dict really) with another list of keys
|
||||
ret = base.copy()
|
||||
if oth.startswith("+"):
|
||||
for k in oth[1:].split(","):
|
||||
ret[k] = True
|
||||
elif oth[:1] in ("-", "/"):
|
||||
for k in oth[1:].split(","):
|
||||
ret.pop(k, None)
|
||||
else:
|
||||
ret = ODict.fromkeys(oth.split(","), True)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def ipnorm(ip: str) -> str:
|
||||
if ":" in ip:
|
||||
# assume /64 clients; drop 4 groups
|
||||
|
|
Loading…
Reference in a new issue