diff --git a/README.md b/README.md
index 3a0b7646..43fad539 100644
--- a/README.md
+++ b/README.md
@@ -1955,6 +1955,8 @@ below are some tweaks roughly ordered by usefulness:
* `-q` disables logging and can help a bunch, even when combined with `-lo` to redirect logs to file
* `--hist` pointing to a fast location (ssd) will make directory listings and searches faster when `-e2d` or `-e2t` is set
* and also makes thumbnails load faster, regardless of e2d/e2t
+* `--dedup` enables deduplication and thus avoids writing to the HDD if someone uploads a dupe
+* `--safe-dedup 1` makes deduplication much faster during upload by skipping verification of file contents; safe if there is no other software editing/moving the files in the volumes
* `--no-hash .` when indexing a network-disk if you don't care about the actual filehashes and only want the names/tags searchable
* if your volumes are on a network-disk such as NFS / SMB / s3, specifying larger values for `--iobuf` and/or `--s-rd-sz` and/or `--s-wr-sz` may help; try setting all of them to `524288` or `1048576` or `4194304`
* `--no-htp --hash-mt=0 --mtag-mt=1 --th-mt=1` minimizes the number of threads; can help in some eccentric environments (like the vscode debugger)
diff --git a/copyparty/cfg.py b/copyparty/cfg.py
index 9c543f35..deea73ab 100644
--- a/copyparty/cfg.py
+++ b/copyparty/cfg.py
@@ -20,7 +20,6 @@ def vf_bmap() -> dict[str, str]:
"no_thumb": "dthumb",
"no_vthumb": "dvthumb",
"no_athumb": "dathumb",
- "safe_dedup": "safededup",
}
for k in (
"dedup",
@@ -59,6 +58,7 @@ def vf_vmap() -> dict[str, str]:
"no_hash": "nohash",
"no_idx": "noidx",
"re_maxage": "scan",
+ "safe_dedup": "safededup",
"th_convt": "convt",
"th_size": "thsize",
"th_crop": "crop",
diff --git a/copyparty/up2k.py b/copyparty/up2k.py
index 7acefa83..1ba6dbf1 100644
--- a/copyparty/up2k.py
+++ b/copyparty/up2k.py
@@ -2681,7 +2681,7 @@ def _handle_json(self, cj: dict[str, Any], depth: int = 1) -> dict[str, Any]:
jcur = self.cur.get(ptop)
reg = self.registry[ptop]
vfs = self.asrv.vfs.all_vols[cj["vtop"]]
- n4g = vfs.flags.get("noforget")
+ n4g = bool(vfs.flags.get("noforget"))
rand = vfs.flags.get("rand") or cj.get("rand")
lost: list[tuple["sqlite3.Cursor", str, str]] = []
diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js
index 96b17fea..96f8d928 100644
--- a/copyparty/web/browser.js
+++ b/copyparty/web/browser.js
@@ -518,6 +518,7 @@ var Ls = {
"u_etaprep": '(preparing to upload)',
"u_hashdone": 'hashing done',
"u_hashing": 'hash',
+ "u_hs": 'handshaking...',
"u_dupdefer": "duplicate; will be processed after all other files",
"u_actx": "click this text to prevent loss of
performance when switching to other windows/tabs",
"u_fixed": "OK! Fixed it 👍",
@@ -1081,6 +1082,7 @@ var Ls = {
"u_etaprep": '(forbereder opplastning)',
"u_hashdone": 'befaring ferdig',
"u_hashing": 'les',
+ "u_hs": 'serveren tenker...',
"u_dupdefer": "duplikat; vil bli håndtert til slutt",
"u_actx": "klikk her for å forhindre tap av
ytelse ved bytte til andre vinduer/faner",
"u_fixed": "OK! Løste seg 👍",
@@ -1644,6 +1646,7 @@ var Ls = {
"u_etaprep": '(准备上传)',
"u_hashdone": '哈希完成',
"u_hashing": '哈希',
+ "u_hs": '正在等待服务器...', //m
"u_dupdefer": "这是一个重复文件。它将在所有其他文件上传后进行处理", //m
"u_actx": "单击此文本以防止切换到其他窗口/选项卡时性能下降", //m
"u_fixed": "好! 已修复 👍",
diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js
index 50afd99b..9b232be0 100644
--- a/copyparty/web/up2k.js
+++ b/copyparty/web/up2k.js
@@ -1745,14 +1745,6 @@ function up2k_init(subtle) {
var mou_ikkai = false;
- if (st.busy.handshake.length &&
- st.busy.handshake[0].t_busied < now - 30 * 1000
- ) {
- console.log("retrying stuck handshake");
- var t = st.busy.handshake.shift();
- st.todo.handshake.unshift(t);
- }
-
var nprev = -1;
for (var a = 0; a < st.todo.upload.length; a++) {
var nf = st.todo.upload[a].nfile;
@@ -2254,6 +2246,9 @@ function up2k_init(subtle) {
if (keepalive)
console.log("sending keepalive handshake", t.name, t);
+ if (!t.srch && !t.t_handshake)
+ pvis.seth(t.n, 2, L.u_hs);
+
var xhr = new XMLHttpRequest();
xhr.onerror = xhr.ontimeout = function () {
if (t.t_busied != me) // t.done ok
@@ -2533,7 +2528,8 @@ function up2k_init(subtle) {
xhr.open('POST', t.purl, true);
xhr.responseType = 'text';
- xhr.timeout = 42000;
+ xhr.timeout = 42000 + (t.srch || t.t_uploaded ? 0 :
+ (t.size / (1048 * 20))); // safededup 20M/s hdd
xhr.send(JSON.stringify(req));
}