copyparty 1.6.9__py2.py3-none-any.whl → 1.6.11__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- copyparty/__main__.py +1 -1
- copyparty/__version__.py +2 -2
- copyparty/httpcli.py +48 -17
- copyparty/th_srv.py +33 -1
- copyparty/up2k.py +13 -6
- copyparty/web/a/up2k.py +5 -7
- copyparty/web/baguettebox.js.gz +0 -0
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/deps/easymde.css.gz +0 -0
- copyparty/web/deps/easymde.js.gz +0 -0
- copyparty/web/deps/marked.js.gz +0 -0
- copyparty/web/deps/mini-fa.css.gz +0 -0
- copyparty/web/deps/sha512.ac.js.gz +0 -0
- copyparty/web/md.js.gz +0 -0
- copyparty/web/svcs.html +3 -4
- copyparty/web/ui.css.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.6.9.data → copyparty-1.6.11.data}/data/share/doc/copyparty/README.md +60 -29
- {copyparty-1.6.9.data → copyparty-1.6.11.data}/scripts/up2k.py +5 -7
- {copyparty-1.6.9.dist-info → copyparty-1.6.11.dist-info}/METADATA +61 -30
- {copyparty-1.6.9.dist-info → copyparty-1.6.11.dist-info}/RECORD +28 -28
- {copyparty-1.6.9.data → copyparty-1.6.11.data}/data/share/doc/copyparty/LICENSE +0 -0
- {copyparty-1.6.9.data → copyparty-1.6.11.data}/scripts/partyfuse.py +0 -0
- {copyparty-1.6.9.dist-info → copyparty-1.6.11.dist-info}/LICENSE +0 -0
- {copyparty-1.6.9.dist-info → copyparty-1.6.11.dist-info}/WHEEL +0 -0
- {copyparty-1.6.9.dist-info → copyparty-1.6.11.dist-info}/entry_points.txt +0 -0
- {copyparty-1.6.9.dist-info → copyparty-1.6.11.dist-info}/top_level.txt +0 -0
copyparty/__main__.py
CHANGED
@@ -752,7 +752,7 @@ def add_ftp(ap):
|
|
752
752
|
|
753
753
|
def add_webdav(ap):
|
754
754
|
ap2 = ap.add_argument_group('WebDAV options')
|
755
|
-
ap2.add_argument("--daw", action="store_true", help="enable full write support. \033[1;31mWARNING:\033[0m This has side-effects -- PUT-operations will now \033[1;31mOVERWRITE\033[0m existing files, rather than inventing new filenames to avoid loss of data. You might want to instead set this as a volflag where needed. By not setting this flag, uploaded files can get written to a filename which the client does not expect (which might be okay, depending on client)")
|
755
|
+
ap2.add_argument("--daw", action="store_true", help="enable full write support, even if client may not be webdav. \033[1;31mWARNING:\033[0m This has side-effects -- PUT-operations will now \033[1;31mOVERWRITE\033[0m existing files, rather than inventing new filenames to avoid loss of data. You might want to instead set this as a volflag where needed. By not setting this flag, uploaded files can get written to a filename which the client does not expect (which might be okay, depending on client)")
|
756
756
|
ap2.add_argument("--dav-inf", action="store_true", help="allow depth:infinite requests (recursive file listing); extremely server-heavy but required for spec compliance -- luckily few clients rely on this")
|
757
757
|
ap2.add_argument("--dav-mac", action="store_true", help="disable apple-garbage filter -- allow macos to create junk files (._* and .DS_Store, .Spotlight-*, .fseventsd, .Trashes, .AppleDouble, __MACOS)")
|
758
758
|
|
copyparty/__version__.py
CHANGED
copyparty/httpcli.py
CHANGED
@@ -861,7 +861,17 @@ class HttpCli(object):
|
|
861
861
|
vn, rem = self.asrv.vfs.get(self.vpath, self.uname, True, False, err=401)
|
862
862
|
depth = self.headers.get("depth", "infinity").lower()
|
863
863
|
|
864
|
-
|
864
|
+
try:
|
865
|
+
topdir = {"vp": "", "st": bos.stat(vn.canonical(rem))}
|
866
|
+
except OSError as ex:
|
867
|
+
if ex.errno != errno.ENOENT:
|
868
|
+
raise
|
869
|
+
raise Pebkac(404)
|
870
|
+
|
871
|
+
if not stat.S_ISDIR(topdir["st"].st_mode):
|
872
|
+
fgen = []
|
873
|
+
|
874
|
+
elif depth == "infinity":
|
865
875
|
if not self.args.dav_inf:
|
866
876
|
self.log("client wants --dav-inf", 3)
|
867
877
|
zb = b'<?xml version="1.0" encoding="utf-8"?>\n<D:error xmlns:D="DAV:"><D:propfind-finite-depth/></D:error>'
|
@@ -900,13 +910,6 @@ class HttpCli(object):
|
|
900
910
|
t2 = " or 'infinity'" if self.args.dav_inf else ""
|
901
911
|
raise Pebkac(412, t.format(depth, t2))
|
902
912
|
|
903
|
-
try:
|
904
|
-
topdir = {"vp": "", "st": os.stat(vn.canonical(rem))}
|
905
|
-
except OSError as ex:
|
906
|
-
if ex.errno != errno.ENOENT:
|
907
|
-
raise
|
908
|
-
raise Pebkac(404)
|
909
|
-
|
910
913
|
fgen = itertools.chain([topdir], fgen) # type: ignore
|
911
914
|
vtop = vjoin(self.args.R, vjoin(vn.vpath, rem))
|
912
915
|
|
@@ -1108,7 +1111,14 @@ class HttpCli(object):
|
|
1108
1111
|
if self.do_log:
|
1109
1112
|
self.log("MKCOL " + self.req)
|
1110
1113
|
|
1111
|
-
|
1114
|
+
try:
|
1115
|
+
return self._mkdir(self.vpath, True)
|
1116
|
+
except Pebkac as ex:
|
1117
|
+
if ex.code >= 500:
|
1118
|
+
raise
|
1119
|
+
|
1120
|
+
self.reply(b"", ex.code)
|
1121
|
+
return True
|
1112
1122
|
|
1113
1123
|
def handle_move(self) :
|
1114
1124
|
dst = self.headers["destination"]
|
@@ -1422,9 +1432,9 @@ class HttpCli(object):
|
|
1422
1432
|
self.log(t, 1)
|
1423
1433
|
raise Pebkac(403, t)
|
1424
1434
|
|
1425
|
-
if is_put and not (self.args.no_dav or self.args.nw):
|
1435
|
+
if is_put and not (self.args.no_dav or self.args.nw) and bos.path.exists(path):
|
1426
1436
|
# allow overwrite if...
|
1427
|
-
# * volflag 'daw' is set
|
1437
|
+
# * volflag 'daw' is set, or client is definitely webdav
|
1428
1438
|
# * and account has delete-access
|
1429
1439
|
# or...
|
1430
1440
|
# * file exists, is empty, sufficiently new
|
@@ -1434,9 +1444,11 @@ class HttpCli(object):
|
|
1434
1444
|
if self.args.dotpart:
|
1435
1445
|
tnam = "." + tnam
|
1436
1446
|
|
1437
|
-
if (
|
1447
|
+
if (
|
1448
|
+
self.can_delete
|
1449
|
+
and (vfs.flags.get("daw") or "x-oc-mtime" in self.headers)
|
1450
|
+
) or (
|
1438
1451
|
not bos.path.exists(os.path.join(fdir, tnam))
|
1439
|
-
and bos.path.exists(path)
|
1440
1452
|
and not bos.path.getsize(path)
|
1441
1453
|
and bos.path.getmtime(path) >= time.time() - self.args.blank_wt
|
1442
1454
|
):
|
@@ -1460,6 +1472,16 @@ class HttpCli(object):
|
|
1460
1472
|
if self.args.nw:
|
1461
1473
|
return post_sz, sha_hex, sha_b64, remains, path, ""
|
1462
1474
|
|
1475
|
+
at = mt = time.time() - lifetime
|
1476
|
+
cli_mt = self.headers.get("x-oc-mtime")
|
1477
|
+
if cli_mt:
|
1478
|
+
try:
|
1479
|
+
mt = int(cli_mt)
|
1480
|
+
times = (int(time.time()), mt)
|
1481
|
+
bos.utime(path, times, False)
|
1482
|
+
except:
|
1483
|
+
pass
|
1484
|
+
|
1463
1485
|
if nameless and "magic" in vfs.flags:
|
1464
1486
|
try:
|
1465
1487
|
ext = self.conn.hsrv.magician.ext(path)
|
@@ -1482,7 +1504,6 @@ class HttpCli(object):
|
|
1482
1504
|
fn = fn2
|
1483
1505
|
path = path2
|
1484
1506
|
|
1485
|
-
at = time.time() - lifetime
|
1486
1507
|
if xau and not runhook(
|
1487
1508
|
self.log,
|
1488
1509
|
xau,
|
@@ -1490,7 +1511,7 @@ class HttpCli(object):
|
|
1490
1511
|
self.vpath,
|
1491
1512
|
self.host,
|
1492
1513
|
self.uname,
|
1493
|
-
|
1514
|
+
mt,
|
1494
1515
|
post_sz,
|
1495
1516
|
self.ip,
|
1496
1517
|
at,
|
@@ -1550,6 +1571,11 @@ class HttpCli(object):
|
|
1550
1571
|
t = "{}\n{}\n{}\n{}\n".format(post_sz, sha_b64, sha_hex[:56], url)
|
1551
1572
|
|
1552
1573
|
h = {"Location": url} if is_put and url else {}
|
1574
|
+
|
1575
|
+
if "x-oc-mtime" in self.headers:
|
1576
|
+
h["X-OC-MTime"] = "accepted"
|
1577
|
+
t = "" # some webdav clients expect/prefer this
|
1578
|
+
|
1553
1579
|
self.reply(t.encode("utf-8"), 201, headers=h)
|
1554
1580
|
return True
|
1555
1581
|
|
@@ -1950,7 +1976,7 @@ class HttpCli(object):
|
|
1950
1976
|
sanitized = sanitize_fn(new_dir, "", [])
|
1951
1977
|
return self._mkdir(vjoin(self.vpath, sanitized))
|
1952
1978
|
|
1953
|
-
def _mkdir(self, vpath ) :
|
1979
|
+
def _mkdir(self, vpath , dav = False) :
|
1954
1980
|
nullwrite = self.args.nw
|
1955
1981
|
vfs, rem = self.asrv.vfs.get(vpath, self.uname, False, True)
|
1956
1982
|
self._assert_safe_rem(rem)
|
@@ -1976,7 +2002,12 @@ class HttpCli(object):
|
|
1976
2002
|
raise Pebkac(500, min_ex())
|
1977
2003
|
|
1978
2004
|
self.out_headers["X-New-Dir"] = quotep(vpath.split("/")[-1])
|
1979
|
-
|
2005
|
+
|
2006
|
+
if dav:
|
2007
|
+
self.reply(b"", 201)
|
2008
|
+
else:
|
2009
|
+
self.redirect(vpath, status=201)
|
2010
|
+
|
1980
2011
|
return True
|
1981
2012
|
|
1982
2013
|
def handle_new_md(self) :
|
copyparty/th_srv.py
CHANGED
@@ -558,12 +558,19 @@ class ThumbSrv(object):
|
|
558
558
|
if "ac" not in ret:
|
559
559
|
raise Exception("not audio")
|
560
560
|
|
561
|
+
try:
|
562
|
+
dur = ret[".dur"][1]
|
563
|
+
except:
|
564
|
+
dur = 0
|
565
|
+
|
561
566
|
src_opus = abspath.lower().endswith(".opus") or ret["ac"][1] == "opus"
|
562
567
|
want_caf = tpath.endswith(".caf")
|
563
568
|
tmp_opus = tpath
|
564
569
|
if want_caf:
|
565
570
|
tmp_opus = tpath.rsplit(".", 1)[0] + ".opus"
|
566
571
|
|
572
|
+
caf_src = abspath if src_opus else tmp_opus
|
573
|
+
|
567
574
|
if not want_caf or (not src_opus and not bos.path.isfile(tmp_opus)):
|
568
575
|
# fmt: off
|
569
576
|
cmd = [
|
@@ -581,7 +588,32 @@ class ThumbSrv(object):
|
|
581
588
|
# fmt: on
|
582
589
|
self._run_ff(cmd)
|
583
590
|
|
584
|
-
|
591
|
+
# iOS fails to play some "insufficiently complex" files
|
592
|
+
# (average file shorter than 8 seconds), so of course we
|
593
|
+
# fix that by mixing in some inaudible pink noise :^)
|
594
|
+
# 6.3 sec seems like the cutoff so lets do 7, and
|
595
|
+
# 7 sec of psyqui-musou.opus @ 3:50 is 174 KiB
|
596
|
+
if want_caf and (dur < 20 or bos.path.getsize(caf_src) < 256 * 1024):
|
597
|
+
# fmt: off
|
598
|
+
cmd = [
|
599
|
+
b"ffmpeg",
|
600
|
+
b"-nostdin",
|
601
|
+
b"-v", b"error",
|
602
|
+
b"-hide_banner",
|
603
|
+
b"-i", fsenc(abspath),
|
604
|
+
b"-filter_complex", b"anoisesrc=a=0.001:d=7:c=pink,asplit[l][r]; [l][r]amerge[s]; [0:a:0][s]amix",
|
605
|
+
b"-map_metadata", b"-1",
|
606
|
+
b"-ac", b"2",
|
607
|
+
b"-c:a", b"libopus",
|
608
|
+
b"-b:a", b"128k",
|
609
|
+
b"-f", b"caf",
|
610
|
+
fsenc(tpath)
|
611
|
+
]
|
612
|
+
# fmt: on
|
613
|
+
self._run_ff(cmd)
|
614
|
+
|
615
|
+
elif want_caf:
|
616
|
+
# simple remux should be safe
|
585
617
|
# fmt: off
|
586
618
|
cmd = [
|
587
619
|
b"ffmpeg",
|
copyparty/up2k.py
CHANGED
@@ -1029,7 +1029,7 @@ class Up2k(object):
|
|
1029
1029
|
zh.update(cv.encode("utf-8", "replace"))
|
1030
1030
|
zh.update(spack(b"<d", cst.st_mtime))
|
1031
1031
|
dhash = base64.urlsafe_b64encode(zh.digest()[:12]).decode("ascii")
|
1032
|
-
sql = "select d from dh where d
|
1032
|
+
sql = "select d from dh where d=? and +h=?"
|
1033
1033
|
try:
|
1034
1034
|
c = db.c.execute(sql, (rd, dhash))
|
1035
1035
|
drd = rd
|
@@ -1313,9 +1313,9 @@ class Up2k(object):
|
|
1313
1313
|
|
1314
1314
|
w, drd, dfn = zb[:-1].decode("utf-8").split("\x00")
|
1315
1315
|
with self.mutex:
|
1316
|
-
q = "select mt, sz from up where
|
1316
|
+
q = "select mt, sz from up where rd=? and fn=? and +w=?"
|
1317
1317
|
try:
|
1318
|
-
mt, sz = cur.execute(q, (
|
1318
|
+
mt, sz = cur.execute(q, (drd, dfn, w)).fetchone()
|
1319
1319
|
except:
|
1320
1320
|
# file moved/deleted since spooling
|
1321
1321
|
continue
|
@@ -2220,7 +2220,7 @@ class Up2k(object):
|
|
2220
2220
|
q = r"select * from up where w = ?"
|
2221
2221
|
argv = [wark]
|
2222
2222
|
else:
|
2223
|
-
q = r"select * from up where substr(w,1,16)
|
2223
|
+
q = r"select * from up where substr(w,1,16)=? and +w=?"
|
2224
2224
|
argv = [wark[:16], wark]
|
2225
2225
|
|
2226
2226
|
c2 = cur.execute(q, tuple(argv))
|
@@ -3297,9 +3297,16 @@ class Up2k(object):
|
|
3297
3297
|
"""
|
3298
3298
|
dupes = []
|
3299
3299
|
sabs = djoin(sptop, srem)
|
3300
|
-
|
3300
|
+
|
3301
|
+
if self.no_expr_idx:
|
3302
|
+
q = r"select rd, fn from up where w = ?"
|
3303
|
+
argv = (wark,)
|
3304
|
+
else:
|
3305
|
+
q = r"select rd, fn from up where substr(w,1,16)=? and +w=?"
|
3306
|
+
argv = (wark[:16], wark)
|
3307
|
+
|
3301
3308
|
for ptop, cur in self.cur.items():
|
3302
|
-
for rd, fn in cur.execute(q,
|
3309
|
+
for rd, fn in cur.execute(q, argv):
|
3303
3310
|
if rd.startswith("//") or fn.startswith("//"):
|
3304
3311
|
rd, fn = s3dec(rd, fn)
|
3305
3312
|
|
copyparty/web/a/up2k.py
CHANGED
@@ -1009,8 +1009,9 @@ class Ctl(object):
|
|
1009
1009
|
file, cid = task
|
1010
1010
|
try:
|
1011
1011
|
upload(file, cid, self.ar.a, stats)
|
1012
|
-
except:
|
1013
|
-
|
1012
|
+
except Exception as ex:
|
1013
|
+
t = "upload failed, retrying: {0} #{1} ({2})\n"
|
1014
|
+
eprint(t.format(file.name, cid[:8], ex))
|
1014
1015
|
# handshake will fix it
|
1015
1016
|
|
1016
1017
|
with self.mutex:
|
@@ -1049,6 +1050,8 @@ def main():
|
|
1049
1050
|
print(ver)
|
1050
1051
|
return
|
1051
1052
|
|
1053
|
+
sys.argv = [x for x in sys.argv if x != "--ws"]
|
1054
|
+
|
1052
1055
|
# fmt: off
|
1053
1056
|
ap = app = argparse.ArgumentParser(formatter_class=APF, description="copyparty up2k uploader / filesearch tool, " + ver, epilog="""
|
1054
1057
|
NOTE:
|
@@ -1067,7 +1070,6 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1067
1070
|
|
1068
1071
|
ap = app.add_argument_group("compatibility")
|
1069
1072
|
ap.add_argument("--cls", action="store_true", help="clear screen before start")
|
1070
|
-
ap.add_argument("--ws", action="store_true", help="copyparty is running on windows; wait before deleting files after uploading")
|
1071
1073
|
|
1072
1074
|
ap = app.add_argument_group("folder sync")
|
1073
1075
|
ap.add_argument("--dl", action="store_true", help="delete local files after uploading")
|
@@ -1131,10 +1133,6 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1131
1133
|
|
1132
1134
|
if ar.dr and not ar.drd:
|
1133
1135
|
print("\npass 2/2: delete")
|
1134
|
-
if getattr(ctl, "up_br") and ar.ws:
|
1135
|
-
# wait for up2k to mtime if there was uploads
|
1136
|
-
time.sleep(4)
|
1137
|
-
|
1138
1136
|
ar.drd = True
|
1139
1137
|
ar.z = True
|
1140
1138
|
Ctl(ar, ctl.stats)
|
copyparty/web/baguettebox.js.gz
CHANGED
Binary file
|
copyparty/web/browser.css.gz
CHANGED
Binary file
|
copyparty/web/browser.js.gz
CHANGED
Binary file
|
Binary file
|
copyparty/web/deps/easymde.js.gz
CHANGED
Binary file
|
copyparty/web/deps/marked.js.gz
CHANGED
Binary file
|
Binary file
|
Binary file
|
copyparty/web/md.js.gz
CHANGED
Binary file
|
copyparty/web/svcs.html
CHANGED
@@ -43,10 +43,9 @@
|
|
43
43
|
<h1>WebDAV</h1>
|
44
44
|
|
45
45
|
<div class="os win">
|
46
|
-
<p><em>note: rclone-FTP is a bit faster, so {% if args.ftp or args.ftps %}try that first{% else %}consider enabling FTP in server settings{% endif %}</em></p>
|
47
46
|
<p>if you can, install <a href="https://winfsp.dev/rel/">winfsp</a>+<a href="https://downloads.rclone.org/rclone-current-windows-amd64.zip">rclone</a> and then paste this in cmd:</p>
|
48
47
|
<pre>
|
49
|
-
rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=
|
48
|
+
rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=owncloud pacer_min_sleep=0.01ms{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
|
50
49
|
rclone mount --vfs-cache-mode writes --dir-cache-time 5s {{ aname }}-dav:{{ rvp }} <b>W:</b>
|
51
50
|
</pre>
|
52
51
|
{% if s %}
|
@@ -69,9 +68,9 @@
|
|
69
68
|
printf '%s\n' "http{{ s }}://{{ ep }}/{{ rvp }} <b>{{ pw }}</b> k" >> /etc/davfs2/secrets
|
70
69
|
printf '%s\n' "http{{ s }}://{{ ep }}/{{ rvp }} <b>mp</b> davfs rw,user,uid=1000,noauto 0 0" >> /etc/fstab
|
71
70
|
</pre>
|
72
|
-
<p>or you can use rclone instead, which is much slower but doesn't require root:</p>
|
71
|
+
<p>or you can use rclone instead, which is much slower but doesn't require root (plus it keeps lastmodified on upload):</p>
|
73
72
|
<pre>
|
74
|
-
rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=
|
73
|
+
rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=owncloud pacer_min_sleep=0.01ms{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
|
75
74
|
rclone mount --vfs-cache-mode writes --dir-cache-time 5s {{ aname }}-dav:{{ rvp }} <b>mp</b>
|
76
75
|
</pre>
|
77
76
|
{% if s %}
|
copyparty/web/ui.css.gz
CHANGED
Binary file
|
copyparty/web/util.js.gz
CHANGED
Binary file
|
@@ -1,29 +1,16 @@
|
|
1
1
|
# 💾🎉 copyparty
|
2
2
|
|
3
|
-
|
4
|
-
* MIT-Licensed, 2019-05-26, ed @ irc.rizon.net
|
3
|
+
turn almost any device into a file server with resumable uploads/downloads using [*any*](#browser-support) web browser
|
5
4
|
|
5
|
+
* server only needs Python (2 or 3), all dependencies optional
|
6
|
+
* 🔌 protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
|
7
|
+
* 📱 [android app](#android-app) // [iPhone shortcuts](#ios-shortcuts)
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
turn your phone or raspi into a portable file server with resumable uploads/downloads using *any* web browser
|
10
|
-
|
11
|
-
* server only needs Python (`2.7` or `3.3+`), all dependencies optional
|
12
|
-
* browse/upload with [IE4](#browser-support) / netscape4.0 on win3.11 (heh)
|
13
|
-
* protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
|
14
|
-
|
15
|
-
**[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
|
9
|
+
👉 **[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
|
16
10
|
|
17
11
|
📷 **screenshots:** [browser](#the-browser) // [upload](#uploading) // [unpost](#unpost) // [thumbnails](#thumbnails) // [search](#searching) // [fsearch](#file-search) // [zip-DL](#zip-downloads) // [md-viewer](#markdown-viewer)
|
18
12
|
|
19
13
|
|
20
|
-
## get the app
|
21
|
-
|
22
|
-
<a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
|
23
|
-
|
24
|
-
(the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet)
|
25
|
-
|
26
|
-
|
27
14
|
## readme toc
|
28
15
|
|
29
16
|
* top
|
@@ -82,12 +69,16 @@ turn your phone or raspi into a portable file server with resumable uploads/down
|
|
82
69
|
* [reverse-proxy](#reverse-proxy) - running copyparty next to other websites
|
83
70
|
* [browser support](#browser-support) - TLDR: yes
|
84
71
|
* [client examples](#client-examples) - interact with copyparty using non-browser clients
|
72
|
+
* [folder sync](#folder-sync) - sync folders to/from copyparty
|
85
73
|
* [mount as drive](#mount-as-drive) - a remote copyparty server as a local filesystem
|
74
|
+
* [android app](#android-app) - upload to copyparty with one tap
|
75
|
+
* [iOS shortcuts](#iOS-shortcuts) - there is no iPhone app, but
|
86
76
|
* [performance](#performance) - defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
|
87
77
|
* [client-side](#client-side) - when uploading files
|
88
78
|
* [security](#security) - some notes on hardening
|
89
79
|
* [gotchas](#gotchas) - behavior that might be unexpected
|
90
80
|
* [cors](#cors) - cross-site request config
|
81
|
+
* [https](#https) - both HTTP and HTTPS are accepted
|
91
82
|
* [recovering from crashes](#recovering-from-crashes)
|
92
83
|
* [client crashes](#client-crashes)
|
93
84
|
* [frefox wsod](#frefox-wsod) - firefox 87 can crash during uploads
|
@@ -139,7 +130,7 @@ some recommended options:
|
|
139
130
|
|
140
131
|
you may also want these, especially on servers:
|
141
132
|
|
142
|
-
* [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service
|
133
|
+
* [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service (see guide inside)
|
143
134
|
* [contrib/systemd/prisonparty.service](contrib/systemd/prisonparty.service) to run it in a chroot (for extra security)
|
144
135
|
* [contrib/rc/copyparty](contrib/rc/copyparty) to run copyparty on FreeBSD
|
145
136
|
* [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) to [reverse-proxy](#reverse-proxy) behind nginx (for better https)
|
@@ -177,7 +168,7 @@ firewall-cmd --reload
|
|
177
168
|
* ☑ write-only folders
|
178
169
|
* ☑ [unpost](#unpost): undo/delete accidental uploads
|
179
170
|
* ☑ [self-destruct](#self-destruct) (specified server-side or client-side)
|
180
|
-
* ☑ symlink/discard
|
171
|
+
* ☑ symlink/discard duplicates (content-matching)
|
181
172
|
* download
|
182
173
|
* ☑ single files in browser
|
183
174
|
* ☑ [folders as zip / tar files](#zip-downloads)
|
@@ -199,7 +190,7 @@ firewall-cmd --reload
|
|
199
190
|
* ☑ search by name/path/date/size
|
200
191
|
* ☑ [search by ID3-tags etc.](#searching)
|
201
192
|
* client support
|
202
|
-
* ☑ [
|
193
|
+
* ☑ [folder sync](#folder-sync)
|
203
194
|
* ☑ [curl-friendly](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
|
204
195
|
* markdown
|
205
196
|
* ☑ [viewer](#markdown-viewer)
|
@@ -278,7 +269,7 @@ server notes:
|
|
278
269
|
|
279
270
|
* iPhones: the volume control doesn't work because [apple doesn't want it to](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11)
|
280
271
|
* *future workaround:* enable the equalizer, make it all-zero, and set a negative boost to reduce the volume
|
281
|
-
* "future" because `AudioContext`
|
272
|
+
* "future" because `AudioContext` can't maintain a stable playback speed in the current iOS version (15.7), maybe one day...
|
282
273
|
|
283
274
|
* Windows: folders cannot be accessed if the name ends with `.`
|
284
275
|
* python or windows bug
|
@@ -1102,13 +1093,15 @@ see the top of [./copyparty/web/browser.css](./copyparty/web/browser.css) where
|
|
1102
1093
|
|
1103
1094
|
## reverse-proxy
|
1104
1095
|
|
1105
|
-
running copyparty next to other websites hosted on an existing webserver such as nginx or apache
|
1096
|
+
running copyparty next to other websites hosted on an existing webserver such as nginx, caddy, or apache
|
1106
1097
|
|
1107
1098
|
you can either:
|
1108
1099
|
* give copyparty its own domain or subdomain (recommended)
|
1109
1100
|
* or do location-based proxying, using `--rp-loc=/stuff` to tell copyparty where it is mounted -- has a slight performance cost and higher chance of bugs
|
1110
1101
|
* if copyparty says `incorrect --rp-loc or webserver config; expected vpath starting with [...]` it's likely because the webserver is stripping away the proxy location from the request URLs -- see the `ProxyPass` in the apache example below
|
1111
1102
|
|
1103
|
+
some reverse proxies (such as [Caddy](https://caddyserver.com/)) can automatically obtain a valid https/tls certificate for you, and some support HTTP/2 and QUIC which could be a nice speed boost
|
1104
|
+
|
1112
1105
|
example webserver configs:
|
1113
1106
|
|
1114
1107
|
* [nginx config](contrib/nginx/copyparty.conf) -- entire domain/subdomain
|
@@ -1186,7 +1179,7 @@ interact with copyparty using non-browser clients
|
|
1186
1179
|
* `(printf 'PUT / HTTP/1.1\r\n\r\n'; cat movie.mkv) >/dev/tcp/127.0.0.1/3923`
|
1187
1180
|
|
1188
1181
|
* python: [up2k.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/up2k.py) is a command-line up2k client [(webm)](https://ocv.me/stuff/u2cli.webm)
|
1189
|
-
* file uploads, file-search, folder sync, autoresume of aborted/broken uploads
|
1182
|
+
* file uploads, file-search, [folder sync](#folder-sync), autoresume of aborted/broken uploads
|
1190
1183
|
* can be downloaded from copyparty: controlpanel -> connect -> [up2k.py](http://127.0.0.1:3923/.cpr/a/up2k.py)
|
1191
1184
|
* see [./bin/README.md#up2kpy](bin/README.md#up2kpy)
|
1192
1185
|
|
@@ -1207,17 +1200,27 @@ you can provide passwords using header `PW: hunter2`, cookie `cppwd=hunter2`, ur
|
|
1207
1200
|
NOTE: curl will not send the original filename if you use `-T` combined with url-params! Also, make sure to always leave a trailing slash in URLs unless you want to override the filename
|
1208
1201
|
|
1209
1202
|
|
1203
|
+
## folder sync
|
1204
|
+
|
1205
|
+
sync folders to/from copyparty
|
1206
|
+
|
1207
|
+
the commandline uploader [up2k.py](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy) with `--dr` is the best way to sync a folder to copyparty; verifies checksums and does files in parallel, and deletes unexpected files on the server after upload has finished which makes file-renames really cheap (it'll rename serverside and skip uploading)
|
1208
|
+
|
1209
|
+
alternatively there is [rclone](./docs/rclone.md) which allows for bidirectional sync and is *way* more flexible (stream files straight from sftp/s3/gcs to copyparty, ...), although there is no integrity check and it won't work with files over 100 MiB if copyparty is behind cloudflare
|
1210
|
+
|
1211
|
+
* starting from rclone v1.63 (currently [in beta](https://beta.rclone.org/?filter=latest)), rclone will also be faster than up2k.py
|
1212
|
+
|
1213
|
+
|
1210
1214
|
## mount as drive
|
1211
1215
|
|
1212
1216
|
a remote copyparty server as a local filesystem; go to the control-panel and click `connect` to see a list of commands to do that
|
1213
1217
|
|
1214
1218
|
alternatively, some alternatives roughly sorted by speed (unreproducible benchmark), best first:
|
1215
1219
|
|
1216
|
-
* [rclone-
|
1220
|
+
* [rclone-webdav](./docs/rclone.md) (25s), read/WRITE ([v1.63-beta](https://beta.rclone.org/?filter=latest))
|
1221
|
+
* [rclone-http](./docs/rclone.md) (26s), read-only
|
1222
|
+
* [partyfuse.py](./bin/#partyfusepy) (35s), read-only
|
1217
1223
|
* [rclone-ftp](./docs/rclone.md) (47s), read/WRITE
|
1218
|
-
* [rclone-webdav](./docs/rclone.md) (51s), read/WRITE
|
1219
|
-
* copyparty-1.5.0's webdav server is faster than rclone-1.60.0 (69s)
|
1220
|
-
* [partyfuse.py](./bin/#partyfusepy) (71s), read-only
|
1221
1224
|
* davfs2 (103s), read/WRITE, *very fast* on small files
|
1222
1225
|
* [win10-webdav](#webdav-server) (138s), read/WRITE
|
1223
1226
|
* [win10-smb2](#smb-server) (387s), read/WRITE
|
@@ -1225,6 +1228,27 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
|
|
1225
1228
|
most clients will fail to mount the root of a copyparty server unless there is a root volume (so you get the admin-panel instead of a browser when accessing it) -- in that case, mount a specific volume instead
|
1226
1229
|
|
1227
1230
|
|
1231
|
+
# android app
|
1232
|
+
|
1233
|
+
upload to copyparty with one tap
|
1234
|
+
|
1235
|
+
<a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
|
1236
|
+
|
1237
|
+
the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet
|
1238
|
+
|
1239
|
+
if you want to run the copyparty server on your android device, see [install on android](#install-on-android)
|
1240
|
+
|
1241
|
+
|
1242
|
+
# iOS shortcuts
|
1243
|
+
|
1244
|
+
there is no iPhone app, but the following shortcuts are almost as good:
|
1245
|
+
|
1246
|
+
* [upload to copyparty](https://www.icloud.com/shortcuts/41e98dd985cb4d3bb433222bc1e9e770) ([offline](https://github.com/9001/copyparty/raw/hovudstraum/contrib/ios/upload-to-copyparty.shortcut)) ([png](https://user-images.githubusercontent.com/241032/226118053-78623554-b0ed-482e-98e4-6d57ada58ea4.png)) based on the [original](https://www.icloud.com/shortcuts/ab415d5b4de3467b9ce6f151b439a5d7) by [Daedren](https://github.com/Daedren) (thx!)
|
1247
|
+
* can strip exif, upload files, pics, vids, links, clipboard
|
1248
|
+
* can download links and rehost the target file on copyparty (see first comment inside the shortcut)
|
1249
|
+
* pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
|
1250
|
+
|
1251
|
+
|
1228
1252
|
# performance
|
1229
1253
|
|
1230
1254
|
defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
|
@@ -1320,6 +1344,13 @@ by default, except for `GET` and `HEAD` operations, all requests must either:
|
|
1320
1344
|
cors can be configured with `--acao` and `--acam`, or the protections entirely disabled with `--allow-csrf`
|
1321
1345
|
|
1322
1346
|
|
1347
|
+
## https
|
1348
|
+
|
1349
|
+
both HTTP and HTTPS are accepted by default, but letting a [reverse proxy](#reverse-proxy) handle the https/tls/ssl would be better (probably more secure by default)
|
1350
|
+
|
1351
|
+
copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
|
1352
|
+
|
1353
|
+
|
1323
1354
|
# recovering from crashes
|
1324
1355
|
|
1325
1356
|
## client crashes
|
@@ -1387,7 +1418,7 @@ these are standalone programs and will never be imported / evaluated by copypart
|
|
1387
1418
|
|
1388
1419
|
the self-contained "binary" [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) will unpack itself and run copyparty, assuming you have python installed of course
|
1389
1420
|
|
1390
|
-
you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](
|
1421
|
+
you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
|
1391
1422
|
|
1392
1423
|
|
1393
1424
|
## copyparty.exe
|
@@ -1009,8 +1009,9 @@ class Ctl(object):
|
|
1009
1009
|
file, cid = task
|
1010
1010
|
try:
|
1011
1011
|
upload(file, cid, self.ar.a, stats)
|
1012
|
-
except:
|
1013
|
-
|
1012
|
+
except Exception as ex:
|
1013
|
+
t = "upload failed, retrying: {0} #{1} ({2})\n"
|
1014
|
+
eprint(t.format(file.name, cid[:8], ex))
|
1014
1015
|
# handshake will fix it
|
1015
1016
|
|
1016
1017
|
with self.mutex:
|
@@ -1049,6 +1050,8 @@ def main():
|
|
1049
1050
|
print(ver)
|
1050
1051
|
return
|
1051
1052
|
|
1053
|
+
sys.argv = [x for x in sys.argv if x != "--ws"]
|
1054
|
+
|
1052
1055
|
# fmt: off
|
1053
1056
|
ap = app = argparse.ArgumentParser(formatter_class=APF, description="copyparty up2k uploader / filesearch tool, " + ver, epilog="""
|
1054
1057
|
NOTE:
|
@@ -1067,7 +1070,6 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1067
1070
|
|
1068
1071
|
ap = app.add_argument_group("compatibility")
|
1069
1072
|
ap.add_argument("--cls", action="store_true", help="clear screen before start")
|
1070
|
-
ap.add_argument("--ws", action="store_true", help="copyparty is running on windows; wait before deleting files after uploading")
|
1071
1073
|
|
1072
1074
|
ap = app.add_argument_group("folder sync")
|
1073
1075
|
ap.add_argument("--dl", action="store_true", help="delete local files after uploading")
|
@@ -1131,10 +1133,6 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1131
1133
|
|
1132
1134
|
if ar.dr and not ar.drd:
|
1133
1135
|
print("\npass 2/2: delete")
|
1134
|
-
if getattr(ctl, "up_br") and ar.ws:
|
1135
|
-
# wait for up2k to mtime if there was uploads
|
1136
|
-
time.sleep(4)
|
1137
|
-
|
1138
1136
|
ar.drd = True
|
1139
1137
|
ar.z = True
|
1140
1138
|
Ctl(ar, ctl.stats)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.6.
|
3
|
+
Version: 1.6.11
|
4
4
|
Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
|
5
5
|
Home-page: https://github.com/9001/copyparty
|
6
6
|
Author: ed
|
@@ -47,30 +47,17 @@ Requires-Dist: pyvips ; extra == 'thumbnails2'
|
|
47
47
|
|
48
48
|
# 💾🎉 copyparty
|
49
49
|
|
50
|
-
|
51
|
-
* MIT-Licensed, 2019-05-26, ed @ irc.rizon.net
|
50
|
+
turn almost any device into a file server with resumable uploads/downloads using [*any*](#browser-support) web browser
|
52
51
|
|
52
|
+
* server only needs Python (2 or 3), all dependencies optional
|
53
|
+
* 🔌 protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
|
54
|
+
* 📱 [android app](#android-app) // [iPhone shortcuts](#ios-shortcuts)
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
turn your phone or raspi into a portable file server with resumable uploads/downloads using *any* web browser
|
57
|
-
|
58
|
-
* server only needs Python (`2.7` or `3.3+`), all dependencies optional
|
59
|
-
* browse/upload with [IE4](#browser-support) / netscape4.0 on win3.11 (heh)
|
60
|
-
* protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
|
61
|
-
|
62
|
-
**[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
|
56
|
+
👉 **[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
|
63
57
|
|
64
58
|
📷 **screenshots:** [browser](#the-browser) // [upload](#uploading) // [unpost](#unpost) // [thumbnails](#thumbnails) // [search](#searching) // [fsearch](#file-search) // [zip-DL](#zip-downloads) // [md-viewer](#markdown-viewer)
|
65
59
|
|
66
60
|
|
67
|
-
## get the app
|
68
|
-
|
69
|
-
<a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
|
70
|
-
|
71
|
-
(the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet)
|
72
|
-
|
73
|
-
|
74
61
|
## readme toc
|
75
62
|
|
76
63
|
* top
|
@@ -129,12 +116,16 @@ turn your phone or raspi into a portable file server with resumable uploads/down
|
|
129
116
|
* [reverse-proxy](#reverse-proxy) - running copyparty next to other websites
|
130
117
|
* [browser support](#browser-support) - TLDR: yes
|
131
118
|
* [client examples](#client-examples) - interact with copyparty using non-browser clients
|
119
|
+
* [folder sync](#folder-sync) - sync folders to/from copyparty
|
132
120
|
* [mount as drive](#mount-as-drive) - a remote copyparty server as a local filesystem
|
121
|
+
* [android app](#android-app) - upload to copyparty with one tap
|
122
|
+
* [iOS shortcuts](#iOS-shortcuts) - there is no iPhone app, but
|
133
123
|
* [performance](#performance) - defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
|
134
124
|
* [client-side](#client-side) - when uploading files
|
135
125
|
* [security](#security) - some notes on hardening
|
136
126
|
* [gotchas](#gotchas) - behavior that might be unexpected
|
137
127
|
* [cors](#cors) - cross-site request config
|
128
|
+
* [https](#https) - both HTTP and HTTPS are accepted
|
138
129
|
* [recovering from crashes](#recovering-from-crashes)
|
139
130
|
* [client crashes](#client-crashes)
|
140
131
|
* [frefox wsod](#frefox-wsod) - firefox 87 can crash during uploads
|
@@ -186,7 +177,7 @@ some recommended options:
|
|
186
177
|
|
187
178
|
you may also want these, especially on servers:
|
188
179
|
|
189
|
-
* [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service
|
180
|
+
* [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service (see guide inside)
|
190
181
|
* [contrib/systemd/prisonparty.service](contrib/systemd/prisonparty.service) to run it in a chroot (for extra security)
|
191
182
|
* [contrib/rc/copyparty](contrib/rc/copyparty) to run copyparty on FreeBSD
|
192
183
|
* [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) to [reverse-proxy](#reverse-proxy) behind nginx (for better https)
|
@@ -224,7 +215,7 @@ firewall-cmd --reload
|
|
224
215
|
* ☑ write-only folders
|
225
216
|
* ☑ [unpost](#unpost): undo/delete accidental uploads
|
226
217
|
* ☑ [self-destruct](#self-destruct) (specified server-side or client-side)
|
227
|
-
* ☑ symlink/discard
|
218
|
+
* ☑ symlink/discard duplicates (content-matching)
|
228
219
|
* download
|
229
220
|
* ☑ single files in browser
|
230
221
|
* ☑ [folders as zip / tar files](#zip-downloads)
|
@@ -246,7 +237,7 @@ firewall-cmd --reload
|
|
246
237
|
* ☑ search by name/path/date/size
|
247
238
|
* ☑ [search by ID3-tags etc.](#searching)
|
248
239
|
* client support
|
249
|
-
* ☑ [
|
240
|
+
* ☑ [folder sync](#folder-sync)
|
250
241
|
* ☑ [curl-friendly](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
|
251
242
|
* markdown
|
252
243
|
* ☑ [viewer](#markdown-viewer)
|
@@ -325,7 +316,7 @@ server notes:
|
|
325
316
|
|
326
317
|
* iPhones: the volume control doesn't work because [apple doesn't want it to](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11)
|
327
318
|
* *future workaround:* enable the equalizer, make it all-zero, and set a negative boost to reduce the volume
|
328
|
-
* "future" because `AudioContext`
|
319
|
+
* "future" because `AudioContext` can't maintain a stable playback speed in the current iOS version (15.7), maybe one day...
|
329
320
|
|
330
321
|
* Windows: folders cannot be accessed if the name ends with `.`
|
331
322
|
* python or windows bug
|
@@ -1149,13 +1140,15 @@ see the top of [./copyparty/web/browser.css](./copyparty/web/browser.css) where
|
|
1149
1140
|
|
1150
1141
|
## reverse-proxy
|
1151
1142
|
|
1152
|
-
running copyparty next to other websites hosted on an existing webserver such as nginx or apache
|
1143
|
+
running copyparty next to other websites hosted on an existing webserver such as nginx, caddy, or apache
|
1153
1144
|
|
1154
1145
|
you can either:
|
1155
1146
|
* give copyparty its own domain or subdomain (recommended)
|
1156
1147
|
* or do location-based proxying, using `--rp-loc=/stuff` to tell copyparty where it is mounted -- has a slight performance cost and higher chance of bugs
|
1157
1148
|
* if copyparty says `incorrect --rp-loc or webserver config; expected vpath starting with [...]` it's likely because the webserver is stripping away the proxy location from the request URLs -- see the `ProxyPass` in the apache example below
|
1158
1149
|
|
1150
|
+
some reverse proxies (such as [Caddy](https://caddyserver.com/)) can automatically obtain a valid https/tls certificate for you, and some support HTTP/2 and QUIC which could be a nice speed boost
|
1151
|
+
|
1159
1152
|
example webserver configs:
|
1160
1153
|
|
1161
1154
|
* [nginx config](contrib/nginx/copyparty.conf) -- entire domain/subdomain
|
@@ -1233,7 +1226,7 @@ interact with copyparty using non-browser clients
|
|
1233
1226
|
* `(printf 'PUT / HTTP/1.1\r\n\r\n'; cat movie.mkv) >/dev/tcp/127.0.0.1/3923`
|
1234
1227
|
|
1235
1228
|
* python: [up2k.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/up2k.py) is a command-line up2k client [(webm)](https://ocv.me/stuff/u2cli.webm)
|
1236
|
-
* file uploads, file-search, folder sync, autoresume of aborted/broken uploads
|
1229
|
+
* file uploads, file-search, [folder sync](#folder-sync), autoresume of aborted/broken uploads
|
1237
1230
|
* can be downloaded from copyparty: controlpanel -> connect -> [up2k.py](http://127.0.0.1:3923/.cpr/a/up2k.py)
|
1238
1231
|
* see [./bin/README.md#up2kpy](bin/README.md#up2kpy)
|
1239
1232
|
|
@@ -1254,17 +1247,27 @@ you can provide passwords using header `PW: hunter2`, cookie `cppwd=hunter2`, ur
|
|
1254
1247
|
NOTE: curl will not send the original filename if you use `-T` combined with url-params! Also, make sure to always leave a trailing slash in URLs unless you want to override the filename
|
1255
1248
|
|
1256
1249
|
|
1250
|
+
## folder sync
|
1251
|
+
|
1252
|
+
sync folders to/from copyparty
|
1253
|
+
|
1254
|
+
the commandline uploader [up2k.py](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy) with `--dr` is the best way to sync a folder to copyparty; verifies checksums and does files in parallel, and deletes unexpected files on the server after upload has finished which makes file-renames really cheap (it'll rename serverside and skip uploading)
|
1255
|
+
|
1256
|
+
alternatively there is [rclone](./docs/rclone.md) which allows for bidirectional sync and is *way* more flexible (stream files straight from sftp/s3/gcs to copyparty, ...), although there is no integrity check and it won't work with files over 100 MiB if copyparty is behind cloudflare
|
1257
|
+
|
1258
|
+
* starting from rclone v1.63 (currently [in beta](https://beta.rclone.org/?filter=latest)), rclone will also be faster than up2k.py
|
1259
|
+
|
1260
|
+
|
1257
1261
|
## mount as drive
|
1258
1262
|
|
1259
1263
|
a remote copyparty server as a local filesystem; go to the control-panel and click `connect` to see a list of commands to do that
|
1260
1264
|
|
1261
1265
|
alternatively, some alternatives roughly sorted by speed (unreproducible benchmark), best first:
|
1262
1266
|
|
1263
|
-
* [rclone-
|
1267
|
+
* [rclone-webdav](./docs/rclone.md) (25s), read/WRITE ([v1.63-beta](https://beta.rclone.org/?filter=latest))
|
1268
|
+
* [rclone-http](./docs/rclone.md) (26s), read-only
|
1269
|
+
* [partyfuse.py](./bin/#partyfusepy) (35s), read-only
|
1264
1270
|
* [rclone-ftp](./docs/rclone.md) (47s), read/WRITE
|
1265
|
-
* [rclone-webdav](./docs/rclone.md) (51s), read/WRITE
|
1266
|
-
* copyparty-1.5.0's webdav server is faster than rclone-1.60.0 (69s)
|
1267
|
-
* [partyfuse.py](./bin/#partyfusepy) (71s), read-only
|
1268
1271
|
* davfs2 (103s), read/WRITE, *very fast* on small files
|
1269
1272
|
* [win10-webdav](#webdav-server) (138s), read/WRITE
|
1270
1273
|
* [win10-smb2](#smb-server) (387s), read/WRITE
|
@@ -1272,6 +1275,27 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
|
|
1272
1275
|
most clients will fail to mount the root of a copyparty server unless there is a root volume (so you get the admin-panel instead of a browser when accessing it) -- in that case, mount a specific volume instead
|
1273
1276
|
|
1274
1277
|
|
1278
|
+
# android app
|
1279
|
+
|
1280
|
+
upload to copyparty with one tap
|
1281
|
+
|
1282
|
+
<a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
|
1283
|
+
|
1284
|
+
the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet
|
1285
|
+
|
1286
|
+
if you want to run the copyparty server on your android device, see [install on android](#install-on-android)
|
1287
|
+
|
1288
|
+
|
1289
|
+
# iOS shortcuts
|
1290
|
+
|
1291
|
+
there is no iPhone app, but the following shortcuts are almost as good:
|
1292
|
+
|
1293
|
+
* [upload to copyparty](https://www.icloud.com/shortcuts/41e98dd985cb4d3bb433222bc1e9e770) ([offline](https://github.com/9001/copyparty/raw/hovudstraum/contrib/ios/upload-to-copyparty.shortcut)) ([png](https://user-images.githubusercontent.com/241032/226118053-78623554-b0ed-482e-98e4-6d57ada58ea4.png)) based on the [original](https://www.icloud.com/shortcuts/ab415d5b4de3467b9ce6f151b439a5d7) by [Daedren](https://github.com/Daedren) (thx!)
|
1294
|
+
* can strip exif, upload files, pics, vids, links, clipboard
|
1295
|
+
* can download links and rehost the target file on copyparty (see first comment inside the shortcut)
|
1296
|
+
* pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
|
1297
|
+
|
1298
|
+
|
1275
1299
|
# performance
|
1276
1300
|
|
1277
1301
|
defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
|
@@ -1367,6 +1391,13 @@ by default, except for `GET` and `HEAD` operations, all requests must either:
|
|
1367
1391
|
cors can be configured with `--acao` and `--acam`, or the protections entirely disabled with `--allow-csrf`
|
1368
1392
|
|
1369
1393
|
|
1394
|
+
## https
|
1395
|
+
|
1396
|
+
both HTTP and HTTPS are accepted by default, but letting a [reverse proxy](#reverse-proxy) handle the https/tls/ssl would be better (probably more secure by default)
|
1397
|
+
|
1398
|
+
copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
|
1399
|
+
|
1400
|
+
|
1370
1401
|
# recovering from crashes
|
1371
1402
|
|
1372
1403
|
## client crashes
|
@@ -1434,7 +1465,7 @@ these are standalone programs and will never be imported / evaluated by copypart
|
|
1434
1465
|
|
1435
1466
|
the self-contained "binary" [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) will unpack itself and run copyparty, assuming you have python installed of course
|
1436
1467
|
|
1437
|
-
you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](
|
1468
|
+
you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
|
1438
1469
|
|
1439
1470
|
|
1440
1471
|
## copyparty.exe
|
@@ -1,6 +1,6 @@
|
|
1
1
|
copyparty/__init__.py,sha256=ZIYqHdNC97NeoBTkFDSZ6E8aAma1tfjLhbax9oQHl4U,1063
|
2
|
-
copyparty/__main__.py,sha256=
|
3
|
-
copyparty/__version__.py,sha256=
|
2
|
+
copyparty/__main__.py,sha256=NeG2cQHE4uRQ02zHZ7gv-NAlRgmTWmVSslPH5Uk84NI,66925
|
3
|
+
copyparty/__version__.py,sha256=Rjr8n-EApIithnjIGWw74_DGKrayh0_AUylCp1sLxk0,247
|
4
4
|
copyparty/authsrv.py,sha256=Sh793NWnpklcz1ZEj-pt0FISjx-_BZJ8fkWm5rbWKrA,62030
|
5
5
|
copyparty/broker_mp.py,sha256=SEJT7qIH7L0YH0e1yHucsUuYJE5m3DKymO57070_UCs,3590
|
6
6
|
copyparty/broker_mpw.py,sha256=GlSn4PRd_OqqeG39FiXgNvPzXVQW6UCiAcqmBSr2q6g,3200
|
@@ -10,7 +10,7 @@ copyparty/cfg.py,sha256=ukauOEs_WKxzkt4MzIfLAU9eKGq9ZGcyIKSFMScc8xg,6436
|
|
10
10
|
copyparty/dxml.py,sha256=lZpg-kn-kQsXRtNY1n6fRaS-b7uXzMCyv8ovKnhZcZc,1548
|
11
11
|
copyparty/fsutil.py,sha256=c4fTvmclKbVABNsjU4rGddsjCgRwi9YExAyo-06ATc8,3932
|
12
12
|
copyparty/ftpd.py,sha256=pPLkQTNmqfZRGfzALzZApEj6N8l3yo24RqDGDqISeyE,13841
|
13
|
-
copyparty/httpcli.py,sha256=
|
13
|
+
copyparty/httpcli.py,sha256=BcoVcyvVq32_ilEvbAjzB1zgvCyK28MXQTWUMB0gVFA,120713
|
14
14
|
copyparty/httpconn.py,sha256=LXyJphs-FtyhFeDF-YUGVXKGf9KvHA86UzVx4FvRZo0,6674
|
15
15
|
copyparty/httpsrv.py,sha256=EQsGZgKvN_D_eZ-XbFPZgFXTQc2Y2EXCo2qQhfWbf_4,14143
|
16
16
|
copyparty/ico.py,sha256=eP_FGZEsnCLr6Q1ypITp7kbMKtQiDeROv0ydrbEKfIY,2643
|
@@ -25,9 +25,9 @@ copyparty/svchub.py,sha256=gqrIWzUT7Cz4Fd_lK0DKd5dLvNQuM0_YhJzpgXeUE78,22903
|
|
25
25
|
copyparty/szip.py,sha256=o8NzYcqUUjg2MPvESa4VnAaANqD_JofBSr7Sb7eWu4I,8166
|
26
26
|
copyparty/tcpsrv.py,sha256=ccUXnAa7IeRPWaaTAuOVcSgdBetlHVoJozsTrZcFx8Q,16633
|
27
27
|
copyparty/th_cli.py,sha256=hcb-GGN7krnHF3LIp3tDix_OYwXnCRoTpsiO0TaDqOg,3826
|
28
|
-
copyparty/th_srv.py,sha256=
|
28
|
+
copyparty/th_srv.py,sha256=O7SJDLBx6pcRUiOR4G6Rqpi7FGthekedGTK3CXIFi_E,22119
|
29
29
|
copyparty/u2idx.py,sha256=n3DSFc67tIk-Jn8-Z5EEG8Xb_qv48KomJFYvoXlmV-U,10493
|
30
|
-
copyparty/up2k.py,sha256=
|
30
|
+
copyparty/up2k.py,sha256=sZem4PlqUnXsNPpn2XzbfU0Zz3EMrPYpMeqYBKuDQd4,121292
|
31
31
|
copyparty/util.py,sha256=hAZ4AN5rMQgDPYKiRdA3Qh-dZ0cBsaODR-mNrSuNwzw,71782
|
32
32
|
copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
33
|
copyparty/bos/bos.py,sha256=Md2RwMauEdOS7SfK5aiHby8T1KgQoTaoEjVCYU98_4I,1560
|
@@ -49,17 +49,17 @@ copyparty/stolen/ifaddr/__init__.py,sha256=_BUN7eM5oD2Jgib6B22tEFSb20fD9urNPPaAl
|
|
49
49
|
copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUuTOrU,2626
|
50
50
|
copyparty/stolen/ifaddr/_shared.py,sha256=cJACl8cOxQ-HSYphZTzKMAjAx_TAFyJwUPjfD102Xqw,6111
|
51
51
|
copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
|
52
|
-
copyparty/web/baguettebox.js.gz,sha256=
|
53
|
-
copyparty/web/browser.css.gz,sha256=
|
52
|
+
copyparty/web/baguettebox.js.gz,sha256=9ZXtLOKGTCRzIisSRIvqnO1s1ZQ90pxzoTU6vPol0m4,7295
|
53
|
+
copyparty/web/browser.css.gz,sha256=9oT_dnWhHdVrERi9GkNQElpcAhG1UtbUurqR033167U,10929
|
54
54
|
copyparty/web/browser.html,sha256=561cy72h48x7g6_ZHXsAS3xYqnNwrXB1KK9VBVBqio8,5286
|
55
|
-
copyparty/web/browser.js.gz,sha256=
|
55
|
+
copyparty/web/browser.js.gz,sha256=28jB3rWCHZsS2a2OZHzI-GQZihMa4RxKyBp9PLL31IU,57919
|
56
56
|
copyparty/web/browser2.html,sha256=3kR3QiDXYqtAo7gOoBtdTP3eRvibUCZHVVAbmAfaAVU,1604
|
57
57
|
copyparty/web/cf.html,sha256=AQSPDFq1-Ww-9SyVLZtjVPfl054aqXs6svi5cQBlAdA,585
|
58
58
|
copyparty/web/copyparty.gif,sha256=S1YS9GrKPbueEob_yTeWqzDcDoRXU_Z209BJ4YF-9pQ,126
|
59
59
|
copyparty/web/dbg-audio.js.gz,sha256=MgESInC83l8nnKTd8JSbSmLy_lXwlypML153FAm2TmU,687
|
60
60
|
copyparty/web/md.css.gz,sha256=gEI11ImLwhWYrsfb4YWx1OS1RgkpxHGsuMTJpcychJg,2011
|
61
61
|
copyparty/web/md.html,sha256=CmkW3Aw2qGowEsFBk-4THRWJBR-fyNmkl1Dr15lPwdg,4063
|
62
|
-
copyparty/web/md.js.gz,sha256
|
62
|
+
copyparty/web/md.js.gz,sha256=-4-0wF1YlLqHyiLpJQHTUPV4bys52hbbA9sKWEeRaFY,4121
|
63
63
|
copyparty/web/md2.css.gz,sha256=83brwCdNBp7n0zr2O3fYFn9OP1i-mXfd-nde78imLGw,680
|
64
64
|
copyparty/web/md2.js.gz,sha256=zpXdpg7yxZYPEU5UphdMQPsYQBkfSJM8z5OIKaoITpw,8209
|
65
65
|
copyparty/web/mde.css.gz,sha256=L6YhxnYBoqT5bSwD99rx8ALXDh8d_1-sCvbc_p3MoAU,929
|
@@ -70,15 +70,15 @@ copyparty/web/msg.html,sha256=JQFDP-jOhBM4pln5bOyncC9lJ6YpN2TMIyNn-bLNSqE,898
|
|
70
70
|
copyparty/web/splash.css.gz,sha256=dVMI8zrGO2glmPDS0QKhVmBgExe3p-QdUUIJ5EUWdrA,927
|
71
71
|
copyparty/web/splash.html,sha256=tqCewuM2HMkkR7MH8ijgtAM1LHqlawqJgTGvG7NzECY,3741
|
72
72
|
copyparty/web/splash.js.gz,sha256=2VuxIx4y0hyW9I5NWG83Bcabk5NJDftQt7a_j9Gb5nY,1235
|
73
|
-
copyparty/web/svcs.html,sha256=
|
73
|
+
copyparty/web/svcs.html,sha256=crtzPR4VKBKVRKY5m1DsDk4vmgBdVLpbOCgRa3nTrYk,9274
|
74
74
|
copyparty/web/svcs.js.gz,sha256=SSVKYYgZkEKMdDLjekvcXB00v-rCVJXh2GD_YtCvu7c,519
|
75
|
-
copyparty/web/ui.css.gz,sha256=
|
75
|
+
copyparty/web/ui.css.gz,sha256=Vx-kzNtCsAq7N3W9n27WE8zd6nNLegT0_v5AWmYyk7g,2418
|
76
76
|
copyparty/web/up2k.js.gz,sha256=fGYvDuq34kVz16occIYU9KUQZF9ZemcQLI57o2_DmK4,21538
|
77
|
-
copyparty/web/util.js.gz,sha256=
|
77
|
+
copyparty/web/util.js.gz,sha256=isC6LW43SGcZn9ueMfmxGmKzSxJtwqjY3_R2AhNPUdM,13078
|
78
78
|
copyparty/web/w.hash.js.gz,sha256=07eXr3ktdGNmFBLpqWCp6LsAx8AqIyy1KDNz2-r3p8U,1059
|
79
79
|
copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
80
80
|
copyparty/web/a/partyfuse.py,sha256=mJKqR8LjX19P4Knqa02ob5ogwPVtJXSqxkEEGZU0r60,32276
|
81
|
-
copyparty/web/a/up2k.py,sha256=
|
81
|
+
copyparty/web/a/up2k.py,sha256=ZplodaoKL19ND5kI7LVi-5wYTCo2Qy8zYesv6OrO4gQ,34969
|
82
82
|
copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
|
83
83
|
copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
|
84
84
|
copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
|
@@ -86,24 +86,24 @@ copyparty/web/dd/4.png,sha256=fIwEVmtZNZtloZuVEKPKnkx3SELwRJmB3US61y7t2lI,248
|
|
86
86
|
copyparty/web/dd/5.png,sha256=Lfpu8-yOlhONuoMbygloKqQVPXSm9gjxH2gUYn5QQAE,250
|
87
87
|
copyparty/web/dd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
88
88
|
copyparty/web/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
89
|
-
copyparty/web/deps/easymde.css.gz,sha256=
|
90
|
-
copyparty/web/deps/easymde.js.gz,sha256=
|
91
|
-
copyparty/web/deps/marked.js.gz,sha256=
|
92
|
-
copyparty/web/deps/mini-fa.css.gz,sha256=
|
89
|
+
copyparty/web/deps/easymde.css.gz,sha256=bidHOWlCCwqvOrsz82ZzkTJzxXTJcKVVt328XZ72wYk,3053
|
90
|
+
copyparty/web/deps/easymde.js.gz,sha256=O0gNqyYoNMQ5wWd2bNO5D9VIS4SeI_GKN1aBPTyd6VI,76953
|
91
|
+
copyparty/web/deps/marked.js.gz,sha256=1xWr45dJMkwk0H58fZiLYmUYj1yaMP0BQ7S85XQgfQU,14819
|
92
|
+
copyparty/web/deps/mini-fa.css.gz,sha256=HKDETLj1IIUG3PhKixczxvPr5FAo-eD5phR03cf5Ijc,584
|
93
93
|
copyparty/web/deps/mini-fa.woff,sha256=L9DNncV2TIyvsrspMbJouvnnt7F068Hbn7YZYvN76AU,2784
|
94
94
|
copyparty/web/deps/prism.css.gz,sha256=dDssFDwbLNlB9QJsOepOdMse8FgrLrHIVpx1gNj4ZvY,1478
|
95
95
|
copyparty/web/deps/prism.js.gz,sha256=DR0OAfTUb6PkzSPgxjnjj7jqlpvuCHdMDJKbsQP7s5E,41428
|
96
96
|
copyparty/web/deps/prismd.css.gz,sha256=hzzspI_ptCygzmsIp9rKsf1M4yU12Ma7TfE-wyoXt3E,1647
|
97
97
|
copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
|
98
|
-
copyparty/web/deps/sha512.ac.js.gz,sha256=
|
98
|
+
copyparty/web/deps/sha512.ac.js.gz,sha256=qELXngcl-Zitrpwolm4EWqVBPyEht013iP7uDuUDPk4,7043
|
99
99
|
copyparty/web/deps/sha512.hw.js.gz,sha256=0xJaw75Tghoblu72C2h4YoU1izSR99mBtDMoGqZ3xvs,8119
|
100
|
-
copyparty-1.6.
|
101
|
-
copyparty-1.6.
|
102
|
-
copyparty-1.6.
|
103
|
-
copyparty-1.6.
|
104
|
-
copyparty-1.6.
|
105
|
-
copyparty-1.6.
|
106
|
-
copyparty-1.6.
|
107
|
-
copyparty-1.6.
|
108
|
-
copyparty-1.6.
|
109
|
-
copyparty-1.6.
|
100
|
+
copyparty-1.6.11.data/data/share/doc/copyparty/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
|
101
|
+
copyparty-1.6.11.data/data/share/doc/copyparty/README.md,sha256=4XP68C2c4bQew3J3SvqaZ7WLtzsk217qWX37BTj-Dms,83258
|
102
|
+
copyparty-1.6.11.data/scripts/partyfuse.py,sha256=zhVQm5m-pWcUyo4aOvzZveOMeLJSY7gB2UGFYXp10XM,32262
|
103
|
+
copyparty-1.6.11.data/scripts/up2k.py,sha256=cgAbhiy6uEIg3dxFhq3qHYOuPxtJlk_94BzNkHfjj7Y,34955
|
104
|
+
copyparty-1.6.11.dist-info/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
|
105
|
+
copyparty-1.6.11.dist-info/METADATA,sha256=Ol7LxCKf5jo5ANwFgaetbAXtMnsbh1AHH9dSKmg74Kk,85345
|
106
|
+
copyparty-1.6.11.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
|
107
|
+
copyparty-1.6.11.dist-info/entry_points.txt,sha256=v3KsE-NQ_WGZkl78BlR8lZ4oHWhGbtjaEw3-iGXLfLQ,54
|
108
|
+
copyparty-1.6.11.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
|
109
|
+
copyparty-1.6.11.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|