quasarr 1.28.0__tar.gz → 1.28.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 (84) hide show
  1. {quasarr-1.28.0 → quasarr-1.28.2}/PKG-INFO +4 -4
  2. {quasarr-1.28.0 → quasarr-1.28.2}/README.md +3 -3
  3. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/api/arr/__init__.py +3 -3
  4. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/api/config/__init__.py +2 -4
  5. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/utils.py +4 -5
  6. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/version.py +1 -1
  7. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/storage/setup.py +18 -6
  8. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/PKG-INFO +4 -4
  9. {quasarr-1.28.0 → quasarr-1.28.2}/LICENSE +0 -0
  10. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/__init__.py +0 -0
  11. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/api/__init__.py +0 -0
  12. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/api/captcha/__init__.py +0 -0
  13. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/api/sponsors_helper/__init__.py +0 -0
  14. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/api/statistics/__init__.py +0 -0
  15. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/__init__.py +0 -0
  16. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/linkcrypters/__init__.py +0 -0
  17. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/linkcrypters/al.py +0 -0
  18. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/linkcrypters/filecrypt.py +0 -0
  19. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/linkcrypters/hide.py +0 -0
  20. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/packages/__init__.py +0 -0
  21. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/__init__.py +0 -0
  22. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/al.py +0 -0
  23. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/by.py +0 -0
  24. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/dd.py +0 -0
  25. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/dj.py +0 -0
  26. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/dl.py +0 -0
  27. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/dt.py +0 -0
  28. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/dw.py +0 -0
  29. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/he.py +0 -0
  30. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/mb.py +0 -0
  31. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/nk.py +0 -0
  32. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/nx.py +0 -0
  33. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/sf.py +0 -0
  34. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/sj.py +0 -0
  35. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/sl.py +0 -0
  36. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/wd.py +0 -0
  37. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/downloads/sources/wx.py +0 -0
  38. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/__init__.py +0 -0
  39. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/cloudflare.py +0 -0
  40. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/html_images.py +0 -0
  41. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/html_templates.py +0 -0
  42. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/imdb_metadata.py +0 -0
  43. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/log.py +0 -0
  44. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/myjd_api.py +0 -0
  45. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/notifications.py +0 -0
  46. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/obfuscated.py +0 -0
  47. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/sessions/__init__.py +0 -0
  48. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/sessions/al.py +0 -0
  49. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/sessions/dd.py +0 -0
  50. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/sessions/dl.py +0 -0
  51. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/sessions/nx.py +0 -0
  52. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/shared_state.py +0 -0
  53. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/statistics.py +0 -0
  54. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/providers/web_server.py +0 -0
  55. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/__init__.py +0 -0
  56. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/__init__.py +0 -0
  57. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/al.py +0 -0
  58. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/by.py +0 -0
  59. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/dd.py +0 -0
  60. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/dj.py +0 -0
  61. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/dl.py +0 -0
  62. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/dt.py +0 -0
  63. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/dw.py +0 -0
  64. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/fx.py +0 -0
  65. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/he.py +0 -0
  66. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/mb.py +0 -0
  67. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/nk.py +0 -0
  68. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/nx.py +0 -0
  69. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/sf.py +0 -0
  70. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/sj.py +0 -0
  71. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/sl.py +0 -0
  72. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/wd.py +0 -0
  73. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/search/sources/wx.py +0 -0
  74. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/storage/__init__.py +0 -0
  75. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/storage/config.py +0 -0
  76. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr/storage/sqlite_database.py +0 -0
  77. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/SOURCES.txt +0 -0
  78. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/dependency_links.txt +0 -0
  79. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/entry_points.txt +0 -0
  80. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/not-zip-safe +0 -0
  81. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/requires.txt +0 -0
  82. {quasarr-1.28.0 → quasarr-1.28.2}/quasarr.egg-info/top_level.txt +0 -0
  83. {quasarr-1.28.0 → quasarr-1.28.2}/setup.cfg +0 -0
  84. {quasarr-1.28.0 → quasarr-1.28.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quasarr
3
- Version: 1.28.0
3
+ Version: 1.28.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
@@ -73,7 +73,7 @@ http://192.168.1.1:8191/v1
73
73
 
74
74
  > ⚠️ Quasarr requires at least one valid hostname to start. It does not provide or endorse any specific sources, but community-maintained lists are available:
75
75
 
76
- 🔗 **[quasarr-hostnames.pages.dev](https://quasarr-hostnames.pages.dev)** — third-party guide for finding hostnames
76
+ 🔗 **[https://quasarr-host.name](https://quasarr-host.name)** — community guide for finding hostnames
77
77
 
78
78
  📋 Alternatively, browse community suggestions via [pastebin search](https://pastebin.com/search?q=hostnames+quasarr) (login required).
79
79
 
@@ -172,7 +172,7 @@ docker run -d \
172
172
  -e 'INTERNAL_ADDRESS'='http://192.168.0.1:8080' \
173
173
  -e 'EXTERNAL_ADDRESS'='https://foo.bar/' \
174
174
  -e 'DISCORD'='https://discord.com/api/webhooks/1234567890/ABCDEFGHIJKLMN' \
175
- -e 'HOSTNAMES'='https://pastebin.com/raw/eX4Mpl3'
175
+ -e 'HOSTNAMES'='https://quasarr-host.name/ini?token=123...'
176
176
  -e 'SILENT'='True' \
177
177
  -e 'DEBUG'='' \
178
178
  -e 'TZ'='Europe/Berlin' \
@@ -202,7 +202,7 @@ Use this only in case you can't run the docker image.
202
202
  --port=8080
203
203
  --discord=https://discord.com/api/webhooks/1234567890/ABCDEFGHIJKLMN
204
204
  --external_address=https://foo.bar/
205
- --hostnames=https://pastebin.com/raw/eX4Mpl3
205
+ --hostnames=https://quasarr-host.name/ini?token=123...
206
206
  ```
207
207
 
208
208
  * `--discord` see `DISCORD`docker variable
@@ -46,7 +46,7 @@ http://192.168.1.1:8191/v1
46
46
 
47
47
  > ⚠️ Quasarr requires at least one valid hostname to start. It does not provide or endorse any specific sources, but community-maintained lists are available:
48
48
 
49
- 🔗 **[quasarr-hostnames.pages.dev](https://quasarr-hostnames.pages.dev)** — third-party guide for finding hostnames
49
+ 🔗 **[https://quasarr-host.name](https://quasarr-host.name)** — community guide for finding hostnames
50
50
 
51
51
  📋 Alternatively, browse community suggestions via [pastebin search](https://pastebin.com/search?q=hostnames+quasarr) (login required).
52
52
 
@@ -145,7 +145,7 @@ docker run -d \
145
145
  -e 'INTERNAL_ADDRESS'='http://192.168.0.1:8080' \
146
146
  -e 'EXTERNAL_ADDRESS'='https://foo.bar/' \
147
147
  -e 'DISCORD'='https://discord.com/api/webhooks/1234567890/ABCDEFGHIJKLMN' \
148
- -e 'HOSTNAMES'='https://pastebin.com/raw/eX4Mpl3'
148
+ -e 'HOSTNAMES'='https://quasarr-host.name/ini?token=123...'
149
149
  -e 'SILENT'='True' \
150
150
  -e 'DEBUG'='' \
151
151
  -e 'TZ'='Europe/Berlin' \
@@ -175,7 +175,7 @@ Use this only in case you can't run the docker image.
175
175
  --port=8080
176
176
  --discord=https://discord.com/api/webhooks/1234567890/ABCDEFGHIJKLMN
177
177
  --external_address=https://foo.bar/
178
- --hostnames=https://pastebin.com/raw/eX4Mpl3
178
+ --hostnames=https://quasarr-host.name/ini?token=123...
179
179
  ```
180
180
 
181
181
  * `--discord` see `DISCORD`docker variable
@@ -327,7 +327,7 @@ def setup_arr_routes(app):
327
327
  else:
328
328
  info(
329
329
  f'Ignoring search request from {request_from} - only imdbid searches are supported')
330
- releases = [{}] # sonarr expects this but we will not support non-imdbid searches
330
+ releases = [] # sonarr expects this but we will not support non-imdbid searches
331
331
 
332
332
  items = ""
333
333
  for release in releases:
@@ -353,8 +353,8 @@ def setup_arr_routes(app):
353
353
  <enclosure url="{release.get("link", "")}" length="{release.get("size", 0)}" type="application/x-nzb" />
354
354
  </item>'''
355
355
 
356
- is_feed_request = not getattr(request.query, 'imdbid', '')
357
- if is_feed_request and not items:
356
+ requires_placeholder_item = not getattr(request.query, 'imdbid', '') and not getattr(request.query, 'q', '')
357
+ if requires_placeholder_item and not items:
358
358
  items = f'''
359
359
  <item>
360
360
  <title>No results found</title>
@@ -54,16 +54,14 @@ def setup_config(app, shared_state):
54
54
  if parsed.scheme not in ("http", "https") or not parsed.netloc:
55
55
  return {"success": False, "error": "Invalid URL format"}
56
56
 
57
- if "/raw/eX4Mpl3" in url:
58
- return {"success": False, "error": "Example URL detected. Please provide a real URL."}
59
-
60
57
  # Fetch content
61
58
  try:
62
59
  resp = requests.get(url, timeout=15)
63
60
  resp.raise_for_status()
64
61
  content = resp.text
65
62
  except requests.RequestException as e:
66
- return {"success": False, "error": f"Failed to fetch URL: {str(e)}"}
63
+ info(f"Failed to fetch hostnames URL: {e}")
64
+ return {"success": False, "error": "Failed to fetch URL. Check the console log for details."}
67
65
 
68
66
  # Parse hostnames
69
67
  allowed_keys = extract_allowed_keys(Config._DEFAULT_CONFIG, 'Hostnames')
@@ -2,6 +2,7 @@
2
2
  # Quasarr
3
3
  # Project by https://github.com/rix1337
4
4
 
5
+ import os
5
6
  import re
6
7
  import socket
7
8
  import sys
@@ -31,10 +32,6 @@ class Unbuffered(object):
31
32
 
32
33
  def is_valid_url(url):
33
34
  """Validate if a URL is properly formatted."""
34
- if "/raw/eX4Mpl3" in url:
35
- print("Example URL detected. Please provide a valid URL found on pastebin or any other public site!")
36
- return False
37
-
38
35
  parsed = urlparse(url)
39
36
  return parsed.scheme in ("http", "https") and bool(parsed.netloc)
40
37
 
@@ -62,6 +59,7 @@ def extract_kv_pairs(input_text, allowed_keys):
62
59
  """
63
60
  kv_pattern = re.compile(rf"^({'|'.join(map(re.escape, allowed_keys))})\s*=\s*(.*)$")
64
61
  kv_pairs = {}
62
+ debug = os.getenv('DEBUG')
65
63
 
66
64
  for line in input_text.splitlines():
67
65
  match = kv_pattern.match(line.strip())
@@ -71,7 +69,8 @@ def extract_kv_pairs(input_text, allowed_keys):
71
69
  elif "[Hostnames]" in line:
72
70
  pass
73
71
  else:
74
- print(f"Skipping line because it does not contain any supported hostname: {line}")
72
+ if debug:
73
+ print(f"Skipping line because it does not contain any supported hostname: {line}")
75
74
 
76
75
  return kv_pairs
77
76
 
@@ -8,7 +8,7 @@ import requests
8
8
 
9
9
 
10
10
  def get_version():
11
- return "1.28.0"
11
+ return "1.28.2"
12
12
 
13
13
 
14
14
  def get_latest_version():
@@ -264,12 +264,12 @@ def hostname_form_html(shared_state, message, show_restart_button=False, show_sk
264
264
  <div class="url-import-section">
265
265
  <h3>📥 Import from URL</h3>
266
266
  <div class="url-import-row">
267
- <input type="text" id="hostnamesUrl" placeholder="https://pastebin.com/raw/..." value="{stored_url}" autocorrect="off" autocomplete="off">
267
+ <input type="text" id="hostnamesUrl" placeholder="https://quasarr-host.name/ini?token=123..." value="{stored_url}" autocorrect="off" autocomplete="off" onfocus="onHostnameFieldFocus()">
268
268
  <button type="button" class="btn-secondary" id="importBtn" onclick="importHostnames()">Import</button>
269
269
  </div>
270
270
  <div id="importStatus" class="import-status"></div>
271
271
  <p style="font-size:0.75rem; color:var(--secondary, #6c757d); margin:0.5rem 0 0 0;">
272
- Paste a URL containing hostname definitions (same format as --hostnames parameter)
272
+ Paste a URL containing hostname definitions (one valid Hostname per line "ab = xyz")
273
273
  </p>
274
274
  </div>
275
275
 
@@ -307,6 +307,20 @@ def hostname_form_html(shared_state, message, show_restart_button=False, show_sk
307
307
  return false;
308
308
  }}
309
309
 
310
+ function onHostnameFieldFocus() {{
311
+ var urlInput = document.getElementById('hostnamesUrl');
312
+ if (urlInput.value.trim() === '') {{
313
+ var hasOpenedHelper = localStorage.getItem('hideHostnameHelperRedirect');
314
+ if (!hasOpenedHelper) {{
315
+ localStorage.setItem('hideHostnameHelperRedirect', 'true');
316
+ window.open('https://quasarr-host.name', '_blank');
317
+ var statusDiv = document.getElementById('importStatus');
318
+ statusDiv.className = 'import-status';
319
+ statusDiv.textContent = 'Opened hostname helper in new tab. Paste the URL here after setup.';
320
+ }}
321
+ }}
322
+ }}
323
+
310
324
  function importHostnames() {{
311
325
  var urlInput = document.getElementById('hostnamesUrl');
312
326
  var url = urlInput.value.trim();
@@ -575,16 +589,14 @@ def hostnames_config(shared_state):
575
589
  if parsed.scheme not in ("http", "https") or not parsed.netloc:
576
590
  return {"success": False, "error": "Invalid URL format"}
577
591
 
578
- if "/raw/eX4Mpl3" in url:
579
- return {"success": False, "error": "Example URL detected. Please provide a real URL."}
580
-
581
592
  # Fetch content
582
593
  try:
583
594
  resp = requests.get(url, timeout=15)
584
595
  resp.raise_for_status()
585
596
  content = resp.text
586
597
  except requests.RequestException as e:
587
- return {"success": False, "error": f"Failed to fetch URL: {str(e)}"}
598
+ info(f"Failed to fetch hostnames URL: {e}")
599
+ return {"success": False, "error": "Failed to fetch URL. Check the console log for details."}
588
600
 
589
601
  # Parse hostnames
590
602
  allowed_keys = extract_allowed_keys(Config._DEFAULT_CONFIG, 'Hostnames')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quasarr
3
- Version: 1.28.0
3
+ Version: 1.28.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
@@ -73,7 +73,7 @@ http://192.168.1.1:8191/v1
73
73
 
74
74
  > ⚠️ Quasarr requires at least one valid hostname to start. It does not provide or endorse any specific sources, but community-maintained lists are available:
75
75
 
76
- 🔗 **[quasarr-hostnames.pages.dev](https://quasarr-hostnames.pages.dev)** — third-party guide for finding hostnames
76
+ 🔗 **[https://quasarr-host.name](https://quasarr-host.name)** — community guide for finding hostnames
77
77
 
78
78
  📋 Alternatively, browse community suggestions via [pastebin search](https://pastebin.com/search?q=hostnames+quasarr) (login required).
79
79
 
@@ -172,7 +172,7 @@ docker run -d \
172
172
  -e 'INTERNAL_ADDRESS'='http://192.168.0.1:8080' \
173
173
  -e 'EXTERNAL_ADDRESS'='https://foo.bar/' \
174
174
  -e 'DISCORD'='https://discord.com/api/webhooks/1234567890/ABCDEFGHIJKLMN' \
175
- -e 'HOSTNAMES'='https://pastebin.com/raw/eX4Mpl3'
175
+ -e 'HOSTNAMES'='https://quasarr-host.name/ini?token=123...'
176
176
  -e 'SILENT'='True' \
177
177
  -e 'DEBUG'='' \
178
178
  -e 'TZ'='Europe/Berlin' \
@@ -202,7 +202,7 @@ Use this only in case you can't run the docker image.
202
202
  --port=8080
203
203
  --discord=https://discord.com/api/webhooks/1234567890/ABCDEFGHIJKLMN
204
204
  --external_address=https://foo.bar/
205
- --hostnames=https://pastebin.com/raw/eX4Mpl3
205
+ --hostnames=https://quasarr-host.name/ini?token=123...
206
206
  ```
207
207
 
208
208
  * `--discord` see `DISCORD`docker variable
File without changes
File without changes
File without changes
File without changes