copyparty 1.16.13__py3-none-any.whl → 1.16.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- copyparty/__main__.py +3 -1
 - copyparty/__version__.py +2 -2
 - copyparty/authsrv.py +18 -7
 - copyparty/cfg.py +8 -1
 - copyparty/httpcli.py +2 -1
 - copyparty/up2k.py +51 -3
 - copyparty/web/a/u2c.py +6 -3
 - copyparty/web/browser.css.gz +0 -0
 - copyparty/web/browser.js.gz +0 -0
 - copyparty/web/up2k.js.gz +0 -0
 - {copyparty-1.16.13.dist-info → copyparty-1.16.14.dist-info}/METADATA +57 -4
 - {copyparty-1.16.13.dist-info → copyparty-1.16.14.dist-info}/RECORD +16 -16
 - {copyparty-1.16.13.dist-info → copyparty-1.16.14.dist-info}/LICENSE +0 -0
 - {copyparty-1.16.13.dist-info → copyparty-1.16.14.dist-info}/WHEEL +0 -0
 - {copyparty-1.16.13.dist-info → copyparty-1.16.14.dist-info}/entry_points.txt +0 -0
 - {copyparty-1.16.13.dist-info → copyparty-1.16.14.dist-info}/top_level.txt +0 -0
 
    
        copyparty/__main__.py
    CHANGED
    
    | 
         @@ -1031,6 +1031,7 @@ def add_upload(ap): 
     | 
|
| 
       1031 
1031 
     | 
    
         
             
                ap2.add_argument("--turbo", metavar="LVL", type=int, default=0, help="configure turbo-mode in up2k client; [\033[32m-1\033[0m] = forbidden/always-off, [\033[32m0\033[0m] = default-off and warn if enabled, [\033[32m1\033[0m] = default-off, [\033[32m2\033[0m] = on, [\033[32m3\033[0m] = on and disable datecheck")
         
     | 
| 
       1032 
1032 
     | 
    
         
             
                ap2.add_argument("--u2j", metavar="JOBS", type=int, default=2, help="web-client: number of file chunks to upload in parallel; 1 or 2 is good for low-latency (same-country) connections, 4-8 for android clients, 16 for cross-atlantic (max=64)")
         
     | 
| 
       1033 
1033 
     | 
    
         
             
                ap2.add_argument("--u2sz", metavar="N,N,N", type=u, default="1,64,96", help="web-client: default upload chunksize (MiB); sets \033[33mmin,default,max\033[0m in the settings gui. Each HTTP POST will aim for \033[33mdefault\033[0m, and never exceed \033[33mmax\033[0m. Cloudflare max is 96. Big values are good for cross-atlantic but may increase HDD fragmentation on some FS. Disable this optimization with [\033[32m1,1,1\033[0m]")
         
     | 
| 
      
 1034 
     | 
    
         
            +
                ap2.add_argument("--u2ow", metavar="NUM", type=int, default=0, help="web-client: default setting for when to overwrite existing files; [\033[32m0\033[0m]=never, [\033[32m1\033[0m]=if-client-newer, [\033[32m2\033[0m]=always (volflag=u2ow)")
         
     | 
| 
       1034 
1035 
     | 
    
         
             
                ap2.add_argument("--u2sort", metavar="TXT", type=u, default="s", help="upload order; [\033[32ms\033[0m]=smallest-first, [\033[32mn\033[0m]=alphabetical, [\033[32mfs\033[0m]=force-s, [\033[32mfn\033[0m]=force-n -- alphabetical is a bit slower on fiber/LAN but makes it easier to eyeball if everything went fine")
         
     | 
| 
       1035 
1036 
     | 
    
         
             
                ap2.add_argument("--write-uplog", action="store_true", help="write POST reports to textfiles in working-directory")
         
     | 
| 
       1036 
1037 
     | 
    
         | 
| 
         @@ -1261,7 +1262,7 @@ def add_optouts(ap): 
     | 
|
| 
       1261 
1262 
     | 
    
         
             
                ap2.add_argument("--no-tarcmp", action="store_true", help="disable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)")
         
     | 
| 
       1262 
1263 
     | 
    
         
             
                ap2.add_argument("--no-lifetime", action="store_true", help="do not allow clients (or server config) to schedule an upload to be deleted after a given time")
         
     | 
| 
       1263 
1264 
     | 
    
         
             
                ap2.add_argument("--no-pipe", action="store_true", help="disable race-the-beam (lockstep download of files which are currently being uploaded) (volflag=nopipe)")
         
     | 
