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

@@ -353,6 +353,17 @@ 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
+ if not items:
357
+ items = f'''
358
+ <item>
359
+ <title>No results found</title>
360
+ <guid isPermaLink="False">0</guid>
361
+ <link>https://github.com/rix1337/Quasarr</link>
362
+ <comments>No results matched your search criteria.</comments>
363
+ <pubDate>{datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")}</pubDate>
364
+ <enclosure url="https://github.com/rix1337/Quasarr" length="0" type="application/x-nzb" />
365
+ </item>'''
366
+
356
367
  return f'''<?xml version="1.0" encoding="UTF-8"?>
357
368
  <rss>
358
369
  <channel>
@@ -8,7 +8,7 @@ import requests
8
8
 
9
9
 
10
10
  def get_version():
11
- return "1.21.1"
11
+ return "1.21.2"
12
12
 
13
13
 
14
14
  def get_latest_version():
@@ -17,9 +17,10 @@ from quasarr.providers.log import info, debug
17
17
 
18
18
  hostname = "by"
19
19
  supported_mirrors = ["rapidgator", "ddownload", "nitroflare"]
20
- XXX_REGEX = re.compile(r"\.xxx\.", re.I)
20
+
21
21
  RESOLUTION_REGEX = re.compile(r"\d{3,4}p", re.I)
22
22
  CODEC_REGEX = re.compile(r"x264|x265|h264|h265|hevc|avc", re.I)
23
+ XXX_REGEX = re.compile(r"\.xxx\.", re.I)
23
24
  IMDB_REGEX = re.compile(r"imdb\.com/title/(tt\d+)")
24
25
 
25
26
 
@@ -5,7 +5,6 @@
5
5
  import re
6
6
  import time
7
7
  from base64 import urlsafe_b64encode
8
- from concurrent.futures import ThreadPoolExecutor, as_completed
9
8
  from datetime import datetime
10
9
  from html import unescape
11
10
 
@@ -16,7 +15,27 @@ from quasarr.providers.log import info, debug
16
15
  from quasarr.providers.sessions.dl import retrieve_and_validate_session, invalidate_session, fetch_via_requests_session
17
16
 
18
17
  hostname = "dl"
19
- supported_mirrors = []
18
+
19
+ RESOLUTION_REGEX = re.compile(r"\d{3,4}p", re.I)
20
+ CODEC_REGEX = re.compile(r"x264|x265|h264|h265|hevc|avc", re.I)
21
+ XXX_REGEX = re.compile(r"\.xxx\.", re.I)
22
+
23
+
24
+ def convert_to_rss_date(iso_date_str):
25
+ """
26
+ Convert ISO format datetime to RSS date format.
27
+ DL date format: '2025-12-15T20:43:06+0100'
28
+ Returns: 'Sun, 15 Dec 2025 20:43:06 +0100'
29
+ Falls back to current time if conversion fails.
30
+ """
31
+ if not iso_date_str:
32
+ return datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")
33
+
34
+ try:
35
+ dt_obj = datetime.fromisoformat(iso_date_str)
36
+ return dt_obj.strftime("%a, %d %b %Y %H:%M:%S %z")
37
+ except Exception:
38
+ return datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")
20
39
 
21
40
 
22
41
  def normalize_title_for_sonarr(title):
@@ -95,21 +114,9 @@ def dl_feed(shared_state, start_time, request_from, mirror=None):
95
114
  thread_url = f"https://www.{host}{thread_url}"
96
115
 
97
116
  # Extract date and convert to RFC 2822 format
98
- date_str = None
99
117
  date_elem = item.select_one('time.u-dt')
100
- if date_elem:
101
- iso_date = date_elem.get('datetime', '')
102
- if iso_date:
103
- try:
104
- # Parse ISO format and convert to RFC 2822
105
- dt = datetime.fromisoformat(iso_date.replace('Z', '+00:00'))
106
- date_str = dt.strftime("%a, %d %b %Y %H:%M:%S %z")
107
- except Exception:
108
- date_str = None
109
-
110
- # Fallback: use current time if no date found
111
- if not date_str:
112
- date_str = datetime.now().strftime("%a, %d %b %Y %H:%M:%S %z")
118
+ iso_date = date_elem.get('datetime', '') if date_elem else ''
119
+ published = convert_to_rss_date(iso_date)
113
120
 
114
121
  mb = 0
115
122
  imdb_id = None
@@ -128,7 +135,7 @@ def dl_feed(shared_state, start_time, request_from, mirror=None):
128
135
  "link": link,
129
136
  "mirror": mirror,
130
137
  "size": mb * 1024 * 1024,
131
- "date": date_str,
138
+ "date": published,
132
139
  "source": thread_url
133
140
  },
134
141
  "type": "protected"
@@ -228,6 +235,15 @@ def _search_single_page(shared_state, host, search_string, search_id, page_num,
228
235
  title = unescape(title)
229
236
  title_normalized = normalize_title_for_sonarr(title)
230
237
 
238
+ # Filter: Skip if no resolution or codec info (unless LazyLibrarian)
239
+ if 'lazylibrarian' not in request_from.lower():
240
+ if not (RESOLUTION_REGEX.search(title_normalized) or CODEC_REGEX.search(title_normalized)):
241
+ continue
242
+
243
+ # Filter: Skip XXX content unless explicitly searched for
244
+ if XXX_REGEX.search(title_normalized) and 'xxx' not in search_string.lower():
245
+ continue
246
+
231
247
  thread_url = title_elem.get('href')
232
248
  if thread_url.startswith('/'):
233
249
  thread_url = f"https://www.{host}{thread_url}"
@@ -235,16 +251,10 @@ def _search_single_page(shared_state, host, search_string, search_id, page_num,
235
251
  if not shared_state.is_valid_release(title_normalized, request_from, search_string, season, episode):
236
252
  continue
237
253
 
238
- minor_info = item.select_one('div.contentRow-minor')
239
- date_str = ""
240
- if minor_info:
241
- date_elem = minor_info.select_one('time.u-dt')
242
- if date_elem:
243
- date_str = date_elem.get('datetime', '')
244
-
245
- # Fallback: use current time if no date found
246
- if not date_str:
247
- date_str = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")
254
+ # Extract date and convert to RFC 2822 format
255
+ date_elem = item.select_one('time.u-dt')
256
+ iso_date = date_elem.get('datetime', '') if date_elem else ''
257
+ published = convert_to_rss_date(iso_date)
248
258
 
249
259
  mb = 0
250
260
  password = ""
@@ -262,7 +272,7 @@ def _search_single_page(shared_state, host, search_string, search_id, page_num,
262
272
  "link": link,
263
273
  "mirror": mirror,
264
274
  "size": mb * 1024 * 1024,
265
- "date": date_str,
275
+ "date": published,
266
276
  "source": thread_url
267
277
  },
268
278
  "type": "protected"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quasarr
3
- Version: 1.21.1
3
+ Version: 1.21.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
@@ -1,6 +1,6 @@
1
1
  quasarr/__init__.py,sha256=4-EVvIdDjMqidqp3xpXfcDl-fSe0J_B415ueZDAKBss,18137
2
2
  quasarr/api/__init__.py,sha256=9Y_DTNYsHeimrXL3mAli8OUg0zqo7QGLF2ft40d3R-c,6822
3
- quasarr/api/arr/__init__.py,sha256=Un2mi_z8aHHhE8ks4Dq50FO3PFHUmBWggrDvU39TVaU,16711
3
+ quasarr/api/arr/__init__.py,sha256=-e7Sge8mzQCtxlixY2pEJ2p2wQ06TckaczFPUZWCz3c,17361
4
4
  quasarr/api/captcha/__init__.py,sha256=2qlcJn_Kp_PWP8-_MJvIlPkRlZitH4B58QbdcFZ6xqU,49765
5
5
  quasarr/api/config/__init__.py,sha256=0K7zqC9dt39Ul1RIJt0zNVdh1b9ARnfC6QFPa2D9FCw,819
6
6
  quasarr/api/sponsors_helper/__init__.py,sha256=kAZabPlplPYRG6Uw7ZHTk5uypualwvhs-NoTOjQhhhA,6369
@@ -39,7 +39,7 @@ quasarr/providers/notifications.py,sha256=bohT-6yudmFnmZMc3BwCGX0n1HdzSVgQG_LDZm
39
39
  quasarr/providers/obfuscated.py,sha256=YydQJHrZ485pHaXK0DHHRW3eLZygGr6c0xnUKD6mcCE,236502
40
40
  quasarr/providers/shared_state.py,sha256=1NUKtm9YXWPvN64By2O2OYH5ke5TmBkJSbSxiNczgtU,29849
41
41
  quasarr/providers/statistics.py,sha256=cEQixYnDMDqtm5wWe40E_2ucyo4mD0n3SrfelhQi1L8,6452
42
- quasarr/providers/version.py,sha256=gwbSbe-TLBE-0LqZeM1tE3yUIUCdoBvCmQNeSPuUT-E,4004
42
+ quasarr/providers/version.py,sha256=l2RNcC0ml5kszaNgMdJVn3cgYuDK2OtV70Jr08dl3AI,4004
43
43
  quasarr/providers/web_server.py,sha256=XPj98T-axxgotovuB-rVw1IPCkJiNdXBlEeFvM_zSlM,1432
44
44
  quasarr/providers/sessions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  quasarr/providers/sessions/al.py,sha256=mlP6SWfCY2HyOSV40uyotQ5T4eSBNYG9A5GWOEAdz-c,9589
@@ -49,10 +49,10 @@ quasarr/providers/sessions/nx.py,sha256=qfW12AB_0nNsAoKOaSF4z0T9DCxMQleWCYf3fqJt
49
49
  quasarr/search/__init__.py,sha256=V59LIiC75mQvasDdTjiWZRbPD1jXO1lhXlKeNVX0iOc,5726
50
50
  quasarr/search/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  quasarr/search/sources/al.py,sha256=yr6wx-VcSOFYK_o3N1bepC4t6Gvt9eDvcG9fQBFg0bg,17203
52
- quasarr/search/sources/by.py,sha256=OPoAqS5kSSNrRVsPlALhX59h3lEZWGA7LlFfL4vH2-o,7914
52
+ quasarr/search/sources/by.py,sha256=vnE3L43V8suPhPHcn6LVxKO1e3mJaDRqIIMg2BGxr_g,7915
53
53
  quasarr/search/sources/dd.py,sha256=pVpdHLZlw2CYklBf_YLkeDWbCNsDLR2iecccR2c2RyI,4889
54
54
  quasarr/search/sources/dj.py,sha256=2HIdg5ddXP4DtjHlyXmuQ8QVhOPt3Hh2kL4uxhFJK-8,7074
55
- quasarr/search/sources/dl.py,sha256=JKNz1fKPnCSBZ5AoZL7BP71aoq08i_1feIIlg_RWf98,12023
55
+ quasarr/search/sources/dl.py,sha256=n7WYKWLLftbNL3uBcGM0n2VaTKspNLfFOTJK3YfkVXw,12375
56
56
  quasarr/search/sources/dt.py,sha256=m1kQ7mC43QlWZyVIkw-OXJGjWiT9IbQuFtHWiR8CjhA,9580
57
57
  quasarr/search/sources/dw.py,sha256=-daUTBTA5izeatrE7TITVlnzNCQ5HfovYMMZ8UTM-2o,7636
58
58
  quasarr/search/sources/fx.py,sha256=JAyD727yDAFIP14bzfi2SkX9paysXGkQdIybShYtdko,8596
@@ -69,9 +69,9 @@ quasarr/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
69
  quasarr/storage/config.py,sha256=hOI7vvIo1YaML3dtAkTmp0HSedWF6brVhRk3d8pJtXI,6300
70
70
  quasarr/storage/setup.py,sha256=Gf7e125KlHsyu-hhq3uFfH7N6i7-8DDONGcYJX0haLs,18261
71
71
  quasarr/storage/sqlite_database.py,sha256=yMqFQfKf0k7YS-6Z3_7pj4z1GwWSXJ8uvF4IydXsuTE,3554
72
- quasarr-1.21.1.dist-info/licenses/LICENSE,sha256=QQFCAfDgt7lSA8oSWDHIZ9aTjFbZaBJdjnGOHkuhK7k,1060
73
- quasarr-1.21.1.dist-info/METADATA,sha256=4HZd5NBTzVWVfQyrSGnuqh7ITVU60oKZyl_8ZoLpHcE,12743
74
- quasarr-1.21.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
75
- quasarr-1.21.1.dist-info/entry_points.txt,sha256=gXi8mUKsIqKVvn-bOc8E5f04sK_KoMCC-ty6b2Hf-jc,40
76
- quasarr-1.21.1.dist-info/top_level.txt,sha256=dipJdaRda5ruTZkoGfZU60bY4l9dtPlmOWwxK_oGSF0,8
77
- quasarr-1.21.1.dist-info/RECORD,,
72
+ quasarr-1.21.2.dist-info/licenses/LICENSE,sha256=QQFCAfDgt7lSA8oSWDHIZ9aTjFbZaBJdjnGOHkuhK7k,1060
73
+ quasarr-1.21.2.dist-info/METADATA,sha256=OAMm_lRULGtRcSlDcgsOZAMZiF3M4JyTwNgw5QKGiWk,12743
74
+ quasarr-1.21.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
75
+ quasarr-1.21.2.dist-info/entry_points.txt,sha256=gXi8mUKsIqKVvn-bOc8E5f04sK_KoMCC-ty6b2Hf-jc,40
76
+ quasarr-1.21.2.dist-info/top_level.txt,sha256=dipJdaRda5ruTZkoGfZU60bY4l9dtPlmOWwxK_oGSF0,8
77
+ quasarr-1.21.2.dist-info/RECORD,,