quasarr 1.17.0__tar.gz → 1.17.2__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.

Potentially problematic release.


This version of quasarr might be problematic. Click here for more details.

Files changed (70) hide show
  1. {quasarr-1.17.0 → quasarr-1.17.2}/PKG-INFO +1 -1
  2. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/api/captcha/__init__.py +43 -25
  3. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/by.py +17 -12
  4. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/version.py +1 -1
  5. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/PKG-INFO +1 -1
  6. {quasarr-1.17.0 → quasarr-1.17.2}/LICENSE +0 -0
  7. {quasarr-1.17.0 → quasarr-1.17.2}/README.md +0 -0
  8. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/__init__.py +0 -0
  9. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/api/__init__.py +0 -0
  10. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/api/arr/__init__.py +0 -0
  11. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/api/config/__init__.py +0 -0
  12. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/api/sponsors_helper/__init__.py +0 -0
  13. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/api/statistics/__init__.py +0 -0
  14. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/__init__.py +0 -0
  15. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/linkcrypters/__init__.py +0 -0
  16. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/linkcrypters/al.py +0 -0
  17. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/linkcrypters/filecrypt.py +0 -0
  18. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/linkcrypters/hide.py +0 -0
  19. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/packages/__init__.py +0 -0
  20. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/__init__.py +0 -0
  21. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/al.py +0 -0
  22. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/dd.py +0 -0
  23. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/dt.py +0 -0
  24. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/dw.py +0 -0
  25. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/mb.py +0 -0
  26. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/nx.py +0 -0
  27. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/sf.py +0 -0
  28. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/sl.py +0 -0
  29. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/downloads/sources/wd.py +0 -0
  30. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/__init__.py +0 -0
  31. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/cloudflare.py +0 -0
  32. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/html_images.py +0 -0
  33. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/html_templates.py +0 -0
  34. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/imdb_metadata.py +0 -0
  35. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/log.py +0 -0
  36. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/myjd_api.py +0 -0
  37. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/notifications.py +0 -0
  38. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/obfuscated.py +0 -0
  39. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/sessions/__init__.py +0 -0
  40. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/sessions/al.py +0 -0
  41. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/sessions/dd.py +0 -0
  42. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/sessions/nx.py +0 -0
  43. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/shared_state.py +0 -0
  44. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/statistics.py +0 -0
  45. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/providers/web_server.py +0 -0
  46. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/__init__.py +0 -0
  47. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/__init__.py +0 -0
  48. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/al.py +0 -0
  49. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/by.py +0 -0
  50. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/dd.py +0 -0
  51. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/dt.py +0 -0
  52. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/dw.py +0 -0
  53. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/fx.py +0 -0
  54. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/mb.py +0 -0
  55. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/nx.py +0 -0
  56. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/sf.py +0 -0
  57. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/sl.py +0 -0
  58. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/search/sources/wd.py +0 -0
  59. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/storage/__init__.py +0 -0
  60. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/storage/config.py +0 -0
  61. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/storage/setup.py +0 -0
  62. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr/storage/sqlite_database.py +0 -0
  63. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/SOURCES.txt +0 -0
  64. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/dependency_links.txt +0 -0
  65. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/entry_points.txt +0 -0
  66. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/not-zip-safe +0 -0
  67. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/requires.txt +0 -0
  68. {quasarr-1.17.0 → quasarr-1.17.2}/quasarr.egg-info/top_level.txt +0 -0
  69. {quasarr-1.17.0 → quasarr-1.17.2}/setup.cfg +0 -0
  70. {quasarr-1.17.0 → quasarr-1.17.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quasarr
3
- Version: 1.17.0
3
+ Version: 1.17.2
4
4
  Summary: Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decrypts links protected by CAPTCHAs.
5
5
  Home-page: https://github.com/rix1337/Quasarr
6
6
  Author: rix1337
@@ -105,28 +105,45 @@ def setup_captcha_routes(app):
105
105
  """Render the bypass UI section for both cutcaptcha and circle captcha pages"""
106
106
  return f'''
107
107
  <div style="margin-top: 40px; padding-top: 20px; border-top: 2px solid #ccc;">
108
- <h3>Bypass CAPTCHA</h3>
109
- <a href="{url}" target="_blank">Protected Link</a>
110
- <form id="bypass-form" action="/captcha/bypass-submit" method="post" enctype="multipart/form-data">
111
- <input type="hidden" name="package_id" value="{package_id}" />
112
- <input type="hidden" name="title" value="{title}" />
113
- <input type="hidden" name="password" value="{password}" />
114
-
115
- <div style="margin-bottom: 15px;">
116
- <label for="links-input"><b>Paste direct download links (one per line):</b></label><br>
117
- <textarea id="links-input" name="links" rows="5" style="width: 100%; padding: 8px; font-family: monospace; resize: vertical;"></textarea>
118
- </div>
119
-
120
- <div style="margin-bottom: 15px;">
121
- <label for="dlc-file"><b>Or upload DLC file:</b></label><br>
122
- <input type="file" id="dlc-file" name="dlc_file" accept=".dlc" />
123
- </div>
124
-
125
- <div>
126
- {render_button("Submit Bypass", "primary", {"type": "submit"})}
127
- </div>
128
- </form>
108
+ <details id="bypassDetails">
109
+ <summary id="bypassSummary">Show CAPTCHA Bypass</summary><br>
110
+ <strong><a href="{url}" target="_blank">Obtain download links here!</a></strong><br><br>
111
+ <form id="bypass-form" action="/captcha/bypass-submit" method="post" enctype="multipart/form-data">
112
+ <input type="hidden" name="package_id" value="{package_id}" />
113
+ <input type="hidden" name="title" value="{title}" />
114
+ <input type="hidden" name="password" value="{password}" />
115
+
116
+ <div>
117
+ <strong>Paste the download links (one per line):</strong>
118
+ <textarea id="links-input" name="links" rows="5" style="width: 100%; padding: 8px; font-family: monospace; resize: vertical;"></textarea>
119
+ </div>
120
+
121
+ <div>
122
+ <strong>Or upload DLC file:</strong><br>
123
+ <input type="file" id="dlc-file" name="dlc_file" accept=".dlc" />
124
+ </div>
125
+
126
+ <div>
127
+ {render_button("Submit", "primary", {"type": "submit"})}
128
+ </div>
129
+ </form>
130
+ </details>
129
131
  </div>
132
+ <script>
133
+ // Handle bypass toggle
134
+ const bypassDetails = document.getElementById('bypassDetails');
135
+ const bypassSummary = document.getElementById('bypassSummary');
136
+
137
+ if (bypassDetails && bypassSummary) {{
138
+ bypassDetails.addEventListener('toggle', () => {{
139
+ if (bypassDetails.open) {{
140
+ bypassSummary.textContent = 'Hide CAPTCHA Bypass';
141
+ }} else {{
142
+ bypassSummary.textContent = 'Show CAPTCHA Bypass';
143
+ }}
144
+ }});
145
+ }}
146
+ </script>
130
147
  '''
131
148
 
132
149
  @app.get('/captcha/delete/<package_id>')
@@ -285,7 +302,6 @@ def setup_captcha_routes(app):
285
302
  <div>
286
303
  <h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
287
304
  <p id="package-title" style="max-width: 370px; word-wrap: break-word; overflow-wrap: break-word;"><b>Package:</b> {title}</p>
288
- <h3>Solve CAPTCHA</h3>
289
305
  <div id="captcha-key"></div>
290
306
  {link_select}<br><br>
291
307
  <input type="hidden" id="link-hidden" value="{prioritized_links[0][0]}" />
@@ -408,8 +424,11 @@ def setup_captcha_routes(app):
408
424
  # Process links input
409
425
  if links_input:
410
426
  info(f"Processing direct links bypass for {title}")
411
- links = [link.strip() for link in links_input.split('\n') if link.strip()]
412
- info(f"Received {len(links)} direct download links")
427
+ raw_links = [link.strip() for link in links_input.split('\n') if link.strip()]
428
+ links = [l for l in raw_links if l.lower().startswith(("http://", "https://"))]
429
+
430
+ info(f"Received {len(links)} valid direct download links "
431
+ f"(from {len(raw_links)} provided)")
413
432
 
414
433
  # Process DLC file
415
434
  elif dlc_upload:
@@ -590,7 +609,6 @@ def setup_captcha_routes(app):
590
609
  <body>
591
610
  <h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
592
611
  <p><b>Package:</b> {title}</p>
593
- <h3>Solve CAPTCHA</h3>
594
612
  <form action="/captcha/decrypt-filecrypt-circle?url={url}&session_id={session_id}&package_id={package_id}" method="post">
595
613
  <input type="image" src="/captcha/circle.php?url={url}&session_id={session_id}" name="button" alt="Circle CAPTCHA">
596
614
  </form>
@@ -4,6 +4,7 @@
4
4
 
5
5
  import concurrent.futures
6
6
  import re
7
+ import time
7
8
  from urllib.parse import urlparse
8
9
 
9
10
  import requests
@@ -39,6 +40,7 @@ def get_by_download_links(shared_state, url, mirror, title): # signature must a
39
40
  r = requests.get(url, headers=headers, timeout=10)
40
41
  return r.text, url
41
42
  except Exception:
43
+ info(f"Error fetching iframe URL: {url}")
42
44
  return None, url
43
45
 
44
46
  with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
@@ -76,23 +78,26 @@ def get_by_download_links(shared_state, url, mirror, title): # signature must a
76
78
  try:
77
79
  r = requests.get(href, headers=headers, timeout=10, allow_redirects=True)
78
80
  if "/404.html" in r.url:
79
- debug(f"Link leads to 404 page for {hostname}: {r.url}")
81
+ info(f"Link leads to 404 page for {hostname}: {r.url}")
80
82
  return None
83
+ time.sleep(1)
81
84
  return r.url
82
85
  except Exception as e:
83
- debug(f"Error resolving link for {hostname}: {e}")
86
+ info(f"Error resolving link for {hostname}: {e}")
84
87
  return None
85
88
 
86
- with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
87
- future_to_hostname = {executor.submit(resolve_redirect, pair): pair[1] for pair in url_hosters}
88
- for future in concurrent.futures.as_completed(future_to_hostname):
89
- resolved_url = future.result()
90
- hostname = future_to_hostname[future]
91
- if not hostname:
92
- hostname = urlparse(resolved_url).hostname
93
- if resolved_url and hostname and hostname.startswith(("ddownload", "rapidgator", "turbobit")):
94
- (links.insert(0, [resolved_url, hostname]) if "rapidgator" in hostname
95
- else links.append([resolved_url, hostname]))
89
+ for pair in url_hosters:
90
+ resolved_url = resolve_redirect(pair)
91
+ hostname = pair[1]
92
+
93
+ if not hostname:
94
+ hostname = urlparse(resolved_url).hostname
95
+
96
+ if resolved_url and hostname and hostname.startswith(("ddownload", "rapidgator", "turbobit", "filecrypt")):
97
+ if "rapidgator" in hostname:
98
+ links.insert(0, [resolved_url, hostname])
99
+ else:
100
+ links.append([resolved_url, hostname])
96
101
 
97
102
 
98
103
  except Exception as e:
@@ -8,7 +8,7 @@ import requests
8
8
 
9
9
 
10
10
  def get_version():
11
- return "1.17.0"
11
+ return "1.17.2"
12
12
 
13
13
 
14
14
  def get_latest_version():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quasarr
3
- Version: 1.17.0
3
+ Version: 1.17.2
4
4
  Summary: Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decrypts links protected by CAPTCHAs.
5
5
  Home-page: https://github.com/rix1337/Quasarr
6
6
  Author: rix1337
File without changes
File without changes
File without changes
File without changes
File without changes