copyparty 1.16.19__tar.gz → 1.16.20__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. {copyparty-1.16.19 → copyparty-1.16.20}/PKG-INFO +1 -1
  2. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/__main__.py +1 -0
  3. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/__version__.py +2 -2
  4. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/httpcli.py +6 -6
  5. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/svchub.py +16 -0
  6. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/tcpsrv.py +1 -1
  7. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/th_srv.py +46 -4
  8. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/browser.css.gz +0 -0
  9. copyparty-1.16.20/copyparty/web/browser.js.gz +0 -0
  10. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/splash.html +1 -1
  11. copyparty-1.16.20/copyparty/web/up2k.js.gz +0 -0
  12. copyparty-1.16.20/copyparty/web/util.js.gz +0 -0
  13. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty.egg-info/PKG-INFO +1 -1
  14. copyparty-1.16.19/copyparty/web/browser.js.gz +0 -0
  15. copyparty-1.16.19/copyparty/web/up2k.js.gz +0 -0
  16. copyparty-1.16.19/copyparty/web/util.js.gz +0 -0
  17. {copyparty-1.16.19 → copyparty-1.16.20}/LICENSE +0 -0
  18. {copyparty-1.16.19 → copyparty-1.16.20}/README.md +0 -0
  19. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/__init__.py +0 -0
  20. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/authsrv.py +0 -0
  21. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/bos/__init__.py +0 -0
  22. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/bos/bos.py +0 -0
  23. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/bos/path.py +0 -0
  24. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/broker_mp.py +0 -0
  25. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/broker_mpw.py +0 -0
  26. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/broker_thr.py +0 -0
  27. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/broker_util.py +0 -0
  28. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/cert.py +0 -0
  29. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/cfg.py +0 -0
  30. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/dxml.py +0 -0
  31. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/fsutil.py +0 -0
  32. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/ftpd.py +0 -0
  33. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/httpconn.py +0 -0
  34. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/httpsrv.py +0 -0
  35. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/ico.py +0 -0
  36. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/mdns.py +0 -0
  37. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/metrics.py +0 -0
  38. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/mtag.py +0 -0
  39. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/multicast.py +0 -0
  40. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/pwhash.py +0 -0
  41. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/res/COPYING.txt +0 -0
  42. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/res/__init__.py +0 -0
  43. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/res/insecure.pem +0 -0
  44. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/smbd.py +0 -0
  45. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/ssdp.py +0 -0
  46. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/star.py +0 -0
  47. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/__init__.py +0 -0
  48. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/__init__.py +0 -0
  49. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/bimap.py +0 -0
  50. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/bit.py +0 -0
  51. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/buffer.py +0 -0
  52. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/dns.py +0 -0
  53. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/label.py +0 -0
  54. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/lex.py +0 -0
  55. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/dnslib/ranges.py +0 -0
  56. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/ifaddr/__init__.py +0 -0
  57. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/ifaddr/_posix.py +0 -0
  58. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/ifaddr/_shared.py +0 -0
  59. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/ifaddr/_win32.py +0 -0
  60. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/qrcodegen.py +0 -0
  61. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/stolen/surrogateescape.py +0 -0
  62. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/sutil.py +0 -0
  63. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/szip.py +0 -0
  64. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/tftpd.py +0 -0
  65. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/th_cli.py +0 -0
  66. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/u2idx.py +0 -0
  67. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/up2k.py +0 -0
  68. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/util.py +0 -0
  69. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/a/__init__.py +0 -0
  70. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/a/partyfuse.py +0 -0
  71. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/a/u2c.py +0 -0
  72. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/a/webdav-cfg.bat +0 -0
  73. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/baguettebox.js.gz +0 -0
  74. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/browser.html +0 -0
  75. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/browser2.html +0 -0
  76. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/cf.html +0 -0
  77. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/dbg-audio.js.gz +0 -0
  78. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/dd/2.png +0 -0
  79. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/dd/3.png +0 -0
  80. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/dd/4.png +0 -0
  81. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/dd/5.png +0 -0
  82. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/dd/__init__.py +0 -0
  83. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/__init__.py +0 -0
  84. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/busy.mp3.gz +0 -0
  85. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/easymde.css.gz +0 -0
  86. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/easymde.js.gz +0 -0
  87. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/fuse.py +0 -0
  88. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/marked.js.gz +0 -0
  89. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/mini-fa.css.gz +0 -0
  90. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/mini-fa.woff +0 -0
  91. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/prism.css.gz +0 -0
  92. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/prism.js.gz +0 -0
  93. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/prismd.css.gz +0 -0
  94. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/scp.woff2 +0 -0
  95. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/sha512.ac.js.gz +0 -0
  96. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/deps/sha512.hw.js.gz +0 -0
  97. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/md.css.gz +0 -0
  98. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/md.html +0 -0
  99. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/md.js.gz +0 -0
  100. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/md2.css.gz +0 -0
  101. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/md2.js.gz +0 -0
  102. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/mde.css.gz +0 -0
  103. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/mde.html +0 -0
  104. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/mde.js.gz +0 -0
  105. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/msg.css.gz +0 -0
  106. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/msg.html +0 -0
  107. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/rups.css.gz +0 -0
  108. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/rups.html +0 -0
  109. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/rups.js.gz +0 -0
  110. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/shares.css.gz +0 -0
  111. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/shares.html +0 -0
  112. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/shares.js.gz +0 -0
  113. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/splash.css.gz +0 -0
  114. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/splash.js.gz +0 -0
  115. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/svcs.html +0 -0
  116. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/svcs.js.gz +0 -0
  117. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/ui.css.gz +0 -0
  118. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty/web/w.hash.js.gz +0 -0
  119. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty.egg-info/SOURCES.txt +0 -0
  120. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty.egg-info/dependency_links.txt +0 -0
  121. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty.egg-info/entry_points.txt +0 -0
  122. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty.egg-info/requires.txt +0 -0
  123. {copyparty-1.16.19 → copyparty-1.16.20}/copyparty.egg-info/top_level.txt +0 -0
  124. {copyparty-1.16.19 → copyparty-1.16.20}/pyproject.toml +0 -0
  125. {copyparty-1.16.19 → copyparty-1.16.20}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copyparty
