1
1
""" Jackett scraper module """
2
+ import traceback
2
3
from typing import Optional
3
4
from pydantic import BaseModel
4
5
from requests import ReadTimeout , RequestException
5
6
from utils .logger import logger
6
7
from utils .settings import settings_manager
7
8
from utils .parser import parser
8
- from utils .request import RateLimitExceeded , get , RateLimiter
9
+ from utils .request import RateLimitExceeded , get , RateLimiter , ping
9
10
10
11
11
12
class JackettConfig (BaseModel ):
@@ -24,9 +25,9 @@ def __init__(self, _):
24
25
self .initialized = self .validate_settings ()
25
26
if not self .initialized and not self .api_key :
26
27
return
27
- self .parse_logging = False
28
28
self .minute_limiter = RateLimiter (max_calls = 60 , period = 60 , raise_on_limit = True )
29
29
self .second_limiter = RateLimiter (max_calls = 1 , period = 10 )
30
+ self .parse_logging = False
30
31
logger .info ("Jackett initialized!" )
31
32
32
33
def validate_settings (self ) -> bool :
@@ -38,8 +39,8 @@ def validate_settings(self) -> bool:
38
39
self .api_key = self .settings .api_key
39
40
try :
40
41
url = f"{ self .settings .url } /api/v2.0/indexers/!status:failing,test:passed/results/torznab?apikey={ self .api_key } &cat=2000&t=movie&q=test"
41
- response = get (url = url , retry_if_failed = False , timeout = 60 )
42
- if response .is_ok :
42
+ response = ping (url = url , timeout = 60 )
43
+ if response .ok :
43
44
return True
44
45
except ReadTimeout :
45
46
return True
@@ -65,18 +66,22 @@ def validate_settings(self) -> bool:
65
66
66
67
def run (self , item ):
67
68
"""Scrape Jackett for the given media items"""
69
+ if item is None or not self .initialized :
70
+ return
68
71
try :
69
72
self ._scrape_item (item )
70
- except RequestException :
73
+ except RateLimitExceeded as e :
71
74
self .minute_limiter .limit_hit ()
72
- logger .debug ("Jackett connection timeout for item: %s" , item .log_string )
75
+ logger .warn ("Jackett rate limit hit for item: %s" , item .log_string )
73
76
return
74
- except RateLimitExceeded :
77
+ except RequestException as e :
75
78
self .minute_limiter .limit_hit ()
76
- logger .debug ("Jackett rate limit hit for item : %s" , item . log_string )
79
+ logger .exception ("Jackett request exception : %s" , e , exc_info = True )
77
80
return
78
81
except Exception as e :
79
- logger .exception ("Jackett exception for item: %s - Exception: %s" , item .log_string , e )
82
+ self .minute_limiter .limit_hit ()
83
+ # logger.debug("Jackett exception for item: %s - Exception: %s", item.log_string, e.args[0], exc_info=True)
84
+ # logger.debug("Exception details: %s", traceback.format_exc())
80
85
return
81
86
82
87
def _scrape_item (self , item ):
@@ -105,8 +110,11 @@ def api_scrape(self, item):
105
110
if response .is_ok :
106
111
data = {}
107
112
streams = response .data ["rss" ]["channel" ].get ("item" , [])
108
- parsed_data_list = [parser .parse (item , stream .get ("title" )) for stream in streams ]
113
+ parsed_data_list = [parser .parse (item , stream .get ("title" )) for stream in streams if type ( stream ) != str ]
109
114
for stream , parsed_data in zip (streams , parsed_data_list ):
115
+ if type (stream ) == str :
116
+ logger .debug ("Found another string: %s" , stream )
117
+ continue
110
118
if parsed_data .get ("fetch" , True ) and parsed_data .get ("title_match" , False ):
111
119
attr = stream .get ("torznab:attr" , [])
112
120
infohash_attr = next ((a for a in attr if a .get ("@name" ) == "infohash" ), None )
@@ -118,6 +126,5 @@ def api_scrape(self, item):
118
126
logger .debug ("Jackett Fetch: %s - Parsed item: %s" , parsed_data ["fetch" ], parsed_data ["string" ])
119
127
if data :
120
128
item .parsed_data .extend (parsed_data_list )
121
- item .parsed_data .append ({self .key : True })
122
129
return data , len (streams )
123
- return {}, len ( streams ) or 0
130
+ return {}, 0
0 commit comments