copyparty 1.19.17__tar.gz → 1.19.19__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.19.17 → copyparty-1.19.19}/PKG-INFO +17 -3
 - {copyparty-1.19.17 → copyparty-1.19.19}/README.md +16 -2
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/__init__.py +6 -1
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/__main__.py +1 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/__version__.py +2 -2
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/authsrv.py +47 -25
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/ftpd.py +1 -1
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/httpcli.py +61 -25
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/httpsrv.py +2 -2
 - copyparty-1.19.19/copyparty/web/a/partyfuse.py.gz +0 -0
 - copyparty-1.19.19/copyparty/web/a/u2c.py.gz +0 -0
 - copyparty-1.19.19/copyparty/web/a/webdav-cfg.txt.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/baguettebox.js.gz +0 -0
 - copyparty-1.19.19/copyparty/web/browser.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/browser.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/dbg-audio.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/md.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/md.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/md2.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/md2.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/mde.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/mde.js.gz +0 -0
 - copyparty-1.19.19/copyparty/web/msg.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/rups.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/rups.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/shares.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/shares.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/splash.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/splash.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/svcs.html +1 -1
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/svcs.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/chi.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/cze.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/deu.js.gz +0 -0
 - copyparty-1.19.19/copyparty/web/tl/epo.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/fin.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/fra.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/grc.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/ita.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/kor.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/nld.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/nno.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/nor.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/pol.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/por.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/rus.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/spa.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/swe.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/tur.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/tl/ukr.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/ui.css.gz +0 -0
 - copyparty-1.19.19/copyparty/web/up2k.js.gz +0 -0
 - copyparty-1.19.19/copyparty/web/util.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/w.hash.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty.egg-info/PKG-INFO +17 -3
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty.egg-info/SOURCES.txt +3 -3
 - {copyparty-1.19.17 → copyparty-1.19.19}/pyproject.toml +2 -1
 - copyparty-1.19.17/copyparty/web/a/partyfuse.py +0 -947
 - copyparty-1.19.17/copyparty/web/a/u2c.py +0 -1718
 - copyparty-1.19.17/copyparty/web/a/webdav-cfg.bat +0 -45
 - copyparty-1.19.17/copyparty/web/browser.css.gz +0 -0
 - copyparty-1.19.17/copyparty/web/msg.css.gz +0 -0
 - copyparty-1.19.17/copyparty/web/tl/epo.js.gz +0 -0
 - copyparty-1.19.17/copyparty/web/up2k.js.gz +0 -0
 - copyparty-1.19.17/copyparty/web/util.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/LICENSE +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/bos/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/bos/bos.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/bos/path.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/broker_mp.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/broker_mpw.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/broker_thr.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/broker_util.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/cert.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/cfg.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/dxml.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/fsutil.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/httpconn.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/ico.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/mdns.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/metrics.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/mtag.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/multicast.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/pwhash.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/qrkode.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/res/COPYING.txt +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/res/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/res/insecure.pem +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/smbd.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/ssdp.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/star.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/bimap.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/bit.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/buffer.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/dns.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/label.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/lex.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/dnslib/ranges.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/ifaddr/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/ifaddr/_posix.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/ifaddr/_shared.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/ifaddr/_win32.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/qrcodegen.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/stolen/surrogateescape.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/sutil.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/svchub.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/szip.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/tcpsrv.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/tftpd.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/th_cli.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/th_srv.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/u2idx.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/up2k.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/util.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/a/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/browser.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/browser2.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/cf.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/__init__.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/busy.mp3.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/easymde.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/easymde.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/fuse.py +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/marked.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/mini-fa.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/mini-fa.woff +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/prism.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/prism.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/prismd.css.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/scp.woff2 +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/sha512.ac.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/deps/sha512.hw.js.gz +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/idp.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/md.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/mde.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/msg.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/opds.xml +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/rups.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/shares.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty/web/splash.html +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty.egg-info/dependency_links.txt +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty.egg-info/entry_points.txt +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty.egg-info/requires.txt +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/copyparty.egg-info/top_level.txt +0 -0
 - {copyparty-1.19.17 → copyparty-1.19.19}/setup.cfg +0 -0
 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Metadata-Version: 2.4
         
     | 
| 
       2 
2 
     | 
    
         
             
            Name: copyparty
         
     | 
| 
       3 
     | 
    
         
            -
            Version: 1.19. 
     | 
| 
      
 3 
     | 
    
         
            +
            Version: 1.19.19
         
     | 
| 
       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
         
     | 
| 
         @@ -86,6 +86,7 @@ made in Norway 🇳🇴 
     | 
|
| 
       86 
86 
     | 
    
         | 
| 
       87 
87 
     | 
    
         
             
            * top
         
     | 
| 
       88 