3
- Version: 1.16.19
3
+ Version: 1.16.20
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
@@ -1369,6 +1369,7 @@ def add_thumbnail(ap):
1369
1369
  ap2.add_argument("--th-r-ffi", metavar="T,T", type=u, default="apng,avif,avifs,bmp,cbz,dds,dib,fit,fits,fts,gif,hdr,heic,heics,heif,heifs,icns,ico,jp2,jpeg,jpg,jpx,jxl,pbm,pcx,pfm,pgm,png,pnm,ppm,psd,qoi,sgi,tga,tif,tiff,webp,xbm,xpm", help="image formats to decode using ffmpeg")
1370
1370
  ap2.add_argument("--th-r-ffv", metavar="T,T", type=u, default="3gp,asf,av1,avc,avi,flv,h264,h265,hevc,m4v,mjpeg,mjpg,mkv,mov,mp4,mpeg,mpeg2,mpegts,mpg,mpg2,mts,nut,ogm,ogv,rm,ts,vob,webm,wmv", help="video formats to decode using ffmpeg")
1371
1371
  ap2.add_argument("--th-r-ffa", metavar="T,T", type=u, default="aac,ac3,aif,aiff,alac,alaw,amr,apac,ape,au,bonk,dfpwm,dts,flac,gsm,ilbc,it,itgz,itxz,itz,m4a,mdgz,mdxz,mdz,mo3,mod,mp2,mp3,mpc,mptm,mt2,mulaw,ogg,okt,opus,ra,s3m,s3gz,s3xz,s3z,tak,tta,ulaw,wav,wma,wv,xm,xmgz,xmxz,xmz,xpk", help="audio formats to decode using ffmpeg")
1372
+ ap2.add_argument("--th-spec-cnv", metavar="T,T", type=u, default="it,itgz,itxz,itz,mdgz,mdxz,mdz,mo3,mod,s3m,s3gz,s3xz,s3z,xm,xmgz,xmxz,xmz,xpk", help="audio formats which provoke https://trac.ffmpeg.org/ticket/10797 (huge ram usage for s3xmodit spectrograms)")
1372
1373
  ap2.add_argument("--au-unpk", metavar="E=F.C", type=u, default="mdz=mod.zip, mdgz=mod.gz, mdxz=mod.xz, s3z=s3m.zip, s3gz=s3m.gz, s3xz=s3m.xz, xmz=xm.zip, xmgz=xm.gz, xmxz=xm.xz, itz=it.zip, itgz=it.gz, itxz=it.xz, cbz=jpg.cbz", help="audio/image formats to decompress before passing to ffmpeg")
1373
1374
 
1374
1375
 
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 16, 19)
3
+ VERSION = (1, 16, 20)
4
4
  CODENAME = "COPYparty"