| 
       1264 
     | 
    
         
            -
                ap2.add_argument("--no-db-ip", action="store_true", help="do not write uploader  
     | 
| 
      
 1265 
     | 
    
         
            +
                ap2.add_argument("--no-db-ip", action="store_true", help="do not write uploader-IP into the database; will also disable unpost, you may want \033[32m--forget-ip\033[0m instead (volflag=no_db_ip)")
         
     | 
| 
       1265 
1266 
     | 
    
         | 
| 
       1266 
1267 
     | 
    
         | 
| 
       1267 
1268 
     | 
    
         
             
            def add_safety(ap):
         
     | 
| 
         @@ -1411,6 +1412,7 @@ def add_db_general(ap, hcores): 
     | 
|
| 
       1411 
1412 
     | 
    
         
             
                ap2.add_argument("--no-dhash", action="store_true", help="disable rescan acceleration; do full database integrity check -- makes the db ~5%% smaller and bootup/rescans 3~10x slower")
         
     | 
| 
       1412 
1413 
     | 
    
         
             
                ap2.add_argument("--re-dhash", action="store_true", help="force a cache rebuild on startup; enable this once if it gets out of sync (should never be necessary)")
         
     | 
| 
       1413 
1414 
     | 
    
         
             
                ap2.add_argument("--no-forget", action="store_true", help="never forget indexed files, even when deleted from disk -- makes it impossible to ever upload the same file twice -- only useful for offloading uploads to a cloud service or something (volflag=noforget)")
         
     | 
| 
      
 1415 
     | 
    
         
            +
                ap2.add_argument("--forget-ip", metavar="MIN", type=int, default=0, help="remove uploader-IP from database (and make unpost impossible) \033[33mMIN\033[0m minutes after upload, for GDPR reasons. Default [\033[32m0\033[0m] is never-forget. [\033[32m1440\033[0m]=day, [\033[32m10080\033[0m]=week, [\033[32m43200\033[0m]=month. (volflag=forget_ip)")
         
     | 
| 
       1414 
1416 
     | 
    
         
             
                ap2.add_argument("--dbd", metavar="PROFILE", default="wal", help="database durability profile; sets the tradeoff between robustness and speed, see \033[33m--help-dbd\033[0m (volflag=dbd)")
         
     | 
| 
       1415 
1417 
     | 
    
         
             
                ap2.add_argument("--xlink", action="store_true", help="on upload: check all volumes for dupes, not just the target volume (probably buggy, not recommended) (volflag=xlink)")
         
     | 
| 
       1416 
1418 
     | 
    
         
             
                ap2.add_argument("--hash-mt", metavar="CORES", type=int, default=hcores, help="num cpu cores to use for file hashing; set 0 or 1 for single-core hashing")
         
     | 
    
        copyparty/__version__.py
    CHANGED
    
    
    
        copyparty/authsrv.py
    CHANGED
    
    | 
         @@ -1382,8 +1382,16 @@ class AuthSrv(object): 
     | 
|
| 
       1382 
1382 
     | 
    
         
             
                        name = name.lower()
         
     | 
| 
       1383 
1383 
     | 
    
         | 
| 
       1384 
1384 
     | 
    
         
             
                        # volflags are snake_case, but a leading dash is the removal operator
         
     | 
| 
       1385 
     | 
    
         
            -
                         
     | 
| 
       1386 
     | 
    
         
            -
             
     | 
| 
      
 1385 
     | 
    
         
            +
                        stripped = name.lstrip("-")
         
     | 
| 
      
 1386 
     | 
    
         
            +
                        zi = len(name) - len(stripped)
         
     | 
| 
      
 1387 
     | 
    
         
            +
                        if zi > 1:
         
     | 
| 
      
 1388 
     | 
    
         
            +
                            t = "WARNING: the config for volume [/%s] specified a volflag with multiple leading hyphens (%s); use one hyphen to remove, or zero hyphens to add a flag. Will now enable flag [%s]"
         
     | 
| 
      
 1389 
     | 
    
         
            +
                            self.log(t % (vpath, name, stripped), 3)
         
     | 
| 
      
 1390 
     | 
    
         
            +
                            name = stripped
         
     | 
| 
      
 1391 
     | 
    
         
            +
                            zi = 0
         
     | 
| 
      
 1392 
     | 
    
         
            +
             
     | 
| 
      
 1393 
     | 
    
         
            +
                        if stripped not in flagdescs and "-" in stripped:
         
     | 
| 
      
 1394 
     | 
    
         
            +
                            name = ("-" * zi) + stripped.replace("-", "_")
         
     | 
| 
       1387 
1395 
     | 
    
         | 
| 
       1388 
1396 
     | 
    
         
             
                    desc = flagdescs.get(name.lstrip("-"), "?").replace("\n", " ")
         
     | 
| 
       1389 
1397 
     | 
    
         | 
| 
         @@ -1569,6 +1577,11 @@ class AuthSrv(object): 
     | 
|
| 
       1569 
1577 
     | 
    
         
             
                    for vol in vfs.all_vols.values():
         
     | 
| 
       1570 
1578 
     | 
    
         
             
                        unknown_flags = set()
         
     | 
| 
       1571 
1579 
     | 
    
         
             
                        for k, v in vol.flags.items():
         
     | 
| 
      
 1580 
     | 
    
         
            +
                            stripped = k.lstrip("-")
         
     | 
| 
      
 1581 
     | 
    
         
            +
                            if k != stripped and stripped not in vol.flags:
         
     | 
| 
      
 1582 
     | 
    
         
            +
                                t = "WARNING: the config for volume [/%s] tried to remove volflag [%s] by specifying [%s] but that volflag was not already set"
         
     | 
| 
      
 1583 
     | 
    
         
            +
                                self.log(t % (vol.vpath, stripped, k), 3)
         
     | 
| 
      
 1584 
     | 
    
         
            +
                            k = stripped
         
     | 
| 
       1572 
1585 
     | 
    
         
             
                            if k not in flagdescs and k not in k_ign:
         
     | 
| 
       1573 
1586 
     | 
    
         
             
                                unknown_flags.add(k)
         
     | 
| 
       1574 
1587 
     | 
    
         
             
                        if unknown_flags:
         
     | 
| 
         @@ -1936,11 +1949,8 @@ class AuthSrv(object): 
     | 
|
| 
       1936 
1949 
     | 
    
         
             
                            if vf not in vol.flags:
         
     | 
| 
       1937 
1950 
     | 
    
         
             
                                vol.flags[vf] = getattr(self.args, ga)
         
     | 
| 
       1938 
1951 
     | 
    
         | 
| 
       1939 
     | 
    
         
            -
                         
     | 
| 
       1940 
     | 
    
         
            -
             
     | 
| 
       1941 
     | 
    
         
            -
                                vol.flags[k] = getattr(self.args, k)
         
     | 
| 
       1942 
     | 
    
         
            -
             
     | 
| 
       1943 
     | 
    
         
            -
                        for k in ("nrand", "u2abort", "ups_who", "zip_who"):
         
     | 
| 
      
 1952 
     | 
    
         
            +
                        zs = "forget_ip nrand u2abort u2ow ups_who zip_who"
         
     | 
| 
      
 1953 
     | 
    
         
            +
                        for k in zs.split():
         
     | 
| 
       1944 
1954 
     | 
    
         
             
                            if k in vol.flags:
         
     | 
| 
       1945 
1955 
     | 
    
         
             
                                vol.flags[k] = int(vol.flags[k])
         
     | 
| 
       1946 
1956 
     | 
    
         | 
| 
         @@ -2415,6 +2425,7 @@ class AuthSrv(object): 
     | 
|
| 
       2415 
2425 
     | 
    
         
             
                            "u2j": self.args.u2j,
         
     | 
| 
       2416 
2426 
     | 
    
         
             
                            "u2sz": self.args.u2sz,
         
     | 
| 
       2417 
2427 
     | 
    
         
             
                            "u2ts": vf["u2ts"],
         
     | 
| 
      
 2428 
     | 
    
         
            +
                            "u2ow": vf["u2ow"],
         
     | 
| 
       2418 
2429 
     | 
    
         
             
                            "frand": bool(vf.get("rand")),
         
     | 
| 
       2419 
2430 
     | 
    
         
             
                            "lifetime": vn.js_ls["lifetime"],
         
     | 
| 
       2420 
2431 
     | 
    
         
             
                            "u2sort": self.args.u2sort,
         
     | 
    
        copyparty/cfg.py
    CHANGED
    
    | 
         @@ -43,6 +43,7 @@ def vf_bmap()   : 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    "gsel",
         
     | 
| 
       44 
44 
     | 
    
         
             
                    "hardlink",
         
     | 
| 
       45 
45 
     | 
    
         
             
                    "magic",
         
     | 
| 
      
 46 
     | 
    
         
            +
                    "no_db_ip",
         
     | 
| 
       46 
47 
     | 
    
         
             
                    "no_sb_md",
         
     | 
| 
       47 
48 
     | 
    
         
             
                    "no_sb_lg",
         
     | 
| 
       48 
49 
     | 
    
         
             
                    "nsort",
         
     | 
| 
         @@ -73,6 +74,7 @@ def vf_vmap()   : 
     | 
|
| 
       73 
74 
     | 
    
         
             
                }
         
     | 
| 
       74 
