copyparty 1.13.0__tar.gz → 1.13.2__tar.gz
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-1.13.0 → copyparty-1.13.2}/PKG-INFO +55 -8
- {copyparty-1.13.0 → copyparty-1.13.2}/README.md +54 -7
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/__main__.py +55 -5
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/__version__.py +2 -2
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/authsrv.py +23 -2
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/broker_mp.py +2 -5
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/cfg.py +16 -2
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/fsutil.py +25 -5
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/httpcli.py +262 -20
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/httpsrv.py +1 -4
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/metrics.py +1 -1
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/mtag.py +72 -3
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/smbd.py +1 -1
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/svchub.py +14 -3
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/tcpsrv.py +6 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/th_cli.py +5 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/th_srv.py +32 -5
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/u2idx.py +18 -3
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/up2k.py +27 -9
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/util.py +41 -6
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/a/u2c.py +14 -5
- copyparty-1.13.2/copyparty/web/baguettebox.js.gz +0 -0
- copyparty-1.13.2/copyparty/web/browser.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/browser.html +1 -1
- copyparty-1.13.2/copyparty/web/browser.js.gz +0 -0
- copyparty-1.13.2/copyparty/web/deps/marked.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/md.html +1 -1
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/mde.html +1 -1
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/msg.html +1 -1
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/splash.html +2 -1
- copyparty-1.13.2/copyparty/web/splash.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/svcs.html +1 -1
- copyparty-1.13.2/copyparty/web/util.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty.egg-info/PKG-INFO +55 -8
- copyparty-1.13.0/copyparty/web/baguettebox.js.gz +0 -0
- copyparty-1.13.0/copyparty/web/browser.css.gz +0 -0
- copyparty-1.13.0/copyparty/web/browser.js.gz +0 -0
- copyparty-1.13.0/copyparty/web/deps/marked.js.gz +0 -0
- copyparty-1.13.0/copyparty/web/splash.js.gz +0 -0
- copyparty-1.13.0/copyparty/web/util.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/LICENSE +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/bos/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/bos/bos.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/bos/path.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/broker_mpw.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/broker_thr.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/broker_util.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/cert.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/dxml.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/ftpd.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/httpconn.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/ico.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/mdns.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/multicast.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/pwhash.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/res/COPYING.txt +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/res/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/res/insecure.pem +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/ssdp.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/star.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/bimap.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/bit.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/buffer.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/dns.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/label.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/lex.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/dnslib/ranges.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/ifaddr/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/ifaddr/_posix.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/ifaddr/_shared.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/ifaddr/_win32.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/qrcodegen.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/stolen/surrogateescape.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/sutil.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/szip.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/tftpd.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/a/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/a/partyfuse.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/a/webdav-cfg.bat +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/browser2.html +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/cf.html +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/dbg-audio.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/dd/2.png +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/dd/3.png +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/dd/4.png +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/dd/5.png +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/dd/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/__init__.py +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/busy.mp3.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/easymde.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/easymde.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/mini-fa.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/mini-fa.woff +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/prism.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/prism.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/prismd.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/scp.woff2 +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/sha512.ac.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/deps/sha512.hw.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/md.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/md.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/md2.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/md2.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/mde.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/mde.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/msg.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/splash.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/svcs.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/ui.css.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/up2k.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty/web/w.hash.js.gz +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty.egg-info/SOURCES.txt +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty.egg-info/dependency_links.txt +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty.egg-info/entry_points.txt +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty.egg-info/requires.txt +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/copyparty.egg-info/top_level.txt +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/pyproject.toml +0 -0
- {copyparty-1.13.0 → copyparty-1.13.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.13.
|
3
|
+
Version: 1.13.2
|
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
|
Author-email: ed <copyparty@ocv.me>
|
6
6
|
License: MIT
|
@@ -101,6 +101,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
101
101
|
* [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
|
102
102
|
* [fix unreliable playback on android](#fix-unreliable-playback-on-android) - due to phone / app settings
|
103
103
|
* [markdown viewer](#markdown-viewer) - and there are *two* editors
|
104
|
+
* [markdown vars](#markdown-vars) - dynamic docs with serverside variable expansion
|
104
105
|
* [other tricks](#other-tricks)
|
105
106
|
* [searching](#searching) - search by size, date, path/name, mp3-tags, ...
|
106
107
|
* [server config](#server-config) - using arguments or config files, or a mix of both
|
@@ -114,6 +115,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
114
115
|
* [tftp server](#tftp-server) - a TFTP server (read/write) can be started using `--tftp 3969`
|
115
116
|
* [smb server](#smb-server) - unsafe, slow, not recommended for wan
|
116
117
|
* [browser ux](#browser-ux) - tweaking the ui
|
118
|
+
* [opengraph](#opengraph) - discord and social-media embeds
|
117
119
|
* [file indexing](#file-indexing) - enables dedup and music search ++
|
118
120
|
* [exclude-patterns](#exclude-patterns) - to save some time
|
119
121
|
* [filesystem guards](#filesystem-guards) - avoid traversing into other filesystems
|
@@ -162,8 +164,9 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
162
164
|
* [dependencies](#dependencies) - mandatory deps
|
163
165
|
* [optional dependencies](#optional-dependencies) - install these to enable bonus features
|
164
166
|
* [optional gpl stuff](#optional-gpl-stuff)
|
165
|
-
* [sfx](#sfx) - the self-contained "binary"
|
167
|
+
* [sfx](#sfx) - the self-contained "binary" (recommended!)
|
166
168
|
* [copyparty.exe](#copypartyexe) - download [copyparty.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) (win8+) or [copyparty32.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty32.exe) (win7+)
|
169
|
+
* [zipapp](#zipapp) - another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz)
|
167
170
|
* [install on android](#install-on-android)
|
168
171
|
* [reporting bugs](#reporting-bugs) - ideas for context to include, and where to submit them
|
169
172
|
* [devnotes](#devnotes) - for build instructions etc, see [./docs/devnotes.md](./docs/devnotes.md)
|
@@ -177,6 +180,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/
|
|
177
180
|
* or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
|
178
181
|
* or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
|
179
182
|
* or if you are on android, [install copyparty in termux](#install-on-android)
|
183
|
+
* or if your computer is messed up and nothing else works, [try the pyz](#zipapp)
|
180
184
|
* or if you prefer to [use docker](./scripts/docker/) 🐋 you can do that too
|
181
185
|
* docker has all deps built-in, so skip this step:
|
182
186
|
|
@@ -280,6 +284,7 @@ also see [comparison to similar software](./docs/versus.md)
|
|
280
284
|
* ☑ ...of videos using FFmpeg
|
281
285
|
* ☑ ...of audio (spectrograms) using FFmpeg
|
282
286
|
* ☑ cache eviction (max-age; maybe max-size eventually)
|
287
|
+
* ☑ multilingual UI (english, norwegian, [add your own](./docs/rice/#translations)))
|
283
288
|
* ☑ SPA (browse while uploading)
|
284
289
|
* server indexing
|
285
290
|
* ☑ [locate files by contents](#file-search)
|
@@ -288,9 +293,11 @@ also see [comparison to similar software](./docs/versus.md)
|
|
288
293
|
* client support
|
289
294
|
* ☑ [folder sync](#folder-sync)
|
290
295
|
* ☑ [curl-friendly](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
|
296
|
+
* ☑ [opengraph](#opengraph) (discord embeds)
|
291
297
|
* markdown
|
292
298
|
* ☑ [viewer](#markdown-viewer)
|
293
299
|
* ☑ editor (sure why not)
|
300
|
+
* ☑ [variables](#markdown-vars)
|
294
301
|
|
295
302
|
PS: something missing? post any crazy ideas you've got as a [feature request](https://github.com/9001/copyparty/issues/new?assignees=9001&labels=enhancement&template=feature_request.md) or [discussion](https://github.com/9001/copyparty/discussions/new?category=ideas) 🤙
|
296
303
|
|
@@ -460,7 +467,7 @@ configuring accounts/volumes with arguments:
|
|
460
467
|
`-v .::r,usr1,usr2:rw,usr3,usr4` = usr1/2 read-only, 3/4 read-write
|
461
468
|
|
462
469
|
permissions:
|
463
|
-
* `r` (read): browse folder contents, download files, download as zip/tar
|
470
|
+
* `r` (read): browse folder contents, download files, download as zip/tar, see filekeys/dirkeys
|
464
471
|
* `w` (write): upload files, move files *into* this folder
|
465
472
|
* `m` (move): move files/folders *from* this folder
|
466
473
|
* `d` (delete): delete files/folders
|
@@ -662,15 +669,21 @@ you can also zip a selection of files or folders by clicking them in the browser
|
|
662
669
|
|
663
670
|
cool trick: download a folder by appending url-params `?tar&opus` or `?tar&mp3` to transcode all audio files (except aac|m4a|mp3|ogg|opus|wma) to opus/mp3 before they're added to the archive
|
664
671
|
* super useful if you're 5 minutes away from takeoff and realize you don't have any music on your phone but your server only has flac files and downloading those will burn through all your data + there wouldn't be enough time anyways
|
665
|
-
* and url-params `&j` / `&w` produce jpeg/webm thumbnails/spectrograms instead of the original audio/video/images
|
672
|
+
* and url-params `&j` / `&w` produce jpeg/webm thumbnails/spectrograms instead of the original audio/video/images (`&p` for audio waveforms)
|
666
673
|
* can also be used to pregenerate thumbnails; combine with `--th-maxage=9999999` or `--th-clean=0`
|
667
674
|
|
668
675
|
|
669
676
|
## uploading
|
670
677
|
|
671
|
-
drag files/folders into the web-browser to upload
|
678
|
+
drag files/folders into the web-browser to upload
|
672
679
|
|
673
|
-
|
680
|
+
dragdrop is the recommended way, but you may also:
|
681
|
+
|
682
|
+
* select some files (not folders) in your file explorer and press CTRL-V inside the browser window
|
683
|
+
* use the [command-line uploader](https://github.com/9001/copyparty/tree/hovudstraum/bin#u2cpy)
|
684
|
+
* upload using [curl or sharex](#client-examples)
|
685
|
+
|
686
|
+
when uploading files through dragdrop or CTRL-V, this initiates an upload using `up2k`; there are two browser-based uploaders available:
|
674
687
|
* `[🎈] bup`, the basic uploader, supports almost every browser since netscape 4.0
|
675
688
|
* `[🚀] up2k`, the good / fancy one
|
676
689
|
|
@@ -897,6 +910,13 @@ other notes,
|
|
897
910
|
* the document preview has a max-width which is the same as an A4 paper when printed
|
898
911
|
|
899
912
|
|
913
|
+
### markdown vars
|
914
|
+
|
915
|
+
dynamic docs with serverside variable expansion to replace stuff like `{{self.ip}}` with the client's IP, or `{{srv.htime}}` with the current time on the server
|
916
|
+
|
917
|
+
see [./srv/expand/](./srv/expand/) for usage and examples
|
918
|
+
|
919
|
+
|
900
920
|
## other tricks
|
901
921
|
|
902
922
|
* you can link a particular timestamp in an audio file by adding it to the URL, such as `&20` / `&20s` / `&1m20` / `&t=1:20` after the `.../#af-c8960dab`
|
@@ -945,6 +965,8 @@ using arguments or config files, or a mix of both:
|
|
945
965
|
|
946
966
|
**NB:** as humongous as this readme is, there is also a lot of undocumented features. Run copyparty with `--help` to see all available global options; all of those can be used in the `[global]` section of config files, and everything listed in `--help-flags` can be used in volumes as volflags.
|
947
967
|
* if running in docker/podman, try this: `docker run --rm -it copyparty/ac --help`
|
968
|
+
* or see this (probably outdated): https://ocv.me/copyparty/helptext.html
|
969
|
+
* or if you prefer plaintext, https://ocv.me/copyparty/helptext.txt
|
948
970
|
|
949
971
|
|
950
972
|
## zeroconf
|
@@ -1121,7 +1143,22 @@ tweaking the ui
|
|
1121
1143
|
* to sort in music order (album, track, artist, title) with filename as fallback, you could `--sort tags/Cirle,tags/.tn,tags/Artist,tags/Title,href`
|
1122
1144
|
* to sort by upload date, first enable showing the upload date in the listing with `-e2d -mte +.up_at` and then `--sort tags/.up_at`
|
1123
1145
|
|
1124
|
-
see [./docs/rice](./docs/rice) for more
|
1146
|
+
see [./docs/rice](./docs/rice) for more, including how to add stuff (css/`<meta>`/...) to the html `<head>` tag, or to add your own translation
|
1147
|
+
|
1148
|
+
|
1149
|
+
## opengraph
|
1150
|
+
|
1151
|
+
discord and social-media embeds
|
1152
|
+
|
1153
|
+
can be enabled globally with `--og` or per-volume with volflag `og`
|
1154
|
+
|
1155
|
+
note that this disables hotlinking because the opengraph spec demands it; to sneak past this intentional limitation, you can enable opengraph selectively by user-agent, for example `--og-ua '(Discord|Twitter|Slack)bot'` (or volflag `og_ua`)
|
1156
|
+
|
1157
|
+
you can also hotlink files regardless by appending `?raw` to the url
|
1158
|
+
|
1159
|
+
NOTE: because discord (and maybe others) strip query args such as `?raw` in opengraph tags, any links which require a filekey or dirkey will not work
|
1160
|
+
|
1161
|
+
if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object)
|
1125
1162
|
|
1126
1163
|
|
1127
1164
|
## file indexing
|
@@ -2035,7 +2072,7 @@ these are standalone programs and will never be imported / evaluated by copypart
|
|
2035
2072
|
|
2036
2073
|
# sfx
|
2037
2074
|
|
2038
|
-
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
|
2075
|
+
the self-contained "binary" (recommended!) [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
|
2039
2076
|
|
2040
2077
|
you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
|
2041
2078
|
|
@@ -2062,6 +2099,16 @@ meanwhile [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/d
|
|
2062
2099
|
then again, if you are already into downloading shady binaries from the internet, you may also want my [minimal builds](./scripts/pyinstaller#ffmpeg) of [ffmpeg](https://ocv.me/stuff/bin/ffmpeg.exe) and [ffprobe](https://ocv.me/stuff/bin/ffprobe.exe) which enables copyparty to extract multimedia-info, do audio-transcoding, and thumbnails/spectrograms/waveforms, however it's much better to instead grab a [recent official build](https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-full.7z) every once ina while if you can afford the size
|
2063
2100
|
|
2064
2101
|
|
2102
|
+
## zipapp
|
2103
|
+
|
2104
|
+
another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
|
2105
|
+
|
2106
|
+
run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
|
2107
|
+
|
2108
|
+
it is a python [zipapp](https://docs.python.org/3/library/zipapp.html) meaning it doesn't have to unpack its own python code anywhere to run, so if the filesystem is busted it has a better chance of getting somewhere
|
2109
|
+
* but note that it currently still needs to extract the web-resources somewhere (they'll land in the default TEMP-folder of your OS)
|
2110
|
+
|
2111
|
+
|
2065
2112
|
# install on android
|
2066
2113
|
|
2067
2114
|
install [Termux](https://termux.com/) + its companion app `Termux:API` (see [ocv.me/termux](https://ocv.me/termux/)) and then copy-paste this into Termux (long-tap) all at once:
|
@@ -47,6 +47,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
47
47
|
* [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
|
48
48
|
* [fix unreliable playback on android](#fix-unreliable-playback-on-android) - due to phone / app settings
|
49
49
|
* [markdown viewer](#markdown-viewer) - and there are *two* editors
|
50
|
+
* [markdown vars](#markdown-vars) - dynamic docs with serverside variable expansion
|
50
51
|
* [other tricks](#other-tricks)
|
51
52
|
* [searching](#searching) - search by size, date, path/name, mp3-tags, ...
|
52
53
|
* [server config](#server-config) - using arguments or config files, or a mix of both
|
@@ -60,6 +61,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
60
61
|
* [tftp server](#tftp-server) - a TFTP server (read/write) can be started using `--tftp 3969`
|
61
62
|
* [smb server](#smb-server) - unsafe, slow, not recommended for wan
|
62
63
|
* [browser ux](#browser-ux) - tweaking the ui
|
64
|
+
* [opengraph](#opengraph) - discord and social-media embeds
|
63
65
|
* [file indexing](#file-indexing) - enables dedup and music search ++
|
64
66
|
* [exclude-patterns](#exclude-patterns) - to save some time
|
65
67
|
* [filesystem guards](#filesystem-guards) - avoid traversing into other filesystems
|
@@ -108,8 +110,9 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
108
110
|
* [dependencies](#dependencies) - mandatory deps
|
109
111
|
* [optional dependencies](#optional-dependencies) - install these to enable bonus features
|
110
112
|
* [optional gpl stuff](#optional-gpl-stuff)
|
111
|
-
* [sfx](#sfx) - the self-contained "binary"
|
113
|
+
* [sfx](#sfx) - the self-contained "binary" (recommended!)
|
112
114
|
* [copyparty.exe](#copypartyexe) - download [copyparty.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) (win8+) or [copyparty32.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty32.exe) (win7+)
|
115
|
+
* [zipapp](#zipapp) - another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz)
|
113
116
|
* [install on android](#install-on-android)
|
114
117
|
* [reporting bugs](#reporting-bugs) - ideas for context to include, and where to submit them
|
115
118
|
* [devnotes](#devnotes) - for build instructions etc, see [./docs/devnotes.md](./docs/devnotes.md)
|
@@ -123,6 +126,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/
|
|
123
126
|
* or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
|
124
127
|
* or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
|
125
128
|
* or if you are on android, [install copyparty in termux](#install-on-android)
|
129
|
+
* or if your computer is messed up and nothing else works, [try the pyz](#zipapp)
|
126
130
|
* or if you prefer to [use docker](./scripts/docker/) 🐋 you can do that too
|
127
131
|
* docker has all deps built-in, so skip this step:
|
128
132
|
|
@@ -226,6 +230,7 @@ also see [comparison to similar software](./docs/versus.md)
|
|
226
230
|
* ☑ ...of videos using FFmpeg
|
227
231
|
* ☑ ...of audio (spectrograms) using FFmpeg
|
228
232
|
* ☑ cache eviction (max-age; maybe max-size eventually)
|
233
|
+
* ☑ multilingual UI (english, norwegian, [add your own](./docs/rice/#translations)))
|
229
234
|
* ☑ SPA (browse while uploading)
|
230
235
|
* server indexing
|
231
236
|
* ☑ [locate files by contents](#file-search)
|
@@ -234,9 +239,11 @@ also see [comparison to similar software](./docs/versus.md)
|
|
234
239
|
* client support
|
235
240
|
* ☑ [folder sync](#folder-sync)
|
236
241
|
* ☑ [curl-friendly](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
|
242
|
+
* ☑ [opengraph](#opengraph) (discord embeds)
|
237
243
|
* markdown
|
238
244
|
* ☑ [viewer](#markdown-viewer)
|
239
245
|
* ☑ editor (sure why not)
|
246
|
+
* ☑ [variables](#markdown-vars)
|
240
247
|
|
241
248
|
PS: something missing? post any crazy ideas you've got as a [feature request](https://github.com/9001/copyparty/issues/new?assignees=9001&labels=enhancement&template=feature_request.md) or [discussion](https://github.com/9001/copyparty/discussions/new?category=ideas) 🤙
|
242
249
|
|
@@ -406,7 +413,7 @@ configuring accounts/volumes with arguments:
|
|
406
413
|
`-v .::r,usr1,usr2:rw,usr3,usr4` = usr1/2 read-only, 3/4 read-write
|
407
414
|
|
408
415
|
permissions:
|
409
|
-
* `r` (read): browse folder contents, download files, download as zip/tar
|
416
|
+
* `r` (read): browse folder contents, download files, download as zip/tar, see filekeys/dirkeys
|
410
417
|
* `w` (write): upload files, move files *into* this folder
|
411
418
|
* `m` (move): move files/folders *from* this folder
|
412
419
|
* `d` (delete): delete files/folders
|
@@ -608,15 +615,21 @@ you can also zip a selection of files or folders by clicking them in the browser
|
|
608
615
|
|
609
616
|
cool trick: download a folder by appending url-params `?tar&opus` or `?tar&mp3` to transcode all audio files (except aac|m4a|mp3|ogg|opus|wma) to opus/mp3 before they're added to the archive
|
610
617
|
* super useful if you're 5 minutes away from takeoff and realize you don't have any music on your phone but your server only has flac files and downloading those will burn through all your data + there wouldn't be enough time anyways
|
611
|
-
* and url-params `&j` / `&w` produce jpeg/webm thumbnails/spectrograms instead of the original audio/video/images
|
618
|
+
* and url-params `&j` / `&w` produce jpeg/webm thumbnails/spectrograms instead of the original audio/video/images (`&p` for audio waveforms)
|
612
619
|
* can also be used to pregenerate thumbnails; combine with `--th-maxage=9999999` or `--th-clean=0`
|
613
620
|
|
614
621
|
|
615
622
|
## uploading
|
616
623
|
|
617
|
-
drag files/folders into the web-browser to upload
|
624
|
+
drag files/folders into the web-browser to upload
|
618
625
|
|
619
|
-
|
626
|
+
dragdrop is the recommended way, but you may also:
|
627
|
+
|
628
|
+
* select some files (not folders) in your file explorer and press CTRL-V inside the browser window
|
629
|
+
* use the [command-line uploader](https://github.com/9001/copyparty/tree/hovudstraum/bin#u2cpy)
|
630
|
+
* upload using [curl or sharex](#client-examples)
|
631
|
+
|
632
|
+
when uploading files through dragdrop or CTRL-V, this initiates an upload using `up2k`; there are two browser-based uploaders available:
|
620
633
|
* `[🎈] bup`, the basic uploader, supports almost every browser since netscape 4.0
|
621
634
|
* `[🚀] up2k`, the good / fancy one
|
622
635
|
|
@@ -843,6 +856,13 @@ other notes,
|
|
843
856
|
* the document preview has a max-width which is the same as an A4 paper when printed
|
844
857
|
|
845
858
|
|
859
|
+
### markdown vars
|
860
|
+
|
861
|
+
dynamic docs with serverside variable expansion to replace stuff like `{{self.ip}}` with the client's IP, or `{{srv.htime}}` with the current time on the server
|
862
|
+
|
863
|
+
see [./srv/expand/](./srv/expand/) for usage and examples
|
864
|
+
|
865
|
+
|
846
866
|
## other tricks
|
847
867
|
|
848
868
|
* you can link a particular timestamp in an audio file by adding it to the URL, such as `&20` / `&20s` / `&1m20` / `&t=1:20` after the `.../#af-c8960dab`
|
@@ -891,6 +911,8 @@ using arguments or config files, or a mix of both:
|
|
891
911
|
|
892
912
|
**NB:** as humongous as this readme is, there is also a lot of undocumented features. Run copyparty with `--help` to see all available global options; all of those can be used in the `[global]` section of config files, and everything listed in `--help-flags` can be used in volumes as volflags.
|
893
913
|
* if running in docker/podman, try this: `docker run --rm -it copyparty/ac --help`
|
914
|
+
* or see this (probably outdated): https://ocv.me/copyparty/helptext.html
|
915
|
+
* or if you prefer plaintext, https://ocv.me/copyparty/helptext.txt
|
894
916
|
|
895
917
|
|
896
918
|
## zeroconf
|
@@ -1067,7 +1089,22 @@ tweaking the ui
|
|
1067
1089
|
* to sort in music order (album, track, artist, title) with filename as fallback, you could `--sort tags/Cirle,tags/.tn,tags/Artist,tags/Title,href`
|
1068
1090
|
* to sort by upload date, first enable showing the upload date in the listing with `-e2d -mte +.up_at` and then `--sort tags/.up_at`
|
1069
1091
|
|
1070
|
-
see [./docs/rice](./docs/rice) for more
|
1092
|
+
see [./docs/rice](./docs/rice) for more, including how to add stuff (css/`<meta>`/...) to the html `<head>` tag, or to add your own translation
|
1093
|
+
|
1094
|
+
|
1095
|
+
## opengraph
|
1096
|
+
|
1097
|
+
discord and social-media embeds
|
1098
|
+
|
1099
|
+
can be enabled globally with `--og` or per-volume with volflag `og`
|
1100
|
+
|
1101
|
+
note that this disables hotlinking because the opengraph spec demands it; to sneak past this intentional limitation, you can enable opengraph selectively by user-agent, for example `--og-ua '(Discord|Twitter|Slack)bot'` (or volflag `og_ua`)
|
1102
|
+
|
1103
|
+
you can also hotlink files regardless by appending `?raw` to the url
|
1104
|
+
|
1105
|
+
NOTE: because discord (and maybe others) strip query args such as `?raw` in opengraph tags, any links which require a filekey or dirkey will not work
|
1106
|
+
|
1107
|
+
if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object)
|
1071
1108
|
|
1072
1109
|
|
1073
1110
|
## file indexing
|
@@ -1981,7 +2018,7 @@ these are standalone programs and will never be imported / evaluated by copypart
|
|
1981
2018
|
|
1982
2019
|
# sfx
|
1983
2020
|
|
1984
|
-
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
|
2021
|
+
the self-contained "binary" (recommended!) [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
|
1985
2022
|
|
1986
2023
|
you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
|
1987
2024
|
|
@@ -2008,6 +2045,16 @@ meanwhile [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/d
|
|
2008
2045
|
then again, if you are already into downloading shady binaries from the internet, you may also want my [minimal builds](./scripts/pyinstaller#ffmpeg) of [ffmpeg](https://ocv.me/stuff/bin/ffmpeg.exe) and [ffprobe](https://ocv.me/stuff/bin/ffprobe.exe) which enables copyparty to extract multimedia-info, do audio-transcoding, and thumbnails/spectrograms/waveforms, however it's much better to instead grab a [recent official build](https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-full.7z) every once ina while if you can afford the size
|
2009
2046
|
|
2010
2047
|
|
2048
|
+
## zipapp
|
2049
|
+
|
2050
|
+
another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
|
2051
|
+
|
2052
|
+
run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
|
2053
|
+
|
2054
|
+
it is a python [zipapp](https://docs.python.org/3/library/zipapp.html) meaning it doesn't have to unpack its own python code anywhere to run, so if the filesystem is busted it has a better chance of getting somewhere
|
2055
|
+
* but note that it currently still needs to extract the web-resources somewhere (they'll land in the default TEMP-folder of your OS)
|
2056
|
+
|
2057
|
+
|
2011
2058
|
# install on android
|
2012
2059
|
|
2013
2060
|
install [Termux](https://termux.com/) + its companion app `Termux:API` (see [ocv.me/termux](https://ocv.me/termux/)) and then copy-paste this into Termux (long-tap) all at once:
|
@@ -43,11 +43,13 @@ from .util import (
|
|
43
43
|
DEF_MTH,
|
44
44
|
IMPLICATIONS,
|
45
45
|
JINJA_VER,
|
46
|
+
MIMES,
|
46
47
|
PARTFTPY_VER,
|
47
48
|
PY_DESC,
|
48
49
|
PYFTPD_VER,
|
49
50
|
SQLITE_VER,
|
50
51
|
UNPLICATIONS,
|
52
|
+
Daemon,
|
51
53
|
align_tab,
|
52
54
|
ansi_re,
|
53
55
|
dedent,
|
@@ -464,6 +466,16 @@ def disable_quickedit() :
|
|
464
466
|
cmode(True, mode | 4)
|
465
467
|
|
466
468
|
|
469
|
+
def sfx_tpoke(top ):
|
470
|
+
files = [os.path.join(dp, p) for dp, dd, df in os.walk(top) for p in dd + df]
|
471
|
+
while True:
|
472
|
+
t = int(time.time())
|
473
|
+
for f in [top] + files:
|
474
|
+
os.utime(f, (t, t))
|
475
|
+
|
476
|
+
time.sleep(78123)
|
477
|
+
|
478
|
+
|
467
479
|
def showlic() :
|
468
480
|
p = os.path.join(E.mod, "res", "COPYING.txt")
|
469
481
|
if not os.path.exists(p):
|
@@ -814,7 +826,7 @@ def build_flags_desc():
|
|
814
826
|
v = v.replace("\n", "\n ")
|
815
827
|
ret += "\n \033[36m{}\033[35m {}".format(k, v)
|
816
828
|
|
817
|
-
return ret
|
829
|
+
return ret
|
818
830
|
|
819
831
|
|
820
832
|
# fmt: off
|
@@ -832,6 +844,8 @@ def add_general(ap, nc, srvname):
|
|
832
844
|
ap2.add_argument("--urlform", metavar="MODE", type=u, default="print,get", help="how to handle url-form POSTs; see \033[33m--help-urlform\033[0m")
|
833
845
|
ap2.add_argument("--wintitle", metavar="TXT", type=u, default="cpp @ $pub", help="server terminal title, for example [\033[32m$ip-10.1.2.\033[0m] or [\033[32m$ip-]")
|
834
846
|
ap2.add_argument("--name", metavar="TXT", type=u, default=srvname, help="server name (displayed topleft in browser and in mDNS)")
|
847
|
+
ap2.add_argument("--mime", metavar="EXT=MIME", type=u, action="append", help="map file \033[33mEXT\033[0mension to \033[33mMIME\033[0mtype, for example [\033[32mjpg=image/jpeg\033[0m]")
|
848
|
+
ap2.add_argument("--mimes", action="store_true", help="list default mimetype mapping and exit")
|
835
849
|
ap2.add_argument("--license", action="store_true", help="show licenses and exit")
|
836
850
|
ap2.add_argument("--version", action="store_true", help="show versions and exit")
|
837
851
|
|
@@ -854,6 +868,7 @@ def add_fs(ap):
|
|
854
868
|
ap2.add_argument("--rm-retry", metavar="T/R", type=u, default=rm_re_def, help="if a file cannot be deleted because it is busy, continue trying for \033[33mT\033[0m seconds, retry every \033[33mR\033[0m seconds; disable with 0/0 (volflag=rm_retry)")
|
855
869
|
ap2.add_argument("--mv-retry", metavar="T/R", type=u, default=rm_re_def, help="if a file cannot be renamed because it is busy, continue trying for \033[33mT\033[0m seconds, retry every \033[33mR\033[0m seconds; disable with 0/0 (volflag=mv_retry)")
|
856
870
|
ap2.add_argument("--iobuf", metavar="BYTES", type=int, default=256*1024, help="file I/O buffer-size; if your volumes are on a network drive, try increasing to \033[32m524288\033[0m or even \033[32m4194304\033[0m (and let me know if that improves your performance)")
|
871
|
+
ap2.add_argument("--mtab-age", metavar="SEC", type=int, default=60, help="rebuild mountpoint cache every \033[33mSEC\033[0m to keep track of sparse-files support; keep low on servers with removable media")
|
857
872
|
|
858
873
|
|
859
874
|
def add_upload(ap):
|
@@ -1187,7 +1202,8 @@ def add_thumbnail(ap):
|
|
1187
1202
|
ap2.add_argument("--th-r-vips", metavar="T,T", type=u, default="avif,exr,fit,fits,fts,gif,hdr,heic,jp2,jpeg,jpg,jpx,jxl,nii,pfm,pgm,png,ppm,svg,tif,tiff,webp", help="image formats to decode using pyvips")
|
1188
1203
|
ap2.add_argument("--th-r-ffi", metavar="T,T", type=u, default="apng,avif,avifs,bmp,dds,dib,fit,fits,fts,gif,hdr,heic,heics,heif,heifs,icns,ico,jp2,jpeg,jpg,jpx,jxl,pbm,pcx,pfm,pgm,png,pnm,ppm,psd,qoi,sgi,tga,tif,tiff,webp,xbm,xpm", help="image formats to decode using ffmpeg")
|
1189
1204
|
ap2.add_argument("--th-r-ffv", metavar="T,T", type=u, default="3gp,asf,av1,avc,avi,flv,h264,h265,hevc,m4v,mjpeg,mjpg,mkv,mov,mp4,mpeg,mpeg2,mpegts,mpg,mpg2,mts,nut,ogm,ogv,rm,ts,vob,webm,wmv", help="video formats to decode using ffmpeg")
|
1190
|
-
ap2.add_argument("--th-r-ffa", metavar="T,T", type=u, default="aac,ac3,aif,aiff,alac,alaw,amr,apac,ape,au,bonk,dfpwm,dts,flac,gsm,ilbc,it,m4a,mo3,mod,mp2,mp3,mpc,mptm,mt2,mulaw,ogg,okt,opus,ra,s3m,tak,tta,ulaw,wav,wma,wv,xm,xpk", help="audio formats to decode using ffmpeg")
|
1205
|
+
ap2.add_argument("--th-r-ffa", metavar="T,T", type=u, default="aac,ac3,aif,aiff,alac,alaw,amr,apac,ape,au,bonk,dfpwm,dts,flac,gsm,ilbc,it,itgz,itxz,itz,m4a,mdgz,mdxz,mdz,mo3,mod,mp2,mp3,mpc,mptm,mt2,mulaw,ogg,okt,opus,ra,s3m,s3gz,s3xz,s3z,tak,tta,ulaw,wav,wma,wv,xm,xmgz,xmxz,xmz,xpk", help="audio formats to decode using ffmpeg")
|
1206
|
+
ap2.add_argument("--au-unpk", metavar="E=F.C", type=u, default="mdz=mod.zip, mdgz=mod.gz, mdxz=mod.xz, s3z=s3m.zip, s3gz=s3m.gz, s3xz=s3m.xz, xmz=xm.zip, xmgz=xm.gz, xmxz=xm.xz, itz=it.zip, itgz=it.gz, itxz=it.xz", help="audio formats to decompress before passing to ffmpeg")
|
1191
1207
|
|
1192
1208
|
|
1193
1209
|
def add_transcoding(ap):
|
@@ -1250,19 +1266,38 @@ def add_txt(ap):
|
|
1250
1266
|
ap2.add_argument("--exp-lg", metavar="V,V,V", type=u, default=DEF_EXP, help="comma/space-separated list of placeholders to expand in prologue/epilogue files (volflag=exp_lg)")
|
1251
1267
|
|
1252
1268
|
|
1269
|
+
def add_og(ap):
|
1270
|
+
ap2 = ap.add_argument_group('og / open graph / discord-embed options')
|
1271
|
+
ap2.add_argument("--og", action="store_true", help="disable hotlinking and return an html document instead; this is required by open-graph, but can also be useful on its own (volflag=og)")
|
1272
|
+
ap2.add_argument("--og-ua", metavar="RE", type=u, default="", help="only disable hotlinking / engage OG behavior if the useragent matches regex \033[33mRE\033[0m (volflag=og_ua)")
|
1273
|
+
ap2.add_argument("--og-tpl", metavar="PATH", type=u, default="", help="do not return the regular copyparty html, but instead load the jinja2 template at \033[33mPATH\033[0m (if path contains 'EXT' then EXT will be replaced with the requested file's extension) (volflag=og_tpl)")
|
1274
|
+
ap2.add_argument("--og-no-head", action="store_true", help="do not automatically add OG entries into <head> (useful if you're doing this yourself in a template or such) (volflag=og_no_head)")
|
1275
|
+
ap2.add_argument("--og-th", metavar="FMT", type=u, default="jf3", help="thumbnail format; j=jpeg, jf=jpeg-uncropped, jf3=jpeg-uncropped-large, w=webm, ... (volflag=og_th)")
|
1276
|
+
ap2.add_argument("--og-title", metavar="TXT", type=u, default="", help="fallback title if there is nothing in the \033[33m-e2t\033[0m database (volflag=og_title)")
|
1277
|
+
ap2.add_argument("--og-title-a", metavar="T", type=u, default="🎵 {{ artist }} - {{ title }}", help="audio title format; takes any metadata key (volflag=og_title_a)")
|
1278
|
+
ap2.add_argument("--og-title-v", metavar="T", type=u, default="{{ title }}", help="video title format; takes any metadata key (volflag=og_title_v)")
|
1279
|
+
ap2.add_argument("--og-title-i", metavar="T", type=u, default="{{ title }}", help="image title format; takes any metadata key (volflag=og_title_i)")
|
1280
|
+
ap2.add_argument("--og-s-title", action="store_true", help="force default title; do not read from tags (volflag=og_s_title)")
|
1281
|
+
ap2.add_argument("--og-desc", metavar="TXT", type=u, default="", help="description text; same for all files, disable with [\033[32m-\033[0m] (volflag=og_desc)")
|
1282
|
+
ap2.add_argument("--og-site", metavar="TXT", type=u, default="", help="sitename; defaults to \033[33m--name\033[0m, disable with [\033[32m-\033[0m] (volflag=og_site)")
|
1283
|
+
ap2.add_argument("--tcolor", metavar="RGB", type=u, default="333", help="accent color (3 or 6 hex digits); may also affect safari and/or android-chrome (volflag=tcolor)")
|
1284
|
+
ap2.add_argument("--uqe", action="store_true", help="query-string parceling; translate a request for \033[33m/foo/.uqe/BASE64\033[0m into \033[33m/foo?TEXT\033[0m, or \033[33m/foo/?TEXT\033[0m if the first character in \033[33mTEXT\033[0m is a slash. Automatically enabled for \033[33m--og\033[0m")
|
1285
|
+
|
1286
|
+
|
1253
1287
|
def add_ui(ap, retry):
|
1254
1288
|
ap2 = ap.add_argument_group('ui options')
|
1255
1289
|
ap2.add_argument("--grid", action="store_true", help="show grid/thumbnails by default (volflag=grid)")
|
1256
1290
|
ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language; one of the following: \033[32meng nor\033[0m")
|
1257
1291
|
ap2.add_argument("--theme", metavar="NUM", type=int, default=0, help="default theme to use (0..7)")
|
1258
1292
|
ap2.add_argument("--themes", metavar="NUM", type=int, default=8, help="number of themes installed")
|
1293
|
+
ap2.add_argument("--au-vol", metavar="0-100", type=int, default=50, choices=range(0, 101), help="default audio/video volume percent")
|
1259
1294
|
ap2.add_argument("--sort", metavar="C,C,C", type=u, default="href", help="default sort order, comma-separated column IDs (see header tooltips), prefix with '-' for descending. Examples: \033[32mhref -href ext sz ts tags/Album tags/.tn\033[0m (volflag=sort)")
|
1260
1295
|
ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files matching \033[33mREGEX\033[0m in file list. Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)")
|
1261
1296
|
ap2.add_argument("--favico", metavar="TXT", type=u, default="c 000 none" if retry else "🎉 000 none", help="\033[33mfavicon-text\033[0m [ \033[33mforeground\033[0m [ \033[33mbackground\033[0m ] ], set blank to disable")
|
1262
1297
|
ap2.add_argument("--mpmc", metavar="URL", type=u, default="", help="change the mediaplayer-toggle mouse cursor; URL to a folder with {2..5}.png inside (or disable with [\033[32m.\033[0m])")
|
1263
1298
|
ap2.add_argument("--js-browser", metavar="L", type=u, help="URL to additional JS to include")
|
1264
1299
|
ap2.add_argument("--css-browser", metavar="L", type=u, help="URL to additional CSS to include")
|
1265
|
-
ap2.add_argument("--html-head", metavar="TXT", type=u, default="", help="text to append to the <head> of all HTML pages")
|
1300
|
+
ap2.add_argument("--html-head", metavar="TXT", type=u, default="", help="text to append to the <head> of all HTML pages; can be @PATH to send the contents of a file at PATH, and/or begin with %% to render as jinja2 template (volflag=html_head)")
|
1266
1301
|
ap2.add_argument("--ih", action="store_true", help="if a folder contains index.html, show that instead of the directory listing by default (can be changed in the client settings UI, or add ?v to URL for override)")
|
1267
1302
|
ap2.add_argument("--textfiles", metavar="CSV", type=u, default="txt,nfo,diz,cue,readme", help="file extensions to present as plaintext")
|
1268
1303
|
ap2.add_argument("--txt-max", metavar="KiB", type=int, default=64, help="max size of embedded textfiles on ?doc= (anything bigger will be lazy-loaded by JS)")
|
@@ -1350,6 +1385,7 @@ def run_argparse(
|
|
1350
1385
|
add_hooks(ap)
|
1351
1386
|
add_stats(ap)
|
1352
1387
|
add_txt(ap)
|
1388
|
+
add_og(ap)
|
1353
1389
|
add_ui(ap, retry)
|
1354
1390
|
add_admin(ap)
|
1355
1391
|
add_logging(ap)
|
@@ -1378,18 +1414,22 @@ def run_argparse(
|
|
1378
1414
|
k2 = "help_" + k.replace("-", "_")
|
1379
1415
|
if vars(ret)[k2]:
|
1380
1416
|
lprint("# %s help page (%s)" % (k, h))
|
1381
|
-
lprint(t + "\033[0m")
|
1417
|
+
lprint(t.rstrip() + "\033[0m")
|
1382
1418
|
sys.exit(0)
|
1383
1419
|
|
1384
1420
|
return ret
|
1385
1421
|
|
1386
1422
|
|
1387
|
-
def main(argv = None) :
|
1423
|
+
def main(argv = None, rsrc = None) :
|
1388
1424
|
time.strptime("19970815", "%Y%m%d") # python#7980
|
1389
1425
|
if WINDOWS:
|
1390
1426
|
os.system("rem") # enables colors
|
1391
1427
|
|
1392
1428
|
init_E(E)
|
1429
|
+
|
1430
|
+
if rsrc: # pyz
|
1431
|
+
E.mod = rsrc
|
1432
|
+
|
1393
1433
|
if argv is None:
|
1394
1434
|
argv = sys.argv
|
1395
1435
|
|
@@ -1413,9 +1453,19 @@ def main(argv = None) :
|
|
1413
1453
|
showlic()
|
1414
1454
|
sys.exit(0)
|
1415
1455
|
|
1456
|
+
if "--mimes" in argv:
|
1457
|
+
print("\n".join("%8s %s" % (k, v) for k, v in sorted(MIMES.items())))
|
1458
|
+
sys.exit(0)
|
1459
|
+
|
1416
1460
|
if EXE:
|
1417
1461
|
print("pybin: {}\n".format(pybin), end="")
|
1418
1462
|
|
1463
|
+
for n, zs in enumerate(argv):
|
1464
|
+
if zs.startswith("--sfx-tpoke="):
|
1465
|
+
Daemon(sfx_tpoke, "sfx-tpoke", (zs.split("=", 1)[1],))
|
1466
|
+
argv.pop(n)
|
1467
|
+
break
|
1468
|
+
|
1419
1469
|
ensure_locale()
|
1420
1470
|
|
1421
1471
|
ensure_webdeps()
|
@@ -17,7 +17,9 @@ from .bos import bos
|
|
17
17
|
from .cfg import flagdescs, permdescs, vf_bmap, vf_cmap, vf_vmap
|
18
18
|
from .pwhash import PWHash
|
19
19
|
from .util import (
|
20
|
+
EXTS,
|
20
21
|
IMPLICATIONS,
|
22
|
+
MIMES,
|
21
23
|
SQLITE_VER,
|
22
24
|
UNPLICATIONS,
|
23
25
|
UTC,
|
@@ -1435,6 +1437,7 @@ class AuthSrv(object):
|
|
1435
1437
|
elif "" not in mount:
|
1436
1438
|
# there's volumes but no root; make root inaccessible
|
1437
1439
|
vfs = VFS(self.log_func, "", "", AXS(), {})
|
1440
|
+
vfs.flags["tcolor"] = self.args.tcolor
|
1438
1441
|
vfs.flags["d2d"] = True
|
1439
1442
|
|
1440
1443
|
maxdepth = 0
|
@@ -1720,7 +1723,11 @@ class AuthSrv(object):
|
|
1720
1723
|
if self.args.e2d or "e2ds" in vol.flags:
|
1721
1724
|
vol.flags["e2d"] = True
|
1722
1725
|
|
1723
|
-
for ga, vf in [
|
1726
|
+
for ga, vf in [
|
1727
|
+
["no_hash", "nohash"],
|
1728
|
+
["no_idx", "noidx"],
|
1729
|
+
["og_ua", "og_ua"],
|
1730
|
+
]:
|
1724
1731
|
if vf in vol.flags:
|
1725
1732
|
ptn = re.compile(vol.flags.pop(vf))
|
1726
1733
|
else:
|
@@ -1766,6 +1773,13 @@ class AuthSrv(object):
|
|
1766
1773
|
t = 'volume "/%s" has invalid %stry [%s]'
|
1767
1774
|
raise Exception(t % (vol.vpath, k, vol.flags.get(k + "try")))
|
1768
1775
|
|
1776
|
+
if vol.flags.get("og"):
|
1777
|
+
self.args.uqe = True
|
1778
|
+
|
1779
|
+
zs = str(vol.flags.get("tcolor", "")).lstrip("#")
|
1780
|
+
if len(zs) == 3: # fc5 => ffcc55
|
1781
|
+
vol.flags["tcolor"] = "".join([x * 2 for x in zs])
|
1782
|
+
|
1769
1783
|
for k1, k2 in IMPLICATIONS:
|
1770
1784
|
if k1 in vol.flags:
|
1771
1785
|
vol.flags[k2] = True
|
@@ -2046,6 +2060,13 @@ class AuthSrv(object):
|
|
2046
2060
|
|
2047
2061
|
self.re_pwd = re.compile(zs)
|
2048
2062
|
|
2063
|
+
# to ensure it propagates into tcpsrv with mp on
|
2064
|
+
if self.args.mime:
|
2065
|
+
for zs in self.args.mime:
|
2066
|
+
ext, mime = zs.split("=", 1)
|
2067
|
+
MIMES[ext] = mime
|
2068
|
+
EXTS.update({v: k for k, v in MIMES.items()})
|
2069
|
+
|
2049
2070
|
def setup_pwhash(self, acct ) :
|
2050
2071
|
self.ah = PWHash(self.args)
|
2051
2072
|
if not self.ah.on:
|
@@ -2403,7 +2424,7 @@ def expand_config_file(
|
|
2403
2424
|
if not cnames:
|
2404
2425
|
t = "warning: tried to read config-files from folder '%s' but it does not contain any "
|
2405
2426
|
if names:
|
2406
|
-
t += ".conf files; the following files were ignored: %s"
|
2427
|
+
t += ".conf files; the following files/subfolders were ignored: %s"
|
2407
2428
|
t = t % (fp, ", ".join(names[:8]))
|
2408
2429
|
else:
|
2409
2430
|
t += "files at all"
|
@@ -53,11 +53,8 @@ class BrokerMp(object):
|
|
53
53
|
def shutdown(self) :
|
54
54
|
self.log("broker", "shutting down")
|
55
55
|
for n, proc in enumerate(self.procs):
|
56
|
-
|
57
|
-
|
58
|
-
name="mp-shutdown-{}-{}".format(n, len(self.procs)),
|
59
|
-
)
|
60
|
-
thr.start()
|
56
|
+
name = "mp-shut-%d-%d" % (n, len(self.procs))
|
57
|
+
Daemon(proc.q_pend.put, name, ((0, "shutdown", []),))
|
61
58
|
|
62
59
|
with self.mutex:
|
63
60
|
procs = self.procs
|
@@ -39,6 +39,9 @@ def vf_bmap() :
|
|
39
39
|
"magic",
|
40
40
|
"no_sb_md",
|
41
41
|
"no_sb_lg",
|
42
|
+
"og",
|
43
|
+
"og_no_head",
|
44
|
+
"og_s_title",
|
42
45
|
"rand",
|
43
46
|
"xdev",
|
44
47
|
"xlink",
|
@@ -61,12 +64,23 @@ def vf_vmap() :
|
|
61
64
|
}
|
62
65
|
for k in (
|
63
66
|
"dbd",
|
67
|
+
"html_head",
|
64
68
|
"lg_sbf",
|
65
69
|
"md_sbf",
|
66
70
|
"nrand",
|
71
|
+
"og_desc",
|
72
|
+
"og_site",
|
73
|
+
"og_th",
|
74
|
+
"og_title",
|
75
|
+
"og_title_a",
|
76
|
+
"og_title_v",
|
77
|
+
"og_title_i",
|
78
|
+
"og_tpl",
|
79
|
+
"og_ua",
|
67
80
|
"mv_retry",
|
68
81
|
"rm_retry",
|
69
82
|
"sort",
|
83
|
+
"tcolor",
|
70
84
|
"unlist",
|
71
85
|
"u2abort",
|
72
86
|
"u2ts",
|
@@ -81,7 +95,6 @@ def vf_cmap() :
|
|
81
95
|
for k in (
|
82
96
|
"exp_lg",
|
83
97
|
"exp_md",
|
84
|
-
"html_head",
|
85
98
|
"mte",
|
86
99
|
"mth",
|
87
100
|
"mtp",
|
@@ -177,6 +190,7 @@ flagcats = {
|
|
177
190
|
"dvthumb": "disables video thumbnails",
|
178
191
|
"dathumb": "disables audio thumbnails (spectrograms)",
|
179
192
|
"dithumb": "disables image thumbnails",
|
193
|
+
"pngquant": "compress audio waveforms 33% better",
|
180
194
|
"thsize": "thumbnail res; WxH",
|
181
195
|
"crop": "center-cropping (y/n/fy/fn)",
|
182
196
|
"th3x": "3x resolution (y/n/fy/fn)",
|
@@ -201,7 +215,7 @@ flagcats = {
|
|
201
215
|
"grid": "show grid/thumbnails by default",
|
202
216
|
"sort": "default sort order",
|
203
217
|
"unlist": "dont list files matching REGEX",
|
204
|
-
"html_head=TXT": "includes TXT in the <head
|
218
|
+
"html_head=TXT": "includes TXT in the <head>, or @PATH for file at PATH",
|
205
219
|
"robots": "allows indexing by search engines (default)",
|
206
220
|
"norobots": "kindly asks search engines to leave",
|
207
221
|
"no_sb_md": "disable js sandbox for markdown files",
|