5
- BUILD_DT = (2025, 4, 8)
5
+ BUILD_DT = (2025, 4, 13)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
@@ -1201,11 +1201,6 @@ class HttpCli(object):
1201
1201
  else:
1202
1202
  return self.tx_res(res_path)
1203
1203
 
1204
- if res_path != undot(res_path):
1205
- t = "malicious user; attempted path traversal; req(%r) vp(%r) => %r"
1206
- self.log(t % (self.req, "/" + self.vpath, res_path), 1)
1207
- self.cbonk(self.conn.hsrv.gmal, self.req, "trav", "path traversal")
1208
-
1209
1204
  self.tx_404()
1210
1205
  return False
1211
1206
 
@@ -4231,6 +4226,7 @@ class HttpCli(object):
4231
4226
  self.log(t % (data_end / M, lower / M, upper / M), 6)
4232
4227
  with self.u2mutex:
4233
4228
  if data_end > self.u2fh.aps.get(ap_data, data_end):
4229
+ fhs = None
4234
4230
  try:
4235
4231
  fhs = self.u2fh.cache[ap_data].all_fhs
4236
4232
  for fh in fhs:
@@ -4238,7 +4234,11 @@ class HttpCli(object):
4238
4234
  self.u2fh.aps[ap_data] = data_end
4239
4235
  self.log("pipe: flushed %d up2k-FDs" % (len(fhs),))
4240
4236
  except Exception as ex:
4241
- self.log("pipe: u2fh flush failed: %r" % (ex,))
4237
+ if fhs is None:
4238
+ err = "file is not being written to right now"
4239
+ else:
4240
+ err = repr(ex)
4241
+ self.log("pipe: u2fh flush failed: " + err)
4242
4242
 
4243
4243
  if lower >= data_end:
4244
4244
  if data_end:
@@ -760,6 +760,7 @@ class SvcHub(object):
760
760
  self.log("optional-dependencies", t, 6)
761
761
 
762
762
  def _check_env(self) :
763
+ al = self.args
763
764
  try:
764
765
  files = os.listdir(E.cfg)
765
766
  except:
@@ -776,6 +777,21 @@ class SvcHub(object):
776
777
  if self.args.bauth_last:
777
778
  self.log("root", "WARNING: ignoring --bauth-last due to --no-bauth", 3)
778
779
 
780
+ have_tcp = False
781
+ for zs in al.i:
782
+ if not zs.startswith("unix:"):
783
+ have_tcp = True
784
+ if not have_tcp:
785
+ zb = False
786
+ zs = "z zm zm4 zm6 zmv zmvv zs zsv zv"
787
+ for zs in zs.split():
788
+ if getattr(al, zs, False):
789
+ setattr(al, zs, False)
790
+ zb = True
791
+ if zb:
792
+ t = "only listening on unix-sockets; cannot enable zeroconf/mdns/ssdp as requested"
793
+ self.log("root", t, 3)
794
+
779
795
  if not self.args.no_dav:
780
796
  from .dxml import DXML_OK
781
797
 
@@ -563,7 +563,7 @@ class TcpSrv(object):
563
563
  ip = None
564
564
  ips = list(t1) + list(t2)
565
565
  qri = self.args.qri
566
- if self.args.zm and not qri:
566
+ if self.args.zm and not qri and ips:
567
567
  name = self.args.name + ".local"
568
568
  t1[name] = next(v for v in (t1 or t2).values())
569
569
  ips = [name] + ips
@@ -7,6 +7,7 @@ import os
7
7
  import re
8
8
  import shutil
9
9
  import subprocess as sp
10
+ import tempfile
10
11
  import threading
11
12
  import time
12
13
 
@@ -19,6 +20,7 @@ from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, au_unpk, ffprobe
19
20
  from .util import BytesIO # type: ignore