75 
     | 
    
         
             
                for k in (
         
     | 
| 
       75 
76 
     | 
    
         
             
                    "dbd",
         
     | 
| 
      
 77 
     | 
    
         
            +
                    "forget_ip",
         
     | 
| 
       76 
78 
     | 
    
         
             
                    "hsortn",
         
     | 
| 
       77 
79 
     | 
    
         
             
                    "html_head",
         
     | 
| 
       78 
80 
     | 
    
         
             
                    "lg_sbf",
         
     | 
| 
         @@ -80,6 +82,7 @@ def vf_vmap()   : 
     | 
|
| 
       80 
82 
     | 
    
         
             
                    "lg_sba",
         
     | 
| 
       81 
83 
     | 
    
         
             
                    "md_sba",
         
     | 
| 
       82 
84 
     | 
    
         
             
                    "nrand",
         
     | 
| 
      
 85 
     | 
    
         
            +
                    "u2ow",
         
     | 
| 
       83 
86 
     | 
    
         
             
                    "og_desc",
         
     | 
| 
       84 
87 
     | 
    
         
             
                    "og_site",
         
     | 
| 
       85 
88 
     | 
    
         
             
                    "og_th",
         
     | 
| 
         @@ -156,7 +159,8 @@ flagcats = { 
     | 
|
| 
       156 
159 
     | 
    
         
             
                    "daw": "enable full WebDAV write support (dangerous);\nPUT-operations will now \033[1;31mOVERWRITE\033[0;35m existing files",
         
     | 
| 
       157 
160 
     | 
    
         
             
                    "nosub": "forces all uploads into the top folder of the vfs",
         
     | 
| 
       158 
161 
     | 
    
         
             
                    "magic": "enables filetype detection for nameless uploads",
         
     | 
| 
       159 
     | 
    
         
            -
                    "gz": "allows server-side gzip of uploads with ?gz 
     | 
| 
      
 162 
     | 
    
         
            +
                    "gz": "allows server-side gzip compression of uploads with ?gz",
         
     | 
| 
      
 163 
     | 
    
         
            +
                    "xz": "allows server-side lzma compression of uploads with ?xz",
         
     | 
| 
       160 
164 
     | 
    
         
             
                    "pk": "forces server-side compression, optional arg: xz,9",
         
     | 
| 
       161 
165 
     | 
    
         
             
                },
         
     | 
| 
       162 
166 
     | 
    
         
             
                "upload rules": {
         
     | 
| 
         @@ -167,6 +171,7 @@ flagcats = { 
     | 
|
| 
       167 
171 
     | 
    
         
             
                    "medialinks": "return medialinks for non-up2k uploads (not hotlinks)",
         
     | 
| 
       168 
172 
     | 
    
         
             
                    "rand": "force randomized filenames, 9 chars long by default",
         
     | 
| 
       169 
173 
     | 
    
         
             
                    "nrand=N": "randomized filenames are N chars long",
         
     | 
| 
      
 174 
     | 
    
         
            +
                    "u2ow=N": "overwrite existing files? 0=no 1=if-older 2=always",
         
     | 
| 
       170 
175 
     | 
    
         
             
                    "u2ts=fc": "[f]orce [c]lient-last-modified or [u]pload-time",
         
     | 
| 
       171 
176 
     | 
    
         
             
                    "u2abort=1": "allow aborting unfinished uploads? 0=no 1=strict 2=ip-chk 3=acct-chk",
         
     | 
| 
       172 
177 
     | 
    
         
             
                    "sz=1k-3m": "allow filesizes between 1 KiB and 3MiB",
         
     | 
| 
         @@ -197,6 +202,8 @@ flagcats = { 
     | 
|
| 
       197 
202 
     | 
    
         
             
                    "nohash=\\.iso$": "skips hashing file contents if path matches *.iso",
         
     | 
| 
       198 
203 
     | 
    
         
             
                    "noidx=\\.iso$": "fully ignores the contents at paths matching *.iso",
         
     | 
| 
       199 
204 
     | 
    
         
             
                    "noforget": "don't forget files when deleted from disk",
         
     | 
| 
      
 205 
     | 
    
         
            +
                    "forget_ip=43200": "forget uploader-IP after 30 days (GDPR)",
         
     | 
| 
      
 206 
     | 
    
         
            +
                    "no_db_ip": "never store uploader-IP in the db; disables unpost",
         
     | 
| 
       200 
207 
     | 
    
         
             
                    "fat32": "avoid excessive reindexing on android sdcardfs",
         
     | 
| 
       201 
208 
     | 
    
         
             
                    "dbd=[acid|swal|wal|yolo]": "database speed-durability tradeoff",
         
     | 
| 
       202 
209 
     | 
    
         
             
                    "xlink": "cross-volume dupe detection / linking (dangerous)",
         
     | 
    
        copyparty/httpcli.py
    CHANGED
    
    | 
         @@ -1803,7 +1803,8 @@ class HttpCli(object): 
     | 
|
| 
       1803 
1803 
     | 
    
         
             
                    dst = unquotep(dst)
         
     | 
| 
       1804 
1804 
     | 
    
         | 
| 
       1805 
1805 
     | 
    
         
             
                    # overwrite=True is default; rfc4918 9.8.4
         
     | 
| 
       1806 
     | 
    
         
            -
                     
     | 
| 
      
 1806 
     | 
    
         
            +
                    zs = self.headers.get("overwrite", "").lower()
         
     | 
| 
      
 1807 
     | 
    
         
            +
                    overwrite = zs not in ["f", "false"]
         
     | 
| 
       1807 
1808 
     | 
    
         | 
| 
       1808 
1809 
     | 
    
         
             
                    try:
         
     | 
| 
       1809 
1810 
     | 
    
         
             
                        fun = self._cp if self.mode == "COPY" else self._mv
         
     | 
    
        copyparty/up2k.py
    CHANGED
    
    | 
         @@ -553,6 +553,7 @@ class Up2k(object): 
     | 
|
| 
       553 
553 
     | 
    
         
             
                        else:
         
     | 
| 
       554 
554 
     | 
    
         
             
                            # important; not deferred by db_act
         
     | 
| 
       555 
555 
     | 
    
         
             
                            timeout = self._check_lifetimes()
         
     | 
| 
      
 556 
     | 
    
         
            +
                            timeout = min(self._check_forget_ip(), timeout)
         
     | 
| 
       556 
557 
     | 
    
         
             
                            try:
         
     | 
| 
       557 
558 
     | 
    
         
             
                                if self.args.shr:
         
     | 
| 
       558 
559 
     | 
    
         
             
                                    timeout = min(self._check_shares(), timeout)
         
     | 
| 
         @@ -613,6 +614,43 @@ class Up2k(object): 
     | 
|
| 
       613 
614 
     | 
    
         
             
                            for v in vols:
         
     | 
| 
       614 
615 
     | 
    
         
             
                                volage[v] = now
         
     | 
| 
       615 
616 
     | 
    
         | 
| 
      
 617 
     | 
    
         
            +
                def _check_forget_ip(self)  :
         
     | 
| 
      
 618 
     | 
    
         
            +
                    now = time.time()
         
     | 
| 
      
 619 
     | 
    
         
            +
                    timeout = now + 9001
         
     | 
| 
      
 620 
     | 
    
         
            +
                    for vp, vol in sorted(self.vfs.all_vols.items()):
         
     | 
| 
      
 621 
     | 
    
         
            +
                        maxage = vol.flags["forget_ip"]
         
     | 
| 
      
 622 
     | 
    
         
            +
                        if not maxage:
         
     | 
| 
      
 623 
     | 
    
         
            +
                            continue
         
     | 
| 
      
 624 
     | 
    
         
            +
             
     | 
| 
      
 625 
     | 
    
         
            +
                        cur = self.cur.get(vol.realpath)
         
     | 
| 
      
 626 
     | 
    
         
            +
                        if not cur:
         
     | 
| 
      
 627 
     | 
    
         
            +
                            continue
         
     | 
| 
      
 628 
     | 
    
         
            +
             
     | 
| 
      
 629 
     | 
    
         
            +
                        cutoff = now - maxage * 60
         
     | 
| 
      
 630 
     | 
    
         
            +
             
     | 
| 
      
 631 
     | 
    
         
            +
                        for _ in range(2):
         
     | 
| 
      
 632 
     | 
    
         
            +
                            q = "select ip, at from up where ip > '' order by +at limit 1"
         
     | 
| 
      
 633 
     | 
    
         
            +
                            hits = cur.execute(q).fetchall()
         
     | 
| 
      
 634 
     | 
    
         
            +
                            if not hits:
         
     | 
| 
      
 635 
     | 
    
         
            +
                                break
         
     | 
| 
      
 636 
     | 
    
         
            +
             
     | 
| 
      
 637 
     | 
    
         
            +
                            remains = hits[0][1] - cutoff
         
     | 
| 
      
 638 
     | 
    
         
            +
                            if remains > 0:
         
     | 
| 
      
 639 
     | 
    
         
            +
                                timeout = min(timeout, now + remains)
         
     | 
| 
      
 640 
     | 
    
         
            +
                                break
         
     | 
| 
      
 641 
     | 
    
         
            +
             
     | 
| 
      
 642 
     | 
    
         
            +
                            q = "update up set ip = '' where ip > '' and at <= %d"
         
     | 
| 
      
 643 
     | 
    
         
            +
                            cur.execute(q % (cutoff,))
         
     | 
| 
      
 644 
     | 
    
         
            +
                            zi = cur.rowcount
         
     | 
| 
      
 645 
     | 
    
         
            +
                            cur.connection.commit()
         
     | 
| 
      
 646 
     | 
    
         
            +
             
     | 
| 
      
 647 
     | 
    
         
            +
                            t = "forget-ip(%d) removed %d IPs from db [/%s]"
         
     | 
| 
      
 648 
     | 
    
         
            +
                            self.log(t % (maxage, zi, vol.vpath))
         
     | 
| 
      
 649 
     | 
    
         
            +
             
     | 
| 
      
 650 
     | 
    
         
            +
                        timeout = min(timeout, now + 900)
         
     | 
| 
      
 651 
     | 
    
         
            +
             
     | 
| 
      
 652 
     | 
    
         
            +
                    return timeout
         
     | 
| 
      
 653 
     | 
    
         
            +
             
     | 
| 
       616 
654 
     | 
    
         
             
                def _check_lifetimes(self)  :
         
     | 
| 
       617 
655 
     | 
    
         
             
                    now = time.time()
         
     | 
| 
       618 
656 
     | 
    
         
             
                    timeout = now + 9001
         
     | 
| 
         @@ -1074,7 +1112,7 @@ class Up2k(object): 
     | 
|
| 
       1074 
1112 
     | 
    
         
             
                    ft = "\033[0;32m{}{:.0}"
         
     | 
| 
       1075 
1113 
     | 
    
         
             
                    ff = "\033[0;35m{}{:.0}"
         
     | 
| 
       1076 
1114 
     | 
    
         
             
                    fv = "\033[0;36m{}:\033[90m{}"
         
     | 
| 
       1077 
     | 
    
         
            -
                    zs = "html_head mv_re_r mv_re_t rm_re_r rm_re_t srch_re_dots srch_re_nodot"
         
     | 
| 
      
 1115 
     | 
    
         
            +
                    zs = "ext_th_d html_head mv_re_r mv_re_t rm_re_r rm_re_t srch_re_dots srch_re_nodot"
         
     | 
| 
       1078 
1116 
     | 
    
         
             
                    fx = set(zs.split())
         
     | 
| 
       1079 
1117 
     | 
    
         
             
                    fd = vf_bmap()
         
     | 
| 
       1080 
1118 
     | 
    
         
             
                    fd.update(vf_cmap())
         
     | 
| 
         @@ -3319,7 +3357,17 @@ class Up2k(object): 
     | 
|
| 
       3319 
3357 
     | 
    
         
             
                        return fname
         
     | 
| 
       3320 
3358 
     | 
    
         | 
| 
       3321 
3359 
     | 
    
         
             
                    fp = djoin(fdir, fname)
         
     | 
| 
       3322 
     | 
    
         
            -
             
     | 
| 
      
 3360 
     | 
    
         
            +
             
     | 
| 
      
 3361 
     | 
    
         
            +
                    ow = job.get("replace") and bos.path.exists(fp)
         
     | 
| 
      
 3362 
     | 
    
         
            +
                    if ow and "mt" in str(job["replace"]).lower():
         
     | 
| 
      
 3363 
     | 
    
         
            +
                        mts = bos.stat(fp).st_mtime
         
     | 
| 
      
 3364 
     | 
    
         
            +
                        mtc = job["lmod"]
         
     | 
| 
      
 3365 
     | 
    
         
            +
                        if mtc < mts:
         
     | 
| 
      
 3366 
     | 
    
         
            +
                            t = "will not overwrite; server %d sec newer than client; %d > %d %r"
         
     | 
| 
      
 3367 
     | 
    
         
            +
                            self.log(t % (mts - mtc, mts, mtc, fp))
         
     | 
| 
      
 3368 
     | 
    
         
            +
                            ow = False
         
     | 
| 
      
 3369 
     | 
    
         
            +
             
     | 
| 
      
 3370 
     | 
    
         
            +
                    if ow:
         
     | 
| 
       3323 
3371 
     | 
    
         
             
                        self.log("replacing existing file at %r" % (fp,))
         
     | 
| 
       3324 
3372 
     | 
    
         
             
                        cur = None
         
     | 
| 
       3325 
3373 
     | 
    
         
             
                        ptop = job["ptop"]
         
     | 
| 
         @@ -3770,7 +3818,7 @@ class Up2k(object): 
     | 
|
| 
       3770 
3818 
     | 
    
         
             
                        db_ip = ""
         
     | 
| 
       3771 
3819 
     | 
    
         
             
                    else:
         
     | 
| 
       3772 
3820 
     | 
    
         
             
                        # plugins may expect this to look like an actual IP
         
     | 
| 
       3773 
     | 
    
         
            -
                        db_ip = "1.1.1.1" if  
     | 
| 
      
 3821 
     | 
    
         
            +
                        db_ip = "1.1.1.1" if "no_db_ip" in vflags else ip
         
     | 
| 
       3774 
3822 
     | 
    
         | 
| 
       3775 
3823 
     | 
    
         
             
                    sql = "insert into up values (?,?,?,?,?,?,?)"
         
     | 
| 
       3776 
3824 
     | 
    
         
             
                    v = (dwark, int(ts), sz, rd, fn, db_ip, int(at or 0))
         
     | 
    
        copyparty/web/a/u2c.py
    CHANGED
    
    | 
         @@ -1,8 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env python3
         
     | 
| 
       2 
2 
     | 
    
         
             
            from __future__ import print_function, unicode_literals
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            S_VERSION = "2. 
     | 
| 
       5 
     | 
    
         
            -
            S_BUILD_DT = "2025- 
     | 
| 
      
 4 
     | 
    
         
            +
            S_VERSION = "2.10"
         
     | 
| 
      
 5 
     | 
    
         
            +
            S_BUILD_DT = "2025-02-19"
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            """
         
     | 
| 
       8 
8 
     | 
    
         
             
            u2c.py: upload to copyparty
         
     | 
| 
         @@ -805,7 +805,9 @@ def handshake(ar, file, search): 
     | 
|
| 
       805 
805 
     | 
    
         
             
                else:
         
     | 
| 
       806 
806 
     | 
    
         
             
                    if ar.touch:
         
     | 
| 
       807 
807 
     | 
    
         
             
                        req["umod"] = True
         
     | 
| 
       808 
     | 
    
         
            -
                    if ar. 
     | 
| 
      
 808 
     | 
    
         
            +
                    if ar.owo:
         
     | 
| 
      
 809 
     | 
    
         
            +
                        req["replace"] = "mt"
         
     | 
| 
      
 810 
     | 
    
         
            +
                    elif ar.ow:
         
     | 
| 
       809 
811 
     | 
    
         
             
                        req["replace"] = True
         
     | 
| 
       810 
812 
     | 
    
         | 
| 
       811 
813 
     | 
    
         
             
                file.recheck = False
         
     | 
| 
         @@ -1536,6 +1538,7 @@ source file/folder selection uses rsync syntax, meaning that: 
     | 
|
| 
       1536 
1538 
     | 
    
         
             
                ap.add_argument("--ok", action="store_true", help="continue even if some local files are inaccessible")
         
     | 
| 
       1537 
1539 
     | 
    
         
             
                ap.add_argument("--touch", action="store_true", help="if last-modified timestamps differ, push local to server (need write+delete perms)")
         
     | 
| 
       1538 
1540 
     | 
    
         
             
                ap.add_argument("--ow", action="store_true", help="overwrite existing files instead of autorenaming")
         
     | 
| 
      
 1541 
     | 
    
         
            +
                ap.add_argument("--owo", action="store_true", help="overwrite existing files if server-file is older")
         
     | 
| 
       1539 
1542 
     | 
    
         
             
                ap.add_argument("--spd", action="store_true", help="print speeds for each file")
         
     | 
| 
       1540 
1543 
     | 
    
         
             
                ap.add_argument("--version", action="store_true", help="show version and exit")
         
     | 
| 
       1541 
1544 
     | 
    
         | 
    
        copyparty/web/browser.css.gz
    CHANGED
    
    | 
         Binary file 
     | 
    
        copyparty/web/browser.js.gz
    CHANGED
    
    | 
         Binary file 
     | 
    
        copyparty/web/up2k.js.gz
    CHANGED
    
    | 
         Binary file 
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Metadata-Version: 2.2
         
     | 
| 
       2 
2 
     | 
    
         
             
            Name: copyparty
         
     | 
| 
       3 
     | 
    
         
            -
            Version: 1.16. 
     | 
| 
      
 3 
     | 
    
         
            +
            Version: 1.16.14
         
     | 
| 
       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
         
     | 
| 
         @@ -151,9 +151,11 @@ turn almost any device into a file server with resumable uploads/downloads using 
     | 
|
| 
       151 
151 
     | 
    
         
             
                * [reverse-proxy](#reverse-proxy) - running copyparty next to other websites
         
     | 
| 
       152 
152 
     | 
    
         
             
                    * [real-ip](#real-ip) - teaching copyparty how to see client IPs
         
     | 
| 
       153 
153 
     | 
    
         
             
                    * [reverse-proxy performance](#reverse-proxy-performance)
         
     | 
| 
      
 154 
     | 
    
         
            +
                * [permanent cloudflare tunnel](#permanent-cloudflare-tunnel) - if you have a domain and want to get your copyparty online real quick
         
     | 
| 
       154 
155 
     | 
    
         
             
                * [prometheus](#prometheus) - metrics/stats can be enabled
         
     | 
| 
       155 
156 
     | 
    
         
             
                * [other extremely specific features](#other-extremely-specific-features) - you'll never find a use for these
         
     | 
| 
       156 
157 
     | 
    
         
             
                    * [custom mimetypes](#custom-mimetypes) - change the association of a file extension
         
     | 
| 
      
 158 
     | 
    
         
            +
                    * [GDPR compliance](#GDPR-compliance) - imagine using copyparty professionally...
         
     | 
| 
       157 
159 
     | 
    
         
             
                    * [feature chickenbits](#feature-chickenbits) - buggy feature? rip it out
         
     | 
| 
       158 
160 
     | 
    
         
             
            * [packages](#packages) - the party might be closer than you think
         
     | 
| 
       159 
161 
     | 
    
         
             
                * [arch package](#arch-package) - now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
         
     | 
| 
         @@ -216,8 +218,8 @@ enable thumbnails (images/audio/video), media indexing, and audio transcoding by 
     | 
|
| 
       216 
218 
     | 
    
         
             
            * **MacOS:** `port install py-Pillow ffmpeg`
         
     | 
| 
       217 
219 
     | 
    
         
             
            * **MacOS** (alternative): `brew install pillow ffmpeg`
         
     | 
| 
       218 
220 
     | 
    
         
             
            * **Windows:** `python -m pip install --user -U Pillow`
         
     | 
| 
       219 
     | 
    
         
            -
              * install python and ffmpeg manually; do not use `winget` or `Microsoft Store` (it breaks $PATH)
         
     | 
| 
       220 
     | 
    
         
            -
              * copyparty.exe comes with `Pillow` and only needs  
     | 
| 
      
 221 
     | 
    
         
            +
              * install [python](https://www.python.org/downloads/windows/) and [ffmpeg](#optional-dependencies) manually; do not use `winget` or `Microsoft Store` (it breaks $PATH)
         
     | 
| 
      
 222 
     | 
    
         
            +
              * copyparty.exe comes with `Pillow` and only needs [ffmpeg](#optional-dependencies) for mediatags/videothumbs
         
     | 
| 
       221 
223 
     | 
    
         
             
            * see [optional dependencies](#optional-dependencies) to enable even more features
         
     | 
| 
       222 
224 
     | 
    
         | 
| 
       223 
225 
     | 
    
         
             
            running copyparty without arguments (for example doubleclicking it on Windows) will give everyone read/write access to the current folder; you may want [accounts and volumes](#accounts-and-volumes)
         
     | 
| 
         @@ -240,6 +242,8 @@ first download [cloudflared](https://developers.cloudflare.com/cloudflare-one/co 
     | 
|
| 
       240 
242 
     | 
    
         | 
| 
       241 
243 
     | 
    
         
             
            as the tunnel starts, it will show a URL which you can share to let anyone browse your stash or upload files to you
         
     | 
| 
       242 
244 
     | 
    
         | 
| 
      
 245 
     | 
    
         
            +
            but if you have a domain, then you probably want to skip the random autogenerated URL and instead make a [permanent cloudflare tunnel](#permanent-cloudflare-tunnel)
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
       243 
247 
     | 
    
         
             
            since people will be connecting through cloudflare, run copyparty with `--xff-hdr cf-connecting-ip` to detect client IPs correctly
         
     | 
| 
       244 
248 
     | 
    
         | 
| 
       245 
249 
     | 
    
         | 
| 
         @@ -458,6 +462,9 @@ upgrade notes 
     | 
|
| 
       458 
462 
     | 
    
         | 
| 
       459 
463 
     | 
    
         
             
            "frequently" asked questions
         
     | 
| 
       460 
464 
     | 
    
         | 
| 
      
 465 
     | 
    
         
            +
            * can I change the 🌲 spinning pine-tree loading animation?
         
     | 
| 
      
 466 
     | 
    
         
            +
              * [yeah...](https://github.com/9001/copyparty/tree/hovudstraum/docs/rice#boring-loader-spinner) :-(
         
     | 
| 
      
 467 
     | 
    
         
            +
             
     | 
| 
       461 
468 
     | 
    
         
             
            * is it possible to block read-access to folders unless you know the exact URL for a particular file inside?
         
     | 
| 
       462 
469 
     | 
    
         
             
              * yes, using the [`g` permission](#accounts-and-volumes), see the examples there
         
     | 
| 
       463 
470 
     | 
    
         
             
              * you can also do this with linux filesystem permissions; `chmod 111 music` will make it possible to access files and folders inside the `music` folder but not list the immediate contents -- also works with other software, not just copyparty
         
     | 
| 
         @@ -480,6 +487,14 @@ upgrade notes 
     | 
|
| 
       480 
487 
     | 
    
         
             
            * copyparty seems to think I am using http, even though the URL is https
         
     | 
| 
       481 
488 
     | 
    
         
             
              * your reverse-proxy is not sending the `X-Forwarded-Proto: https` header; this could be because your reverse-proxy itself is confused. Ensure that none of the intermediates (such as cloudflare) are terminating https before the traffic hits your entrypoint
         
     | 
| 
       482 
489 
     | 
    
         | 
| 
      
 490 
     | 
    
         
            +
            * thumbnails are broken (you get a colorful square which says the filetype instead)
         
     | 
| 
      
 491 
     | 
    
         
            +
              * you need to install `FFmpeg` or `Pillow`; see [thumbnails](#thumbnails)
         
     | 
| 
      
 492 
     | 
    
         
            +
             
     | 
| 
      
 493 
     | 
    
         
            +
            * thumbnails are broken (some images appear, but other files just get a blank box, and/or the broken-image placeholder)
         
     | 
| 
      
 494 
     | 
    
         
            +
              * probably due to a reverse-proxy messing with the request URLs and stripping the query parameters (`?th=w`), so check your URL rewrite rules
         
     | 
| 
      
 495 
     | 
    
         
            +
              * could also be due to incorrect caching settings in reverse-proxies and/or CDNs, so make sure that nothing is set to ignore the query string
         
     | 
| 
      
 496 
     | 
    
         
            +
              * could also be due to misbehaving privacy-related browser extensions, so try to disable those
         
     | 
| 
      
 497 
     | 
    
         
            +
             
     | 
| 
       483 
498 
     | 
    
         
             
            * i want to learn python and/or programming and am considering looking at the copyparty source code in that occasion
         
     | 
| 
       484 
499 
     | 
    
         
             
              * ```bash
         
     | 
| 
       485 
500 
     | 
    
         
             
                 _|  _      __   _  _|_
         
     | 
| 
         @@ -710,6 +725,7 @@ press `g` or `田` to toggle grid-view instead of the file listing  and `t` togg 
     | 
|
| 
       710 
725 
     | 
    
         
             
            it does static images with Pillow / pyvips / FFmpeg, and uses FFmpeg for video files, so you may want to `--no-thumb` or maybe just `--no-vthumb` depending on how dangerous your users are
         
     | 
| 
       711 
726 
     | 
    
         
             
            * pyvips is 3x faster than Pillow, Pillow is 3x faster than FFmpeg
         
     | 
| 
       712 
727 
     | 
    
         
             
            * disable thumbnails for specific volumes with volflag `dthumb` for all, or `dvthumb` / `dathumb` / `dithumb` for video/audio/images only
         
     | 
| 
      
 728 
     | 
    
         
            +
            * for installing FFmpeg on windows, see [optional dependencies](#optional-dependencies)
         
     | 
| 
       713 
729 
     | 
    
         | 
| 
       714 
730 
     | 
    
         
             
            audio files are converted into spectrograms using FFmpeg unless you `--no-athumb` (and some FFmpeg builds may need `--th-ff-swr`)
         
     | 
| 
       715 
731 
     | 
    
         | 
| 
         @@ -821,8 +837,11 @@ the up2k UI is the epitome of polished intuitive experiences: 
     | 
|
| 
       821 
837 
     | 
    
         
             
            * "parallel uploads" specifies how many chunks to upload at the same time
         
     | 
| 
       822 
838 
     | 
    
         
             
            * `[🏃]` analysis of other files should continue while one is uploading
         
     | 
| 
       823 
839 
     | 
    
         
             
            * `[🥔]` shows a simpler UI for faster uploads from slow devices
         
     | 
| 
      
 840 
     | 
    
         
            +
            * `[🛡️]` decides when to overwrite existing files on the server
         
     | 
| 
      
 841 
     | 
    
         
            +
              * `🛡️` = never (generate a new filename instead)
         
     | 
| 
      
 842 
     | 
    
         
            +
              * `🕒` = overwrite if the server-file is older
         
     | 
| 
      
 843 
     | 
    
         
            +
              * `♻️` = always overwrite if the files are different
         
     | 
| 
       824 
844 
     | 
    
         
             
            * `[🎲]` generate random filenames during upload
         
     | 
| 
       825 
     | 
    
         
            -
            * `[📅]` preserve last-modified timestamps; server times will match yours
         
     | 
| 
       826 
845 
     | 
    
         
             
            * `[🔎]` switch between upload and [file-search](#file-search) mode
         
     | 
| 
       827 
846 
     | 
    
         
             
              * ignore `[🔎]` if you add files by dragging them into the browser
         
     | 
| 
       828 
847 
     | 
    
         | 
| 
         @@ -2039,6 +2058,26 @@ in summary, `haproxy > caddy > traefik > nginx > apache > lighttpd`, and use uds 
     | 
|
| 
       2039 
2058 
     | 
    
         
             
            * if these results are bullshit because my config exampels are bad, please submit corrections!
         
     | 
| 
       2040 
2059 
     | 
    
         | 
| 
       2041 
2060 
     | 
    
         | 
| 
      
 2061 
     | 
    
         
            +
            ## permanent cloudflare tunnel
         
     | 
| 
      
 2062 
     | 
    
         
            +
             
     | 
| 
      
 2063 
     | 
    
         
            +
            if you have a domain and want to get your copyparty online real quick,  either from your home-PC behind a CGNAT or from a server without an existing [reverse-proxy](#reverse-proxy) setup, one approach is to create a [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/) (formerly "Argo Tunnel")
         
     | 
| 
      
 2064 
     | 
    
         
            +
             
     | 
| 
      
 2065 
     | 
    
         
            +
            I'd recommend making a `Locally-managed tunnel` for more control, but if you prefer to make a `Remotely-managed tunnel` then this is currently how:
         
     | 
| 
      
 2066 
     | 
    
         
            +
             
     | 
| 
      
 2067 
     | 
    
         
            +
            * `cloudflare dashboard` » `zero trust` » `networks` » `tunnels` » `create a tunnel` » `cloudflared` » choose a cool `subdomain` and leave the `path` blank, and use `service type` = `http` and `URL` = `127.0.0.1:3923`
         
     | 
| 
      
 2068 
     | 
    
         
            +
             
     | 
| 
      
 2069 
     | 
    
         
            +
            * and if you want to just run the tunnel without installing it, skip the `cloudflared service install BASE64` step and instead do `cloudflared --no-autoupdate tunnel run --token BASE64`
         
     | 
| 
      
 2070 
     | 
    
         
            +
             
     | 
| 
      
 2071 
     | 
    
         
            +
            NOTE: since people will be connecting through cloudflare, as mentioned in [real-ip](#real-ip) you should run copyparty with `--xff-hdr cf-connecting-ip` to detect client IPs correctly
         
     | 
| 
      
 2072 
     | 
    
         
            +
             
     | 
| 
      
 2073 
     | 
    
         
            +
            config file example:
         
     | 
| 
      
 2074 
     | 
    
         
            +
             
     | 
| 
      
 2075 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 2076 
     | 
    
         
            +
            [global]
         
     | 
| 
      
 2077 
     | 
    
         
            +
              xff-hdr: cf-connecting-ip
         
     | 
| 
      
 2078 
     | 
    
         
            +
            ```
         
     | 
| 
      
 2079 
     | 
    
         
            +
             
     | 
| 
      
 2080 
     | 
    
         
            +
             
     | 
| 
       2042 
2081 
     | 
    
         
             
            ## prometheus
         
     | 
| 
       2043 
2082 
     | 
    
         | 
| 
       2044 
2083 
     | 
    
         
             
            metrics/stats can be enabled  at URL `/.cpr/metrics` for grafana / prometheus / etc (openmetrics 1.0.0)
         
     | 
| 
         @@ -2125,6 +2164,18 @@ in a config file, this is the same as: 
     | 
|
| 
       2125 
2164 
     | 
    
         
             
            run copyparty with `--mimes` to list all the default mappings
         
     | 
| 
       2126 
2165 
     | 
    
         | 
| 
       2127 
2166 
     | 
    
         | 
| 
      
 2167 
     | 
    
         
            +
            ### GDPR compliance
         
     | 
| 
      
 2168 
     | 
    
         
            +
             
     | 
| 
      
 2169 
     | 
    
         
            +
            imagine using copyparty professionally...  **TINLA/IANAL; EU laws are hella confusing**
         
     | 
| 
      
 2170 
     | 
    
         
            +
             
     | 
| 
      
 2171 
     | 
    
         
            +
            * remember to disable logging, or configure logrotation to an acceptable timeframe with `-lo cpp-%Y-%m%d.txt.xz` or similar
         
     | 
| 
      
 2172 
     | 
    
         
            +
             
     | 
| 
      
 2173 
     | 
    
         
            +
            * if running with the database enabled (recommended), then have it forget uploader-IPs after some time using `--forget-ip 43200`
         
     | 
| 
      
 2174 
     | 
    
         
            +
              * don't set it too low; [unposting](#unpost) a file is no longer possible after this takes effect
         
     | 
| 
      
 2175 
     | 
    
         
            +
             
     | 
| 
      
 2176 
     | 
    
         
            +
            * if you actually *are* a lawyer then I'm open for feedback, would be fun
         
     | 
| 
      
 2177 
     | 
    
         
            +
             
     | 
| 
      
 2178 
     | 
    
         
            +
             
     | 
| 
       2128 
2179 
     | 
    
         
             
            ### feature chickenbits
         
     | 
| 
       2129 
2180 
     | 
    
         | 
| 
       2130 
2181 
     | 
    
         
             
            buggy feature? rip it out  by setting any of the following environment variables to disable its associated bell or whistle,
         
     | 
| 
         @@ -2642,6 +2693,8 @@ enable [smb](#smb-server) support (**not** recommended): `impacket==0.12.0` 
     | 
|
| 
       2642 
2693 
     | 
    
         | 
| 
       2643 
2694 
     | 
    
         
             
            `pyvips` gives higher quality thumbnails than `Pillow` and is 320% faster, using 270% more ram: `sudo apt install libvips42 && python3 -m pip install --user -U pyvips`
         
     | 
| 
       2644 
2695 
     | 
    
         | 
| 
      
 2696 
     | 
    
         
            +
            to install FFmpeg on Windows, grab [a recent build](https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-full.7z) -- you need `ffmpeg.exe` and `ffprobe.exe` from inside the `bin` folder; copy them into `C:\Windows\System32` or any other folder that's in your `%PATH%`
         
     | 
| 
      
 2697 
     | 
    
         
            +
             
     | 
| 
       2645 
2698 
     | 
    
         | 
| 
       2646 
2699 
     | 
    
         
             
            ### dependency chickenbits
         
     | 
| 
       2647 
2700 
     | 
    
         | 
| 
         @@ -1,17 +1,17 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            copyparty/__init__.py,sha256=VR6ZZhB9IxaK5TDXDTBM_OIP5ydkrdbaEnstktLM__s,2649
         
     | 
| 
       2 
     | 
    
         
            -
            copyparty/__main__.py,sha256= 
     | 
| 
       3 
     | 
    
         
            -
            copyparty/__version__.py,sha256 
     | 
| 
       4 
     | 
    
         
            -
            copyparty/authsrv.py,sha256 
     | 
| 
      
 2 
     | 
    
         
            +
            copyparty/__main__.py,sha256=JDjMsCiOMMBPs8HR8vpgEJMgnxq-qjX-hcgxKHF9WX4,117137
         
     | 
| 
      
 3 
     | 
    
         
            +
            copyparty/__version__.py,sha256=-v6S2kv2wFcsrV1NBHpDXFZYQtr_j2DfwN5pjYFcYX4,252
         
     | 
| 
      
 4 
     | 
    
         
            +
            copyparty/authsrv.py,sha256=EqlE2YztBcZHF5MHStZawA8ZKSlm-ePkrhsen90lKE8,107740
         
     | 
| 
       5 
5 
     | 
    
         
             
            copyparty/broker_mp.py,sha256=QdOXXvV2Xn6J0CysEqyY3GZbqxQMyWnTpnba-a5lMc0,4987
         
     | 
| 
       6 
6 
     | 
    
         
             
            copyparty/broker_mpw.py,sha256=PpSS4SK3pItlpfD8OwVr3QmJEPKlUgaf2nuMOozixgU,3347
         
     | 
| 
       7 
7 
     | 
    
         
             
            copyparty/broker_thr.py,sha256=fjoYtpSscUA7-nMl4r1n2R7UK3J9lrvLS3rUZ-iJzKQ,1721
         
     | 
| 
       8 
8 
     | 
    
         
             
            copyparty/broker_util.py,sha256=76mfnFOpX1gUUvtjm8UQI7jpTIaVINX10QonM-B7ggc,1680
         
     | 
| 
       9 
9 
     | 
    
         
             
            copyparty/cert.py,sha256=0ZAPeXeMR164vWn9GQU3JDKooYXEq_NOQkDeg543ivg,8009
         
     | 
| 
       10 
     | 
    
         
            -
            copyparty/cfg.py,sha256 
     | 
| 
      
 10 
     | 
    
         
            +
            copyparty/cfg.py,sha256=Z04AuNy-viZiiVJ8fLf3RULgH4w8ZidjsAVj4cmJKlA,13272
         
     | 
| 
       11 
11 
     | 
    
         
             
            copyparty/dxml.py,sha256=vu5uZQtwvwoqnFHbULs2Zh_y2DETu0T-ENpMZ1i2CV4,2505
         
     | 
| 
       12 
12 
     | 
    
         
             
            copyparty/fsutil.py,sha256=IVOFG8zBQPMQDDv7RIStSJHwHiAnVNROZS37O5k465A,4524
         
     | 
| 
       13 
13 
     | 
    
         
             
            copyparty/ftpd.py,sha256=T97SFS7JFtvRLbJX8C4fJSYwe13vhN3-E6emtlVmqLA,17608
         
     | 
| 
       14 
     | 
    
         
            -
            copyparty/httpcli.py,sha256= 
     | 
| 
      
 14 
     | 
    
         
            +
            copyparty/httpcli.py,sha256=QKgO3TTweln1N_w6Du7PDs1HJrT1c_zISUDZoima_X0,219162
         
     | 
| 
       15 
15 
     | 
    
         
             
            copyparty/httpconn.py,sha256=mQSgljh0Q-jyWjF4tQLrHbRKRe9WKl19kGqsGMsJpWo,6880
         
     | 
| 
       16 
16 
     | 
    
         
             
            copyparty/httpsrv.py,sha256=pxH_Eh8ElBLvOEDejgpP9Bvk65HNEou-03aYIcgXhrs,18090
         
     | 
| 
       17 
17 
     | 
    
         
             
            copyparty/ico.py,sha256=eWSxEae4wOCfheHl-m-wchYvFRAR_97kJDb4NGaB-Z8,3561
         
     | 
| 
         @@ -31,7 +31,7 @@ copyparty/tftpd.py,sha256=PXgG4rTmiaU_TavSyZWD5cFphdfChs9YvNY21qfExt8,13611 
     | 
|
| 
       31 
31 
     | 
    
         
             
            copyparty/th_cli.py,sha256=PxDAmUvO_8Vm5edXiWtsCft0Fw69QL9rCHf9zLmUNeA,4800
         
     | 
| 
       32 
32 
     | 
    
         
             
            copyparty/th_srv.py,sha256=tHbh_Ve3v8tYclWH2thLs5oFufeXgJi1duUMveKIx9k,30725
         
     | 
| 
       33 
33 
     | 
    
         
             
            copyparty/u2idx.py,sha256=G6MDbD4I_sJSOwaNFZ6XLTQhnEDrB12pVKuKhzQ_leE,13676
         
     | 
| 
       34 
     | 
    
         
            -
            copyparty/up2k.py,sha256= 
     | 
| 
      
 34 
     | 
    
         
            +
            copyparty/up2k.py,sha256=flkVZkHy7cfRZh7DSbTMbr4jfw7poZDOX3gFu5vyFxM,176973
         
     | 
| 
       35 
35 
     | 
    
         
             
            copyparty/util.py,sha256=Y_znSn3hBNYaaduwcCB7mmBYsi6vv9CYC1zJ9rq9yeQ,99435
         
     | 
| 
       36 
36 
     | 
    
         
             
            copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       37 
37 
     | 
    
         
             
            copyparty/bos/bos.py,sha256=Wb7eWsXJgR5AFlBR9ZOyKrLTwy-Kct9RrGiOu4Jo37Y,1622
         
     | 
| 
         @@ -55,9 +55,9 @@ copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUu 
     | 
|
| 
       55 
55 
     | 
    
         
             
            copyparty/stolen/ifaddr/_shared.py,sha256=uNC4SdEIgdSLKvuUzsf1aM-H1Xrc_9mpLoOT43YukGs,6206
         
     | 
| 
       56 
56 
     | 
    
         
             
            copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
         
     | 
| 
       57 
57 
     | 
    
         
             
            copyparty/web/baguettebox.js.gz,sha256=r2c_hOZV_RTyl4CqWWX14FDWP8nnDVwGkDl4Sfk0rU4,8239
         
     | 
| 
       58 
     | 
    
         
            -
            copyparty/web/browser.css.gz,sha256= 
     | 
| 
      
 58 
     | 
    
         
            +
            copyparty/web/browser.css.gz,sha256=_HiFW5vPUusWadoqdY8ZihuWizY9UECAc5nIamBPRi4,11654
         
     | 
| 
       59 
59 
     | 
    
         
             
            copyparty/web/browser.html,sha256=auvhLVE_t0aIN0q-nk0zOWFqITgDhroMAAviBNLoFfc,4788
         
     | 
| 
       60 
     | 
    
         
            -
            copyparty/web/browser.js.gz,sha256= 
     | 
| 
      
 60 
     | 
    
         
            +
            copyparty/web/browser.js.gz,sha256=7XJ99kbDhfTelhK92K2MhJu1f47XSHhYtztjAhxPOk4,92085
         
     | 
| 
       61 
61 
     | 
    
         
             
            copyparty/web/browser2.html,sha256=NRUZ08GH-e2YcGXcoz0UjYg6JIVF42u4IMX4HHwWTmg,1587
         
     | 
| 
       62 
62 
     | 
    
         
             
            copyparty/web/cf.html,sha256=lJThtNFNAQT1ClCHHlivAkDGE0LutedwopXD62Z8Nys,589
         
     | 
| 
       63 
63 
     | 
    
         
             
            copyparty/web/dbg-audio.js.gz,sha256=Ma-KZtK8LnmiwNvNKFKXMPYl_Nn_3U7GsJ6-DRWC2HE,688
         
     | 
| 
         @@ -83,12 +83,12 @@ copyparty/web/splash.js.gz,sha256=4VqNznN10-bT33IJm3VWzBEJ1s08XZyxFB1TYPUkuAo,27 
     | 
|
| 
       83 
83 
     | 
    
         
             
            copyparty/web/svcs.html,sha256=dnE1fG15zOpq7u0GYt8ij6BUv_LTwsiipFeneVYlMsM,14140
         
     | 
| 
       84 
84 
     | 
    
         
             
            copyparty/web/svcs.js.gz,sha256=lMXEP9W-VlXyANlva4q0ASSxvvHYlE2CrmxGgZXZop0,713
         
     | 
| 
       85 
85 
     | 
    
         
             
            copyparty/web/ui.css.gz,sha256=0sHIwGsL3_xH8Uu6N0Ag3bKBTjf-e_yfFbKynEZXAnk,2800
         
     | 
| 
       86 
     | 
    
         
            -
            copyparty/web/up2k.js.gz,sha256= 
     | 
| 
      
 86 
     | 
    
         
            +
            copyparty/web/up2k.js.gz,sha256=o3FAMh8TxmN7SfiI15yQddyR1JSpzhHWC4u6qztNJgY,24057
         
     | 
| 
       87 
87 
     | 
    
         
             
            copyparty/web/util.js.gz,sha256=wD3tP5j1iE5Uj5AvLW5zZbQJXDIFDlqgBTGdXeRVqo0,15110
         
     | 
| 
       88 
88 
     | 
    
         
             
            copyparty/web/w.hash.js.gz,sha256=l3GpSJD6mcU-1CRWkIj7PybgbjlfSr8oeO3vortIrQk,1105
         
     | 
| 
       89 
89 
     | 
    
         
             
            copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       90 
90 
     | 
    
         
             
            copyparty/web/a/partyfuse.py,sha256=9p5Hpg_IBiSimv7j9kmPhCGpy-FLXSRUOYnLjJ5JifU,28049
         
     | 
| 
       91 
     | 
    
         
            -
            copyparty/web/a/u2c.py,sha256= 
     | 
| 
      
 91 
     | 
    
         
            +
            copyparty/web/a/u2c.py,sha256=oRKEApPuaXiOkmUyA-WGCDjtWsn8FirSW6nCJtx9sgk,53157
         
     | 
| 
       92 
92 
     | 
    
         
             
            copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
         
     | 
| 
       93 
93 
     | 
    
         
             
            copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
         
     | 
| 
       94 
94 
     | 
    
         
             
            copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
         
     | 
| 
         @@ -109,9 +109,9 @@ copyparty/web/deps/prismd.css.gz,sha256=ObUlksQVr-OuYlTz-I4B23TeBg2QDVVGRnWBz8cV 
     | 
|
| 
       109 
109 
     | 
    
         
             
            copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
         
     | 
| 
       110 
110 
     | 
    
         
             
            copyparty/web/deps/sha512.ac.js.gz,sha256=lFZaCLumgWxrvEuDr4bqdKHsqjX82AbVAb7_F45Yk88,7033
         
     | 
| 
       111 
111 
     | 
    
         
             
            copyparty/web/deps/sha512.hw.js.gz,sha256=UAed2_ocklZCnIzcSYz2h4P1ycztlCLj-ewsRTud2lU,7939
         
     | 
| 
       112 
     | 
    
         
            -
            copyparty-1.16. 
     | 
| 
       113 
     | 
    
         
            -
            copyparty-1.16. 
     | 
| 
       114 
     | 
    
         
            -
            copyparty-1.16. 
     | 
| 
       115 
     | 
    
         
            -
            copyparty-1.16. 
     | 
| 
       116 
     | 
    
         
            -
            copyparty-1.16. 
     | 
| 
       117 
     | 
    
         
            -
            copyparty-1.16. 
     | 
| 
      
 112 
     | 
    
         
            +
            copyparty-1.16.14.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
         
     | 
| 
      
 113 
     | 
    
         
            +
            copyparty-1.16.14.dist-info/METADATA,sha256=MwVuGqaNzreAqN-HP6IfmsOzEKGS6_iYy2BB3dCvFbU,157768
         
     | 
| 
      
 114 
     | 
    
         
            +
            copyparty-1.16.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
         
     | 
| 
      
 115 
     | 
    
         
            +
            copyparty-1.16.14.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
         
     | 
| 
      
 116 
     | 
    
         
            +
            copyparty-1.16.14.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
         
     | 
| 
      
 117 
     | 
    
         
            +
            copyparty-1.16.14.dist-info/RECORD,,
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |