quasarr 1.23.0__py3-none-any.whl → 1.24.1__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.

@@ -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
- has_junkies_links = any(
86
- (sj and sj in link) or (dj and dj in link)
87
- for link in prioritized_links
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="_blank">🔗 Obtain the download links here!</a></strong><br><br>
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
- # KeepLinks uses nested arrays like FileCrypt: [["url", "mirror"]]
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
- # ToLink uses nested arrays like FileCrypt: [["url", "mirror"]]
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="_blank">🔗 Obtain the download links here!</a></strong><br><br>
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
- info(f"Decompression error: {e}, trying with header...")
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 also failed with header: {e2}")
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
- package_exists = shared_state.get_db("protected").retrieve(package_id)
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"