quasarr 1.29.0__py3-none-any.whl → 1.31.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 +452 -230
- quasarr/downloads/__init__.py +7 -0
- quasarr/downloads/linkcrypters/filecrypt.py +2 -36
- quasarr/downloads/packages/__init__.py +52 -38
- quasarr/downloads/sources/dl.py +24 -122
- quasarr/downloads/sources/wx.py +96 -54
- quasarr/providers/jd_cache.py +131 -0
- quasarr/providers/obfuscated.py +6 -6
- quasarr/providers/utils.py +177 -0
- quasarr/providers/version.py +1 -1
- quasarr/search/sources/wx.py +40 -24
- {quasarr-1.29.0.dist-info → quasarr-1.31.0.dist-info}/METADATA +1 -3
- {quasarr-1.29.0.dist-info → quasarr-1.31.0.dist-info}/RECORD +17 -16
- {quasarr-1.29.0.dist-info → quasarr-1.31.0.dist-info}/WHEEL +0 -0
- {quasarr-1.29.0.dist-info → quasarr-1.31.0.dist-info}/entry_points.txt +0 -0
- {quasarr-1.29.0.dist-info → quasarr-1.31.0.dist-info}/licenses/LICENSE +0 -0
- {quasarr-1.29.0.dist-info → quasarr-1.31.0.dist-info}/top_level.txt +0 -0
quasarr/providers/utils.py
CHANGED
|
@@ -6,9 +6,12 @@ import os
|
|
|
6
6
|
import re
|
|
7
7
|
import socket
|
|
8
8
|
import sys
|
|
9
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
10
|
+
from io import BytesIO
|
|
9
11
|
from urllib.parse import urlparse
|
|
10
12
|
|
|
11
13
|
import requests
|
|
14
|
+
from PIL import Image
|
|
12
15
|
|
|
13
16
|
# Fallback user agent when FlareSolverr is not available
|
|
14
17
|
FALLBACK_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
|
|
@@ -187,3 +190,177 @@ def is_site_usable(shared_state, shorthand):
|
|
|
187
190
|
password = config.get('password')
|
|
188
191
|
|
|
189
192
|
return bool(user and password)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# =============================================================================
|
|
196
|
+
# LINK STATUS CHECKING
|
|
197
|
+
# =============================================================================
|
|
198
|
+
|
|
199
|
+
def generate_status_url(href, crypter_type):
|
|
200
|
+
"""
|
|
201
|
+
Generate a status URL for crypters that support it.
|
|
202
|
+
Returns None if status URL cannot be generated.
|
|
203
|
+
"""
|
|
204
|
+
if crypter_type == "hide":
|
|
205
|
+
# hide.cx links: https://hide.cx/folder/{UUID} or /container/{UUID} → https://hide.cx/state/{UUID}
|
|
206
|
+
match = re.search(r'hide\.cx/(?:folder/|container/)?([a-f0-9-]{36})', href, re.IGNORECASE)
|
|
207
|
+
if match:
|
|
208
|
+
uuid = match.group(1)
|
|
209
|
+
return f"https://hide.cx/state/{uuid}"
|
|
210
|
+
|
|
211
|
+
elif crypter_type == "tolink":
|
|
212
|
+
# tolink links: https://tolink.to/f/{ID} → https://tolink.to/f/{ID}/s/status.png
|
|
213
|
+
match = re.search(r'tolink\.to/f/([a-zA-Z0-9]+)', href, re.IGNORECASE)
|
|
214
|
+
if match:
|
|
215
|
+
link_id = match.group(1)
|
|
216
|
+
return f"https://tolink.to/f/{link_id}/s/status.png"
|
|
217
|
+
|
|
218
|
+
return None
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def detect_crypter_type(url):
|
|
222
|
+
"""Detect crypter type from URL for status checking."""
|
|
223
|
+
url_lower = url.lower()
|
|
224
|
+
if 'hide.' in url_lower:
|
|
225
|
+
return "hide"
|
|
226
|
+
elif 'tolink.' in url_lower:
|
|
227
|
+
return "tolink"
|
|
228
|
+
elif 'filecrypt.' in url_lower:
|
|
229
|
+
return "filecrypt"
|
|
230
|
+
elif 'keeplinks.' in url_lower:
|
|
231
|
+
return "keeplinks"
|
|
232
|
+
return None
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def image_has_green(image_data):
|
|
236
|
+
"""
|
|
237
|
+
Analyze image data to check if it contains green pixels.
|
|
238
|
+
Returns True if any significant green is detected (indicating online status).
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
img = Image.open(BytesIO(image_data))
|
|
242
|
+
# Convert palette images with transparency to RGBA first to avoid warning
|
|
243
|
+
if img.mode == 'P' and 'transparency' in img.info:
|
|
244
|
+
img = img.convert('RGBA')
|
|
245
|
+
img = img.convert('RGB')
|
|
246
|
+
|
|
247
|
+
pixels = list(img.getdata())
|
|
248
|
+
|
|
249
|
+
for r, g, b in pixels:
|
|
250
|
+
# Check if pixel is greenish: green channel is dominant
|
|
251
|
+
# and has a reasonable absolute value
|
|
252
|
+
if g > 100 and g > r * 1.3 and g > b * 1.3:
|
|
253
|
+
return True
|
|
254
|
+
|
|
255
|
+
return False
|
|
256
|
+
except Exception:
|
|
257
|
+
# If we can't analyze, assume online to not skip valid links
|
|
258
|
+
return True
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def fetch_status_image(status_url, shared_state=None):
|
|
262
|
+
"""
|
|
263
|
+
Fetch a status image and return (status_url, image_data).
|
|
264
|
+
Returns (status_url, None) on failure.
|
|
265
|
+
"""
|
|
266
|
+
try:
|
|
267
|
+
headers = {}
|
|
268
|
+
if shared_state:
|
|
269
|
+
user_agent = shared_state.values.get("user_agent")
|
|
270
|
+
if user_agent:
|
|
271
|
+
headers["User-Agent"] = user_agent
|
|
272
|
+
response = requests.get(status_url, headers=headers, timeout=10)
|
|
273
|
+
if response.status_code == 200:
|
|
274
|
+
return (status_url, response.content)
|
|
275
|
+
except Exception:
|
|
276
|
+
pass
|
|
277
|
+
return (status_url, None)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def check_links_online_status(links_with_status, shared_state=None):
|
|
281
|
+
"""
|
|
282
|
+
Check online status for links that have status URLs.
|
|
283
|
+
Returns list of links that are online (or have no status URL to check).
|
|
284
|
+
|
|
285
|
+
links_with_status: list of [href, identifier, status_url] where status_url can be None
|
|
286
|
+
shared_state: optional shared state for user agent
|
|
287
|
+
"""
|
|
288
|
+
links_to_check = [(i, link) for i, link in enumerate(links_with_status) if link[2]]
|
|
289
|
+
|
|
290
|
+
if not links_to_check:
|
|
291
|
+
# No status URLs to check, return all links as potentially online
|
|
292
|
+
return [[link[0], link[1]] for link in links_with_status]
|
|
293
|
+
|
|
294
|
+
# Batch fetch status images
|
|
295
|
+
status_results = {} # status_url -> has_green
|
|
296
|
+
status_urls = list(set(link[2] for _, link in links_to_check))
|
|
297
|
+
|
|
298
|
+
batch_size = 10
|
|
299
|
+
for i in range(0, len(status_urls), batch_size):
|
|
300
|
+
batch = status_urls[i:i + batch_size]
|
|
301
|
+
with ThreadPoolExecutor(max_workers=batch_size) as executor:
|
|
302
|
+
futures = [executor.submit(fetch_status_image, url, shared_state) for url in batch]
|
|
303
|
+
for future in as_completed(futures):
|
|
304
|
+
try:
|
|
305
|
+
status_url, image_data = future.result()
|
|
306
|
+
if image_data:
|
|
307
|
+
status_results[status_url] = image_has_green(image_data)
|
|
308
|
+
else:
|
|
309
|
+
# Could not fetch, assume online
|
|
310
|
+
status_results[status_url] = True
|
|
311
|
+
except Exception:
|
|
312
|
+
pass
|
|
313
|
+
|
|
314
|
+
# Filter to online links
|
|
315
|
+
online_links = []
|
|
316
|
+
|
|
317
|
+
for link in links_with_status:
|
|
318
|
+
href, identifier, status_url = link
|
|
319
|
+
if not status_url:
|
|
320
|
+
# No status URL, include link
|
|
321
|
+
online_links.append([href, identifier])
|
|
322
|
+
elif status_url in status_results:
|
|
323
|
+
if status_results[status_url]:
|
|
324
|
+
online_links.append([href, identifier])
|
|
325
|
+
else:
|
|
326
|
+
# Status check failed, include link
|
|
327
|
+
online_links.append([href, identifier])
|
|
328
|
+
|
|
329
|
+
return online_links
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def filter_offline_links(links, shared_state=None, log_func=None):
|
|
333
|
+
"""
|
|
334
|
+
Filter out offline links from a list of [url, identifier] pairs.
|
|
335
|
+
Only checks links where status can be verified (hide.cx, tolink).
|
|
336
|
+
Returns filtered list of [url, identifier] pairs.
|
|
337
|
+
"""
|
|
338
|
+
if not links:
|
|
339
|
+
return links
|
|
340
|
+
|
|
341
|
+
# Build list with status URLs
|
|
342
|
+
links_with_status = []
|
|
343
|
+
for link in links:
|
|
344
|
+
url = link[0]
|
|
345
|
+
identifier = link[1] if len(link) > 1 else "unknown"
|
|
346
|
+
crypter_type = detect_crypter_type(url)
|
|
347
|
+
status_url = generate_status_url(url, crypter_type) if crypter_type else None
|
|
348
|
+
links_with_status.append([url, identifier, status_url])
|
|
349
|
+
|
|
350
|
+
# Check if any links can be verified
|
|
351
|
+
verifiable_count = sum(1 for l in links_with_status if l[2])
|
|
352
|
+
if verifiable_count == 0:
|
|
353
|
+
# Nothing to verify, return original links
|
|
354
|
+
return links
|
|
355
|
+
|
|
356
|
+
if log_func:
|
|
357
|
+
log_func(f"Checking online status for {verifiable_count} verifiable link(s)...")
|
|
358
|
+
|
|
359
|
+
# Check status and filter
|
|
360
|
+
online_links = check_links_online_status(links_with_status, shared_state)
|
|
361
|
+
|
|
362
|
+
if log_func and len(online_links) < len(links):
|
|
363
|
+
offline_count = len(links) - len(online_links)
|
|
364
|
+
log_func(f"Filtered out {offline_count} offline link(s)")
|
|
365
|
+
|
|
366
|
+
return online_links
|
quasarr/providers/version.py
CHANGED
quasarr/search/sources/wx.py
CHANGED
|
@@ -131,6 +131,7 @@ def wx_feed(shared_state, start_time, request_from, mirror=None):
|
|
|
131
131
|
def wx_search(shared_state, start_time, request_from, search_string, mirror=None, season=None, episode=None):
|
|
132
132
|
"""
|
|
133
133
|
Search using internal API.
|
|
134
|
+
Deduplicates results by fulltitle - each unique release appears only once.
|
|
134
135
|
"""
|
|
135
136
|
releases = []
|
|
136
137
|
host = shared_state.values["config"]("Hostnames").get(hostname)
|
|
@@ -201,6 +202,9 @@ def wx_search(shared_state, start_time, request_from, search_string, mirror=None
|
|
|
201
202
|
|
|
202
203
|
debug(f"{hostname.upper()}: Found {len(items)} items in search results")
|
|
203
204
|
|
|
205
|
+
# Track seen titles to deduplicate (mirrors have same fulltitle)
|
|
206
|
+
seen_titles = set()
|
|
207
|
+
|
|
204
208
|
for item in items:
|
|
205
209
|
try:
|
|
206
210
|
uid = item.get('uid')
|
|
@@ -238,29 +242,34 @@ def wx_search(shared_state, start_time, request_from, search_string, mirror=None
|
|
|
238
242
|
title = title.replace(' ', '.')
|
|
239
243
|
|
|
240
244
|
if shared_state.is_valid_release(title, request_from, search_string, season, episode):
|
|
241
|
-
|
|
242
|
-
if
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
"
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
245
|
+
# Skip if we've already seen this exact title
|
|
246
|
+
if title in seen_titles:
|
|
247
|
+
debug(f"{hostname.upper()}: Skipping duplicate main title: {title}")
|
|
248
|
+
else:
|
|
249
|
+
seen_titles.add(title)
|
|
250
|
+
published = detail_item.get('updated_at') or detail_item.get('created_at')
|
|
251
|
+
if not published:
|
|
252
|
+
published = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")
|
|
253
|
+
password = f"www.{host}"
|
|
254
|
+
|
|
255
|
+
payload = urlsafe_b64encode(
|
|
256
|
+
f"{title}|{source}|{mirror}|0|{password}|{item_imdb_id or ''}".encode("utf-8")
|
|
257
|
+
).decode("utf-8")
|
|
258
|
+
link = f"{shared_state.values['internal_address']}/download/?payload={payload}"
|
|
259
|
+
|
|
260
|
+
releases.append({
|
|
261
|
+
"details": {
|
|
262
|
+
"title": title,
|
|
263
|
+
"hostname": hostname,
|
|
264
|
+
"imdb_id": item_imdb_id,
|
|
265
|
+
"link": link,
|
|
266
|
+
"mirror": mirror,
|
|
267
|
+
"size": 0,
|
|
268
|
+
"date": published,
|
|
269
|
+
"source": source
|
|
270
|
+
},
|
|
271
|
+
"type": "protected"
|
|
272
|
+
})
|
|
264
273
|
|
|
265
274
|
if 'releases' in detail_item and isinstance(detail_item['releases'], list):
|
|
266
275
|
debug(f"{hostname.upper()}: Found {len(detail_item['releases'])} releases for {uid}")
|
|
@@ -279,6 +288,13 @@ def wx_search(shared_state, start_time, request_from, search_string, mirror=None
|
|
|
279
288
|
debug(f"{hostname.upper()}: ✗ Release filtered out: {release_title}")
|
|
280
289
|
continue
|
|
281
290
|
|
|
291
|
+
# Skip if we've already seen this exact title (deduplication)
|
|
292
|
+
if release_title in seen_titles:
|
|
293
|
+
debug(f"{hostname.upper()}: Skipping duplicate release: {release_title}")
|
|
294
|
+
continue
|
|
295
|
+
|
|
296
|
+
seen_titles.add(release_title)
|
|
297
|
+
|
|
282
298
|
release_uid = release.get('uid')
|
|
283
299
|
if release_uid:
|
|
284
300
|
release_source = f"https://{host}/detail/{uid}?release={release_uid}"
|
|
@@ -323,7 +339,7 @@ def wx_search(shared_state, start_time, request_from, search_string, mirror=None
|
|
|
323
339
|
debug(f"{hostname.upper()}: {traceback.format_exc()}")
|
|
324
340
|
continue
|
|
325
341
|
|
|
326
|
-
debug(f"{hostname.upper()}: Returning {len(releases)} total releases")
|
|
342
|
+
debug(f"{hostname.upper()}: Returning {len(releases)} total releases (deduplicated)")
|
|
327
343
|
|
|
328
344
|
except Exception as e:
|
|
329
345
|
info(f"Error in {hostname.upper()} search: {e}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quasarr
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.31.0
|
|
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
|
|
@@ -45,8 +45,6 @@ Quasarr will confidently handle the rest. Some CAPTCHA types require [Tampermonk
|
|
|
45
45
|
|
|
46
46
|
# Instructions
|
|
47
47
|
|
|
48
|
-
# Instructions
|
|
49
|
-
|
|
50
48
|
1. Set up and run [JDownloader 2](https://jdownloader.org/download/index)
|
|
51
49
|
2. Configure the integrations below
|
|
52
50
|
3. (Optional) Set up [FlareSolverr 3](https://github.com/FlareSolverr/FlareSolverr) for sites that require it
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
quasarr/__init__.py,sha256=cEtxN2AuwKvrxpIvAR7UL997VtYQ4iN3Eo3ZnP-WjZQ,14682
|
|
2
2
|
quasarr/api/__init__.py,sha256=UOyyuOjF2WN6Um2wwQNHjFA-Rj0prb11z8SCjbifKJU,6940
|
|
3
3
|
quasarr/api/arr/__init__.py,sha256=BNEugX1hUF5kn8MIgdoyE1HeyabpojjxAa6RlXSem74,17518
|
|
4
|
-
quasarr/api/captcha/__init__.py,sha256=
|
|
4
|
+
quasarr/api/captcha/__init__.py,sha256=2d7fTTo-FOXufsG_MxyaDPt8r1KVbXbSXnJAgrt8Qvo,72591
|
|
5
5
|
quasarr/api/config/__init__.py,sha256=m0DrbanI0lK_PaZA6ey3osj5l1_tMjjYjoFKkzrdPu0,13692
|
|
6
6
|
quasarr/api/sponsors_helper/__init__.py,sha256=kAZabPlplPYRG6Uw7ZHTk5uypualwvhs-NoTOjQhhhA,6369
|
|
7
7
|
quasarr/api/statistics/__init__.py,sha256=NrBAjjHkIUE95HhPUGIfNqh2IqBqJ_zm00S90Y-Qnus,7038
|
|
8
|
-
quasarr/downloads/__init__.py,sha256=
|
|
8
|
+
quasarr/downloads/__init__.py,sha256=6COdDlJkNuWuJq7DLVqqb0fuH1b3HtsbvA0mlmtLeIs,11972
|
|
9
9
|
quasarr/downloads/linkcrypters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
quasarr/downloads/linkcrypters/al.py,sha256=mfUG5VclC_-FcGoZL9zHYD7dz7X_YpaNmoKkgiyl9-0,8812
|
|
11
|
-
quasarr/downloads/linkcrypters/filecrypt.py,sha256=
|
|
11
|
+
quasarr/downloads/linkcrypters/filecrypt.py,sha256=He8b7HjoPA-LmRwVwY0l_5JAVlJ3sYOXs5tcWXooqI4,17055
|
|
12
12
|
quasarr/downloads/linkcrypters/hide.py,sha256=8YmNm49JmVa1zZdTHpjK9gnQrX435Cq5fo4JTNsIpds,4850
|
|
13
|
-
quasarr/downloads/packages/__init__.py,sha256=
|
|
13
|
+
quasarr/downloads/packages/__init__.py,sha256=6U4rk7hWoQCidIZy5O3-Pt5P7ZWEavHdbqZB0arxN1Y,18679
|
|
14
14
|
quasarr/downloads/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
quasarr/downloads/sources/al.py,sha256=g587VESZRZHZ03uxHKpufEr5qAtzbyGLmoijksU35jk,27297
|
|
16
16
|
quasarr/downloads/sources/by.py,sha256=kmUTn3izayRCV7W-t0E4kYE8qTbt3L3reCLozfvRGcU,3807
|
|
17
17
|
quasarr/downloads/sources/dd.py,sha256=8X2tOle3qTq0b60Aa3o0uqp2vNELDHYYj99ERI7U_X0,2971
|
|
18
18
|
quasarr/downloads/sources/dj.py,sha256=wY00hVRNhucZBG1hfExKqayhP1ISD8FFQm7wHYxutOk,404
|
|
19
|
-
quasarr/downloads/sources/dl.py,sha256=
|
|
19
|
+
quasarr/downloads/sources/dl.py,sha256=HF0kCzjY1elA6oVjIRlP37lLkAXStQTva2dRYLBTOE0,14823
|
|
20
20
|
quasarr/downloads/sources/dt.py,sha256=80yIHAivsqoPKAaFdZ4wPFBVGCbHNUO130pv7EO2LTM,2605
|
|
21
21
|
quasarr/downloads/sources/dw.py,sha256=_28-E58Hs9NVwHyLt2M1oYUxVZ-wpE5dQv8gMNhiAPM,2622
|
|
22
22
|
quasarr/downloads/sources/he.py,sha256=AA6OrIkD3KS_w1ClvXyW1_9hujM6A8P_5VcMHRM6ngg,3680
|
|
@@ -27,20 +27,21 @@ quasarr/downloads/sources/sf.py,sha256=ecPHNsNiRNXTfQX9MBLzJKqrEc1IpkrKkBXpihTPh
|
|
|
27
27
|
quasarr/downloads/sources/sj.py,sha256=Bkv0c14AXct50n_viaTNK3bYG-Bpvx8x2D0UN_6gm78,404
|
|
28
28
|
quasarr/downloads/sources/sl.py,sha256=jWprFt1Hew1T67fB1O_pc9YWgc3NVh30KXSwSyS50Pc,3186
|
|
29
29
|
quasarr/downloads/sources/wd.py,sha256=kr1I1uJa7ZkEPH2LA6alXTJEn0LBPgLCwIh3wLXwCv8,4447
|
|
30
|
-
quasarr/downloads/sources/wx.py,sha256=
|
|
30
|
+
quasarr/downloads/sources/wx.py,sha256=NzNNeqVL6sKkFKyreW-oerrreb5QP2tUGHTWHM5pMCU,7013
|
|
31
31
|
quasarr/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
32
|
quasarr/providers/cloudflare.py,sha256=9iet8runc2VHVcA0_2z1qkrL6D5JKqz1ndktqCgsJFs,7873
|
|
33
33
|
quasarr/providers/html_images.py,sha256=2n82gTJg7E7q2ytPFN4FWouYTIlmPYu_iHFtG7uktIA,28482
|
|
34
34
|
quasarr/providers/html_templates.py,sha256=YMwdi7l_tHL0-qsUnwi4aPrE5Q6ZDxbjsPIfr-6uemY,10265
|
|
35
35
|
quasarr/providers/imdb_metadata.py,sha256=10L4kZkt6Fg0HGdNcc6KCtIQHRYEqdarLyaMVN6mT8w,4843
|
|
36
|
+
quasarr/providers/jd_cache.py,sha256=TfoQWetKZA7vO_qj2wFOGhgmVSXiMhwGpjl7HtLc_-c,5372
|
|
36
37
|
quasarr/providers/log.py,sha256=_g5RwtfuksARXnvryhsngzoJyFcNzj6suqd3ndqZM0Y,313
|
|
37
38
|
quasarr/providers/myjd_api.py,sha256=Z3PEiO3c3UfDSr4Up5rgwTAnjloWHb-H1RkJ6BLKZv8,34140
|
|
38
39
|
quasarr/providers/notifications.py,sha256=bohT-6yudmFnmZMc3BwCGX0n1HdzSVgQG_LDZm_38dI,4630
|
|
39
|
-
quasarr/providers/obfuscated.py,sha256=
|
|
40
|
+
quasarr/providers/obfuscated.py,sha256=8FcmY9cjvjOoth-6LrPZ1CZZbpKplcaMMBE06FkdYgA,1339187
|
|
40
41
|
quasarr/providers/shared_state.py,sha256=-TIiH2lkCfovq7bzUZicpUjXEjS87ZHCcevsFgySOqw,29944
|
|
41
42
|
quasarr/providers/statistics.py,sha256=cEQixYnDMDqtm5wWe40E_2ucyo4mD0n3SrfelhQi1L8,6452
|
|
42
|
-
quasarr/providers/utils.py,sha256=
|
|
43
|
-
quasarr/providers/version.py,sha256=
|
|
43
|
+
quasarr/providers/utils.py,sha256=mcUPbcXMsLmrYv0CTZO5a9aOt2-JLyL3SZxu6N8OyjU,12075
|
|
44
|
+
quasarr/providers/version.py,sha256=bjolkJyZ2IG4sc5GvrvZfwTeYTHWNvMAMp2vgnpPVZ0,4004
|
|
44
45
|
quasarr/providers/web_server.py,sha256=AYd0KRxdDWMBr87BP8wlSMuL4zZo0I_rY-vHBai6Pfg,1688
|
|
45
46
|
quasarr/providers/sessions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
47
|
quasarr/providers/sessions/al.py,sha256=WXue9LaT4y0BzsbKtHbN6bb_72c4AZZWR9NP-vg9-cg,12462
|
|
@@ -65,14 +66,14 @@ quasarr/search/sources/sf.py,sha256=3z_fvcafOh7U4D_vgq9yC8ktKeazI9fiAi96hCeXb5Q,
|
|
|
65
66
|
quasarr/search/sources/sj.py,sha256=JRzoCDohClmGH7aXOz82KVUt6pZsZoBDBXvwvQrAijM,7074
|
|
66
67
|
quasarr/search/sources/sl.py,sha256=5e5S7JvdbNOc2EthyOkfC4aTpG8O7fn4WS2O3_EXjnM,9463
|
|
67
68
|
quasarr/search/sources/wd.py,sha256=O02j3irSlVw2qES82g_qHuavAk-njjSRH1dHSCnOUas,7540
|
|
68
|
-
quasarr/search/sources/wx.py,sha256=
|
|
69
|
+
quasarr/search/sources/wx.py,sha256=zlRvg7Ls-DFRo4sUBMRAXZRMfE2mnaXCkzP7pu53pIY,13842
|
|
69
70
|
quasarr/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
71
|
quasarr/storage/config.py,sha256=SSTgIce2FVYoVTK_6OCU3msknhxuLA3EC4Kcrrf_dxQ,6378
|
|
71
72
|
quasarr/storage/setup.py,sha256=0Gm6sHLmlcKvOGeli9eVuRVEP0Slz8-K5jZG0cNXaew,42041
|
|
72
73
|
quasarr/storage/sqlite_database.py,sha256=yMqFQfKf0k7YS-6Z3_7pj4z1GwWSXJ8uvF4IydXsuTE,3554
|
|
73
|
-
quasarr-1.
|
|
74
|
-
quasarr-1.
|
|
75
|
-
quasarr-1.
|
|
76
|
-
quasarr-1.
|
|
77
|
-
quasarr-1.
|
|
78
|
-
quasarr-1.
|
|
74
|
+
quasarr-1.31.0.dist-info/licenses/LICENSE,sha256=QQFCAfDgt7lSA8oSWDHIZ9aTjFbZaBJdjnGOHkuhK7k,1060
|
|
75
|
+
quasarr-1.31.0.dist-info/METADATA,sha256=4jot6IFM_BIQwf8Ftx74l9W26M-2EaK8LXxC9XUn3qE,11009
|
|
76
|
+
quasarr-1.31.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
77
|
+
quasarr-1.31.0.dist-info/entry_points.txt,sha256=gXi8mUKsIqKVvn-bOc8E5f04sK_KoMCC-ty6b2Hf-jc,40
|
|
78
|
+
quasarr-1.31.0.dist-info/top_level.txt,sha256=dipJdaRda5ruTZkoGfZU60bY4l9dtPlmOWwxK_oGSF0,8
|
|
79
|
+
quasarr-1.31.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|