mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
add option to store markdown backups elsewhere
`--md-hist` / volflag `md_hist` specifies where to put old versions of markdown files when edited using the web-ui; * `s` = create `.hist` subfolder next to the markdown file (the default, both previously and now) * `v` = use the volume's hist-path, either according to `--hist` or the `hist` volflag. NOTE: old versions will not be retrievable through the web-ui * `n` = nope / disabled; overwrite without backup
This commit is contained in:
parent
43bbd566d7
commit
fc88341820
|
@ -1431,6 +1431,7 @@ def add_db_metadata(ap):
|
||||||
|
|
||||||
def add_txt(ap):
|
def add_txt(ap):
|
||||||
ap2 = ap.add_argument_group('textfile options')
|
ap2 = ap.add_argument_group('textfile options')
|
||||||
|
ap2.add_argument("--md-hist", metavar="TXT", type=u, default="s", help="where to store old version of markdown files; [\033[32ms\033[0m]=subfolder, [\033[32mv\033[0m]=volume-histpath, [\033[32mn\033[0m]=nope/disabled (volflag=md_hist)")
|
||||||
ap2.add_argument("-mcr", metavar="SEC", type=int, default=60, help="the textfile editor will check for serverside changes every \033[33mSEC\033[0m seconds")
|
ap2.add_argument("-mcr", metavar="SEC", type=int, default=60, help="the textfile editor will check for serverside changes every \033[33mSEC\033[0m seconds")
|
||||||
ap2.add_argument("-emp", action="store_true", help="enable markdown plugins -- neat but dangerous, big XSS risk")
|
ap2.add_argument("-emp", action="store_true", help="enable markdown plugins -- neat but dangerous, big XSS risk")
|
||||||
ap2.add_argument("--exp", action="store_true", help="enable textfile expansion -- replace {{self.ip}} and such; see \033[33m--help-exp\033[0m (volflag=exp)")
|
ap2.add_argument("--exp", action="store_true", help="enable textfile expansion -- replace {{self.ip}} and such; see \033[33m--help-exp\033[0m (volflag=exp)")
|
||||||
|
|
|
@ -83,6 +83,7 @@ def vf_vmap() -> dict[str, str]:
|
||||||
"md_sbf",
|
"md_sbf",
|
||||||
"lg_sba",
|
"lg_sba",
|
||||||
"md_sba",
|
"md_sba",
|
||||||
|
"md_hist",
|
||||||
"nrand",
|
"nrand",
|
||||||
"u2ow",
|
"u2ow",
|
||||||
"og_desc",
|
"og_desc",
|
||||||
|
@ -291,6 +292,7 @@ flagcats = {
|
||||||
"og_ua": "if defined: only send OG html if useragent matches this regex",
|
"og_ua": "if defined: only send OG html if useragent matches this regex",
|
||||||
},
|
},
|
||||||
"textfiles": {
|
"textfiles": {
|
||||||
|
"md_hist": "where to put markdown backups; s=subfolder, v=volHist, n=nope",
|
||||||
"exp": "enable textfile expansion; see --help-exp",
|
"exp": "enable textfile expansion; see --help-exp",
|
||||||
"exp_md": "placeholders to expand in markdown files; see --help",
|
"exp_md": "placeholders to expand in markdown files; see --help",
|
||||||
"exp_lg": "placeholders to expand in prologue/epilogue; see --help",
|
"exp_lg": "placeholders to expand in prologue/epilogue; see --help",
|
||||||
|
|
|
@ -57,6 +57,7 @@ from .util import (
|
||||||
UnrecvEOF,
|
UnrecvEOF,
|
||||||
WrongPostKey,
|
WrongPostKey,
|
||||||
absreal,
|
absreal,
|
||||||
|
afsenc,
|
||||||
alltrace,
|
alltrace,
|
||||||
atomic_move,
|
atomic_move,
|
||||||
b64dec,
|
b64dec,
|
||||||
|
@ -3501,6 +3502,7 @@ class HttpCli(object):
|
||||||
|
|
||||||
fp = os.path.join(fp, fn)
|
fp = os.path.join(fp, fn)
|
||||||
rem = "{}/{}".format(rp, fn).strip("/")
|
rem = "{}/{}".format(rp, fn).strip("/")
|
||||||
|
dbv, vrem = vfs.get_dbv(rem)
|
||||||
|
|
||||||
if not rem.endswith(".md") and not self.can_delete:
|
if not rem.endswith(".md") and not self.can_delete:
|
||||||
raise Pebkac(400, "only markdown pls")
|
raise Pebkac(400, "only markdown pls")
|
||||||
|
@ -3555,13 +3557,27 @@ class HttpCli(object):
|
||||||
mdir, mfile = os.path.split(fp)
|
mdir, mfile = os.path.split(fp)
|
||||||
fname, fext = mfile.rsplit(".", 1) if "." in mfile else (mfile, "md")
|
fname, fext = mfile.rsplit(".", 1) if "." in mfile else (mfile, "md")
|
||||||
mfile2 = "{}.{:.3f}.{}".format(fname, srv_lastmod, fext)
|
mfile2 = "{}.{:.3f}.{}".format(fname, srv_lastmod, fext)
|
||||||
try:
|
|
||||||
|
dp = ""
|
||||||
|
hist_cfg = dbv.flags["md_hist"]
|
||||||
|
if hist_cfg == "v":
|
||||||
|
vrd = vsplit(vrem)[0]
|
||||||
|
zb = hashlib.sha512(afsenc(vrd)).digest()
|
||||||
|
zs = ub64enc(zb).decode("ascii")[:24].lower()
|
||||||
|
dp = "%s/md/%s/%s/%s" % (dbv.histpath, zs[:2], zs[2:4], zs)
|
||||||
|
self.log("moving old version to %s/%s" % (dp, mfile2))
|
||||||
|
if bos.makedirs(dp):
|
||||||
|
with open(os.path.join(dp, "dir.txt"), "wb") as f:
|
||||||
|
f.write(afsenc(vrd))
|
||||||
|
elif hist_cfg == "s":
|
||||||
dp = os.path.join(mdir, ".hist")
|
dp = os.path.join(mdir, ".hist")
|
||||||
bos.mkdir(dp)
|
try:
|
||||||
hidedir(dp)
|
bos.mkdir(dp)
|
||||||
except:
|
hidedir(dp)
|
||||||
pass
|
except:
|
||||||
wrename(self.log, fp, os.path.join(mdir, ".hist", mfile2), vfs.flags)
|
pass
|
||||||
|
if dp:
|
||||||
|
wrename(self.log, fp, os.path.join(dp, mfile2), vfs.flags)
|
||||||
|
|
||||||
assert self.parser.gen # !rm
|
assert self.parser.gen # !rm
|
||||||
p_field, _, p_data = next(self.parser.gen)
|
p_field, _, p_data = next(self.parser.gen)
|
||||||
|
@ -3634,13 +3650,12 @@ class HttpCli(object):
|
||||||
wunlink(self.log, fp, vfs.flags)
|
wunlink(self.log, fp, vfs.flags)
|
||||||
raise Pebkac(403, t)
|
raise Pebkac(403, t)
|
||||||
|
|
||||||
vfs, rem = vfs.get_dbv(rem)
|
|
||||||
self.conn.hsrv.broker.say(
|
self.conn.hsrv.broker.say(
|
||||||
"up2k.hash_file",
|
"up2k.hash_file",
|
||||||
vfs.realpath,
|
dbv.realpath,
|
||||||
vfs.vpath,
|
dbv.vpath,
|
||||||
vfs.flags,
|
dbv.flags,
|
||||||
vsplit(rem)[0],
|
vsplit(vrem)[0],
|
||||||
fn,
|
fn,
|
||||||
self.ip,
|
self.ip,
|
||||||
new_lastmod,
|
new_lastmod,
|
||||||
|
@ -6020,9 +6035,11 @@ class HttpCli(object):
|
||||||
# check for old versions of files,
|
# check for old versions of files,
|
||||||
# [num-backups, most-recent, hist-path]
|
# [num-backups, most-recent, hist-path]
|
||||||
hist: dict[str, tuple[int, float, str]] = {}
|
hist: dict[str, tuple[int, float, str]] = {}
|
||||||
histdir = os.path.join(fsroot, ".hist")
|
|
||||||
ptn = RE_MDV
|
|
||||||
try:
|
try:
|
||||||
|
if vf["md_hist"] != "s":
|
||||||
|
raise Exception()
|
||||||
|
histdir = os.path.join(fsroot, ".hist")
|
||||||
|
ptn = RE_MDV
|
||||||
for hfn in bos.listdir(histdir):
|
for hfn in bos.listdir(histdir):
|
||||||
m = ptn.match(hfn)
|
m = ptn.match(hfn)
|
||||||
if not m:
|
if not m:
|
||||||
|
|
|
@ -174,6 +174,7 @@ class Cfg(Namespace):
|
||||||
lang="eng",
|
lang="eng",
|
||||||
log_badpwd=1,
|
log_badpwd=1,
|
||||||
logout=573,
|
logout=573,
|
||||||
|
md_hist="s",
|
||||||
mte={"a": True},
|
mte={"a": True},
|
||||||
mth={},
|
mth={},
|
||||||
mtp=[],
|
mtp=[],
|
||||||
|
|
Loading…
Reference in a new issue