quasarr 1.23.0__py3-none-any.whl → 1.24.0__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.
Potentially problematic release.
This version of quasarr might be problematic. Click here for more details.
- quasarr/api/captcha/__init__.py +44 -19
- quasarr/downloads/__init__.py +217 -278
- quasarr/downloads/sources/al.py +28 -3
- quasarr/downloads/sources/by.py +8 -2
- quasarr/downloads/sources/dd.py +15 -8
- quasarr/downloads/sources/dj.py +11 -2
- quasarr/downloads/sources/dl.py +49 -57
- quasarr/downloads/sources/dt.py +34 -12
- quasarr/downloads/sources/dw.py +9 -3
- quasarr/downloads/sources/he.py +10 -4
- quasarr/downloads/sources/mb.py +10 -4
- quasarr/downloads/sources/nk.py +9 -3
- quasarr/downloads/sources/nx.py +31 -10
- quasarr/downloads/sources/sf.py +61 -55
- quasarr/downloads/sources/sj.py +11 -2
- quasarr/downloads/sources/sl.py +22 -9
- quasarr/downloads/sources/wd.py +9 -3
- quasarr/downloads/sources/wx.py +12 -13
- quasarr/providers/obfuscated.py +27 -23
- quasarr/providers/sessions/al.py +38 -10
- quasarr/providers/version.py +1 -1
- quasarr/search/sources/dl.py +10 -6
- {quasarr-1.23.0.dist-info → quasarr-1.24.0.dist-info}/METADATA +2 -2
- {quasarr-1.23.0.dist-info → quasarr-1.24.0.dist-info}/RECORD +28 -28
- {quasarr-1.23.0.dist-info → quasarr-1.24.0.dist-info}/WHEEL +0 -0
- {quasarr-1.23.0.dist-info → quasarr-1.24.0.dist-info}/entry_points.txt +0 -0
- {quasarr-1.23.0.dist-info → quasarr-1.24.0.dist-info}/licenses/LICENSE +0 -0
- {quasarr-1.23.0.dist-info → quasarr-1.24.0.dist-info}/top_level.txt +0 -0
quasarr/api/captcha/__init__.py
CHANGED
|
@@ -8,7 +8,7 @@ from base64 import urlsafe_b64encode, urlsafe_b64decode
|
|
|
8
8
|
from urllib.parse import quote, unquote, urljoin
|
|
9
9
|
|
|
10
10
|
import requests
|
|
11
|
-
from bottle import request, response, redirect
|
|
11
|
+
from bottle import request, response, redirect, HTTPResponse
|
|
12
12
|
|
|
13
13
|
import quasarr.providers.html_images as images
|
|
14
14
|
from quasarr.downloads.linkcrypters.filecrypt import get_filecrypt_links, DLC
|
|
@@ -24,6 +24,21 @@ def js_single_quoted_string_safe(text):
|
|
|
24
24
|
return text.replace('\\', '\\\\').replace("'", "\\'")
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def check_package_exists(package_id):
|
|
28
|
+
if not shared_state.get_db("protected").retrieve(package_id):
|
|
29
|
+
raise HTTPResponse(
|
|
30
|
+
status=404,
|
|
31
|
+
body=render_centered_html(f'''
|
|
32
|
+
<h1><img src="{images.logo}" class="logo"/>Quasarr</h1>
|
|
33
|
+
<p><b>Error:</b> Package not found or already solved.</p>
|
|
34
|
+
<p>
|
|
35
|
+
{render_button("Back", "secondary", {"onclick": "location.href='/captcha'"})}
|
|
36
|
+
</p>
|
|
37
|
+
'''),
|
|
38
|
+
content_type="text/html"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
27
42
|
def setup_captcha_routes(app):
|
|
28
43
|
@app.get('/captcha')
|
|
29
44
|
def check_captcha():
|
|
@@ -82,10 +97,16 @@ def setup_captcha_routes(app):
|
|
|
82
97
|
|
|
83
98
|
sj = shared_state.values["config"]("Hostnames").get("sj")
|
|
84
99
|
dj = shared_state.values["config"]("Hostnames").get("dj")
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
|
|
101
|
+
def is_junkies_link(link):
|
|
102
|
+
"""Check if link is a junkies link (handles [[url, mirror]] format)."""
|
|
103
|
+
url = link[0] if isinstance(link, (list, tuple)) else link
|
|
104
|
+
mirror = link[1] if isinstance(link, (list, tuple)) and len(link) > 1 else ""
|
|
105
|
+
if mirror == "junkies":
|
|
106
|
+
return True
|
|
107
|
+
return (sj and sj in url) or (dj and dj in url)
|
|
108
|
+
|
|
109
|
+
has_junkies_links = any(is_junkies_link(link) for link in prioritized_links)
|
|
89
110
|
|
|
90
111
|
# KeepLinks uses nested arrays like FileCrypt: [["url", "mirror"]]
|
|
91
112
|
has_keeplinks_links = any(
|
|
@@ -182,7 +203,7 @@ def setup_captcha_routes(app):
|
|
|
182
203
|
<a href="#" id="show-setup-btn" style="color: #58a6ff;">ℹ️ Show instructions again</a>
|
|
183
204
|
</div>
|
|
184
205
|
|
|
185
|
-
<strong><a href="{url_with_quick_transfer_params}" target="
|
|
206
|
+
<strong><a href="{url_with_quick_transfer_params}" target="_self">🔗 Obtain the download links here!</a></strong><br><br>
|
|
186
207
|
|
|
187
208
|
<form id="bypass-form" action="/captcha/bypass-submit" method="post" enctype="multipart/form-data">
|
|
188
209
|
<input type="hidden" name="package_id" value="{package_id}" />
|
|
@@ -242,7 +263,9 @@ def setup_captcha_routes(app):
|
|
|
242
263
|
title = payload.get("title")
|
|
243
264
|
password = payload.get("password")
|
|
244
265
|
urls = payload.get("links")
|
|
245
|
-
url = urls[0]
|
|
266
|
+
url = urls[0][0] if isinstance(urls[0], (list, tuple)) else urls[0]
|
|
267
|
+
|
|
268
|
+
check_package_exists(package_id)
|
|
246
269
|
|
|
247
270
|
return render_centered_html(f"""
|
|
248
271
|
<!DOCTYPE html>
|
|
@@ -276,7 +299,9 @@ def setup_captcha_routes(app):
|
|
|
276
299
|
title = payload.get("title")
|
|
277
300
|
password = payload.get("password")
|
|
278
301
|
urls = payload.get("links")
|
|
279
|
-
|
|
302
|
+
|
|
303
|
+
check_package_exists(package_id)
|
|
304
|
+
|
|
280
305
|
url = urls[0][0] if isinstance(urls[0], (list, tuple)) else urls[0]
|
|
281
306
|
|
|
282
307
|
return render_centered_html(f"""
|
|
@@ -311,7 +336,9 @@ def setup_captcha_routes(app):
|
|
|
311
336
|
title = payload.get("title")
|
|
312
337
|
password = payload.get("password")
|
|
313
338
|
urls = payload.get("links")
|
|
314
|
-
|
|
339
|
+
|
|
340
|
+
check_package_exists(package_id)
|
|
341
|
+
|
|
315
342
|
url = urls[0][0] if isinstance(urls[0], (list, tuple)) else urls[0]
|
|
316
343
|
|
|
317
344
|
return render_centered_html(f"""
|
|
@@ -400,7 +427,7 @@ def setup_captcha_routes(app):
|
|
|
400
427
|
<a href="#" id="show-setup-btn" style="color: #58a6ff;">ℹ️ Show instructions again</a>
|
|
401
428
|
</div>
|
|
402
429
|
|
|
403
|
-
<strong><a href="{url_with_quick_transfer_params}" target="
|
|
430
|
+
<strong><a href="{url_with_quick_transfer_params}" target="_self">🔗 Obtain the download links here!</a></strong><br><br>
|
|
404
431
|
|
|
405
432
|
<form id="bypass-form" action="/captcha/bypass-submit" method="post" enctype="multipart/form-data">
|
|
406
433
|
<input type="hidden" name="package_id" value="{package_id}" />
|
|
@@ -501,12 +528,12 @@ def setup_captcha_routes(app):
|
|
|
501
528
|
try:
|
|
502
529
|
decompressed = zlib.decompress(decoded, -15) # -15 = raw deflate, no zlib header
|
|
503
530
|
except Exception as e:
|
|
504
|
-
|
|
531
|
+
debug(f"Decompression error: {e}, trying with header...")
|
|
505
532
|
try:
|
|
506
533
|
# Fallback: try with zlib header
|
|
507
534
|
decompressed = zlib.decompress(decoded)
|
|
508
535
|
except Exception as e2:
|
|
509
|
-
info(f"Decompression
|
|
536
|
+
info(f"Decompression failed without and with header: {e2}")
|
|
510
537
|
return render_centered_html(f'''<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
511
538
|
<p><b>Error:</b> Failed to decompress data: {str(e)}</p>
|
|
512
539
|
<p>
|
|
@@ -635,6 +662,8 @@ def setup_captcha_routes(app):
|
|
|
635
662
|
desired_mirror = payload.get("mirror")
|
|
636
663
|
prioritized_links = payload.get("links")
|
|
637
664
|
|
|
665
|
+
check_package_exists(package_id)
|
|
666
|
+
|
|
638
667
|
if not prioritized_links:
|
|
639
668
|
# No links found, show an error message
|
|
640
669
|
return render_centered_html(f'''
|
|
@@ -858,13 +887,7 @@ def setup_captcha_routes(app):
|
|
|
858
887
|
{render_button("Back", "secondary", {"onclick": "location.href='/captcha'"})}
|
|
859
888
|
</p>''')
|
|
860
889
|
|
|
861
|
-
|
|
862
|
-
if not package_exists:
|
|
863
|
-
return render_centered_html(f'''<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
864
|
-
<p><b>Error:</b> Package not found or already solved.</p>
|
|
865
|
-
<p>
|
|
866
|
-
{render_button("Back", "secondary", {"onclick": "location.href='/captcha'"})}
|
|
867
|
-
</p>''')
|
|
890
|
+
check_package_exists(package_id)
|
|
868
891
|
|
|
869
892
|
# Process links input
|
|
870
893
|
if links_input:
|
|
@@ -1041,6 +1064,8 @@ def setup_captcha_routes(app):
|
|
|
1041
1064
|
original_url = payload.get("original_url", "")
|
|
1042
1065
|
url = payload.get("links")[0] if payload.get("links") else None
|
|
1043
1066
|
|
|
1067
|
+
check_package_exists(package_id)
|
|
1068
|
+
|
|
1044
1069
|
if not url or not session_id or not package_id:
|
|
1045
1070
|
response.status = 400
|
|
1046
1071
|
return "Missing required parameters"
|