button to abort copy/move; closes #572

This commit is contained in:
ed 2025-08-12 21:46:42 +00:00
parent c9fd608732
commit 715d374ee4
7 changed files with 78 additions and 10 deletions

View file

@ -1319,6 +1319,7 @@ def add_optouts(ap):
ap2.add_argument("--no-del", action="store_true", help="disable delete operations") ap2.add_argument("--no-del", action="store_true", help="disable delete operations")
ap2.add_argument("--no-mv", action="store_true", help="disable move/rename operations") ap2.add_argument("--no-mv", action="store_true", help="disable move/rename operations")
ap2.add_argument("--no-cp", action="store_true", help="disable copy operations") ap2.add_argument("--no-cp", action="store_true", help="disable copy operations")
ap2.add_argument("--no-fs-abrt", action="store_true", help="disable ability to abort ongoing copy/move")
ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show \033[33m--name\033[0m in <title>") ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show \033[33m--name\033[0m in <title>")
ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI") ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI")
ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI") ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI")

View file

@ -1987,6 +1987,9 @@ class HttpCli(object):
if "eshare" in self.uparam: if "eshare" in self.uparam:
return self.handle_eshare() return self.handle_eshare()
if "fs_abrt" in self.uparam:
return self.handle_fs_abrt()
if "application/octet-stream" in ctype: if "application/octet-stream" in ctype:
return self.handle_post_binary() return self.handle_post_binary()
@ -5958,7 +5961,9 @@ class HttpCli(object):
self.asrv.vfs.get(vdst, self.uname, False, True, False, True) self.asrv.vfs.get(vdst, self.uname, False, True, False, True)
wunlink(self.log, dabs, dvn.flags) wunlink(self.log, dabs, dvn.flags)
x = self.conn.hsrv.broker.ask("up2k.handle_mv", self.uname, self.ip, vsrc, vdst) x = self.conn.hsrv.broker.ask(
"up2k.handle_mv", self.ouparam.get("akey"), self.uname, self.ip, vsrc, vdst
)
self.loud_reply(x.get(), status=201) self.loud_reply(x.get(), status=201)
return True return True
@ -5988,10 +5993,21 @@ class HttpCli(object):
self.asrv.vfs.get(vdst, self.uname, False, True, False, True) self.asrv.vfs.get(vdst, self.uname, False, True, False, True)
wunlink(self.log, dabs, dvn.flags) wunlink(self.log, dabs, dvn.flags)
x = self.conn.hsrv.broker.ask("up2k.handle_cp", self.uname, self.ip, vsrc, vdst) x = self.conn.hsrv.broker.ask(
"up2k.handle_cp", self.ouparam.get("akey"), self.uname, self.ip, vsrc, vdst
)
self.loud_reply(x.get(), status=201) self.loud_reply(x.get(), status=201)
return True return True
def handle_fs_abrt(self):
if self.args.no_fs_abrt:
t = "aborting an ongoing copy/move is disabled in server config"
raise Pebkac(403, t)
self.conn.hsrv.broker.say("up2k.handle_fs_abrt", self.uparam["fs_abrt"])
self.loud_reply("aborting", status=200)
return True
def tx_ls(self, ls: dict[str, Any]) -> bool: def tx_ls(self, ls: dict[str, Any]) -> bool:
dirs = ls["dirs"] dirs = ls["dirs"]
files = ls["files"] files = ls["files"]

View file

@ -39,9 +39,9 @@ from .th_srv import (
HAVE_FFPROBE, HAVE_FFPROBE,
HAVE_HEIF, HAVE_HEIF,
HAVE_PIL, HAVE_PIL,
HAVE_RAW,
HAVE_VIPS, HAVE_VIPS,
HAVE_WEBP, HAVE_WEBP,
HAVE_RAW,
ThumbSrv, ThumbSrv,
) )
from .up2k import Up2k from .up2k import Up2k

View file

@ -144,6 +144,7 @@ class Up2k(object):
self.salt = self.args.warksalt self.salt = self.args.warksalt
self.r_hash = re.compile("^[0-9a-zA-Z_-]{44}$") self.r_hash = re.compile("^[0-9a-zA-Z_-]{44}$")
self.abrt_key = ""
self.gid = 0 self.gid = 0
self.gt0 = 0 self.gt0 = 0
@ -3988,6 +3989,9 @@ class Up2k(object):
except: except:
pass pass
def handle_fs_abrt(self, akey: str) -> None:
self.abrt_key = akey
def handle_rm( def handle_rm(
self, self,
uname: str, uname: str,
@ -4197,7 +4201,7 @@ class Up2k(object):
return n_files, ok + ok2, ng + ng2 return n_files, ok + ok2, ng + ng2
def handle_cp(self, uname: str, ip: str, svp: str, dvp: str) -> str: def handle_cp(self, abrt: str, uname: str, ip: str, svp: str, dvp: str) -> str:
if svp == dvp or dvp.startswith(svp + "/"): if svp == dvp or dvp.startswith(svp + "/"):
raise Pebkac(400, "cp: cannot copy parent into subfolder") raise Pebkac(400, "cp: cannot copy parent into subfolder")
@ -4244,6 +4248,8 @@ class Up2k(object):
dvpf = dvp + svpf[len(svp) :] dvpf = dvp + svpf[len(svp) :]
self._cp_file(uname, ip, svpf, dvpf, curs) self._cp_file(uname, ip, svpf, dvpf, curs)
if abrt and abrt == self.abrt_key:
raise Pebkac(400, "filecopy aborted by http-api")
for v in curs: for v in curs:
v.connection.commit() v.connection.commit()
@ -4411,7 +4417,7 @@ class Up2k(object):
return "k" return "k"
def handle_mv(self, uname: str, ip: str, svp: str, dvp: str) -> str: def handle_mv(self, abrt: str, uname: str, ip: str, svp: str, dvp: str) -> str:
if svp == dvp or dvp.startswith(svp + "/"): if svp == dvp or dvp.startswith(svp + "/"):
raise Pebkac(400, "mv: cannot move parent into subfolder") raise Pebkac(400, "mv: cannot move parent into subfolder")
@ -4466,6 +4472,8 @@ class Up2k(object):
dvpf = dvp + svpf[len(svp) :] dvpf = dvp + svpf[len(svp) :]
self._mv_file(uname, ip, svpf, dvpf, curs) self._mv_file(uname, ip, svpf, dvpf, curs)
if abrt and abrt == self.abrt_key:
raise Pebkac(400, "filemove aborted by http-api")
for v in curs: for v in curs:
v.connection.commit() v.connection.commit()

View file

@ -1930,6 +1930,11 @@ html.y #tree.nowrap .ntree a+a:hover {
padding: 0; padding: 0;
font-size: 1.5em; font-size: 1.5em;
} }
#fs_abrt {
margin-top: 1em;
text-shadow: 0;
box-shadow: 1px 1px 0 var(--bg-d3);
}
#doc { #doc {
overflow: visible; overflow: visible;
background: #fff; background: #fff;

View file

@ -427,6 +427,7 @@ var Ls = {
"fcp_ok": "copy OK", "fcp_ok": "copy OK",
"fp_busy": "moving {0} items...\n\n{1}", "fp_busy": "moving {0} items...\n\n{1}",
"fcp_busy": "copying {0} items...\n\n{1}", "fcp_busy": "copying {0} items...\n\n{1}",
"fp_abrt": "aborting...",
"fp_err": "move failed:\n", "fp_err": "move failed:\n",
"fcp_err": "copy failed:\n", "fcp_err": "copy failed:\n",
"fp_confirm": "move these {0} items here?", "fp_confirm": "move these {0} items here?",
@ -1057,6 +1058,7 @@ var Ls = {
"fcp_ok": "kopiering OK", "fcp_ok": "kopiering OK",
"fp_busy": "flytter {0} filer...\n\n{1}", "fp_busy": "flytter {0} filer...\n\n{1}",
"fcp_busy": "kopierer {0} filer...\n\n{1}", "fcp_busy": "kopierer {0} filer...\n\n{1}",
"fp_abrt": "avbryter...",
"fp_err": "flytting feilet:\n", "fp_err": "flytting feilet:\n",
"fcp_err": "kopiering feilet:\n", "fcp_err": "kopiering feilet:\n",
"fp_confirm": "flytt disse {0} filene hit?", "fp_confirm": "flytt disse {0} filene hit?",
@ -1686,6 +1688,7 @@ var Ls = {
"fcp_ok": "复制成功", //m "fcp_ok": "复制成功", //m
"fp_busy": "正在移动 {0} 项...\n\n{1}", "fp_busy": "正在移动 {0} 项...\n\n{1}",
"fcp_busy": "正在复制 {0} 项...\n\n{1}", //m "fcp_busy": "正在复制 {0} 项...\n\n{1}", //m
"fp_abrt": "正在中止...", //m
"fp_err": "移动失败:\n", "fp_err": "移动失败:\n",
"fcp_err": "复制失败:\n", //m "fcp_err": "复制失败:\n", //m
"fp_confirm": "将这些 {0} 项移动到这里?", "fp_confirm": "将这些 {0} 项移动到这里?",
@ -2319,6 +2322,7 @@ var Ls = {
"fcp_ok": "kopírování OK", "fcp_ok": "kopírování OK",
"fp_busy": "přesouvám {0} položek...\n\n{1}", "fp_busy": "přesouvám {0} položek...\n\n{1}",
"fcp_busy": "kopíruji {0} položek...\n\n{1}", "fcp_busy": "kopíruji {0} položek...\n\n{1}",
"fp_abrt": "přerušuji...", //m
"fp_err": "přesun selhal:\n", "fp_err": "přesun selhal:\n",
"fcp_err": "kopírování selhalo:\n", "fcp_err": "kopírování selhalo:\n",
"fp_confirm": "přesunout těchto {0} položek sem?", "fp_confirm": "přesunout těchto {0} položek sem?",
@ -2948,6 +2952,7 @@ var Ls = {
"fcp_ok": "Kopieren OK", "fcp_ok": "Kopieren OK",
"fp_busy": "Verschiebe {0} Elemente...\n\n{1}", "fp_busy": "Verschiebe {0} Elemente...\n\n{1}",
"fcp_busy": "Kopiere {0} Elemente...\n\n{1}", "fcp_busy": "Kopiere {0} Elemente...\n\n{1}",
"fp_abrt": "Abbrechen...", //m
"fp_err": "Verschieben fehlgeschlagen:\n", "fp_err": "Verschieben fehlgeschlagen:\n",
"fcp_err": "Kopieren fehlgeschlagen:\n", "fcp_err": "Kopieren fehlgeschlagen:\n",
"fp_confirm": "Diese {0} Elemente hierher verschieben?", "fp_confirm": "Diese {0} Elemente hierher verschieben?",
@ -3577,6 +3582,7 @@ var Ls = {
"fcp_ok": "kopiointi OK", "fcp_ok": "kopiointi OK",
"fp_busy": "siirretään {0} kohdetta...\n\n{1}", "fp_busy": "siirretään {0} kohdetta...\n\n{1}",
"fcp_busy": "kopioidaan {0} kohdetta...\n\n{1}", "fcp_busy": "kopioidaan {0} kohdetta...\n\n{1}",
"fp_abrt": "keskeytetään...", //m
"fp_err": "siirto epäonnistui:\n", "fp_err": "siirto epäonnistui:\n",
"fcp_err": "kopiointi epäonnistui:\n", "fcp_err": "kopiointi epäonnistui:\n",
"fp_confirm": "siirrä nämä {0} kohdetta tänne?", "fp_confirm": "siirrä nämä {0} kohdetta tänne?",
@ -4206,6 +4212,7 @@ var Ls = {
"fcp_ok": "copie OK", "fcp_ok": "copie OK",
"fp_busy": "déplacement de {0} éléments…\n\n{1}", "fp_busy": "déplacement de {0} éléments…\n\n{1}",
"fcp_busy": "copie de {0} éléments…\n\n{1}", "fcp_busy": "copie de {0} éléments…\n\n{1}",
"fp_abrt": "abandon en cours...", //m
"fp_err": "deplacement échoué:\n", "fp_err": "deplacement échoué:\n",
"fcp_err": "copie échouée:\n", "fcp_err": "copie échouée:\n",
"fp_confirm": "déplacer ces {0} éléments ici ?", "fp_confirm": "déplacer ces {0} éléments ici ?",
@ -4835,6 +4842,7 @@ var Ls = {
"fcp_ok": "αντιγραφή OK", "fcp_ok": "αντιγραφή OK",
"fp_busy": "μετακίνηση {0} αντικειμένων...\n\n{1}", "fp_busy": "μετακίνηση {0} αντικειμένων...\n\n{1}",
"fcp_busy": "αντιγραφή {0} αντικειμένων...\n\n{1}", "fcp_busy": "αντιγραφή {0} αντικειμένων...\n\n{1}",
"fp_abrt": "γίνεται ακύρωση...", //m
"fp_err": "αποτυχία μετακίνησης:\n", "fp_err": "αποτυχία μετακίνησης:\n",
"fcp_err": "αποτυχία αντιγραφής:\n", "fcp_err": "αποτυχία αντιγραφής:\n",
"fp_confirm": "να μετακινηθούν αυτά τα {0} αντικείμενα εδώ;", "fp_confirm": "να μετακινηθούν αυτά τα {0} αντικείμενα εδώ;",
@ -5464,6 +5472,7 @@ var Ls = {
"fcp_ok": "copia OK", "fcp_ok": "copia OK",
"fp_busy": "spostando {0} elementi...\n\n{1}", "fp_busy": "spostando {0} elementi...\n\n{1}",
"fcp_busy": "copiando {0} elementi...\n\n{1}", "fcp_busy": "copiando {0} elementi...\n\n{1}",
"fp_abrt": "annullamento in corso...", //m
"fp_err": "spostamento fallito:\n", "fp_err": "spostamento fallito:\n",
"fcp_err": "copia fallita:\n", "fcp_err": "copia fallita:\n",
"fp_confirm": "spostare questi {0} elementi qui?", "fp_confirm": "spostare questi {0} elementi qui?",
@ -6093,6 +6102,7 @@ var Ls = {
"fcp_ok": "Kopiëren OK", "fcp_ok": "Kopiëren OK",
"fp_busy": "{0} items verplaatsen...\n\n{1}", "fp_busy": "{0} items verplaatsen...\n\n{1}",
"fcp_busy": "{0} items kopiëren...\n\n{1}", "fcp_busy": "{0} items kopiëren...\n\n{1}",
"fp_abrt": "afbreken...", //m
"fp_err": "Verplaatsen mislukt:\n", "fp_err": "Verplaatsen mislukt:\n",
"fcp_err": "Kopieëren mislukt:\n", "fcp_err": "Kopieëren mislukt:\n",
"fp_confirm": "Verplaats deze {0} items hierheen?", "fp_confirm": "Verplaats deze {0} items hierheen?",
@ -6723,6 +6733,7 @@ var Ls = {
"fcp_ok": "kopiering OK", "fcp_ok": "kopiering OK",
"fp_busy": "flyttar {0} filer...\n\n{1}", "fp_busy": "flyttar {0} filer...\n\n{1}",
"fcp_busy": "kopierar {0} filer...\n\n{1}", "fcp_busy": "kopierar {0} filer...\n\n{1}",
"fp_abrt": "avbryt...",
"fp_err": "flytting feila:\n", "fp_err": "flytting feila:\n",
"fcp_err": "kopiering feila:\n", "fcp_err": "kopiering feila:\n",
"fp_confirm": "flytt disse {0} filene hit?", "fp_confirm": "flytt disse {0} filene hit?",
@ -7349,6 +7360,7 @@ var Ls = {
"fcp_ok": "przekopiowano", "fcp_ok": "przekopiowano",
"fp_busy": "przenoszenie {0} elementów...\n\n{1}", "fp_busy": "przenoszenie {0} elementów...\n\n{1}",
"fcp_busy": "kopiowanie {0} elementów...\n\n{1}", "fcp_busy": "kopiowanie {0} elementów...\n\n{1}",
"fp_abrt": "przerywanie...", //m
"fp_err": "nie udało się przenieść:\n", "fp_err": "nie udało się przenieść:\n",
"fcp_err": "nie udało się skopiować:\n", "fcp_err": "nie udało się skopiować:\n",
"fp_confirm": "przenieść tutaj {0} elementy(ów)?", "fp_confirm": "przenieść tutaj {0} elementy(ów)?",
@ -7978,6 +7990,7 @@ var Ls = {
"fcp_ok": "успешно скопировано", "fcp_ok": "успешно скопировано",
"fp_busy": "перемещаю {0} файлов...\n\n{1}", "fp_busy": "перемещаю {0} файлов...\n\n{1}",
"fcp_busy": "копирую {0} файлов...\n\n{1}", "fcp_busy": "копирую {0} файлов...\n\n{1}",
"fp_abrt": "прерывание...", //m
"fp_err": "ошибка перемещения:\n", "fp_err": "ошибка перемещения:\n",
"fcp_err": "ошибка копирования:\n", "fcp_err": "ошибка копирования:\n",
"fp_confirm": "переместить эти {0} файлов сюда?", "fp_confirm": "переместить эти {0} файлов сюда?",
@ -8606,6 +8619,7 @@ var Ls = {
"fcp_ok": "copia correcta", "fcp_ok": "copia correcta",
"fp_busy": "moviendo {0} elementos...\n\n{1}", "fp_busy": "moviendo {0} elementos...\n\n{1}",
"fcp_busy": "copiando {0} elementos...\n\n{1}", "fcp_busy": "copiando {0} elementos...\n\n{1}",
"fp_abrt": "cancelando...", //m
"fp_err": "fallo al mover:\n", "fp_err": "fallo al mover:\n",
"fcp_err": "fallo al copiar:\n", "fcp_err": "fallo al copiar:\n",
"fp_confirm": "¿mover estos {0} elementos aquí?", "fp_confirm": "¿mover estos {0} elementos aquí?",
@ -9235,6 +9249,7 @@ var Ls = {
"fcp_ok": "копіювання OK", "fcp_ok": "копіювання OK",
"fp_busy": "переміщення {0} елементів...\n\n{1}", "fp_busy": "переміщення {0} елементів...\n\n{1}",
"fcp_busy": "копіювання {0} елементів...\n\n{1}", "fcp_busy": "копіювання {0} елементів...\n\n{1}",
"fp_abrt": "переривання...", //m
"fp_err": "переміщення невдале:\n", "fp_err": "переміщення невдале:\n",
"fcp_err": "копіювання невдале:\n", "fcp_err": "копіювання невдале:\n",
"fp_confirm": "перемістити ці {0} елементи сюди?", "fp_confirm": "перемістити ці {0} елементи сюди?",
@ -9882,6 +9897,7 @@ var ACtx = !IPHONE && (window.AudioContext || window.webkitAudioContext),
hash0 = location.hash, hash0 = location.hash,
sloc0 = '' + location, sloc0 = '' + location,
noih = /[?&]v\b/.exec(sloc0), noih = /[?&]v\b/.exec(sloc0),
abrt_key = "",
rtt = null, rtt = null,
ldks = [], ldks = [],
dks = {}, dks = {},
@ -12414,6 +12430,15 @@ function fmt_ren(re, md, fmt) {
} }
function fs_abrt() {
toast.inf(30, L.fp_abrt);
fileman.f.length = 0;
var xhr = new XHR();
xhr.open('POST', '/?fs_abrt=' + abrt_key, true);
xhr.send();
}
var fileman = (function () { var fileman = (function () {
var bren = ebi('fren'), var bren = ebi('fren'),
bdel = ebi('fdel'), bdel = ebi('fdel'),
@ -12424,6 +12449,7 @@ var fileman = (function () {
t_paste, t_paste,
r = {}; r = {};
r.f = [];
r.clip = null; r.clip = null;
try { try {
r.bus = new BroadcastChannel("fileman_bus"); r.bus = new BroadcastChannel("fileman_bus");
@ -12711,6 +12737,8 @@ var fileman = (function () {
base = vsplit(sel[0].vp)[0], base = vsplit(sel[0].vp)[0],
mkeys; mkeys;
r.f = f;
for (var a = 0; a < sel.length; a++) { for (var a = 0; a < sel.length; a++) {
var vp = sel[a].vp; var vp = sel[a].vp;
if (vp.endsWith('/')) if (vp.endsWith('/'))
@ -12990,7 +13018,9 @@ var fileman = (function () {
return rn_cancel(); return rn_cancel();
} }
toast.show('inf r', 0, esc(L.fr_busy.format(f.length, f[0].ofn))); var msg = esc(L.fr_busy.format(f.length, f[0].ofn));
msg += '\n<a id="fs_abrt" class="btn" href="#" onclick="fs_abrt()">' + L.fs_abrt + '</a>';
toast.show('inf r', 0, msg);
var dst = base + uricom_enc(f[0].inew.value, false); var dst = base + uricom_enc(f[0].inew.value, false);
function rename_cb() { function rename_cb() {
@ -13004,8 +13034,10 @@ var fileman = (function () {
return rn_apply_loop(); return rn_apply_loop();
} }
abrt_key = randstr(9);
var xhr = new XHR(); var xhr = new XHR();
xhr.open('POST', f[0].src + '?move=' + dst, true); xhr.open('POST', f[0].src + '?move=' + dst + '&akey=' + abrt_key, true);
xhr.onload = xhr.onerror = rename_cb; xhr.onload = xhr.onerror = rename_cb;
xhr.send(); xhr.send();
} }
@ -13267,6 +13299,8 @@ var fileman = (function () {
srcdir = vsplit(r.clip[0])[0], srcdir = vsplit(r.clip[0])[0],
links = QSA('#files tbody td:nth-child(2) a'); links = QSA('#files tbody td:nth-child(2) a');
r.f = f;
for (var a = 0, aa = links.length; a < aa; a++) for (var a = 0, aa = links.length; a < aa; a++)
indir.push(uricom_dec(vsplit(noq_href(links[a]))[1])); indir.push(uricom_dec(vsplit(noq_href(links[a]))[1]));
@ -13298,13 +13332,17 @@ var fileman = (function () {
if (!t.dst) if (!t.dst)
return paster(); return paster();
toast.show('inf r', 0, esc((r.ccp ? L.fcp_busy : L.fp_busy).format(f.length + 1, uricom_dec(t.src)))); var msg = esc((r.ccp ? L.fcp_busy : L.fp_busy).format(f.length + 1, uricom_dec(t.src)));
msg += '\n<a id="fs_abrt" class="btn" href="#" onclick="fs_abrt()">' + L.fs_abrt + '</a>';
toast.show('inf r', 0, msg);
var xhr = new XHR(), var xhr = new XHR(),
act = r.ccp ? '?copy=' : '?move=', act = r.ccp ? '?copy=' : '?move=',
dst = get_evpath() + uricom_enc(t.dst); dst = get_evpath() + uricom_enc(t.dst);
xhr.open('POST', t.src + act + dst, true); abrt_key = randstr(9);
xhr.open('POST', t.src + act + dst + '&akey=' + abrt_key, true);
xhr.onload = xhr.onerror = paste_cb; xhr.onload = xhr.onerror = paste_cb;
xhr.send(); xhr.send();
} }

View file

@ -143,7 +143,7 @@ class Cfg(Namespace):
def __init__(self, a=None, v=None, c=None, **ka0): def __init__(self, a=None, v=None, c=None, **ka0):
ka = {} ka = {}
ex = "allow_flac allow_wav chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only ih ihead localtime magic nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_fnugg no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_zip nrand nsort nw og og_no_head og_s_title ohead q rand re_dirsz reflink rmagic rss smb srch_dbg srch_excl stats uqe usernames vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs" ex = "allow_flac allow_wav chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only ih ihead localtime magic nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_fnugg no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_u2abrt no_zip nrand nsort nw og og_no_head og_s_title ohead q rand re_dirsz reflink rmagic rss smb srch_dbg srch_excl stats uqe usernames vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
ka.update(**{k: False for k in ex.split()}) ka.update(**{k: False for k in ex.split()})
ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump re_dhash see_dots plain_ip" ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump re_dhash see_dots plain_ip"