copyparty 1.18.9__py3-none-any.whl → 1.18.10__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/__init__.py +0 -4
- copyparty/__main__.py +12 -5
- copyparty/__version__.py +2 -2
- copyparty/authsrv.py +8 -2
- copyparty/httpcli.py +22 -15
- copyparty/httpsrv.py +2 -1
- copyparty/mtag.py +5 -1
- copyparty/tcpsrv.py +2 -3
- copyparty/th_cli.py +2 -2
- copyparty/th_srv.py +68 -2
- copyparty/up2k.py +18 -16
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/splash.js.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.18.9.dist-info → copyparty-1.18.10.dist-info}/METADATA +29 -2
- {copyparty-1.18.9.dist-info → copyparty-1.18.10.dist-info}/RECORD +21 -26
- copyparty/web/dd/2.png +0 -0
- copyparty/web/dd/3.png +0 -0
- copyparty/web/dd/4.png +0 -0
- copyparty/web/dd/5.png +0 -0
- copyparty/web/dd/__init__.py +0 -0
- {copyparty-1.18.9.dist-info → copyparty-1.18.10.dist-info}/WHEEL +0 -0
- {copyparty-1.18.9.dist-info → copyparty-1.18.10.dist-info}/entry_points.txt +0 -0
- {copyparty-1.18.9.dist-info → copyparty-1.18.10.dist-info}/licenses/LICENSE +0 -0
- {copyparty-1.18.9.dist-info → copyparty-1.18.10.dist-info}/top_level.txt +0 -0
copyparty/__init__.py
CHANGED
copyparty/__main__.py
CHANGED
@@ -87,6 +87,10 @@ u = unicode
|
|
87
87
|
printed = []
|
88
88
|
zsid = uuid.uuid4().urn[4:]
|
89
89
|
|
90
|
+
CFG_DEF = [os.environ.get("PRTY_CONFIG", "")]
|
91
|
+
if not CFG_DEF[0]:
|
92
|
+
CFG_DEF.pop()
|
93
|
+
|
90
94
|
|
91
95
|
class RiceFormatter(argparse.HelpFormatter):
|
92
96
|
def __init__(self, *args , **kwargs ) :
|
@@ -566,7 +570,7 @@ def get_sects():
|
|
566
570
|
|
567
571
|
--grp takes groupname:username1,username2,...
|
568
572
|
and groupnames can be used instead of usernames in -v
|
569
|
-
by prefixing the groupname with
|
573
|
+
by prefixing the groupname with @
|
570
574
|
|
571
575
|
list of permissions:
|
572
576
|
"r" (read): list folder contents, download files
|
@@ -982,7 +986,7 @@ def build_flags_desc():
|
|
982
986
|
|
983
987
|
def add_general(ap, nc, srvname):
|
984
988
|
ap2 = ap.add_argument_group('general options')
|
985
|
-
ap2.add_argument("-c", metavar="PATH", type=u, action="append", help="add config file")
|
989
|
+
ap2.add_argument("-c", metavar="PATH", type=u, default=CFG_DEF, action="append", help="add config file")
|
986
990
|
ap2.add_argument("-nc", metavar="NUM", type=int, default=nc, help="max num clients")
|
987
991
|
ap2.add_argument("-j", metavar="CORES", type=int, default=1, help="max num cpu cores, 0=all")
|
988
992
|
ap2.add_argument("-a", metavar="ACCT", type=u, action="append", help="add account, \033[33mUSER\033[0m:\033[33mPASS\033[0m; example [\033[32med:wark\033[0m]")
|
@@ -1101,7 +1105,7 @@ def add_tls(ap, cert_path):
|
|
1101
1105
|
ap2 = ap.add_argument_group('SSL/TLS options')
|
1102
1106
|
ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls -- force plaintext")
|
1103
1107
|
ap2.add_argument("--https-only", action="store_true", help="disable plaintext -- force tls")
|
1104
|
-
ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to TLS certificate")
|
1108
|
+
ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to file containing a concatenation of TLS key and certificate chain")
|
1105
1109
|
ap2.add_argument("--ssl-ver", metavar="LIST", type=u, default="", help="set allowed ssl/tls versions; [\033[32mhelp\033[0m] shows available versions; default is what your python version considers safe")
|
1106
1110
|
ap2.add_argument("--ciphers", metavar="LIST", type=u, default="", help="set allowed ssl/tls ciphers; [\033[32mhelp\033[0m] shows available ciphers")
|
1107
1111
|
ap2.add_argument("--ssl-dbg", action="store_true", help="dump some tls info")
|
@@ -1138,6 +1142,7 @@ def add_auth(ap):
|
|
1138
1142
|
ap2.add_argument("--idp-db", metavar="PATH", type=u, default=idp_db, help="where to store the known IdP users/groups (if you run multiple copyparty instances, make sure they use different DBs)")
|
1139
1143
|
ap2.add_argument("--idp-store", metavar="N", type=int, default=1, help="how to use \033[33m--idp-db\033[0m; [\033[32m0\033[0m] = entirely disable, [\033[32m1\033[0m] = write-only (effectively disabled), [\033[32m2\033[0m] = remember users, [\033[32m3\033[0m] = remember users and groups.\nNOTE: Will remember and restore the IdP-volumes of all users for all eternity if set to 2 or 3, even when user is deleted from your IdP")
|
1140
1144
|
ap2.add_argument("--idp-adm", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to use /?idp (the cache management UI)")
|
1145
|
+
ap2.add_argument("--idp-cookie", metavar="S", type=int, default=0, help="generate a session-token for IdP users which is written to cookie \033[33mcppws\033[0m (or \033[33mcppwd\033[0m if plaintext), to reduce the load on the IdP server, lifetime \033[33mS\033[0m seconds.\n └─note: The expiration time is a client hint only; the actual lifetime of the session-token is infinite (until next restart with \033[33m--ses-db\033[0m wiped)")
|
1141
1146
|
ap2.add_argument("--no-bauth", action="store_true", help="disable basic-authentication support; do not accept passwords from the 'Authenticate' header at all. NOTE: This breaks support for the android app")
|
1142
1147
|
ap2.add_argument("--bauth-last", action="store_true", help="keeps basic-authentication enabled, but only as a last-resort; if a cookie is also provided then the cookie wins")
|
1143
1148
|
ap2.add_argument("--ses-db", metavar="PATH", type=u, default=ses_db, help="where to store the sessions database (if you run multiple copyparty instances, make sure they use different DBs)")
|
@@ -1435,6 +1440,8 @@ def add_transcoding(ap):
|
|
1435
1440
|
ap2 = ap.add_argument_group('transcoding options')
|
1436
1441
|
ap2.add_argument("--q-opus", metavar="KBPS", type=int, default=128, help="target bitrate for transcoding to opus; set 0 to disable")
|
1437
1442
|
ap2.add_argument("--q-mp3", metavar="QUALITY", type=u, default="q2", help="target quality for transcoding to mp3, for example [\033[32m192k\033[0m] (CBR) or [\033[32mq0\033[0m] (CQ/CRF, q0=maxquality, q9=smallest); set 0 to disable")
|
1443
|
+
ap2.add_argument("--allow-wav", action="store_true", help="allow transcoding to wav (lossless, uncompressed)")
|
1444
|
+
ap2.add_argument("--allow-flac", action="store_true", help="allow transcoding to flac (lossless, compressed)")
|
1438
1445
|
ap2.add_argument("--no-caf", action="store_true", help="disable transcoding to caf-opus (affects iOS v12~v17), will use mp3 instead")
|
1439
1446
|
ap2.add_argument("--no-owa", action="store_true", help="disable transcoding to webm-opus (iOS v18 and later), will use mp3 instead")
|
1440
1447
|
ap2.add_argument("--no-acode", action="store_true", help="disable audio transcoding")
|
@@ -1553,7 +1560,7 @@ def add_ui(ap, retry):
|
|
1553
1560
|
ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files/folders matching \033[33mREGEX\033[0m in file list. WARNING: Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)")
|
1554
1561
|
ap2.add_argument("--favico", metavar="TXT", type=u, default="c 000 none" if retry else "🎉 000 none", help="\033[33mfavicon-text\033[0m [ \033[33mforeground\033[0m [ \033[33mbackground\033[0m ] ], set blank to disable")
|
1555
1562
|
ap2.add_argument("--ext-th", metavar="E=VP", type=u, action="append", help="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)")
|
1556
|
-
ap2.add_argument("--mpmc",
|
1563
|
+
ap2.add_argument("--mpmc", type=u, default="", help=argparse.SUPPRESS)
|
1557
1564
|
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]")
|
1558
1565
|
ap2.add_argument("--css-browser", metavar="L", type=u, default="", help="URL to additional CSS to include in the filebrowser html")
|
1559
1566
|
ap2.add_argument("--js-browser", metavar="L", type=u, default="", help="URL to additional JS to include in the filebrowser html")
|
@@ -1778,7 +1785,7 @@ def main(argv = None) :
|
|
1778
1785
|
argv[idx] = nk + ov
|
1779
1786
|
time.sleep(2)
|
1780
1787
|
|
1781
|
-
da = len(argv) == 1
|
1788
|
+
da = len(argv) == 1 and not CFG_DEF
|
1782
1789
|
try:
|
1783
1790
|
if da:
|
1784
1791
|
argv.extend(["--qr"])
|
copyparty/__version__.py
CHANGED
copyparty/authsrv.py
CHANGED
@@ -1705,7 +1705,8 @@ class AuthSrv(object):
|
|
1705
1705
|
t = "Read-access has been disabled due to failsafe: No volumes were defined by the config-file. This failsafe is to prevent unintended access if this is due to accidental loss of config. You can override this safeguard and allow read/write to the working-directory by adding the following arguments: -v .::rw"
|
1706
1706
|
self.log(t, 1)
|
1707
1707
|
axs = AXS()
|
1708
|
-
|
1708
|
+
zvf = {"tcolor": self.args.tcolor}
|
1709
|
+
vfs = VFS(self.log_func, absreal("."), "", "", axs, zvf)
|
1709
1710
|
if not axs.uread:
|
1710
1711
|
self.badcfg1 = True
|
1711
1712
|
elif "" not in mount:
|
@@ -2742,6 +2743,8 @@ class AuthSrv(object):
|
|
2742
2743
|
"s_name": self.args.bname,
|
2743
2744
|
"have_up2k_idx": "e2d" in vf,
|
2744
2745
|
"have_acode": not self.args.no_acode,
|
2746
|
+
"have_c2flac": self.args.allow_flac,
|
2747
|
+
"have_c2wav": self.args.allow_wav,
|
2745
2748
|
"have_shr": self.args.shr,
|
2746
2749
|
"have_zip": not self.args.no_zip,
|
2747
2750
|
"have_mv": not self.args.no_mv,
|
@@ -2854,7 +2857,10 @@ class AuthSrv(object):
|
|
2854
2857
|
|
2855
2858
|
n = []
|
2856
2859
|
q = "insert into us values (?,?,?)"
|
2857
|
-
|
2860
|
+
accs = list(self.acct)
|
2861
|
+
if self.args.idp_h_usr and self.args.idp_cookie:
|
2862
|
+
accs.extend(self.idp_accs.keys())
|
2863
|
+
for uname in accs:
|
2858
2864
|
if uname not in ases:
|
2859
2865
|
sid = ub64enc(os.urandom(blen)).decode("ascii")
|
2860
2866
|
cur.execute(q, (uname, sid, int(time.time())))
|
copyparty/httpcli.py
CHANGED
@@ -653,6 +653,9 @@ class HttpCli(object):
|
|
653
653
|
self.pw = ""
|
654
654
|
self.uname = idp_usr
|
655
655
|
self.html_head += "<script>var is_idp=1</script>\n"
|
656
|
+
zs = self.asrv.ases.get(idp_usr)
|
657
|
+
if zs:
|
658
|
+
self.set_idp_cookie(zs)
|
656
659
|
else:
|
657
660
|
self.log("unknown username: %r" % (idp_usr,), 1)
|
658
661
|
|
@@ -1191,15 +1194,6 @@ class HttpCli(object):
|
|
1191
1194
|
self.reply(b"ssdp is disabled in server config", 404)
|
1192
1195
|
return False
|
1193
1196
|
|
1194
|
-
if self.vpath.startswith(".cpr/dd/") and self.args.mpmc:
|
1195
|
-
if self.args.mpmc == ".":
|
1196
|
-
raise Pebkac(404)
|
1197
|
-
|
1198
|
-
loc = self.args.mpmc.rstrip("/") + self.vpath[self.vpath.rfind("/") :]
|
1199
|
-
h = {"Location": loc, "Cache-Control": "max-age=39"}
|
1200
|
-
self.reply(b"", 301, headers=h)
|
1201
|
-
return True
|
1202
|
-
|
1203
1197
|
if self.vpath == ".cpr/metrics":
|
1204
1198
|
return self.conn.hsrv.metrics.tx(self)
|
1205
1199
|
|
@@ -2075,16 +2069,16 @@ class HttpCli(object):
|
|
2075
2069
|
rnd, lifetime, xbu, xau = self.upload_flags(vfs)
|
2076
2070
|
lim = vfs.get_dbv(rem)[0].lim
|
2077
2071
|
fdir = vfs.canonical(rem)
|
2078
|
-
if lim:
|
2079
|
-
fdir, rem = lim.all(
|
2080
|
-
self.ip, rem, remains, vfs.realpath, fdir, self.conn.hsrv.broker
|
2081
|
-
)
|
2082
|
-
|
2083
2072
|
fn = None
|
2084
2073
|
if rem and not self.trailing_slash and not bos.path.isdir(fdir):
|
2085
2074
|
fdir, fn = os.path.split(fdir)
|
2086
2075
|
rem, _ = vsplit(rem)
|
2087
2076
|
|
2077
|
+
if lim:
|
2078
|
+
fdir, rem = lim.all(
|
2079
|
+
self.ip, rem, remains, vfs.realpath, fdir, self.conn.hsrv.broker
|
2080
|
+
)
|
2081
|
+
|
2088
2082
|
bos.makedirs(fdir, vf=vfs.flags)
|
2089
2083
|
|
2090
2084
|
open_ka = {"fun": open}
|
@@ -3024,6 +3018,19 @@ class HttpCli(object):
|
|
3024
3018
|
|
3025
3019
|
return dur > 0, msg
|
3026
3020
|
|
3021
|
+
def set_idp_cookie(self, ases) :
|
3022
|
+
k = "cppws" if self.is_https else "cppwd"
|
3023
|
+
ck = gencookie(
|
3024
|
+
k,
|
3025
|
+
ases,
|
3026
|
+
self.args.R,
|
3027
|
+
self.args.cookie_lax,
|
3028
|
+
self.is_https,
|
3029
|
+
self.args.idp_cookie,
|
3030
|
+
"; HttpOnly",
|
3031
|
+
)
|
3032
|
+
self.out_headers["Set-Cookie"] = ck
|
3033
|
+
|
3027
3034
|
def handle_mkdir(self) :
|
3028
3035
|
new_dir = self.parser.require("name", 512)
|
3029
3036
|
self.parser.drop()
|
@@ -4662,7 +4669,7 @@ class HttpCli(object):
|
|
4662
4669
|
# for f in fgen: print(repr({k: f[k] for k in ["vp", "ap"]}))
|
4663
4670
|
cfmt = ""
|
4664
4671
|
if self.thumbcli and not self.args.no_bacode:
|
4665
|
-
for zs in ("opus", "mp3", "w", "j", "p"):
|
4672
|
+
for zs in ("opus", "mp3", "flac", "wav", "w", "j", "p"):
|
4666
4673
|
if zs in self.ouparam or uarg == zs:
|
4667
4674
|
cfmt = zs
|
4668
4675
|
|
copyparty/httpsrv.py
CHANGED
@@ -319,7 +319,8 @@ class HttpSrv(object):
|
|
319
319
|
spins = 0
|
320
320
|
while self.ncli >= self.nclimax:
|
321
321
|
if not spins:
|
322
|
-
|
322
|
+
t = "at connection limit (global-option 'nc'); waiting"
|
323
|
+
self.log(self.name, t, 3)
|
323
324
|
|
324
325
|
spins += 1
|
325
326
|
time.sleep(0.1)
|
copyparty/mtag.py
CHANGED
@@ -61,6 +61,8 @@ HAVE_FFPROBE = not os.environ.get("PRTY_NO_FFPROBE") and have_ff("ffprobe")
|
|
61
61
|
CBZ_PICS = set("png jpg jpeg gif bmp tga tif tiff webp avif".split())
|
62
62
|
CBZ_01 = re.compile(r"(^|[^0-9v])0+[01]\b")
|
63
63
|
|
64
|
+
FMT_AU = set("mp3 ogg flac wav".split())
|
65
|
+
|
64
66
|
|
65
67
|
class MParser(object):
|
66
68
|
def __init__(self, cmdline ) :
|
@@ -236,7 +238,7 @@ def parse_ffprobe(txt ) :
|
|
236
238
|
ret = {} # processed
|
237
239
|
md = {} # raw tags
|
238
240
|
|
239
|
-
is_audio = fmt.get("format_name") in
|
241
|
+
is_audio = fmt.get("format_name") in FMT_AU
|
240
242
|
if fmt.get("filename", "").split(".")[-1].lower() in ["m4a", "aac"]:
|
241
243
|
is_audio = True
|
242
244
|
|
@@ -264,6 +266,8 @@ def parse_ffprobe(txt ) :
|
|
264
266
|
["channel_layout", "chs"],
|
265
267
|
["sample_rate", ".hz"],
|
266
268
|
["bit_rate", ".aq"],
|
269
|
+
["bits_per_sample", ".bps"],
|
270
|
+
["bits_per_raw_sample", ".bprs"],
|
267
271
|
["duration", ".dur"],
|
268
272
|
]
|
269
273
|
|
copyparty/tcpsrv.py
CHANGED
@@ -580,8 +580,7 @@ class TcpSrv(object):
|
|
580
580
|
if not ip:
|
581
581
|
return ""
|
582
582
|
|
583
|
-
if ":" in ip
|
584
|
-
ip = "[{}]".format(ip)
|
583
|
+
hip = "[%s]" % (ip,) if ":" in ip else ip
|
585
584
|
|
586
585
|
if self.args.http_only:
|
587
586
|
https = ""
|
@@ -593,7 +592,7 @@ class TcpSrv(object):
|
|
593
592
|
ports = t1.get(ip, t2.get(ip, []))
|
594
593
|
dport = 443 if https else 80
|
595
594
|
port = "" if dport in ports or not ports else ":{}".format(ports[0])
|
596
|
-
txt = "http{}://{}{}/{}".format(https,
|
595
|
+
txt = "http{}://{}{}/{}".format(https, hip, port, self.args.qrl)
|
597
596
|
|
598
597
|
btxt = txt.encode("utf-8")
|
599
598
|
if PY2:
|
copyparty/th_cli.py
CHANGED
@@ -85,7 +85,7 @@ class ThumbCli(object):
|
|
85
85
|
if rem.startswith(".hist/th/") and rem.split(".")[-1] in ["webp", "jpg", "png"]:
|
86
86
|
return os.path.join(ptop, rem)
|
87
87
|
|
88
|
-
if fmt[:1] in "jw":
|
88
|
+
if fmt[:1] in "jw" and fmt != "wav":
|
89
89
|
sfmt = fmt[:1]
|
90
90
|
|
91
91
|
if sfmt == "j" and self.args.th_no_jpg:
|
@@ -126,7 +126,7 @@ class ThumbCli(object):
|
|
126
126
|
|
127
127
|
tpath = thumb_path(histpath, rem, mtime, fmt, self.fmt_ffa)
|
128
128
|
tpaths = [tpath]
|
129
|
-
if fmt[:1] == "w":
|
129
|
+
if fmt[:1] == "w" and fmt != "wav":
|
130
130
|
# also check for jpg (maybe webp is unavailable)
|
131
131
|
tpaths.append(tpath.rsplit(".", 1)[0] + ".jpg")
|
132
132
|
|
copyparty/th_srv.py
CHANGED
@@ -47,7 +47,7 @@ HAVE_AVIF = False
|
|
47
47
|
HAVE_WEBP = False
|
48
48
|
|
49
49
|
EXTS_TH = set(["jpg", "webp", "png"])
|
50
|
-
EXTS_AC = set(["opus", "owa", "caf", "mp3"])
|
50
|
+
EXTS_AC = set(["opus", "owa", "caf", "mp3", "flac", "wav"])
|
51
51
|
EXTS_SPEC_SAFE = set("aif aiff flac mp3 opus wav".split())
|
52
52
|
|
53
53
|
PTN_TS = re.compile("^-?[0-9a-f]{8,10}$")
|
@@ -352,8 +352,10 @@ class ThumbSrv(object):
|
|
352
352
|
tex = tpath.rsplit(".", 1)[-1]
|
353
353
|
want_mp3 = tex == "mp3"
|
354
354
|
want_opus = tex in ("opus", "owa", "caf")
|
355
|
+
want_flac = tex == "flac"
|
356
|
+
want_wav = tex == "wav"
|
355
357
|
want_png = tex == "png"
|
356
|
-
want_au = want_mp3 or want_opus
|
358
|
+
want_au = want_mp3 or want_opus or want_flac or want_wav
|
357
359
|
for lib in self.args.th_dec:
|
358
360
|
can_au = lib == "ff" and (
|
359
361
|
ext in self.fmt_ffa or ext in self.fmt_ffv
|
@@ -368,6 +370,10 @@ class ThumbSrv(object):
|
|
368
370
|
funs.append(self.conv_opus)
|
369
371
|
elif want_mp3:
|
370
372
|
funs.append(self.conv_mp3)
|
373
|
+
elif want_flac:
|
374
|
+
funs.append(self.conv_flac)
|
375
|
+
elif want_wav:
|
376
|
+
funs.append(self.conv_wav)
|
371
377
|
elif want_png:
|
372
378
|
funs.append(self.conv_waves)
|
373
379
|
png_ok = True
|
@@ -803,6 +809,66 @@ class ThumbSrv(object):
|
|
803
809
|
# fmt: on
|
804
810
|
self._run_ff(cmd, vn, oom=300)
|
805
811
|
|
812
|
+
def conv_flac(self, abspath , tpath , fmt , vn ) :
|
813
|
+
if self.args.no_acode or not self.args.allow_flac:
|
814
|
+
raise Exception("flac not permitted in server config")
|
815
|
+
|
816
|
+
self.wait4ram(0.2, tpath)
|
817
|
+
tags, rawtags = ffprobe(abspath, int(vn.flags["convt"] / 2))
|
818
|
+
if "ac" not in tags:
|
819
|
+
raise Exception("not audio")
|
820
|
+
|
821
|
+
self.log("conv2 flac", 6)
|
822
|
+
|
823
|
+
# fmt: off
|
824
|
+
cmd = [
|
825
|
+
b"ffmpeg",
|
826
|
+
b"-nostdin",
|
827
|
+
b"-v", b"error",
|
828
|
+
b"-hide_banner",
|
829
|
+
b"-i", fsenc(abspath),
|
830
|
+
b"-map", b"0:a:0",
|
831
|
+
b"-c:a", b"flac",
|
832
|
+
fsenc(tpath)
|
833
|
+
]
|
834
|
+
# fmt: on
|
835
|
+
self._run_ff(cmd, vn, oom=300)
|
836
|
+
|
837
|
+
def conv_wav(self, abspath , tpath , fmt , vn ) :
|
838
|
+
if self.args.no_acode or not self.args.allow_wav:
|
839
|
+
raise Exception("wav not permitted in server config")
|
840
|
+
|
841
|
+
self.wait4ram(0.2, tpath)
|
842
|
+
tags, rawtags = ffprobe(abspath, int(vn.flags["convt"] / 2))
|
843
|
+
if "ac" not in tags:
|
844
|
+
raise Exception("not audio")
|
845
|
+
|
846
|
+
bits = tags[".bps"][1]
|
847
|
+
if bits == 0.0:
|
848
|
+
bits = tags[".bprs"][1]
|
849
|
+
|
850
|
+
codec = b"pcm_s32le"
|
851
|
+
if bits <= 16.0:
|
852
|
+
codec = b"pcm_s16le"
|
853
|
+
elif bits <= 24.0:
|
854
|
+
codec = b"pcm_s24le"
|
855
|
+
|
856
|
+
self.log("conv2 wav", 6)
|
857
|
+
|
858
|
+
# fmt: off
|
859
|
+
cmd = [
|
860
|
+
b"ffmpeg",
|
861
|
+
b"-nostdin",
|
862
|
+
b"-v", b"error",
|
863
|
+
b"-hide_banner",
|
864
|
+
b"-i", fsenc(abspath),
|
865
|
+
b"-map", b"0:a:0",
|
866
|
+
b"-c:a", codec,
|
867
|
+
fsenc(tpath)
|
868
|
+
]
|
869
|
+
# fmt: on
|
870
|
+
self._run_ff(cmd, vn, oom=300)
|
871
|
+
|
806
872
|
def conv_opus(self, abspath , tpath , fmt , vn ) :
|
807
873
|
if self.args.no_acode or not self.args.q_opus:
|
808
874
|
raise Exception("disabled in server config")
|
copyparty/up2k.py
CHANGED
@@ -83,7 +83,10 @@ if TYPE_CHECKING:
|
|
83
83
|
from .svchub import SvcHub
|
84
84
|
|
85
85
|
zsg = "avif,avifs,bmp,gif,heic,heics,heif,heifs,ico,j2p,j2k,jp2,jpeg,jpg,jpx,png,tga,tif,tiff,webp"
|
86
|
-
|
86
|
+
ICV_EXTS = set(zsg.split(","))
|
87
|
+
|
88
|
+
zsg = "3gp,asf,av1,avc,avi,flv,m4v,mjpeg,mjpg,mkv,mov,mp4,mpeg,mpeg2,mpegts,mpg,mpg2,mts,nut,ogm,ogv,rm,vob,webm,wmv"
|
89
|
+
VCV_EXTS = set(zsg.split(","))
|
87
90
|
|
88
91
|
zsg = "nohash noidx xdev xvol"
|
89
92
|
VF_AFFECTS_INDEXING = set(zsg.split(" "))
|
@@ -1470,7 +1473,7 @@ class Up2k(object):
|
|
1470
1473
|
unreg = []
|
1471
1474
|
files = []
|
1472
1475
|
fat32 = True
|
1473
|
-
cv = ""
|
1476
|
+
cv = vcv = ""
|
1474
1477
|
|
1475
1478
|
th_cvd = self.args.th_coversd
|
1476
1479
|
th_cvds = self.args.th_coversd_set
|
@@ -1564,25 +1567,24 @@ class Up2k(object):
|
|
1564
1567
|
|
1565
1568
|
rsz += sz
|
1566
1569
|
files.append((sz, lmod, iname))
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1570
|
+
if sz:
|
1571
|
+
liname = iname.lower()
|
1572
|
+
ext = liname.rsplit(".", 1)[-1]
|
1573
|
+
if (
|
1571
1574
|
liname in th_cvds
|
1572
|
-
or (
|
1573
|
-
|
1574
|
-
and liname.rsplit(".", 1)[-1] in CV_EXTS
|
1575
|
-
and not iname.startswith(".")
|
1576
|
-
)
|
1577
|
-
)
|
1578
|
-
and (
|
1575
|
+
or (not cv and ext in ICV_EXTS and not iname.startswith("."))
|
1576
|
+
) and (
|
1579
1577
|
not cv
|
1580
1578
|
or liname not in th_cvds
|
1581
1579
|
or cv.lower() not in th_cvds
|
1582
1580
|
or th_cvd.index(liname) < th_cvd.index(cv.lower())
|
1583
|
-
)
|
1584
|
-
|
1585
|
-
|
1581
|
+
):
|
1582
|
+
cv = iname
|
1583
|
+
elif not vcv and ext in VCV_EXTS and not iname.startswith("."):
|
1584
|
+
vcv = iname
|
1585
|
+
|
1586
|
+
if not cv:
|
1587
|
+
cv = vcv
|
1586
1588
|
|
1587
1589
|
if not self.args.no_dirsz:
|
1588
1590
|
tnf += len(files)
|
copyparty/web/browser.css.gz
CHANGED
Binary file
|
copyparty/web/browser.js.gz
CHANGED
Binary file
|
copyparty/web/splash.js.gz
CHANGED
Binary file
|
copyparty/web/util.js.gz
CHANGED
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.18.
|
3
|
+
Version: 1.18.10
|
4
4
|
Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
|
5
5
|
Author-email: ed <copyparty@ocv.me>
|
6
6
|
License: MIT
|
@@ -37,6 +37,13 @@ Requires-Python: >=3.3
|
|
37
37
|
Description-Content-Type: text/markdown
|
38
38
|
License-File: LICENSE
|
39
39
|
Requires-Dist: Jinja2
|
40
|
+
Provides-Extra: all
|
41
|
+
Requires-Dist: argon2-cffi; extra == "all"
|
42
|
+
Requires-Dist: partftpy>=0.4.0; extra == "all"
|
43
|
+
Requires-Dist: Pillow; extra == "all"
|
44
|
+
Requires-Dist: pyftpdlib; extra == "all"
|
45
|
+
Requires-Dist: pyopenssl; extra == "all"
|
46
|
+
Requires-Dist: pyzmq; extra == "all"
|
40
47
|
Provides-Extra: thumbnails
|
41
48
|
Requires-Dist: Pillow; extra == "thumbnails"
|
42
49
|
Provides-Extra: thumbnails2
|
@@ -205,6 +212,8 @@ made in Norway 🇳🇴
|
|
205
212
|
|
206
213
|
just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py)** -- that's it! 🎉
|
207
214
|
|
215
|
+
> ℹ️ the sfx is a [self-extractor](https://github.com/9001/copyparty/issues/270) which unpacks an embedded `tar.gz` into `$TEMP` -- if this looks too scary, you can use the [zipapp](#zipapp) which has slightly worse performance
|
216
|
+
|
208
217
|
* or install through [pypi](https://pypi.org/project/copyparty/): `python3 -m pip install --user -U copyparty`
|
209
218
|
* or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
|
210
219
|
* or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
|
@@ -571,12 +580,17 @@ anyone trying to bruteforce a password gets banned according to `--ban-pw`; defa
|
|
571
580
|
|
572
581
|
and if you want to use config files instead of commandline args (good!) then here's the same examples as a configfile; save it as `foobar.conf` and use it like this: `python copyparty-sfx.py -c foobar.conf`
|
573
582
|
|
583
|
+
* you can also `PRTY_CONFIG=foobar.conf python copyparty-sfx.py` (convenient in docker etc)
|
584
|
+
|
574
585
|
```yaml
|
575
586
|
[accounts]
|
576
587
|
u1: p1 # create account "u1" with password "p1"
|
577
588
|
u2: p2 # (note that comments must have
|
578
589
|
u3: p3 # two spaces before the # sign)
|
579
590
|
|
591
|
+
[groups]
|
592
|
+
g1: u1, u2 # create a group
|
593
|
+
|
580
594
|
[/] # this URL will be mapped to...
|
581
595
|
/srv # ...this folder on the server filesystem
|
582
596
|
accs:
|
@@ -586,6 +600,7 @@ and if you want to use config files instead of commandline args (good!) then her
|
|
586
600
|
/mnt/music # which is mapped to this folder
|
587
601
|
accs:
|
588
602
|
r: u1, u2 # only these accounts can read,
|
603
|
+
r: @g1 # (exactly the same, just with a group instead)
|
589
604
|
rw: u3 # and only u3 can read-write
|
590
605
|
|
591
606
|
[/inc]
|
@@ -1142,6 +1157,9 @@ open the `[🎺]` media-player-settings tab to configure it,
|
|
1142
1157
|
* `[awo]` is `opus` in a `weba` file, good for iPhones (iOS 17.5 and newer) but Apple is still fixing some state-confusion bugs as of iOS 18.2.1
|
1143
1158
|
* `[caf]` is `opus` in a `caf` file, good for iPhones (iOS 11 through 17), technically unsupported by Apple but works for the most part
|
1144
1159
|
* `[mp3]` -- the myth, the legend, the undying master of mediocre sound quality that definitely works everywhere
|
1160
|
+
* `[flac]` -- lossless but compressed, for LAN and/or fiber playback on electrostatic headphones
|
1161
|
+
* `[wav]` -- lossless and uncompressed, for LAN and/or fiber playback on electrostatic headphones connected to very old equipment
|
1162
|
+
* `flac` and `wav` must be enabled with `--allow-flac` / `--allow-wav` to allow spending the disk space
|
1145
1163
|
* "tint" reduces the contrast of the playback bar
|
1146
1164
|
|
1147
1165
|
|
@@ -1483,6 +1501,8 @@ note that this disables hotlinking because the opengraph spec demands it; to sne
|
|
1483
1501
|
|
1484
1502
|
you can also hotlink files regardless by appending `?raw` to the url
|
1485
1503
|
|
1504
|
+
> WARNING: if you plan to use WebDAV, then `--og-ua` / `og_ua` must be configured
|
1505
|
+
|
1486
1506
|
if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object)
|
1487
1507
|
|
1488
1508
|
|
@@ -1939,6 +1959,8 @@ you can disable the built-in password-based login system, and instead replace it
|
|
1939
1959
|
|
1940
1960
|
* the regular config-defined users will be used as a fallback for requests which don't include a valid (trusted) IdP username header
|
1941
1961
|
|
1962
|
+
* if your IdP-server is slow, consider `--idp-cookie` and let requests with the cookie `cppws` bypass the IdP; experimental sessions-based feature added for a party
|
1963
|
+
|
1942
1964
|
some popular identity providers are [Authelia](https://www.authelia.com/) (config-file based) and [authentik](https://goauthentik.io/) (GUI-based, more complex)
|
1943
1965
|
|
1944
1966
|
there is a [docker-compose example](./docs/examples/docker/idp-authelia-traefik) which is hopefully a good starting point (alternatively see [./docs/idp.md](./docs/idp.md) if you're the DIY type)
|
@@ -2487,6 +2509,7 @@ quick summary of more eccentric web-browsers trying to view a directory index:
|
|
2487
2509
|
| **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
|
2488
2510
|
| **sony psp** 5.50 | can browse, upload/mkdir/msg (thx dwarf) [screenshot](https://github.com/user-attachments/assets/9d21f020-1110-4652-abeb-6fc09c533d4f) |
|
2489
2511
|
| **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
|
2512
|
+
| **Nintendo Wii (Opera 9.0 "Internet Channel")** | can browse, can't upload or download (no local storage), can view images - works best with `?b=u`, default view broken |
|
2490
2513
|
|
2491
2514
|
<p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
|
2492
2515
|
|
@@ -2757,6 +2780,10 @@ optionally also specify `--ah-cli` to enter an interactive mode where it will ha
|
|
2757
2780
|
|
2758
2781
|
the default configs take about 0.4 sec and 256 MiB RAM to process a new password on a decent laptop
|
2759
2782
|
|
2783
|
+
when generating hashes using `--ah-cli` for docker or systemd services, make sure it is using the same `--ah-salt` by:
|
2784
|
+
* inspecting the generated salt using `--show-ah-salt` in copyparty service configuration
|
2785
|
+
* setting the same `--ah-salt` in both environments
|
2786
|
+
|
2760
2787
|
|
2761
2788
|
## https
|
2762
2789
|
|
@@ -2901,7 +2928,7 @@ then again, if you are already into downloading shady binaries from the internet
|
|
2901
2928
|
|
2902
2929
|
## zipapp
|
2903
2930
|
|
2904
|
-
another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, is slow, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it does not unpack any temporary files to disk, so it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
|
2931
|
+
another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, is slow, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but, unlike the sfx, it is a completely normal zipfile which does not unpack any temporary files to disk, so it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
|
2905
2932
|
|
2906
2933
|
run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
|
2907
2934
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
copyparty/__init__.py,sha256=
|
2
|
-
copyparty/__main__.py,sha256=
|
3
|
-
copyparty/__version__.py,sha256=
|
4
|
-
copyparty/authsrv.py,sha256=
|
1
|
+
copyparty/__init__.py,sha256=SJtQjM-9PP9K-IaoM9M3iNKvRApp0omOrAN6YtXTPNM,2599
|
2
|
+
copyparty/__main__.py,sha256=F9x45nQDLPe4s-QHMQhWhnZsdOqHZ8FuJrs-xN7WKvg,128395
|
3
|
+
copyparty/__version__.py,sha256=efITsXVBc-tiLxawt-9axHNIw551PrdvusgzacjpmRw,249
|
4
|
+
copyparty/authsrv.py,sha256=7DGDYZseSe7ghT9FY5M5dSQaYtkcRQs7Lv5fX0vvPRg,122824
|
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
|
@@ -11,13 +11,13 @@ copyparty/cfg.py,sha256=THceFupFmsZWF8iJKDDHR_XUEU3TNQgDRJB50iLiC1k,15734
|
|
11
11
|
copyparty/dxml.py,sha256=vu5uZQtwvwoqnFHbULs2Zh_y2DETu0T-ENpMZ1i2CV4,2505
|
12
12
|
copyparty/fsutil.py,sha256=NC_CJC4TDag399vVDH9_uQfdfpTMwRFLNxERSWhlVvs,4594
|
13
13
|
copyparty/ftpd.py,sha256=S0w6iMR8AlzLc_Aqn-TKuUJ-vNbmeQF6SQs614-NFOE,18107
|
14
|
-
copyparty/httpcli.py,sha256=
|
14
|
+
copyparty/httpcli.py,sha256=HMEWwIgfSxhNVKLrZeGVa6lqXblDciW7UxiG2tppaYA,232884
|
15
15
|
copyparty/httpconn.py,sha256=IA9fdCjigawZ4kWhgvVN3nSiy5pb3W2qaE6rFqUYdq0,6943
|
16
|
-
copyparty/httpsrv.py,sha256=
|
16
|
+
copyparty/httpsrv.py,sha256=Qyhna6GTIHnmpUBwUicdtDrXGwct8oKap0LqEtGD5X4,18911
|
17
17
|
copyparty/ico.py,sha256=-7QjF_jIxnPo4Vr0oUPksQ_U_Ef0HRsSPm3s71idOz8,3879
|
18
18
|
copyparty/mdns.py,sha256=G73OWWg1copda47LgayCRK7qjVrk6cnUGpMR5ugmi7o,18315
|
19
19
|
copyparty/metrics.py,sha256=1dim0ShnsD5cfspRbeN9Mt14wOIxPRtxCZY2IScikKw,8974
|
20
|
-
copyparty/mtag.py,sha256=
|
20
|
+
copyparty/mtag.py,sha256=uAHixYCzB52dN9rhmRV_As_YX_baL5Ha-oRnTtmDdcg,20053
|
21
21
|
copyparty/multicast.py,sha256=Me4XEEJijvvK2lMRwmGU2hsaI5_E9AEpCjIC4b9UefA,12393
|
22
22
|
copyparty/pwhash.py,sha256=zHoz9FHGkFBxoRvSfG1XyjN3ibww_h5GE6_m5yS-fws,4246
|
23
23
|
copyparty/smbd.py,sha256=Czo8SRkkl4ndCwEUe9Cbr8v0YOnyQHzubGSguPizuTc,14651
|
@@ -26,12 +26,12 @@ copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
|
|
26
26
|
copyparty/sutil.py,sha256=E65jAaOzHlJYnqsOKDMPVT8kALPUVexpkSStWBdItkY,3231
|
27
27
|
copyparty/svchub.py,sha256=lAa-4HfD1LSv3Sn3pOtgLWGHyPhtGDXSCzGvpVB21E0,49140
|
28
28
|
copyparty/szip.py,sha256=9srQzjsTBrBadf6QMh4YRAL70rkZLevAOHqXWK5jvr8,8846
|
29
|
-
copyparty/tcpsrv.py,sha256=
|
29
|
+
copyparty/tcpsrv.py,sha256=AND0QFPs8xD5-Jzr-_KcOa2dYx5AdZPboKo_M0cuh5g,20478
|
30
30
|
copyparty/tftpd.py,sha256=QuPcdx77gLmEpit3lLc0x4Px6BrBBKJpJl4VqINc5O8,14254
|
31
|
-
copyparty/th_cli.py,sha256=
|
32
|
-
copyparty/th_srv.py,sha256=
|
31
|
+
copyparty/th_cli.py,sha256=1tq5yFTSa6ppy9xXuxUsm1SqF7Ps69b0cm4gAGM0vVo,5460
|
32
|
+
copyparty/th_srv.py,sha256=0WyPJRhKhCphGBe3gC53yNrlu0IT7WQ6WaWVSGxzpog,34749
|
33
33
|
copyparty/u2idx.py,sha256=4Y5OOPyVkc-pS0z6e3p4StXAMnjHobSOMmMsvNUTD34,13674
|
34
|
-
copyparty/up2k.py,sha256=
|
34
|
+
copyparty/up2k.py,sha256=lN6jB_hv-dbdDwvm61MLKFTjazLZbQ-buXmh5ANi4UY,179456
|
35
35
|
copyparty/util.py,sha256=XQN86nmxN4RgWWw4k1dIbWeIAR_Dqh_7Z4X9WobwRFI,105732
|
36
36
|
copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
copyparty/bos/bos.py,sha256=DYt5mJJNt-935rU7HRm8kt_whpcVSI0uSphvD7PXrJo,2247
|
@@ -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=MxRofvhXjmUN7RtXtC17_9AlROVNUT-66WwJ_pHLY9c,8258
|
58
|
-
copyparty/web/browser.css.gz,sha256=
|
58
|
+
copyparty/web/browser.css.gz,sha256=Q4tBdkN0TTjrc-NTKrJy3RUoaeh7mJOe7_a95kGKf9M,11767
|
59
59
|
copyparty/web/browser.html,sha256=lhelkXI8_HGfuqo_5b6XEGzf8VNodOMXE9kbv31JtbM,4790
|
60
|
-
copyparty/web/browser.js.gz,sha256=
|
60
|
+
copyparty/web/browser.js.gz,sha256=02kCf8mpq2N7R6Xcl7RVRqLdMepu2tdNhdOglXAOZog,199166
|
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
|
@@ -80,22 +80,17 @@ copyparty/web/shares.html,sha256=ZZ9BIuzhbVtJCAZOb_PAaEY_z9jo8i93QEJolNDHX3g,257
|
|
80
80
|
copyparty/web/shares.js.gz,sha256=KEOx1OxQeEQNHNjsPXCvtWGFIRQSKy_tP7XSvreNCXk,966
|
81
81
|
copyparty/web/splash.css.gz,sha256=S8_A7JJl71xACRBYGzafeaD82OacW6Fa7oKPiNyrhAs,1087
|
82
82
|
copyparty/web/splash.html,sha256=0MvDe1lKfGqczi7d4nKjWjG0cRVyvs8J6sDEj3DCPSI,6376
|
83
|
-
copyparty/web/splash.js.gz,sha256=
|
83
|
+
copyparty/web/splash.js.gz,sha256=FyuMJyupQ-aLk9gemy8U0R6XT83hMRtarvPcKkmjoY0,7766
|
84
84
|
copyparty/web/svcs.html,sha256=mamJdq0hsmHqG2BQsf9jg8G9bAl338wUhUZ2WtXOlGQ,14865
|
85
85
|
copyparty/web/svcs.js.gz,sha256=AYatNKyT_bKRWX8sb3WD_iujBY3L4P7HWBrsuMctsLs,722
|
86
86
|
copyparty/web/ui.css.gz,sha256=e3iIflzddmjoyPrun_1jsu9j7fbdonNQLyhEE2oKKOQ,2819
|
87
87
|
copyparty/web/up2k.js.gz,sha256=aoq6uXrL77zlYQnx9y9VNUVL7YBOHc4u-zFlIrQSX14,24811
|
88
|
-
copyparty/web/util.js.gz,sha256=
|
88
|
+
copyparty/web/util.js.gz,sha256=IpbiLt7QS9o-Yzj_07nwz3SghQWxX69TN5cH-AIhDKU,15512
|
89
89
|
copyparty/web/w.hash.js.gz,sha256=cFH6Xo4YRgH9Wr7RmHMSEfpuTmmIvEmzmSvv4RLmyPU,1193
|
90
90
|
copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
91
91
|
copyparty/web/a/partyfuse.py,sha256=9p5Hpg_IBiSimv7j9kmPhCGpy-FLXSRUOYnLjJ5JifU,28049
|
92
92
|
copyparty/web/a/u2c.py,sha256=f_KR1ZhOjJYBnyYlJbBXY-TnNITeT7HOf0R3pR_9DIM,53248
|
93
93
|
copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
|
94
|
-
copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
|
95
|
-
copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
|
96
|
-
copyparty/web/dd/4.png,sha256=fIwEVmtZNZtloZuVEKPKnkx3SELwRJmB3US61y7t2lI,248
|
97
|
-
copyparty/web/dd/5.png,sha256=Lfpu8-yOlhONuoMbygloKqQVPXSm9gjxH2gUYn5QQAE,250
|
98
|
-
copyparty/web/dd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
99
94
|
copyparty/web/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
100
95
|
copyparty/web/deps/busy.mp3.gz,sha256=EVphk1_HYyRKJmtpeK99vbAstF7ub1f9ndu020H8PQ8,106
|
101
96
|
copyparty/web/deps/easymde.css.gz,sha256=vWxfueI64rPikuqFj69wJBtGisqf93AheQtOZqgUI_c,3041
|
@@ -110,9 +105,9 @@ copyparty/web/deps/prismd.css.gz,sha256=ObUlksQVr-OuYlTz-I4B23TeBg2QDVVGRnWBz8cV
|
|
110
105
|
copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
|
111
106
|
copyparty/web/deps/sha512.ac.js.gz,sha256=lFZaCLumgWxrvEuDr4bqdKHsqjX82AbVAb7_F45Yk88,7033
|
112
107
|
copyparty/web/deps/sha512.hw.js.gz,sha256=UAed2_ocklZCnIzcSYz2h4P1ycztlCLj-ewsRTud2lU,7939
|
113
|
-
copyparty-1.18.
|
114
|
-
copyparty-1.18.
|
115
|
-
copyparty-1.18.
|
116
|
-
copyparty-1.18.
|
117
|
-
copyparty-1.18.
|
118
|
-
copyparty-1.18.
|
108
|
+
copyparty-1.18.10.dist-info/licenses/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
|
109
|
+
copyparty-1.18.10.dist-info/METADATA,sha256=nM2VOQmUUXuiEFQ-Yqkzs-Y4jDYJY4FJS0NOeTEnvyg,169618
|
110
|
+
copyparty-1.18.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
111
|
+
copyparty-1.18.10.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
|
112
|
+
copyparty-1.18.10.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
|
113
|
+
copyparty-1.18.10.dist-info/RECORD,,
|
copyparty/web/dd/2.png
DELETED
Binary file
|
copyparty/web/dd/3.png
DELETED
Binary file
|
copyparty/web/dd/4.png
DELETED
Binary file
|
copyparty/web/dd/5.png
DELETED
Binary file
|
copyparty/web/dd/__init__.py
DELETED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|