copyparty 1.19.15__py3-none-any.whl → 1.19.17__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 +19 -0
- copyparty/__main__.py +47 -11
- copyparty/__version__.py +2 -2
- copyparty/authsrv.py +45 -9
- copyparty/bos/bos.py +5 -1
- copyparty/cfg.py +20 -0
- copyparty/ftpd.py +5 -3
- copyparty/httpcli.py +114 -27
- copyparty/mdns.py +53 -18
- copyparty/mtag.py +18 -4
- copyparty/qrkode.py +107 -0
- copyparty/res/COPYING.txt +76 -5
- copyparty/smbd.py +1 -1
- copyparty/stolen/qrcodegen.py +1 -64
- copyparty/svchub.py +13 -2
- copyparty/tcpsrv.py +6 -7
- copyparty/tftpd.py +1 -1
- copyparty/th_srv.py +11 -5
- copyparty/up2k.py +40 -16
- copyparty/util.py +63 -16
- copyparty/web/baguettebox.js.gz +0 -0
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.html +3 -1
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/splash.html +3 -0
- copyparty/web/splash.js.gz +0 -0
- copyparty/web/tl/chi.js.gz +0 -0
- copyparty/web/tl/cze.js.gz +0 -0
- copyparty/web/tl/deu.js.gz +0 -0
- copyparty/web/tl/epo.js.gz +0 -0
- copyparty/web/tl/fin.js.gz +0 -0
- copyparty/web/tl/fra.js.gz +0 -0
- copyparty/web/tl/grc.js.gz +0 -0
- copyparty/web/tl/ita.js.gz +0 -0
- copyparty/web/tl/kor.js.gz +0 -0
- copyparty/web/tl/nld.js.gz +0 -0
- copyparty/web/tl/nno.js.gz +0 -0
- copyparty/web/tl/nor.js.gz +0 -0
- copyparty/web/tl/pol.js.gz +0 -0
- copyparty/web/tl/por.js.gz +0 -0
- copyparty/web/tl/rus.js.gz +0 -0
- copyparty/web/tl/spa.js.gz +0 -0
- copyparty/web/tl/swe.js.gz +0 -0
- copyparty/web/tl/tur.js.gz +0 -0
- copyparty/web/tl/ukr.js.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.19.15.dist-info → copyparty-1.19.17.dist-info}/METADATA +47 -2
- {copyparty-1.19.15.dist-info → copyparty-1.19.17.dist-info}/RECORD +52 -32
- {copyparty-1.19.15.dist-info → copyparty-1.19.17.dist-info}/WHEEL +0 -0
- {copyparty-1.19.15.dist-info → copyparty-1.19.17.dist-info}/entry_points.txt +0 -0
- {copyparty-1.19.15.dist-info → copyparty-1.19.17.dist-info}/licenses/LICENSE +0 -0
- {copyparty-1.19.15.dist-info → copyparty-1.19.17.dist-info}/top_level.txt +0 -0
copyparty/res/COPYING.txt
CHANGED
|
@@ -6,15 +6,15 @@ License: MIT
|
|
|
6
6
|
|
|
7
7
|
https://github.com/pallets/jinja/
|
|
8
8
|
Copyright (c) 2007 Pallets
|
|
9
|
-
License: BSD
|
|
9
|
+
License: BSD-3-Clause
|
|
10
10
|
|
|
11
11
|
https://github.com/pallets/markupsafe/
|
|
12
12
|
Copyright (c) 2010 Pallets
|
|
13
|
-
License: BSD
|
|
13
|
+
License: BSD-3-Clause
|
|
14
14
|
|
|
15
15
|
https://github.com/paulc/dnslib/
|
|
16
16
|
Copyright (c) 2010-2017 Paul Chakravarti
|
|
17
|
-
License: BSD
|
|
17
|
+
License: BSD-2-Clause
|
|
18
18
|
|
|
19
19
|
https://github.com/pydron/ifaddr/
|
|
20
20
|
Copyright (c) 2014 Stefan C. Mueller
|
|
@@ -36,6 +36,10 @@ https://github.com/ahupp/python-magic/
|
|
|
36
36
|
Copyright (c) 2001-2014 Adam Hupp
|
|
37
37
|
License: MIT
|
|
38
38
|
|
|
39
|
+
https://github.com/fusepy/fusepy
|
|
40
|
+
Copyright (c) 2012 Giorgos Verigakis
|
|
41
|
+
License: ISC
|
|
42
|
+
|
|
39
43
|
[07m--- client-side --- software ---[0m
|
|
40
44
|
|
|
41
45
|
https://github.com/Daninet/hash-wasm/
|
|
@@ -50,6 +54,10 @@ https://github.com/feimosi/baguetteBox.js/
|
|
|
50
54
|
Copyright (c) 2017 Marek Grzybek
|
|
51
55
|
License: MIT
|
|
52
56
|
|
|
57
|
+
https://github.com/cure53/DOMPurify/
|
|
58
|
+
Copyright (c) 2025 Cure53 / Mario Heiderich
|
|
59
|
+
License: Apache-2.0 or MPL-2.0
|
|
60
|
+
|
|
53
61
|
https://github.com/markedjs/marked/
|
|
54
62
|
Copyright (c) 2018+, MarkedJS
|
|
55
63
|
Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/)
|
|
@@ -68,11 +76,11 @@ License: MIT
|
|
|
68
76
|
|
|
69
77
|
https://github.com/adobe-fonts/source-code-pro/
|
|
70
78
|
Copyright (c) 2010-2019 Adobe
|
|
71
|
-
License:
|
|
79
|
+
License: OFL-1.1
|
|
72
80
|
|
|
73
81
|
https://github.com/FortAwesome/Font-Awesome/
|
|
74
82
|
Copyright (c) 2022 Fonticons, Inc.
|
|
75
|
-
License:
|
|
83
|
+
License: OFL-1.1
|
|
76
84
|
|
|
77
85
|
|
|
78
86
|
|
|
@@ -108,6 +116,69 @@ Redistribution and use in source and binary forms, with or without modification,
|
|
|
108
116
|
|
|
109
117
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
110
118
|
|
|
119
|
+
[07m--- ISC License ---[0m
|
|
120
|
+
|
|
121
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
122
|
+
|
|
123
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
124
|
+
|
|
125
|
+
[07m--- Apache License v2.0 ---[0m
|
|
126
|
+
|
|
127
|
+
Apache License
|
|
128
|
+
Version 2.0, January 2004
|
|
129
|
+
http://www.apache.org/licenses/
|
|
130
|
+
|
|
131
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
132
|
+
|
|
133
|
+
1. Definitions.
|
|
134
|
+
|
|
135
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
|
136
|
+
|
|
137
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
|
138
|
+
|
|
139
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
|
140
|
+
|
|
141
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
|
142
|
+
|
|
143
|
+
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
|
144
|
+
|
|
145
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
|
146
|
+
|
|
147
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
|
148
|
+
|
|
149
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
|
150
|
+
|
|
151
|
+
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
|
152
|
+
|
|
153
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
|
154
|
+
|
|
155
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
|
156
|
+
|
|
157
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
|
158
|
+
|
|
159
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
|
160
|
+
|
|
161
|
+
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
|
162
|
+
|
|
163
|
+
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
|
164
|
+
|
|
165
|
+
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
|
166
|
+
|
|
167
|
+
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
|
168
|
+
|
|
169
|
+
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
|
170
|
+
|
|
171
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
|
172
|
+
|
|
173
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
|
174
|
+
|
|
175
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
|
176
|
+
|
|
177
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
|
178
|
+
|
|
179
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
|
180
|
+
|
|
181
|
+
|
|
111
182
|
[07m--- SIL Open Font License v1.1 ---[0m
|
|
112
183
|
|
|
113
184
|
PREAMBLE
|
copyparty/smbd.py
CHANGED
copyparty/stolen/qrcodegen.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# https://github.com/nayuki/QR-Code-generator/blob/daa3114/python/qrcodegen.py
|
|
5
5
|
# the original ^ is extremely well commented so refer to that for explanations
|
|
6
6
|
|
|
7
|
-
# hacks: binary-only, auto-ecc,
|
|
7
|
+
# hacks: binary-only, auto-ecc, py2-compat
|
|
8
8
|
|
|
9
9
|
from __future__ import print_function, unicode_literals
|
|
10
10
|
|
|
@@ -168,52 +168,6 @@ class QrCode(object):
|
|
|
168
168
|
self._apply_mask(msk) # Apply the final choice of mask
|
|
169
169
|
self._draw_format_bits(msk) # Overwrite old format bits
|
|
170
170
|
|
|
171
|
-
def render(self, zoom=1, pad=4) :
|
|
172
|
-
tab = self.modules
|
|
173
|
-
sz = self.size
|
|
174
|
-
if sz % 2 and zoom == 1:
|
|
175
|
-
tab.append([False] * sz)
|
|
176
|
-
|
|
177
|
-
tab = [[False] * sz] * pad + tab + [[False] * sz] * pad
|
|
178
|
-
tab = [[False] * pad + x + [False] * pad for x in tab]
|
|
179
|
-
|
|
180
|
-
rows = []
|
|
181
|
-
if zoom == 1:
|
|
182
|
-
for y in range(0, len(tab), 2):
|
|
183
|
-
row = ""
|
|
184
|
-
for x in range(len(tab[y])):
|
|
185
|
-
v = 2 if tab[y][x] else 0
|
|
186
|
-
v += 1 if tab[y + 1][x] else 0
|
|
187
|
-
row += " ▄▀█"[v]
|
|
188
|
-
rows.append(row)
|
|
189
|
-
else:
|
|
190
|
-
for tr in tab:
|
|
191
|
-
row = ""
|
|
192
|
-
for zb in tr:
|
|
193
|
-
row += " █"[int(zb)] * 2
|
|
194
|
-
rows.append(row)
|
|
195
|
-
|
|
196
|
-
return "\n".join(rows)
|
|
197
|
-
|
|
198
|
-
def to_png(self, zoom, pad, bg, fg, ap) :
|
|
199
|
-
from PIL import Image
|
|
200
|
-
|
|
201
|
-
tab = self.modules
|
|
202
|
-
sz = self.size
|
|
203
|
-
psz = sz + pad * 2
|
|
204
|
-
if bg:
|
|
205
|
-
img = Image.new("RGB", (psz, psz), bg)
|
|
206
|
-
else:
|
|
207
|
-
img = Image.new("RGBA", (psz, psz), (0, 0, 0, 0))
|
|
208
|
-
fg = (fg[0], fg[1], fg[2], 255)
|
|
209
|
-
for y in range(sz):
|
|
210
|
-
for x in range(sz):
|
|
211
|
-
if tab[y][x]:
|
|
212
|
-
img.putpixel((x + pad, y + pad), fg)
|
|
213
|
-
if zoom != 1:
|
|
214
|
-
img = img.resize((sz * zoom, sz * zoom), Image.Resampling.NEAREST)
|
|
215
|
-
img.save(ap)
|
|
216
|
-
|
|
217
171
|
def _draw_function_patterns(self) :
|
|
218
172
|
# Draw horizontal and vertical timing patterns
|
|
219
173
|
for i in range(self.size):
|
|
@@ -608,20 +562,3 @@ def _get_bit(x , i ) :
|
|
|
608
562
|
|
|
609
563
|
class DataTooLongError(ValueError):
|
|
610
564
|
pass
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
def qr2svg(qr , border ) :
|
|
614
|
-
parts = []
|
|
615
|
-
for y in range(qr.size):
|
|
616
|
-
sy = border + y
|
|
617
|
-
for x in range(qr.size):
|
|
618
|
-
if qr.modules[y][x]:
|
|
619
|
-
parts.append("M%d,%dh1v1h-1z" % (border + x, sy))
|
|
620
|
-
t = """\
|
|
621
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
622
|
-
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 {0} {0}" stroke="none">
|
|
623
|
-
<rect width="100%" height="100%" fill="#F7F7F7"/>
|
|
624
|
-
<path d="{1}" fill="#111111"/>
|
|
625
|
-
</svg>
|
|
626
|
-
"""
|
|
627
|
-
return t.format(qr.size + border * 2, " ".join(parts))
|
copyparty/svchub.py
CHANGED
|
@@ -61,6 +61,7 @@ from .util import (
|
|
|
61
61
|
build_netmap,
|
|
62
62
|
expat_ver,
|
|
63
63
|
gzip,
|
|
64
|
+
html_escape,
|
|
64
65
|
load_ipr,
|
|
65
66
|
load_ipu,
|
|
66
67
|
lock_file,
|
|
@@ -241,8 +242,8 @@ class SvcHub(object):
|
|
|
241
242
|
t = "WARNING: --th-ram-max is very small (%.2f GiB); will not be able to %s"
|
|
242
243
|
self.log("root", t % (args.th_ram_max, zs), 3)
|
|
243
244
|
|
|
244
|
-
if args.chpw and args.have_idp_hdrs:
|
|
245
|
-
t = "ERROR: user-changeable passwords is
|
|
245
|
+
if args.chpw and args.have_idp_hdrs and "pw" not in args.auth_ord.split(","):
|
|
246
|
+
t = "ERROR: user-changeable passwords is not compatible with your current configuration. Choose one of these options to fix it:\n option1: disable --chpw\n option2: remove all use of IdP features; --idp-*\n option3: change --auth-ord to something like pw,idp,ipu"
|
|
246
247
|
self.log("root", t, 1)
|
|
247
248
|
raise Exception(t)
|
|
248
249
|
|
|
@@ -284,6 +285,9 @@ class SvcHub(object):
|
|
|
284
285
|
ch = "abcdefghijklmnopqrstuvwx"[int(args.theme / 2)]
|
|
285
286
|
args.theme = "{0}{1} {0} {1}".format(ch, bri)
|
|
286
287
|
|
|
288
|
+
if args.no_stack:
|
|
289
|
+
args.stack_who = "no"
|
|
290
|
+
|
|
287
291
|
if args.nid:
|
|
288
292
|
args.du_who = "no"
|
|
289
293
|
args.du_iwho = n_du_who(args.du_who)
|
|
@@ -1161,6 +1165,13 @@ class SvcHub(object):
|
|
|
1161
1165
|
if len(al.tcolor) == 3: # fc5 => ffcc55
|
|
1162
1166
|
al.tcolor = "".join([x * 2 for x in al.tcolor])
|
|
1163
1167
|
|
|
1168
|
+
if self.args.name_url:
|
|
1169
|
+
zs = html_escape(self.args.name_url, True, True)
|
|
1170
|
+
zs = '<a href="%s">%s</a>' % (zs, self.args.name)
|
|
1171
|
+
else:
|
|
1172
|
+
zs = self.args.name
|
|
1173
|
+
self.args.name_html = zs
|
|
1174
|
+
|
|
1164
1175
|
zs = al.u2sz
|
|
1165
1176
|
zsl = [x.strip() for x in zs.split(",")]
|
|
1166
1177
|
if len(zsl) not in (1, 3):
|
copyparty/tcpsrv.py
CHANGED
|
@@ -9,7 +9,7 @@ import time
|
|
|
9
9
|
|
|
10
10
|
from .__init__ import ANYWIN, PY2, TYPE_CHECKING, unicode
|
|
11
11
|
from .cert import gencert
|
|
12
|
-
from .
|
|
12
|
+
from .qrkode import QrCode, qr2png, qr2svg, qr2txt, qrgen
|
|
13
13
|
from .util import (
|
|
14
14
|
E_ACCESS,
|
|
15
15
|
E_ADDR_IN_USE,
|
|
@@ -21,6 +21,7 @@ from .util import (
|
|
|
21
21
|
VF_CAREFUL,
|
|
22
22
|
Netdev,
|
|
23
23
|
atomic_move,
|
|
24
|
+
get_adapters,
|
|
24
25
|
min_ex,
|
|
25
26
|
sunpack,
|
|
26
27
|
termsize,
|
|
@@ -453,8 +454,6 @@ class TcpSrv(object):
|
|
|
453
454
|
self._distribute_netdevs()
|
|
454
455
|
|
|
455
456
|
def detect_interfaces(self, listen_ips ) :
|
|
456
|
-
from .stolen.ifaddr import get_adapters
|
|
457
|
-
|
|
458
457
|
listen_ips = [x for x in listen_ips if not x.startswith(("unix:", "fd:"))]
|
|
459
458
|
|
|
460
459
|
nics = get_adapters(True)
|
|
@@ -627,7 +626,7 @@ class TcpSrv(object):
|
|
|
627
626
|
|
|
628
627
|
pad = self.args.qrp
|
|
629
628
|
zoom = self.args.qrz
|
|
630
|
-
qrc =
|
|
629
|
+
qrc = qrgen(btxt)
|
|
631
630
|
|
|
632
631
|
for zs in self.args.qr_file or []:
|
|
633
632
|
self._qr2file(qrc, zs)
|
|
@@ -640,7 +639,7 @@ class TcpSrv(object):
|
|
|
640
639
|
except:
|
|
641
640
|
zoom = 1
|
|
642
641
|
|
|
643
|
-
qr = qrc
|
|
642
|
+
qr = qr2txt(qrc, zoom, pad)
|
|
644
643
|
if self.args.no_ansi:
|
|
645
644
|
return "{}\n{}".format(txt, qr)
|
|
646
645
|
|
|
@@ -681,12 +680,12 @@ class TcpSrv(object):
|
|
|
681
680
|
if zoom not in (1, 2):
|
|
682
681
|
raise Exception("invalid zoom for qr.txt; must be 1 or 2")
|
|
683
682
|
with open(ap, "wb") as f:
|
|
684
|
-
f.write(qrc
|
|
683
|
+
f.write(qr2txt(qrc, zoom, pad).encode("utf-8"))
|
|
685
684
|
elif ap.endswith(".svg"):
|
|
686
685
|
with open(ap, "wb") as f:
|
|
687
686
|
f.write(qr2svg(qrc, pad).encode("utf-8"))
|
|
688
687
|
else:
|
|
689
|
-
qrc
|
|
688
|
+
qr2png(qrc, zoom, pad, self._h2i(bg), self._h2i(fg), ap)
|
|
690
689
|
|
|
691
690
|
def _h2i(self, hs):
|
|
692
691
|
try:
|
copyparty/tftpd.py
CHANGED
copyparty/th_srv.py
CHANGED
|
@@ -378,7 +378,7 @@ class ThumbSrv(object):
|
|
|
378
378
|
else:
|
|
379
379
|
ap_unpk = abspath
|
|
380
380
|
|
|
381
|
-
if not bos.path.exists(tpath):
|
|
381
|
+
if ap_unpk and not bos.path.exists(tpath):
|
|
382
382
|
tex = tpath.rsplit(".", 1)[-1]
|
|
383
383
|
want_mp3 = tex == "mp3"
|
|
384
384
|
want_opus = tex in ("opus", "owa", "caf")
|
|
@@ -421,12 +421,14 @@ class ThumbSrv(object):
|
|
|
421
421
|
except:
|
|
422
422
|
pass
|
|
423
423
|
|
|
424
|
+
conv_ok = False
|
|
424
425
|
for fun in funs:
|
|
425
426
|
try:
|
|
426
427
|
if not png_ok and tpath.endswith(".png"):
|
|
427
428
|
raise Exception("png only allowed for waveforms")
|
|
428
429
|
|
|
429
430
|
fun(ap_unpk, ttpath, fmt, vn)
|
|
431
|
+
conv_ok = True
|
|
430
432
|
break
|
|
431
433
|
except Exception as ex:
|
|
432
434
|
msg = "%s could not create thumbnail of %r\n%s"
|
|
@@ -448,16 +450,20 @@ class ThumbSrv(object):
|
|
|
448
450
|
except:
|
|
449
451
|
pass
|
|
450
452
|
|
|
451
|
-
if abspath != ap_unpk:
|
|
453
|
+
if abspath != ap_unpk and ap_unpk:
|
|
452
454
|
wunlink(self.log, ap_unpk, vn.flags)
|
|
453
455
|
|
|
454
456
|
try:
|
|
455
457
|
atomic_move(self.log, ttpath, tpath, vn.flags)
|
|
456
458
|
except Exception as ex:
|
|
457
|
-
if not os.path.exists(tpath):
|
|
459
|
+
if conv_ok and not os.path.exists(tpath):
|
|
458
460
|
t = "failed to move [%s] to [%s]: %r"
|
|
459
461
|
self.log(t % (ttpath, tpath, ex), 3)
|
|
460
|
-
|
|
462
|
+
elif not conv_ok:
|
|
463
|
+
try:
|
|
464
|
+
open(tpath, "ab").close()
|
|
465
|
+
except:
|
|
466
|
+
pass
|
|
461
467
|
|
|
462
468
|
untemp = []
|
|
463
469
|
with self.mutex:
|
|
@@ -677,7 +683,7 @@ class ThumbSrv(object):
|
|
|
677
683
|
return
|
|
678
684
|
|
|
679
685
|
c = "90"
|
|
680
|
-
t = "FFmpeg failed (probably a corrupt
|
|
686
|
+
t = "FFmpeg failed (probably a corrupt file):\n"
|
|
681
687
|
if (
|
|
682
688
|
(not self.args.th_ff_jpg or time.time() - int(self.args.th_ff_jpg) < 60)
|
|
683
689
|
and cmd[-1].lower().endswith(b".webp")
|
copyparty/up2k.py
CHANGED
|
@@ -10,6 +10,7 @@ import re
|
|
|
10
10
|
import shutil
|
|
11
11
|
import stat
|
|
12
12
|
import subprocess as sp
|
|
13
|
+
import sys
|
|
13
14
|
import tempfile
|
|
14
15
|
import threading
|
|
15
16
|
import time
|
|
@@ -27,6 +28,7 @@ from .mtag import MParser, MTag
|
|
|
27
28
|
from .util import (
|
|
28
29
|
E_FS_CRIT,
|
|
29
30
|
E_FS_MEH,
|
|
31
|
+
HAVE_FICLONE,
|
|
30
32
|
HAVE_SQLITE3,
|
|
31
33
|
SYMTIME,
|
|
32
34
|
VF_CAREFUL,
|
|
@@ -85,13 +87,17 @@ DB_VER = 6
|
|
|
85
87
|
if TYPE_CHECKING:
|
|
86
88
|
from .svchub import SvcHub
|
|
87
89
|
|
|
90
|
+
USE_FICLONE = HAVE_FICLONE and sys.version_info < (3, 14)
|
|
91
|
+
if USE_FICLONE:
|
|
92
|
+
import fcntl
|
|
93
|
+
|
|
88
94
|
zsg = "avif,avifs,bmp,gif,heic,heics,heif,heifs,ico,j2p,j2k,jp2,jpeg,jpg,jpx,png,tga,tif,tiff,webp"
|
|
89
95
|
ICV_EXTS = set(zsg.split(","))
|
|
90
96
|
|
|
91
97
|
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"
|
|
92
98
|
VCV_EXTS = set(zsg.split(","))
|
|
93
99
|
|
|
94
|
-
zsg = "aif,aiff,alac,ape,flac,m4a,mp3,oga,ogg,opus,tak,tta,wav,wma,wv"
|
|
100
|
+
zsg = "aif,aiff,alac,ape,flac,m4a,mp3,oga,ogg,opus,tak,tta,wav,wma,wv,cbz,epub"
|
|
95
101
|
ACV_EXTS = set(zsg.split(","))
|
|
96
102
|
|
|
97
103
|
zsg = "nohash noidx xdev xvol"
|
|
@@ -3282,7 +3288,7 @@ class Up2k(object):
|
|
|
3282
3288
|
job["size"],
|
|
3283
3289
|
job["addr"],
|
|
3284
3290
|
job["at"],
|
|
3285
|
-
|
|
3291
|
+
None,
|
|
3286
3292
|
)
|
|
3287
3293
|
t = hr.get("rejectmsg") or ""
|
|
3288
3294
|
if t or not hr:
|
|
@@ -3514,11 +3520,26 @@ class Up2k(object):
|
|
|
3514
3520
|
|
|
3515
3521
|
linked = False
|
|
3516
3522
|
try:
|
|
3517
|
-
if
|
|
3518
|
-
|
|
3523
|
+
if rm and bos.path.exists(dst):
|
|
3524
|
+
wunlink(self.log, dst, flags)
|
|
3525
|
+
|
|
3519
3526
|
if not is_mv and not flags.get("dedup"):
|
|
3520
3527
|
raise Exception("dedup is disabled in config")
|
|
3521
3528
|
|
|
3529
|
+
if "reflink" in flags:
|
|
3530
|
+
if not USE_FICLONE:
|
|
3531
|
+
raise Exception("reflink") # python 3.14 or newer; no need
|
|
3532
|
+
try:
|
|
3533
|
+
with open(fsenc(src), "rb") as fi, open(fsenc(dst), "wb") as fo:
|
|
3534
|
+
fcntl.ioctl(fo.fileno(), fcntl.FICLONE, fi.fileno())
|
|
3535
|
+
except:
|
|
3536
|
+
if bos.path.exists(dst):
|
|
3537
|
+
wunlink(self.log, dst, flags)
|
|
3538
|
+
raise
|
|
3539
|
+
if lmod:
|
|
3540
|
+
bos.utime_c(self.log, dst, int(lmod), False)
|
|
3541
|
+
return
|
|
3542
|
+
|
|
3522
3543
|
lsrc = src
|
|
3523
3544
|
ldst = dst
|
|
3524
3545
|
fs1 = bos.stat(os.path.dirname(src)).st_dev
|
|
@@ -3545,9 +3566,6 @@ class Up2k(object):
|
|
|
3545
3566
|
lsrc = lsrc.replace("/", "\\")
|
|
3546
3567
|
ldst = ldst.replace("/", "\\")
|
|
3547
3568
|
|
|
3548
|
-
if rm and bos.path.exists(dst):
|
|
3549
|
-
wunlink(self.log, dst, flags)
|
|
3550
|
-
|
|
3551
3569
|
try:
|
|
3552
3570
|
if "hardlink" in flags:
|
|
3553
3571
|
os.link(fsenc(absreal(src)), fsenc(dst))
|
|
@@ -3962,7 +3980,7 @@ class Up2k(object):
|
|
|
3962
3980
|
sz,
|
|
3963
3981
|
ip,
|
|
3964
3982
|
at or time.time(),
|
|
3965
|
-
|
|
3983
|
+
None,
|
|
3966
3984
|
)
|
|
3967
3985
|
t = hr.get("rejectmsg") or ""
|
|
3968
3986
|
if t or not hr:
|
|
@@ -4197,7 +4215,7 @@ class Up2k(object):
|
|
|
4197
4215
|
st.st_size,
|
|
4198
4216
|
ip,
|
|
4199
4217
|
time.time(),
|
|
4200
|
-
|
|
4218
|
+
None,
|
|
4201
4219
|
):
|
|
4202
4220
|
t = "delete blocked by xbd server config: %r"
|
|
4203
4221
|
self.log(t % (abspath,), 1)
|
|
@@ -4237,7 +4255,7 @@ class Up2k(object):
|
|
|
4237
4255
|
st.st_size,
|
|
4238
4256
|
ip,
|
|
4239
4257
|
time.time(),
|
|
4240
|
-
|
|
4258
|
+
None,
|
|
4241
4259
|
)
|
|
4242
4260
|
|
|
4243
4261
|
if is_dir:
|
|
@@ -4365,7 +4383,7 @@ class Up2k(object):
|
|
|
4365
4383
|
fsize,
|
|
4366
4384
|
ip,
|
|
4367
4385
|
time.time(),
|
|
4368
|
-
|
|
4386
|
+
None,
|
|
4369
4387
|
):
|
|
4370
4388
|
t = "copy blocked by xbr server config: %r" % (svp,)
|
|
4371
4389
|
self.log(t, 1)
|
|
@@ -4465,7 +4483,7 @@ class Up2k(object):
|
|
|
4465
4483
|
fsize,
|
|
4466
4484
|
ip,
|
|
4467
4485
|
time.time(),
|
|
4468
|
-
|
|
4486
|
+
None,
|
|
4469
4487
|
)
|
|
4470
4488
|
|
|
4471
4489
|
return "k"
|
|
@@ -4616,7 +4634,7 @@ class Up2k(object):
|
|
|
4616
4634
|
fsize,
|
|
4617
4635
|
ip,
|
|
4618
4636
|
time.time(),
|
|
4619
|
-
|
|
4637
|
+
None,
|
|
4620
4638
|
):
|
|
4621
4639
|
t = "move blocked by xbr server config: %r" % (svp,)
|
|
4622
4640
|
self.log(t, 1)
|
|
@@ -4656,7 +4674,7 @@ class Up2k(object):
|
|
|
4656
4674
|
fsize,
|
|
4657
4675
|
ip,
|
|
4658
4676
|
time.time(),
|
|
4659
|
-
|
|
4677
|
+
None,
|
|
4660
4678
|
)
|
|
4661
4679
|
|
|
4662
4680
|
return "k"
|
|
@@ -4667,6 +4685,12 @@ class Up2k(object):
|
|
|
4667
4685
|
has_dupes = False
|
|
4668
4686
|
if w:
|
|
4669
4687
|
if c2 and c2 != c1:
|
|
4688
|
+
if "nodupem" in dvn.flags:
|
|
4689
|
+
q = "select w from up where substr(w,1,16) = ?"
|
|
4690
|
+
for (w2,) in c2.execute(q, (w[:16],)):
|
|
4691
|
+
if w == w2:
|
|
4692
|
+
t = "file exists in target volume, and dupes are forbidden in config"
|
|
4693
|
+
raise Pebkac(400, t)
|
|
4670
4694
|
self._copy_tags(c1, c2, w)
|
|
4671
4695
|
|
|
4672
4696
|
xlink = bool(svn.flags.get("xlink"))
|
|
@@ -4775,7 +4799,7 @@ class Up2k(object):
|
|
|
4775
4799
|
fsize,
|
|
4776
4800
|
ip,
|
|
4777
4801
|
time.time(),
|
|
4778
|
-
|
|
4802
|
+
None,
|
|
4779
4803
|
)
|
|
4780
4804
|
|
|
4781
4805
|
return "k"
|
|
@@ -5112,7 +5136,7 @@ class Up2k(object):
|
|
|
5112
5136
|
job["size"],
|
|
5113
5137
|
job["addr"],
|
|
5114
5138
|
job["t0"],
|
|
5115
|
-
|
|
5139
|
+
None,
|
|
5116
5140
|
)
|
|
5117
5141
|
t = hr.get("rejectmsg") or ""
|
|
5118
5142
|
if t or not hr:
|