88 
     | 
    
         
             
                * [quickstart](#quickstart) - just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py)** -- that's it! 🎉
         
     | 
| 
      
 89 
     | 
    
         
            +
                    * [mirrors](#mirrors) - other places to download copyparty from
         
     | 
| 
       89 
90 
     | 
    
         
             
                    * [at home](#at-home) - make it accessible over the internet
         
     | 
| 
       90 
91 
     | 
    
         
             
                    * [on servers](#on-servers) - you may also want these, especially on servers
         
     | 
| 
       91 
92 
     | 
    
         
             
                * [features](#features) - also see [comparison to similar software](./docs/versus.md)
         
     | 
| 
         @@ -222,7 +223,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/ 
     | 
|
| 
       222 
223 
     | 
    
         | 
| 
       223 
224 
     | 
    
         
             
            * or install through [pypi](https://pypi.org/project/copyparty/): `python3 -m pip install --user -U copyparty`
         
     | 
| 
       224 
225 
     | 
    
         
             
            * or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
         
     | 
| 
       225 
     | 
    
         
            -
            * or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
         
     | 
| 
      
 226 
     | 
    
         
            +
            * or install [on arch](#arch-package) / [homebrew](#homebrew-formulae) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
         
     | 
| 
       226 
227 
     | 
    
         
             
            * or if you are on android, [install copyparty in termux](#install-on-android)
         
     | 
| 
       227 
228 
     | 
    
         
             
            * or maybe an iPhone or iPad? [install in a-Shell on iOS](#install-on-iOS)
         
     | 
| 
       228 
229 
     | 
    
         
             
            * or maybe you have a [synology nas / dsm](./docs/synology-dsm.md)
         
     | 
| 
         @@ -260,6 +261,18 @@ some recommended options: 
     | 
|
| 
       260 
261 
     | 
    
         
             
              * see [accounts and volumes](#accounts-and-volumes) (or `--help-accounts`) for the syntax and other permissions
         
     | 
| 
       261 
262 
     | 
    
         | 
| 
       262 
263 
     | 
    
         | 
| 
      
 264 
     | 
    
         
            +
            ### mirrors
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
            other places to download copyparty from  (non-github links):
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
            * https://copyparty.eu/ (hetzner, finland, official mirror):
         
     | 
| 
      
 269 
     | 
    
         
            +
              * https://copyparty.eu/py = https://copyparty.eu/copyparty-sfx.py = the sfx
         
     | 
| 
      
 270 
     | 
    
         
            +
              * https://copyparty.eu/en = https://copyparty.eu/copyparty-en.py = the english-only sfx
         
     | 
| 
      
 271 
     | 
    
         
            +
              * https://copyparty.eu/pyz = https://copyparty.eu/copyparty.pyz = the zipapp
         
     | 
| 
      
 272 
     | 
    
         
            +
              * https://copyparty.eu/enz = https://copyparty.eu/copyparty-en.pyz = the enterprise pyz
         
     | 
| 
      
 273 
     | 
    
         
            +
              * https://copyparty.eu/cli = online cli helptext
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
       263 
276 
     | 
    
         
             
            ### at home
         
     | 
| 
       264 
277 
     | 
    
         | 
| 
       265 
278 
     | 
    
         
             
            make it accessible over the internet  by starting a [cloudflare quicktunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/) like so:
         
     | 
| 
         @@ -3131,7 +3144,8 @@ another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty 
     | 
|
| 
       3131 
3144 
     | 
    
         
             
            run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
         
     | 
| 
       3132 
3145 
     | 
    
         | 
| 
       3133 
3146 
     | 
    
         
             
            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
         
     | 
| 
       3134 
     | 
    
         
            -
             
     | 
| 
      
 3147 
     | 
    
         
            +
             
     | 
| 
      
 3148 
     | 
    
         
            +
            > there is also [copyparty-en.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty-en.pyz), english-only and without smb support (enterprise-friendly)
         
     | 
| 
       3135 
3149 
     | 
    
         | 
| 
       3136 
3150 
     | 
    
         | 
| 
       3137 
3151 
     | 
    
         
             
            # install on android
         
     | 
| 
         @@ -21,6 +21,7 @@ made in Norway 🇳🇴 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            * top
         
     | 
| 
       23 
23 
     | 
    
         
             
                * [quickstart](#quickstart) - just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py)** -- that's it! 🎉
         
     | 
| 
      
 24 
     | 
    
         
            +
                    * [mirrors](#mirrors) - other places to download copyparty from
         
     | 
| 
       24 
25 
     | 
    
         
             
                    * [at home](#at-home) - make it accessible over the internet
         
     | 
| 
       25 
26 
     | 
    
         
             
                    * [on servers](#on-servers) - you may also want these, especially on servers
         
     | 
| 
       26 
27 
     | 
    
         
             
                * [features](#features) - also see [comparison to similar software](./docs/versus.md)
         
     | 
| 
         @@ -157,7 +158,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/ 
     | 
|
| 
       157 
158 
     | 
    
         | 
| 
       158 
159 
     | 
    
         
             
            * or install through [pypi](https://pypi.org/project/copyparty/): `python3 -m pip install --user -U copyparty`
         
     | 
| 
       159 
160 
     | 
    
         
             
            * or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
         
     | 
| 
       160 
     | 
    
         
            -
            * or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
         
     | 
| 
      
 161 
     | 
    
         
            +
            * or install [on arch](#arch-package) / [homebrew](#homebrew-formulae) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
         
     | 
| 
       161 
162 
     | 
    
         
             
            * or if you are on android, [install copyparty in termux](#install-on-android)
         
     | 
| 
       162 
163 
     | 
    
         
             
            * or maybe an iPhone or iPad? [install in a-Shell on iOS](#install-on-iOS)
         
     | 
| 
       163 
164 
     | 
    
         
             
            * or maybe you have a [synology nas / dsm](./docs/synology-dsm.md)
         
     | 
| 
         @@ -195,6 +196,18 @@ some recommended options: 
     | 
|
| 
       195 
196 
     | 
    
         
             
              * see [accounts and volumes](#accounts-and-volumes) (or `--help-accounts`) for the syntax and other permissions
         
     | 
| 
       196 
197 
     | 
    
         | 
| 
       197 
198 
     | 
    
         | 
| 
      
 199 
     | 
    
         
            +
            ### mirrors
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
            other places to download copyparty from  (non-github links):
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
            * https://copyparty.eu/ (hetzner, finland, official mirror):
         
     | 
| 
      
 204 
     | 
    
         
            +
              * https://copyparty.eu/py = https://copyparty.eu/copyparty-sfx.py = the sfx
         
     | 
| 
      
 205 
     | 
    
         
            +
              * https://copyparty.eu/en = https://copyparty.eu/copyparty-en.py = the english-only sfx
         
     | 
| 
      
 206 
     | 
    
         
            +
              * https://copyparty.eu/pyz = https://copyparty.eu/copyparty.pyz = the zipapp
         
     | 
| 
      
 207 
     | 
    
         
            +
              * https://copyparty.eu/enz = https://copyparty.eu/copyparty-en.pyz = the enterprise pyz
         
     | 
| 
      
 208 
     | 
    
         
            +
              * https://copyparty.eu/cli = online cli helptext
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
       198 
211 
     | 
    
         
             
            ### at home
         
     | 
| 
       199 
212 
     | 
    
         | 
| 
       200 
213 
     | 
    
         
             
            make it accessible over the internet  by starting a [cloudflare quicktunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/) like so:
         
     | 
| 
         @@ -3066,7 +3079,8 @@ another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty 
     | 
|
| 
       3066 
3079 
     | 
    
         
             
            run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
         
     | 
| 
       3067 
3080 
     | 
    
         | 
| 
       3068 
3081 
     | 
    
         
             
            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
         
     | 
| 
       3069 
     | 
    
         
            -
             
     | 
| 
      
 3082 
     | 
    
         
            +
             
     | 
| 
      
 3083 
     | 
    
         
            +
            > there is also [copyparty-en.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty-en.pyz), english-only and without smb support (enterprise-friendly)
         
     | 
| 
       3070 
3084 
     | 
    
         | 
| 
       3071 
3085 
     | 
    
         | 
| 
       3072 
3086 
     | 
    
         
             
            # install on android
         
     | 
| 
         @@ -52,7 +52,7 @@ except: 
     | 
|
| 
       52 
52 
     | 
    
         
             
            zs = """
         
     | 
| 
       53 
53 
     | 
    
         
             
            web/a/partyfuse.py
         
     | 
| 
       54 
54 
     | 
    
         
             
            web/a/u2c.py
         
     | 
| 
       55 
     | 
    
         
            -
            web/a/webdav-cfg. 
     | 
| 
      
 55 
     | 
    
         
            +
            web/a/webdav-cfg.txt
         
     | 
| 
       56 
56 
     | 
    
         
             
            web/baguettebox.js
         
     | 
| 
       57 
57 
     | 
    
         
             
            web/browser.css
         
     | 
| 
       58 
58 
     | 
    
         
             
            web/browser.html
         
     | 
| 
         @@ -122,6 +122,11 @@ web/util.js 
     | 
|
| 
       122 
122 
     | 
    
         
             
            web/w.hash.js
         
     | 
| 
       123 
123 
     | 
    
         
             
            """
         
     | 
| 
       124 
124 
     | 
    
         
             
            RES = set(zs.strip().split("\n"))
         
     | 
| 
      
 125 
     | 
    
         
            +
            RESM = {
         
     | 
| 
      
 126 
     | 
    
         
            +
                "web/a/partyfuse.txt": "web/a/partyfuse.py",
         
     | 
| 
      
 127 
     | 
    
         
            +
                "web/a/u2c.txt": "web/a/u2c.py",
         
     | 
| 
      
 128 
     | 
    
         
            +
                "web/a/webdav-cfg.bat": "web/a/webdav-cfg.txt",
         
     | 
| 
      
 129 
     | 
    
         
            +
            }
         
     | 
| 
       125 
130 
     | 
    
         | 
| 
       126 
131 
     | 
    
         | 
| 
       127 
132 
     | 
    
         
             
            class EnvParams(object):
         
     | 
| 
         @@ -1788,6 +1788,7 @@ def add_ui(ap, retry ): 
     | 
|
| 
       1788 
1788 
     | 
    
         
             
                ap2.add_argument("--ufavico", metavar="TXT", type=u, default="", help="URL to .ico/png/gif/svg file; \033[33m--favico\033[0m takes precedence unless disabled (volflag=ufavico)")
         
     | 
| 
       1789 
1789 
     | 
    
         
             
                ap2.add_argument("--ext-th", metavar="E=VP", type=u, action="append", help="\033[34mREPEATABLE:\033[0m use thumbnail-image \033[33mVP\033[0m for file-extension \033[33mE\033[0m, example: [\033[32mexe=/.res/exe.png\033[0m] (volflag=ext_th)")
         
     | 
| 
       1790 
1790 
     | 
    
         
             
                ap2.add_argument("--mpmc", type=u, default="", help=argparse.SUPPRESS)
         
     | 
| 
      
 1791 
     | 
    
         
            +
                ap2.add_argument("--notooltips", action="store_true", help="tooltips disabled as default")
         
     | 
| 
       1791 
1792 
     | 
    
         
             
                ap2.add_argument("--spinner", metavar="TXT", type=u, default="🌲", help="\033[33memoji\033[0m or \033[33memoji,css\033[0m Example: [\033[32m🥖,padding:0\033[0m]")
         
     | 
| 
       1792 
1793 
     | 
    
         
             
                ap2.add_argument("--css-browser", metavar="L", type=u, default="", help="URL to additional CSS to include in the filebrowser html")
         
     | 
| 
       1793 
1794 
     | 
    
         
             
                ap2.add_argument("--js-browser", metavar="L", type=u, default="", help="URL to additional JS to include in the filebrowser html")
         
     | 
| 
         @@ -391,6 +391,9 @@ class VFS(object): 
     | 
|
| 
       391 
391 
     | 
    
         
             
                    self.vpath = vpath  # absolute path in the virtual filesystem
         
     | 
| 
       392 
392 
     | 
    
         
             
                    self.vpath0 = vpath0  # original vpath (before idp expansion)
         
     | 
| 
       393 
393 
     | 
    
         
             
                    self.axs = axs
         
     | 
| 
      
 394 
     | 
    
         
            +
                    self.uaxs                               = {}
         
     | 
| 
      
 395 
     | 
    
         
            +
             
     | 
| 
      
 396 
     | 
    
         
            +
             
     | 
| 
       394 
397 
     | 
    
         
             
                    self.flags = flags  # config options
         
     | 
| 
       395 
398 
     | 
    
         
             
                    self.root = self
         
     | 
| 
       396 
399 
     | 
    
         
             
                    self.dev = 0  # st_dev
         
     | 
| 
         @@ -548,29 +551,19 @@ class VFS(object): 
     | 
|
| 
       548 
551 
     | 
    
         | 
| 
       549 
552 
     | 
    
         
             
                def can_access(
         
     | 
| 
       550 
553 
     | 
    
         
             
                    self, vpath , uname 
         
     | 
| 
       551 
     | 
    
         
            -
                ) 
     | 
| 
       552 
     | 
    
         
            -
                    """can Read,Write,Move,Delete,Get,Upget,Admin,Dot"""
         
     | 
| 
      
 554 
     | 
    
         
            +
                )          :
         
     | 
| 
      
 555 
     | 
    
         
            +
                    """can Read,Write,Move,Delete,Get,Upget,Html,Admin,Dot"""
         
     | 
| 
      
 556 
     | 
    
         
            +
                    # NOTE: only used by get_perms, which is only used by hooks; the lowest of fruits
         
     | 
| 
       553 
557 
     | 
    
         
             
                    if vpath:
         
     | 
| 
       554 
558 
     | 
    
         
             
                        vn, _ = self._find(undot(vpath))
         
     | 
| 
       555 
559 
     | 
    
         
             
                    else:
         
     | 
| 
       556 
560 
     | 
    
         
             
                        vn = self
         
     | 
| 
       557 
561 
     | 
    
         | 
| 
       558 
     | 
    
         
            -
                     
     | 
| 
       559 
     | 
    
         
            -
                    return (
         
     | 
| 
       560 
     | 
    
         
            -
                        uname in c.uread,
         
     | 
| 
       561 
     | 
    
         
            -
                        uname in c.uwrite,
         
     | 
| 
       562 
     | 
    
         
            -
                        uname in c.umove,
         
     | 
| 
       563 
     | 
    
         
            -
                        uname in c.udel,
         
     | 
| 
       564 
     | 
    
         
            -
                        uname in c.uget,
         
     | 
| 
       565 
     | 
    
         
            -
                        uname in c.upget,
         
     | 
| 
       566 
     | 
    
         
            -
                        uname in c.uadmin,
         
     | 
| 
       567 
     | 
    
         
            -
                        uname in c.udot,
         
     | 
| 
       568 
     | 
    
         
            -
                    )
         
     | 
| 
       569 
     | 
    
         
            -
                    # skip uhtml because it's rarely needed
         
     | 
| 
      
 562 
     | 
    
         
            +
                    return vn.uaxs[uname]
         
     | 
| 
       570 
563 
     | 
    
         | 
| 
       571 
564 
     | 
    
         
             
                def get_perms(self, vpath , uname )  :
         
     | 
| 
       572 
565 
     | 
    
         
             
                    zbl = self.can_access(vpath, uname)
         
     | 
| 
       573 
     | 
    
         
            -
                    ret = "".join(ch for ch, ok in zip(" 
     | 
| 
      
 566 
     | 
    
         
            +
                    ret = "".join(ch for ch, ok in zip("rwmdgGha.", zbl) if ok)
         
     | 
| 
       574 
567 
     | 
    
         
             
                    if "rwmd" in ret and "a." in ret:
         
     | 
| 
       575 
568 
     | 
    
         
             
                        ret += "A"
         
     | 
| 
       576 
569 
     | 
    
         
             
                    return ret
         
     | 
| 
         @@ -763,20 +756,17 @@ class VFS(object): 
     | 
|
| 
       763 
756 
     | 
    
         
             
                                virt_vis[name] = vn2
         
     | 
| 
       764 
757 
     | 
    
         
             
                                continue
         
     | 
| 
       765 
758 
     | 
    
         | 
| 
       766 
     | 
    
         
            -
                             
     | 
| 
       767 
     | 
    
         
            -
                            zx = vn2.axs
         
     | 
| 
       768 
     | 
    
         
            -
                            axs = [zx.uread, zx.uwrite, zx.umove, zx.udel, zx.uget]
         
     | 
| 
      
 759 
     | 
    
         
            +
                            u_has = vn2.uaxs.get(uname) or [False] * 9
         
     | 
| 
       769 
760 
     | 
    
         
             
                            for pset in permsets:
         
     | 
| 
       770 
761 
     | 
    
         
             
                                ok = True
         
     | 
| 
       771 
     | 
    
         
            -
                                for req,  
     | 
| 
       772 
     | 
    
         
            -
                                    if req and  
     | 
| 
      
 762 
     | 
    
         
            +
                                for req, zb in zip(pset, u_has):
         
     | 
| 
      
 763 
     | 
    
         
            +
                                    if req and not zb:
         
     | 
| 
       773 
764 
     | 
    
         
             
                                        ok = False
         
     | 
| 
      
 765 
     | 
    
         
            +
                                        break
         
     | 
| 
       774 
766 
     | 
    
         
             
                                if ok:
         
     | 
| 
      
 767 
     | 
    
         
            +
                                    virt_vis[name] = vn2
         
     | 
| 
       775 
768 
     | 
    
         
             
                                    break
         
     | 
| 
       776 
769 
     | 
    
         | 
| 
       777 
     | 
    
         
            -
                            if ok:
         
     | 
| 
       778 
     | 
    
         
            -
                                virt_vis[name] = vn2
         
     | 
| 
       779 
     | 
    
         
            -
             
     | 
| 
       780 
770 
     | 
    
         
             
                    if ".hist" in abspath:
         
     | 
| 
       781 
771 
     | 
    
         
             
                        p = abspath.replace("\\", "/") if WINDOWS else abspath
         
     | 
| 
       782 
772 
     | 
    
         
             
                        if p.endswith("/.hist"):
         
     | 
| 
         @@ -1984,6 +1974,23 @@ class AuthSrv(object): 
     | 
|
| 
       1984 
1974 
     | 
    
         
             
                            umap[usr].sort()
         
     | 
| 
       1985 
1975 
     | 
    
         
             
                        setattr(vfs, "a" + perm, umap)
         
     | 
| 
       1986 
1976 
     | 
    
         | 
| 
      
 1977 
     | 
    
         
            +
                    for vol in vfs.all_nodes.values():
         
     | 
| 
      
 1978 
     | 
    
         
            +
                        za = vol.axs
         
     | 
| 
      
 1979 
     | 
    
         
            +
                        vol.uaxs = {
         
     | 
| 
      
 1980 
     | 
    
         
            +
                            un: (
         
     | 
| 
      
 1981 
     | 
    
         
            +
                                un in za.uread,
         
     | 
| 
      
 1982 
     | 
    
         
            +
                                un in za.uwrite,
         
     | 
| 
      
 1983 
     | 
    
         
            +
                                un in za.umove,
         
     | 
| 
      
 1984 
     | 
    
         
            +
                                un in za.udel,
         
     | 
| 
      
 1985 
     | 
    
         
            +
                                un in za.uget,
         
     | 
| 
      
 1986 
     | 
    
         
            +
                                un in za.upget,
         
     | 
| 
      
 1987 
     | 
    
         
            +
                                un in za.uhtml,
         
     | 
| 
      
 1988 
     | 
    
         
            +
                                un in za.uadmin,
         
     | 
| 
      
 1989 
     | 
    
         
            +
                                un in za.udot,
         
     | 
| 
      
 1990 
     | 
    
         
            +
                            )
         
     | 
| 
      
 1991 
     | 
    
         
            +
                            for un in unames
         
     | 
| 
      
 1992 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1993 
     | 
    
         
            +
             
     | 
| 
       1987 
1994 
     | 
    
         
             
                    all_users = {}
         
     | 
| 
       1988 
1995 
     | 
    
         
             
                    missing_users = {}
         
     | 
| 
       1989 
1996 
     | 
    
         
             
                    associated_users = {}
         
     | 
| 
         @@ -2317,6 +2324,10 @@ class AuthSrv(object): 
     | 
|
| 
       2317 
2324 
     | 
    
         
             
                    free_umask = False
         
     | 
| 
       2318 
2325 
     | 
    
         
             
                    have_reflink = False
         
     | 
| 
       2319 
2326 
     | 
    
         
             
                    for vol in vfs.all_nodes.values():
         
     | 
| 
      
 2327 
     | 
    
         
            +
                        if os.path.isfile(vol.realpath):
         
     | 
| 
      
 2328 
     | 
    
         
            +
                            vol.flags["is_file"] = True
         
     | 
| 
      
 2329 
     | 
    
         
            +
                            vol.flags["d2d"] = True
         
     | 
| 
      
 2330 
     | 
    
         
            +
             
     | 
| 
       2320 
2331 
     | 
    
         
             
                        if (self.args.e2ds and vol.axs.uwrite) or self.args.e2dsa:
         
     | 
| 
       2321 
2332 
     | 
    
         
             
                            vol.flags["e2ds"] = True
         
     | 
| 
       2322 
2333 
     | 
    
         | 
| 
         @@ -2631,7 +2642,14 @@ class AuthSrv(object): 
     | 
|
| 
       2631 
2642 
     | 
    
         
             
                                errors = True
         
     | 
| 
       2632 
2643 
     | 
    
         | 
| 
       2633 
2644 
     | 
    
         
             
                    for vol in vfs.all_nodes.values():
         
     | 
| 
       2634 
     | 
    
         
            -
                        if not vol. 
     | 
| 
      
 2645 
     | 
    
         
            +
                        if not vol.flags.get("is_file"):
         
     | 
| 
      
 2646 
     | 
    
         
            +
                            continue
         
     | 
| 
      
 2647 
     | 
    
         
            +
                        zs = "og opds xlink"
         
     | 
| 
      
 2648 
     | 
    
         
            +
                        for zs in zs.split():
         
     | 
| 
      
 2649 
     | 
    
         
            +
                            vol.flags.pop(zs, None)
         
     | 
| 
      
 2650 
     | 
    
         
            +
             
     | 
| 
      
 2651 
     | 
    
         
            +
                    for vol in vfs.all_nodes.values():
         
     | 
| 
      
 2652 
     | 
    
         
            +
                        if not vol.realpath or vol.flags.get("is_file"):
         
     | 
| 
       2635 
2653 
     | 
    
         
             
                            continue
         
     | 
| 
       2636 
2654 
     | 
    
         
             
                        ccs = vol.flags["casechk"][:1].lower()
         
     | 
| 
       2637 
2655 
     | 
    
         
             
                        if ccs in ("y", "n"):
         
     | 
| 
         @@ -3077,6 +3095,10 @@ class AuthSrv(object): 
     | 
|
| 
       3077 
3095 
     | 
    
         
             
                        for zs in zs.split():
         
     | 
| 
       3078 
3096 
     | 
    
         
             
                            if vf.get(zs):
         
     | 
| 
       3079 
3097 
     | 
    
         
             
                                js_htm[zs] = 1
         
     | 
| 
      
 3098 
     | 
    
         
            +
                        zs = "notooltips"
         
     | 
| 
      
 3099 
     | 
    
         
            +
                        for zs in zs.split():
         
     | 
| 
      
 3100 
     | 
    
         
            +
                            if getattr(self.args, zs, False):
         
     | 
| 
      
 3101 
     | 
    
         
            +
                                js_htm[zs] = 1
         
     | 
| 
       3080 
3102 
     | 
    
         
             
                        vn.js_htm = json_hesc(json.dumps(js_htm))
         
     | 
| 
       3081 
3103 
     | 
    
         | 
| 
       3082 
3104 
     | 
    
         
             
                    vols = list(vfs.all_nodes.values())
         
     | 
| 
         @@ -3421,7 +3443,7 @@ class AuthSrv(object): 
     | 
|
| 
       3421 
3443 
     | 
    
         
             
                            raise Exception("volume not found: " + zs)
         
     | 
| 
       3422 
3444 
     | 
    
         | 
| 
       3423 
3445 
     | 
    
         
             
                    self.log(str({"users": users, "vols": vols, "flags": flags}))
         
     | 
| 
       3424 
     | 
    
         
            -
                    t = "/{}: read({}) write({}) move({}) del({}) dots({}) get({}) upGet({}) uadmin({})"
         
     | 
| 
      
 3446 
     | 
    
         
            +
                    t = "/{}: read({}) write({}) move({}) del({}) dots({}) get({}) upGet({}) html({}) uadmin({})"
         
     | 
| 
       3425 
3447 
     | 
    
         
             
                    for k, zv in self.vfs.all_vols.items():
         
     | 
| 
       3426 
3448 
     | 
    
         
             
                        vc = zv.axs
         
     | 
| 
       3427 
3449 
     | 
    
         
             
                        vs = [
         
     | 
| 
         @@ -194,7 +194,7 @@ class FtpFs(AbstractedFS): 
     | 
|
| 
       194 
194 
     | 
    
         
             
                            if not avfs:
         
     | 
| 
       195 
195 
     | 
    
         
             
                                raise FSE(t.format(vpath), 1)
         
     | 
| 
       196 
196 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
                            cr, cw, cm, cd, _, _, _, _ = avfs. 
     | 
| 
      
 197 
     | 
    
         
            +
                            cr, cw, cm, cd, _, _, _, _, _ = avfs.uaxs[self.h.uname]
         
     | 
| 
       198 
198 
     | 
    
         
             
                            if r and not cr or w and not cw or m and not cm or d and not cd:
         
     | 
| 
       199 
199 
     | 
    
         
             
                                raise FSE(t.format(vpath), 1)
         
     | 
| 
       200 
200 
     | 
    
         | 
| 
         @@ -30,7 +30,7 @@ try: 
     | 
|
| 
       30 
30 
     | 
    
         
             
            except:
         
     | 
| 
       31 
31 
     | 
    
         
             
                pass
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
            from .__init__ import ANYWIN, RES, TYPE_CHECKING, EnvParams, unicode
         
     | 
| 
      
 33 
     | 
    
         
            +
            from .__init__ import ANYWIN, RES, RESM, TYPE_CHECKING, EnvParams, unicode
         
     | 
| 
       34 
34 
     | 
    
         
             
            from .__version__ import S_VERSION
         
     | 
| 
       35 
35 
     | 
    
         
             
            from .authsrv import LEELOO_DALLAS, VFS  # typechk
         
     | 
| 
       36 
36 
     | 
    
         
             
            from .bos import bos
         
     | 
| 
         @@ -161,6 +161,12 @@ RE_MDV = re.compile(r"(.*)\.([0-9]+\.[0-9]{3})(\.[Mm][Dd])$") 
     | 
|
| 
       161 
161 
     | 
    
         | 
| 
       162 
162 
     | 
    
         
             
            UPARAM_CC_OK = set("doc move tree".split())
         
     | 
| 
       163 
163 
     | 
    
         | 
| 
      
 164 
     | 
    
         
            +
            PERMS_rwh = [
         
     | 
| 
      
 165 
     | 
    
         
            +
                [True, False],
         
     | 
| 
      
 166 
     | 
    
         
            +
                [False, True],
         
     | 
| 
      
 167 
     | 
    
         
            +
                [False, False, False, False, False, False, True],
         
     | 
| 
      
 168 
     | 
    
         
            +
            ]
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
       164 
170 
     | 
    
         | 
| 
       165 
171 
     | 
    
         
             
            class HttpCli(object):
         
     | 
| 
       166 
172 
     | 
    
         
             
                """
         
     | 
| 
         @@ -224,6 +230,7 @@ class HttpCli(object): 
     | 
|
| 
       224 
230 
     | 
    
         
             
                    self.can_delete = False
         
     | 
| 
       225 
231 
     | 
    
         
             
                    self.can_get = False
         
     | 
| 
       226 
232 
     | 
    
         
             
                    self.can_upget = False
         
     | 
| 
      
 233 
     | 
    
         
            +
                    self.can_html = False
         
     | 
| 
       227 
234 
     | 
    
         
             
                    self.can_admin = False
         
     | 
| 
       228 
235 
     | 
    
         
             
                    self.can_dot = False
         
     | 
| 
       229 
236 
     | 
    
         
             
                    self.out_headerlist   = []
         
     | 
| 
         @@ -732,18 +739,21 @@ class HttpCli(object): 
     | 
|
| 
       732 
739 
     | 
    
         
             
                    if "bcasechk" in vn.flags and not vn.casechk(rem, True):
         
     | 
| 
       733 
740 
     | 
    
         
             
                        return self.tx_404() and False
         
     | 
| 
       734 
741 
     | 
    
         | 
| 
       735 
     | 
    
         
            -
                     
     | 
| 
       736 
     | 
    
         
            -
                         
     | 
| 
       737 
     | 
    
         
            -
             
     | 
| 
       738 
     | 
    
         
            -
             
     | 
| 
       739 
     | 
    
         
            -
             
     | 
| 
       740 
     | 
    
         
            -
             
     | 
| 
       741 
     | 
    
         
            -
             
     | 
| 
       742 
     | 
    
         
            -
             
     | 
| 
       743 
     | 
    
         
            -
             
     | 
| 
       744 
     | 
    
         
            -
             
     | 
| 
       745 
     | 
    
         
            -
             
     | 
| 
       746 
     | 
    
         
            -
             
     | 
| 
      
 742 
     | 
    
         
            +
                    try:
         
     | 
| 
      
 743 
     | 
    
         
            +
                        (
         
     | 
| 
      
 744 
     | 
    
         
            +
                            self.can_read,
         
     | 
| 
      
 745 
     | 
    
         
            +
                            self.can_write,
         
     | 
| 
      
 746 
     | 
    
         
            +
                            self.can_move,
         
     | 
| 
      
 747 
     | 
    
         
            +
                            self.can_delete,
         
     | 
| 
      
 748 
     | 
    
         
            +
                            self.can_get,
         
     | 
| 
      
 749 
     | 
    
         
            +
                            self.can_upget,
         
     | 
| 
      
 750 
     | 
    
         
            +
                            self.can_html,
         
     | 
| 
      
 751 
     | 
    
         
            +
                            self.can_admin,
         
     | 
| 
      
 752 
     | 
    
         
            +
                            self.can_dot,
         
     | 
| 
      
 753 
     | 
    
         
            +
                        ) = avn.uaxs[self.uname]
         
     | 
| 
      
 754 
     | 
    
         
            +
                    except:
         
     | 
| 
      
 755 
     | 
    
         
            +
                        pass  # default is all-false
         
     | 
| 
      
 756 
     | 
    
         
            +
             
     | 
| 
       747 
757 
     | 
    
         
             
                    self.avn = avn
         
     | 
| 
       748 
758 
     | 
    
         
             
                    self.vn = vn  # note: do not dbv due to walk/zipgen
         
     | 
| 
       749 
759 
     | 
    
         
             
                    self.rem = rem
         
     | 
| 
         @@ -1270,6 +1280,20 @@ class HttpCli(object): 
     | 
|
| 
       1270 
1280 
     | 
    
         
             
                            else:
         
     | 
| 
       1271 
1281 
     | 
    
         
             
                                return self.tx_res(res_path)
         
     | 
| 
       1272 
1282 
     | 
    
         | 
| 
      
 1283 
     | 
    
         
            +
                        if res_path in RESM:
         
     | 
| 
      
 1284 
     | 
    
         
            +
                            ap = self.E.mod_ + RESM[res_path]
         
     | 
| 
      
 1285 
     | 
    
         
            +
                            if (
         
     | 
| 
      
 1286 
     | 
    
         
            +
                                "txt" not in self.uparam
         
     | 
| 
      
 1287 
     | 
    
         
            +
                                and "mime" not in self.uparam
         
     | 
| 
      
 1288 
     | 
    
         
            +
                                and not self.ouparam.get("dl")
         
     | 
| 
      
 1289 
     | 
    
         
            +
                            ):
         
     | 
| 
      
 1290 
     | 
    
         
            +
                                # return mimetype matching request extension
         
     | 
| 
      
 1291 
     | 
    
         
            +
                                self.ouparam["dl"] = res_path.split("/")[-1]
         
     | 
| 
      
 1292 
     | 
    
         
            +
                            if bos.path.exists(ap) or bos.path.exists(ap + ".gz"):
         
     | 
| 
      
 1293 
     | 
    
         
            +
                                return self.tx_file(ap)
         
     | 
| 
      
 1294 
     | 
    
         
            +
                            else:
         
     | 
| 
      
 1295 
     | 
    
         
            +
                                return self.tx_res(res_path)
         
     | 
| 
      
 1296 
     | 
    
         
            +
             
     | 
| 
       1273 
1297 
     | 
    
         
             
                        self.tx_404()
         
     | 
| 
       1274 
1298 
     | 
    
         
             
                        return False
         
     | 
| 
       1275 
1299 
     | 
    
         | 
| 
         @@ -4161,8 +4185,11 @@ class HttpCli(object): 
     | 
|
| 
       4161 
4185 
     | 
    
         
             
                    # force download
         
     | 
| 
       4162 
4186 
     | 
    
         | 
| 
       4163 
4187 
     | 
    
         
             
                    if "dl" in self.ouparam:
         
     | 
| 
       4164 
     | 
    
         
            -
                        cdis =  
     | 
| 
       4165 
     | 
    
         
            -
                         
     | 
| 
      
 4188 
     | 
    
         
            +
                        cdis = self.ouparam["dl"] or req_path
         
     | 
| 
      
 4189 
     | 
    
         
            +
                        zs = gen_content_disposition(os.path.basename(cdis))
         
     | 
| 
      
 4190 
     | 
    
         
            +
                        self.out_headers["Content-Disposition"] = zs
         
     | 
| 
      
 4191 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 4192 
     | 
    
         
            +
                        cdis = req_path
         
     | 
| 
       4166 
4193 
     | 
    
         | 
| 
       4167 
4194 
     | 
    
         
             
                    #
         
     | 
| 
       4168 
4195 
     | 
    
         
             
                    # if-modified
         
     | 
| 
         @@ -4228,7 +4255,7 @@ class HttpCli(object): 
     | 
|
| 
       4228 
4255 
     | 
    
         
             
                    elif "mime" in self.uparam:
         
     | 
| 
       4229 
4256 
     | 
    
         
             
                        mime = str(self.uparam.get("mime"))
         
     | 
| 
       4230 
4257 
     | 
    
         
             
                    else:
         
     | 
| 
       4231 
     | 
    
         
            -
                        mime = guess_mime( 
     | 
| 
      
 4258 
     | 
    
         
            +
                        mime = guess_mime(cdis)
         
     | 
| 
       4232 
4259 
     | 
    
         | 
| 
       4233 
4260 
     | 
    
         
             
                    logmsg += unicode(status) + logtail
         
     | 
| 
       4234 
4261 
     | 
    
         | 
| 
         @@ -4335,8 +4362,11 @@ class HttpCli(object): 
     | 
|
| 
       4335 
4362 
     | 
    
         
             
                    # force download
         
     | 
| 
       4336 
4363 
     | 
    
         | 
| 
       4337 
4364 
     | 
    
         
             
                    if "dl" in self.ouparam:
         
     | 
| 
       4338 
     | 
    
         
            -
                        cdis =  
     | 
| 
       4339 
     | 
    
         
            -
                         
     | 
| 
      
 4365 
     | 
    
         
            +
                        cdis = self.ouparam["dl"] or req_path
         
     | 
| 
      
 4366 
     | 
    
         
            +
                        zs = gen_content_disposition(os.path.basename(cdis))
         
     | 
| 
      
 4367 
     | 
    
         
            +
                        self.out_headers["Content-Disposition"] = zs
         
     | 
| 
      
 4368 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 4369 
     | 
    
         
            +
                        cdis = req_path
         
     | 
| 
       4340 
4370 
     | 
    
         | 
| 
       4341 
4371 
     | 
    
         
             
                    #
         
     | 
| 
       4342 
4372 
     | 
    
         
             
                    # if-modified
         
     | 
| 
         @@ -4464,7 +4494,7 @@ class HttpCli(object): 
     | 
|
| 
       4464 
4494 
     | 
    
         
             
                    elif "rmagic" in self.vn.flags:
         
     | 
| 
       4465 
4495 
     | 
    
         
             
                        mime = guess_mime(req_path, fs_path)
         
     | 
| 
       4466 
4496 
     | 
    
         
             
                    else:
         
     | 
| 
       4467 
     | 
    
         
            -
                        mime = guess_mime( 
     | 
| 
      
 4497 
     | 
    
         
            +
                        mime = guess_mime(cdis)
         
     | 
| 
       4468 
4498 
     | 
    
         | 
| 
       4469 
4499 
     | 
    
         
             
                    if "nohtml" in self.vn.flags and "html" in mime:
         
     | 
| 
       4470 
4500 
     | 
    
         
             
                        mime = "text/plain; charset=utf-8"
         
     | 
| 
         @@ -5238,7 +5268,7 @@ class HttpCli(object): 
     | 
|
| 
       5238 
5268 
     | 
    
         
             
                        dls.append((perc, hsent, spd, eta, idle, usr, erd, rds, fn))
         
     | 
| 
       5239 
5269 
     | 
    
         | 
| 
       5240 
5270 
     | 
    
         
             
                    if self.args.have_unlistc:
         
     | 
| 
       5241 
     | 
    
         
            -
                        allvols = self.asrv.vfs. 
     | 
| 
      
 5271 
     | 
    
         
            +
                        allvols = self.asrv.vfs.all_nodes
         
     | 
| 
       5242 
5272 
     | 
    
         
             
                        rvol = [x for x in rvol if "unlistcr" not in allvols[x[1:-1]].flags]
         
     | 
| 
       5243 
5273 
     | 
    
         
             
                        wvol = [x for x in wvol if "unlistcw" not in allvols[x[1:-1]].flags]
         
     | 
| 
       5244 
5274 
     | 
    
         | 
| 
         @@ -5517,7 +5547,7 @@ class HttpCli(object): 
     | 
|
| 
       5517 
5547 
     | 
    
         
             
                            rem,
         
     | 
| 
       5518 
5548 
     | 
    
         
             
                            self.uname,
         
     | 
| 
       5519 
5549 
     | 
    
         
             
                            not self.args.no_scandir,
         
     | 
| 
       5520 
     | 
    
         
            -
                             
     | 
| 
      
 5550 
     | 
    
         
            +
                            PERMS_rwh,
         
     | 
| 
       5521 
5551 
     | 
    
         
             
                        )
         
     | 
| 
       5522 
5552 
     | 
    
         
             
                        dots = self.uname in vn.axs.udot
         
     | 
| 
       5523 
5553 
     | 
    
         
             
                        dk_sz = vn.flags.get("dk")
         
     | 
| 
         @@ -5549,7 +5579,13 @@ class HttpCli(object): 
     | 
|
| 
       5549 
5579 
     | 
    
         
             
                    for x in vfs_virt:
         
     | 
| 
       5550 
5580 
     | 
    
         
             
                        if x != excl:
         
     | 
| 
       5551 
5581 
     | 
    
         
             
                            try:
         
     | 
| 
       5552 
     | 
    
         
            -
                                dvn, drem = vfs.get(vjoin(top, x), self.uname,  
     | 
| 
      
 5582 
     | 
    
         
            +
                                dvn, drem = vfs.get(vjoin(top, x), self.uname, False, False)
         
     | 
| 
      
 5583 
     | 
    
         
            +
                                if (
         
     | 
| 
      
 5584 
     | 
    
         
            +
                                    self.uname not in dvn.axs.uread
         
     | 
| 
      
 5585 
     | 
    
         
            +
                                    and self.uname not in dvn.axs.uwrite
         
     | 
| 
      
 5586 
     | 
    
         
            +
                                    and self.uname not in dvn.axs.uhtml
         
     | 
| 
      
 5587 
     | 
    
         
            +
                                ):
         
     | 
| 
      
 5588 
     | 
    
         
            +
                                    raise Exception()
         
     | 
| 
       5553 
5589 
     | 
    
         
             
                                bos.stat(dvn.canonical(drem, False))
         
     | 
| 
       5554 
5590 
     | 
    
         
             
                            except:
         
     | 
| 
       5555 
5591 
     | 
    
         
             
                                x += "\n"
         
     | 
| 
         @@ -6474,8 +6510,7 @@ class HttpCli(object): 
     | 
|
| 
       6474 
6510 
     | 
    
         
             
                        return self.tx_svg("upload\nonly")
         
     | 
| 
       6475 
6511 
     | 
    
         | 
| 
       6476 
6512 
     | 
    
         
             
                    if not self.can_read and self.can_get and self.avn:
         
     | 
| 
       6477 
     | 
    
         
            -
                         
     | 
| 
       6478 
     | 
    
         
            -
                        if self.uname not in axs.uhtml:
         
     | 
| 
      
 6513 
     | 
    
         
            +
                        if not self.can_html:
         
     | 
| 
       6479 
6514 
     | 
    
         
             
                            pass
         
     | 
| 
       6480 
6515 
     | 
    
         
             
                        elif is_dir:
         
     | 
| 
       6481 
6516 
     | 
    
         
             
                            for fn in ("index.htm", "index.html"):
         
     | 
| 
         @@ -6496,6 +6531,7 @@ class HttpCli(object): 
     | 
|
| 
       6496 
6531 
     | 
    
         | 
| 
       6497 
6532 
     | 
    
         
             
                                fk_pass = True
         
     | 
| 
       6498 
6533 
     | 
    
         
             
                                is_dir = False
         
     | 
| 
      
 6534 
     | 
    
         
            +
                                add_og = False
         
     | 
| 
       6499 
6535 
     | 
    
         
             
                                rem = vjoin(rem, fn)
         
     | 
| 
       6500 
6536 
     | 
    
         
             
                                vrem = vjoin(vrem, fn)
         
     | 
| 
       6501 
6537 
     | 
    
         
             
                                abspath = ap2
         
     | 
| 
         @@ -6689,7 +6725,7 @@ class HttpCli(object): 
     | 
|
| 
       6689 
6725 
     | 
    
         
             
                        rem,
         
     | 
| 
       6690 
6726 
     | 
    
         
             
                        self.uname,
         
     | 
| 
       6691 
6727 
     | 
    
         
             
                        not self.args.no_scandir,
         
     | 
| 
       6692 
     | 
    
         
            -
                         
     | 
| 
      
 6728 
     | 
    
         
            +
                        PERMS_rwh,
         
     | 
| 
       6693 
6729 
     | 
    
         
             
                        lstat="lt" in self.uparam,
         
     | 
| 
       6694 
6730 
     | 
    
         
             
                        throw=True,
         
     | 
| 
       6695 
6731 
     | 
    
         
             
                    )
         
     | 
| 
         @@ -378,8 +378,8 @@ class HttpSrv(object): 
     | 
|
| 
       378 
378 
     | 
    
         
             
                            if nloris < nconn / 2:
         
     | 
| 
       379 
379 
     | 
    
         
             
                                continue
         
     | 
| 
       380 
380 
     | 
    
         | 
| 
       381 
     | 
    
         
            -
                            t = " 
     | 
| 
       382 
     | 
    
         
            -
                            self.log(self.name, t 
     | 
| 
      
 381 
     | 
    
         
            +
                            t = "slow%s (idle-conn): %s banned for %d min"  # slowloris
         
     | 
| 
      
 382 
     | 
    
         
            +
                            self.log(self.name, t % ("loris", ip, self.args.loris), 1)
         
     | 
| 
       383 
383 
     | 
    
         
             
                            self.bans[ip] = int(time.time() + self.args.loris * 60)
         
     | 
| 
       384 
384 
     | 
    
         | 
| 
       385 
385 
     | 
    
         
             
                        if self.args.log_conn:
         
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         @@ -64,7 +64,7 @@ 
     | 
|
| 
       64 
64 
     | 
    
         
             
                            <li>old version of rclone? replace all <code>=</code> with <code> </code> (space)</li>
         
     | 
| 
       65 
65 
     | 
    
         
             
                        </ul>
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                        <p>if you want to use the native WebDAV client in windows instead (slow and buggy), first run <a href="{{ r }}/.cpr/a/webdav-cfg.bat">webdav-cfg.bat</a> to remove the 47 MiB filesize limit (also fixes latency and password login), then connect:</p>
         
     | 
| 
      
 67 
     | 
    
         
            +
                        <p>if you want to use the native WebDAV client in windows instead (slow and buggy), first run <a href="{{ r }}/.cpr/a/webdav-cfg.txt?dl=webdav-cfg.bat">webdav-cfg.bat</a> to remove the 47 MiB filesize limit (also fixes latency and password login), then connect:</p>
         
     | 
| 
       68 
68 
     | 
    
         
             
                        <pre>
         
     | 
| 
       69 
69 
     | 
    
         
             
                            {%- if un %}
         
     | 
| 
       70 
70 
     | 
    
         
             
                            net use <b>w:</b> http{{ s }}://{{ ep }}/{{ rvp }}{% if accs %} <b>{{ pw }}</b> /user:{{ b_un }}{% endif %}
         
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     | 
| 
         Binary file 
     |