20
21
  from .util import (
21
22
  FFMPEG_URL,
23
+ VF_CAREFUL,
22
24
  Cooldown,
23
25
  Daemon,
24
26
  afsenc,
@@ -46,6 +48,7 @@ HAVE_WEBP = False
46
48
 
47
49
  EXTS_TH = set(["jpg", "webp", "png"])
48
50
  EXTS_AC = set(["opus", "owa", "caf", "mp3"])
51
+ EXTS_SPEC_SAFE = set("aif aiff flac mp3 opus wav".split())
49
52
 
50
53
  PTN_TS = re.compile("^-?[0-9a-f]{8,10}$")
51
54
 
@@ -164,12 +167,15 @@ class ThumbSrv(object):
164
167
 
165
168
  self.mutex = threading.Lock()
166
169
  self.busy = {}
170
+ self.untemp = {}
167
171
  self.ram = {}
168
172
  self.memcond = threading.Condition(self.mutex)
169
173
  self.stopping = False
170
174
  self.rm_nullthumbs = True # forget failed conversions on startup
171
175
  self.nthr = max(1, self.args.th_mt)
172
176
 
177
+ self.exts_spec_unsafe = set(self.args.th_spec_cnv.split(","))
178
+
173
179
  self.q = Queue(self.nthr * 4)
174
180
  for n in range(self.nthr):
175
181
  Daemon(self.worker, "thumb-{}-{}".format(n, self.nthr))
@@ -410,10 +416,18 @@ class ThumbSrv(object):
410
416
  self.log(t % (ttpath, tpath, ex), 3)
411
417
  pass
412
418
 
419
+ untemp = []
413
420
  with self.mutex:
414
421
  subs = self.busy[tpath]
415
422
  del self.busy[tpath]
416
423
  self.ram.pop(ttpath, None)
424
+ untemp = self.untemp.pop(ttpath, None) or []
425
+
426
+ for ap in untemp:
427
+ try:
428
+ wunlink(self.log, ap, VF_CAREFUL)
429
+ except:
430
+ pass
417
431
 
418
432
  for x in subs:
419
433
  with x:
@@ -666,15 +680,43 @@ class ThumbSrv(object):
666
680
  if "ac" not in ret:
667
681
  raise Exception("not audio")
668
682
 
683
+ fext = abspath.split(".")[-1].lower()
684
+
669
685
  # https://trac.ffmpeg.org/ticket/10797
670
686
  # expect 1 GiB every 600 seconds when duration is tricky;
671
687
  # simple filetypes are generally safer so let's special-case those
672
- safe = ("flac", "wav", "aif", "aiff", "opus")
673
- coeff = 1800 if abspath.split(".")[-1].lower() in safe else 600
674
- dur = ret[".dur"][1] if ".dur" in ret else 300
688
+ coeff = 1800 if fext in EXTS_SPEC_SAFE else 600
689
+ dur = ret[".dur"][1] if ".dur" in ret else 900
675
690
  need = 0.2 + dur / coeff
676
691
  self.wait4ram(need, tpath)
677
692
 
693
+ infile = abspath
694
+ if dur >= 900 or fext in self.exts_spec_unsafe:
695
+ with tempfile.NamedTemporaryFile(suffix=".spec.flac", delete=False) as f:
696
+ f.write(b"h")
697
+ infile = f.name
698
+ try:
699
+ self.untemp[tpath].append(infile)
700
+ except:
701
+ self.untemp[tpath] = [infile]
702
+
703
+ # fmt: off
704
+ cmd = [
705
+ b"ffmpeg",
706
+ b"-nostdin",
707
+ b"-v", b"error",
708
+ b"-hide_banner",
709
+ b"-i", fsenc(abspath),
710
+ b"-map", b"0:a:0",
711
+ b"-ac", b"1",
712
+ b"-ar", b"48000",
713
+ b"-sample_fmt", b"s16",
714
+ b"-t", b"900",
715
+ b"-y", fsenc(infile),
716
+ ]
717
+ # fmt: on
718
+ self._run_ff(cmd, vn)
719
+
678
720
  fc = "[0:a:0]aresample=48000{},showspectrumpic=s="
679
721
  if "3" in fmt:
680
722
  fc += "1280x1024,crop=1420:1056:70:48[o]"
@@ -694,7 +736,7 @@ class ThumbSrv(object):
694
736
  b"-nostdin",
695
737
  b"-v", b"error",
696
738
  b"-hide_banner",
697
- b"-i", fsenc(abspath),
739
+ b"-i", fsenc(infile),
698
740
  b"-filter_complex", fc.encode("utf-8"),
699
741
  b"-map", b"[o]",
700
742
  b"-frames:v", b"1",
@@ -122,7 +122,7 @@
122
122
  <input type="hidden" id="la" name="act" value="login" />
123
123
  <input type="password" id="lp" name="cppwd" placeholder=" password" />
124
124
  <input type="hidden" name="uhash" id="uhash" value="x" />
125
- <input type="submit" id="ls" value="Login" />
125
+ <input type="submit" id="ls" value="login" />
126
126
  {% if chpw %}
127
127
  <a id="x" href="#">change password</a>
128
128
  {% endif %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copyparty
3
- Version: 1.16.19
3
+ Version: 1.16.20
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
Binary file
Binary file
File without changes
File without changes
File without changes
File without changes