diff --git a/bin/u2c.py b/bin/u2c.py index de074f91..8de25850 100755 --- a/bin/u2c.py +++ b/bin/u2c.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 from __future__ import print_function, unicode_literals -S_VERSION = "1.12" -S_BUILD_DT = "2023-12-08" +S_VERSION = "1.13" +S_BUILD_DT = "2024-01-24" """ u2c.py: upload to copyparty @@ -560,8 +560,11 @@ def handshake(ar, file, search): } if search: req["srch"] = 1 - elif ar.dr: - req["replace"] = True + else: + if ar.touch: + req["umod"] = True + if ar.dr: + req["replace"] = True headers = {"Content-Type": "text/plain"} # <=1.5.1 compat if pw: @@ -1129,6 +1132,7 @@ source file/folder selection uses rsync syntax, meaning that: ap.add_argument("-s", action="store_true", help="file-search (disables upload)") ap.add_argument("-x", type=unicode, metavar="REGEX", default="", help="skip file if filesystem-abspath matches REGEX, example: '.*/\\.hist/.*'") ap.add_argument("--ok", action="store_true", help="continue even if some local files are inaccessible") + ap.add_argument("--touch", action="store_true", help="if last-modified timestamps differ, push local to server (need write+delete perms)") ap.add_argument("--version", action="store_true", help="show version and exit") ap = app.add_argument_group("compatibility") diff --git a/copyparty/up2k.py b/copyparty/up2k.py index e240051e..bded33bd 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -2689,6 +2689,28 @@ class Up2k(object): fk = self.gen_fk(alg, self.args.fk_salt, ap, job["size"], ino) ret["fk"] = fk[: vfs.flags["fk"]] + if ( + not ret["hash"] + and cur + and cj.get("umod") + and int(cj["lmod"]) != int(job["lmod"]) + and not self.args.nw + and cj["user"] in vfs.axs.uwrite + and cj["user"] in vfs.axs.udel + ): + sql = "update up set mt=? where substr(w,1,16)=? and +rd=? and +fn=?" + try: + cur.execute(sql, (cj["lmod"], wark[:16], job["prel"], job["name"])) + cur.connection.commit() + + ap = djoin(job["ptop"], job["prel"], job["name"]) + times = (int(time.time()), int(cj["lmod"])) + bos.utime(ap, times, False) + + self.log("touched %s from %d to %d" % (ap, job["lmod"], cj["lmod"])) + except Exception as ex: + self.log("umod failed, %r" % (ex,), 3) + return ret def _untaken(self, fdir: str, job: dict[str, Any], ts: float) -> str: diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 8ecc7648..9d045717 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -200,6 +200,8 @@ var Ls = { "ct_idxh": "show index.html instead of folder listing", "ct_sbars": "show scrollbars", + "cut_umod": "if a file already exists on the server, update the server's last-modified timestamp to match your local file (requires write+delete permissions)", + "cut_turbo": "the yolo button, you probably DO NOT want to enable this:$N$Nuse this if you were uploading a huge amount of files and had to restart for some reason, and want to continue the upload ASAP$N$Nthis replaces the hash-check with a simple "does this have the same filesize on the server?" so if the file contents are different it will NOT be uploaded$N$Nyou should turn this off when the upload is done, and then "upload" the same files again to let the client verify them", "cut_datechk": "has no effect unless the turbo button is enabled$N$Nreduces the yolo factor by a tiny amount; checks whether the file timestamps on the server matches yours$N$Nshould theoretically catch most unfinished / corrupted uploads, but is not a substitute for doing a verification pass with turbo disabled afterwards", @@ -687,6 +689,8 @@ var Ls = { "ct_idxh": "vis index.html istedenfor fil-liste", "ct_sbars": "vis rullgardiner / skrollefelt", + "cut_umod": "i tilfelle en fil du laster opp allerede finnes på serveren, så skal serverens tidsstempel oppdateres slik at det stemmer overens med din lokale fil (krever rettighetene write+delete)", + "cut_turbo": "forenklet befaring ved opplastning; bør sannsynlig ikke skrus på:$N$Nnyttig dersom du var midt i en svær opplastning som måtte restartes av en eller annen grunn, og du vil komme igang igjen så raskt som overhodet mulig.$N$Nnår denne er skrudd på så forenkles befaringen kraftig; istedenfor å utføre en trygg sjekk på om filene finnes på serveren i god stand, så sjekkes kun om filstørrelsen stemmer. Så dersom en korrupt fil skulle befinne seg på serveren allerede, på samme sted med samme størrelse og navn, så blir det ikke oppdaget.$N$Ndet anbefales å kun benytte denne funksjonen for å komme seg raskt igjennom selve opplastningen, for så å skru den av, og til slutt "laste opp" de samme filene én gang til -- slik at integriteten kan verifiseres", "cut_datechk": "har ingen effekt dersom turbo er avslått$N$Ngjør turbo bittelitt tryggere ved å sjekke datostemplingen på filene (i tillegg til filstørrelse)$N$Nburde oppdage og gjenoppta de fleste ufullstendige opplastninger, men er ikke en fullverdig erstatning for å deaktivere turbo og gjøre en skikkelig sjekk", @@ -1191,6 +1195,7 @@ ebi('op_cfg').innerHTML = ( '