copyparty 1.6.9__py2.py3-none-any.whl → 1.6.10__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 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
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 6, 9)
3
+ VERSION = (1, 6, 10)
4
4
  CODENAME = "cors k"
5
- BUILD_DT = (2023, 3, 16)
5
+ BUILD_DT = (2023, 3, 20)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
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
- if depth == "infinity":
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
 
@@ -1422,9 +1425,9 @@ class HttpCli(object):
1422
1425
  self.log(t, 1)
1423
1426
  raise Pebkac(403, t)
1424
1427
 
1425
- if is_put and not (self.args.no_dav or self.args.nw):
1428
+ if is_put and not (self.args.no_dav or self.args.nw) and bos.path.exists(path):
1426
1429
  # allow overwrite if...
1427
- # * volflag 'daw' is set
1430
+ # * volflag 'daw' is set, or client is definitely webdav
1428
1431
  # * and account has delete-access
1429
1432
  # or...
1430
1433
  # * file exists, is empty, sufficiently new
@@ -1434,9 +1437,11 @@ class HttpCli(object):
1434
1437
  if self.args.dotpart:
1435
1438
  tnam = "." + tnam
1436
1439
 
1437
- if (vfs.flags.get("daw") and self.can_delete) or (
1440
+ if (
1441
+ self.can_delete
1442
+ and (vfs.flags.get("daw") or "x-oc-mtime" in self.headers)
1443
+ ) or (
1438
1444
  not bos.path.exists(os.path.join(fdir, tnam))
1439
- and bos.path.exists(path)
1440
1445
  and not bos.path.getsize(path)
1441
1446
  and bos.path.getmtime(path) >= time.time() - self.args.blank_wt
1442
1447
  ):
@@ -1460,6 +1465,16 @@ class HttpCli(object):
1460
1465
  if self.args.nw:
1461
1466
  return post_sz, sha_hex, sha_b64, remains, path, ""
1462
1467
 
1468
+ at = mt = time.time() - lifetime
1469
+ cli_mt = self.headers.get("x-oc-mtime")
1470
+ if cli_mt:
1471
+ try:
1472
+ mt = int(cli_mt)
1473
+ times = (int(time.time()), mt)
1474
+ bos.utime(path, times, False)
1475
+ except:
1476
+ pass
1477
+
1463
1478
  if nameless and "magic" in vfs.flags:
1464
1479
  try:
1465
1480
  ext = self.conn.hsrv.magician.ext(path)
@@ -1482,7 +1497,6 @@ class HttpCli(object):
1482
1497
  fn = fn2
1483
1498
  path = path2
1484
1499
 
1485
- at = time.time() - lifetime
1486
1500
  if xau and not runhook(
1487
1501
  self.log,
1488
1502
  xau,
@@ -1490,7 +1504,7 @@ class HttpCli(object):
1490
1504
  self.vpath,
1491
1505
  self.host,
1492
1506
  self.uname,
1493
- at,
1507
+ mt,
1494
1508
  post_sz,
1495
1509
  self.ip,
1496
1510
  at,
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
- if want_caf:
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/web/svcs.html CHANGED
@@ -46,7 +46,7 @@
46
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
47
  <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
48
  <pre>
49
- rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=other{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
49
+ rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=owncloud{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
50
50
  rclone mount --vfs-cache-mode writes --dir-cache-time 5s {{ aname }}-dav:{{ rvp }} <b>W:</b>
51
51
  </pre>
52
52
  {% if s %}
@@ -69,9 +69,9 @@
69
69
  printf '%s\n' "http{{ s }}://{{ ep }}/{{ rvp }} <b>{{ pw }}</b> k" >> /etc/davfs2/secrets
70
70
  printf '%s\n' "http{{ s }}://{{ ep }}/{{ rvp }} <b>mp</b> davfs rw,user,uid=1000,noauto 0 0" >> /etc/fstab
71
71
  </pre>
72
- <p>or you can use rclone instead, which is much slower but doesn't require root:</p>
72
+ <p>or you can use rclone instead, which is much slower but doesn't require root (plus it keeps lastmodified on upload):</p>
73
73
  <pre>
74
- rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=other{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
74
+ rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=owncloud{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
75
75
  rclone mount --vfs-cache-mode writes --dir-cache-time 5s {{ aname }}-dav:{{ rvp }} <b>mp</b>
76
76
  </pre>
77
77
  {% if s %}
@@ -1,29 +1,16 @@
1
1
  # 💾🎉 copyparty
2
2
 
3
- * portable file sharing hub (py2/py3) [(on PyPI)](https://pypi.org/project/copyparty/)
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
- ## summary
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
@@ -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
- * ☑ [sync folder to server](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy)
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` is broken in the current iOS version (15.1), maybe one day...
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,6 +1200,15 @@ 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 for instance), although syncing to copyparty is about 5x slower than up2k.py if you have many small files in particular
1210
+
1211
+
1210
1212
  ## mount as drive
1211
1213
 
1212
1214
  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
@@ -1225,6 +1227,27 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
1225
1227
  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
1228
 
1227
1229
 
1230
+ # android app
1231
+
1232
+ upload to copyparty with one tap
1233
+
1234
+ <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>
1235
+
1236
+ the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet
1237
+
1238
+ if you want to run the copyparty server on your android device, see [install on android](#install-on-android)
1239
+
1240
+
1241
+ # iOS shortcuts
1242
+
1243
+ there is no iPhone app, but the following shortcuts are almost as good:
1244
+
1245
+ * [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!)
1246
+ * can strip exif, upload files, pics, vids, links, clipboard
1247
+ * can download links and rehost the target file on copyparty (see first comment inside the shortcut)
1248
+ * pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
1249
+
1250
+
1228
1251
  # performance
1229
1252
 
1230
1253
  defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
@@ -1320,6 +1343,13 @@ by default, except for `GET` and `HEAD` operations, all requests must either:
1320
1343
  cors can be configured with `--acao` and `--acam`, or the protections entirely disabled with `--allow-csrf`
1321
1344
 
1322
1345
 
1346
+ ## https
1347
+
1348
+ 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)
1349
+
1350
+ copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
1351
+
1352
+
1323
1353
  # recovering from crashes
1324
1354
 
1325
1355
  ## client crashes
@@ -1387,7 +1417,7 @@ these are standalone programs and will never be imported / evaluated by copypart
1387
1417
 
1388
1418
  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
1419
 
1390
- you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](#./docs/devnotes.md#sfx-repack)
1420
+ you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
1391
1421
 
1392
1422
 
1393
1423
  ## copyparty.exe
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.6.9
3
+ Version: 1.6.10
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
- * portable file sharing hub (py2/py3) [(on PyPI)](https://pypi.org/project/copyparty/)
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
- ## summary
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
@@ -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
- * ☑ [sync folder to server](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy)
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` is broken in the current iOS version (15.1), maybe one day...
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,6 +1247,15 @@ 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 for instance), although syncing to copyparty is about 5x slower than up2k.py if you have many small files in particular
1257
+
1258
+
1257
1259
  ## mount as drive
1258
1260
 
1259
1261
  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
@@ -1272,6 +1274,27 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
1272
1274
  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
1275
 
1274
1276
 
1277
+ # android app
1278
+
1279
+ upload to copyparty with one tap
1280
+
1281
+ <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>
1282
+
1283
+ the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet
1284
+
1285
+ if you want to run the copyparty server on your android device, see [install on android](#install-on-android)
1286
+
1287
+
1288
+ # iOS shortcuts
1289
+
1290
+ there is no iPhone app, but the following shortcuts are almost as good:
1291
+
1292
+ * [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!)
1293
+ * can strip exif, upload files, pics, vids, links, clipboard
1294
+ * can download links and rehost the target file on copyparty (see first comment inside the shortcut)
1295
+ * pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
1296
+
1297
+
1275
1298
  # performance
1276
1299
 
1277
1300
  defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
@@ -1367,6 +1390,13 @@ by default, except for `GET` and `HEAD` operations, all requests must either:
1367
1390
  cors can be configured with `--acao` and `--acam`, or the protections entirely disabled with `--allow-csrf`
1368
1391
 
1369
1392
 
1393
+ ## https
1394
+
1395
+ 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)
1396
+
1397
+ copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
1398
+
1399
+
1370
1400
  # recovering from crashes
1371
1401
 
1372
1402
  ## client crashes
@@ -1434,7 +1464,7 @@ these are standalone programs and will never be imported / evaluated by copypart
1434
1464
 
1435
1465
  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
1466
 
1437
- you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](#./docs/devnotes.md#sfx-repack)
1467
+ you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
1438
1468
 
1439
1469
 
1440
1470
  ## copyparty.exe
@@ -1,6 +1,6 @@
1
1
  copyparty/__init__.py,sha256=ZIYqHdNC97NeoBTkFDSZ6E8aAma1tfjLhbax9oQHl4U,1063
2
- copyparty/__main__.py,sha256=g4skZeniCre3SHHXmS7YQQw5U-OCHLtWyhE8LKwJakA,66891
3
- copyparty/__version__.py,sha256=phw_xFNyG8ZYW5GwqPxta-ZhG9hgAfNzeuuGeR4D2A8,247
2
+ copyparty/__main__.py,sha256=NeG2cQHE4uRQ02zHZ7gv-NAlRgmTWmVSslPH5Uk84NI,66925
3
+ copyparty/__version__.py,sha256=wp65Vl0D_UcBkVaU9A6sBpd0yYrElMXJHqgAUtnqjDM,248
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=G9jaDyEAF82JCZpZYSHzIvGBTSFwEcncPSNcTxQ5aYo,119888
13
+ copyparty/httpcli.py,sha256=uU13dj9SzBpfdzfEceuqIYkxhm7IqUd_n3BdacVaUzI,120318
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,7 +25,7 @@ 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=Y1Z51K91D6lBqq810sSu1wltQnruPvhJnhliX5rAj6k,20969
28
+ copyparty/th_srv.py,sha256=O7SJDLBx6pcRUiOR4G6Rqpi7FGthekedGTK3CXIFi_E,22119
29
29
  copyparty/u2idx.py,sha256=n3DSFc67tIk-Jn8-Z5EEG8Xb_qv48KomJFYvoXlmV-U,10493
30
30
  copyparty/up2k.py,sha256=0I-YREZDULliJTuxyqhz2j1XT2QnM3da1ojc31ZY_0Y,121148
31
31
  copyparty/util.py,sha256=hAZ4AN5rMQgDPYKiRdA3Qh-dZ0cBsaODR-mNrSuNwzw,71782
@@ -70,7 +70,7 @@ 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=yf-2pYOKa7EEmFbY_SGjnAjhzCH4DlynbcRHe6GicqY,9354
73
+ copyparty/web/svcs.html,sha256=B49Z5EiMrDqREbfJwqUTehRo1aht7h0uLMkHBA1w2wo,9399
74
74
  copyparty/web/svcs.js.gz,sha256=SSVKYYgZkEKMdDLjekvcXB00v-rCVJXh2GD_YtCvu7c,519
75
75
  copyparty/web/ui.css.gz,sha256=kU3LGyd2MpBzbp1_7Dy1_11V9Nw7QPuNQlpLB_z0uEk,2377
76
76
  copyparty/web/up2k.js.gz,sha256=fGYvDuq34kVz16occIYU9KUQZF9ZemcQLI57o2_DmK4,21538
@@ -97,13 +97,13 @@ copyparty/web/deps/prismd.css.gz,sha256=hzzspI_ptCygzmsIp9rKsf1M4yU12Ma7TfE-wyoX
97
97
  copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
98
98
  copyparty/web/deps/sha512.ac.js.gz,sha256=IzAmZIkSyMbnn7GK3k5PW085PNcZxtk_u4UW_E1d6ek,7043
99
99
  copyparty/web/deps/sha512.hw.js.gz,sha256=0xJaw75Tghoblu72C2h4YoU1izSR99mBtDMoGqZ3xvs,8119
100
- copyparty-1.6.9.data/data/share/doc/copyparty/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
101
- copyparty-1.6.9.data/data/share/doc/copyparty/README.md,sha256=SG-Kd3cYnahsKrjGjQeC2_rcC1TUr9NIaf0kgZyJ0cM,80896
102
- copyparty-1.6.9.data/scripts/partyfuse.py,sha256=zhVQm5m-pWcUyo4aOvzZveOMeLJSY7gB2UGFYXp10XM,32262
103
- copyparty-1.6.9.data/scripts/up2k.py,sha256=6J3zq9wZPgRTti32p2d7kg5YHfZvlu4ZZiElU3492bU,35116
104
- copyparty-1.6.9.dist-info/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
105
- copyparty-1.6.9.dist-info/METADATA,sha256=oI9g3XQj2tOIuB42qWkuwvRSA9MD_lijW-8w61zQyK8,82982
106
- copyparty-1.6.9.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
107
- copyparty-1.6.9.dist-info/entry_points.txt,sha256=v3KsE-NQ_WGZkl78BlR8lZ4oHWhGbtjaEw3-iGXLfLQ,54
108
- copyparty-1.6.9.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
109
- copyparty-1.6.9.dist-info/RECORD,,
100
+ copyparty-1.6.10.data/data/share/doc/copyparty/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
101
+ copyparty-1.6.10.data/data/share/doc/copyparty/README.md,sha256=y3QDX75CclBacxOCdR9dju63UNk4AjxjXsP9rz_auKg,83126
102
+ copyparty-1.6.10.data/scripts/partyfuse.py,sha256=zhVQm5m-pWcUyo4aOvzZveOMeLJSY7gB2UGFYXp10XM,32262
103
+ copyparty-1.6.10.data/scripts/up2k.py,sha256=6J3zq9wZPgRTti32p2d7kg5YHfZvlu4ZZiElU3492bU,35116
104
+ copyparty-1.6.10.dist-info/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
105
+ copyparty-1.6.10.dist-info/METADATA,sha256=7TfK1Wjh9RlVFpRP1C9sS1UHNtoFw_yMCnDPsWGPbhU,85213
106
+ copyparty-1.6.10.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
107
+ copyparty-1.6.10.dist-info/entry_points.txt,sha256=v3KsE-NQ_WGZkl78BlR8lZ4oHWhGbtjaEw3-iGXLfLQ,54
108
+ copyparty-1.6.10.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
109
+ copyparty-1.6.10.dist-info/RECORD,,