mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-07-09 22:43:44 +08:00
fix indexer async
This commit is contained in:
@@ -1,23 +1,18 @@
|
||||
import re
|
||||
from typing import Tuple, List, Optional
|
||||
|
||||
from app.core.cache import cached
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.http import RequestUtils, AsyncRequestUtils
|
||||
from app.utils.singleton import Singleton
|
||||
from app.utils.string import StringUtils
|
||||
|
||||
|
||||
class TNodeSpider:
|
||||
_indexerid = None
|
||||
_domain = None
|
||||
_name = ""
|
||||
_proxy = None
|
||||
_cookie = None
|
||||
_ua = None
|
||||
_token = None
|
||||
class TNodeSpider(metaclass=Singleton):
|
||||
_size = 100
|
||||
_timeout = 15
|
||||
_searchurl = "%sapi/torrent/advancedSearch"
|
||||
_baseurl = "%sapi/torrent/advancedSearch"
|
||||
_downloadurl = "%sapi/torrent/download/%s"
|
||||
_pageurl = "%storrent/info/%s"
|
||||
|
||||
@@ -25,19 +20,16 @@ class TNodeSpider:
|
||||
if indexer:
|
||||
self._indexerid = indexer.get('id')
|
||||
self._domain = indexer.get('domain')
|
||||
self._searchurl = self._searchurl % self._domain
|
||||
self._searchurl = self._baseurl % self._domain
|
||||
self._name = indexer.get('name')
|
||||
if indexer.get('proxy'):
|
||||
self._proxy = settings.PROXY
|
||||
self._cookie = indexer.get('cookie')
|
||||
self._ua = indexer.get('ua')
|
||||
self._timeout = indexer.get('timeout') or 15
|
||||
self.init_config()
|
||||
|
||||
def init_config(self):
|
||||
self.__get_token()
|
||||
|
||||
def __get_token(self):
|
||||
@cached(region="indexer_spider", maxsize=1, ttl=60 * 60 * 24, skip_empty=True)
|
||||
def __get_token(self) -> Optional[str]:
|
||||
if not self._domain:
|
||||
return
|
||||
res = RequestUtils(ua=self._ua,
|
||||
@@ -47,14 +39,29 @@ class TNodeSpider:
|
||||
if res and res.status_code == 200:
|
||||
csrf_token = re.search(r'<meta name="x-csrf-token" content="(.+?)">', res.text)
|
||||
if csrf_token:
|
||||
self._token = csrf_token.group(1)
|
||||
return csrf_token.group(1)
|
||||
return None
|
||||
|
||||
def search(self, keyword: str, page: Optional[int] = 0) -> Tuple[bool, List[dict]]:
|
||||
if not self._token:
|
||||
logger.warn(f"{self._name} 未获取到token,无法搜索")
|
||||
return True, []
|
||||
@cached(region="indexer_spider", maxsize=1, ttl=60 * 60 * 24, skip_empty=True)
|
||||
async def __async_get_token(self) -> Optional[str]:
|
||||
if not self._domain:
|
||||
return
|
||||
res = await AsyncRequestUtils(ua=self._ua,
|
||||
cookies=self._cookie,
|
||||
proxies=self._proxy,
|
||||
timeout=self._timeout).get_res(url=self._domain)
|
||||
if res and res.status_code == 200:
|
||||
csrf_token = re.search(r'<meta name="x-csrf-token" content="(.+?)">', res.text)
|
||||
if csrf_token:
|
||||
_token = csrf_token.group(1)
|
||||
return None
|
||||
|
||||
def __get_params(self, keyword: str = None, page: Optional[int] = 0) -> dict:
|
||||
"""
|
||||
获取搜索参数
|
||||
"""
|
||||
search_type = "imdbid" if (keyword and keyword.startswith('tt')) else "title"
|
||||
params = {
|
||||
return {
|
||||
"page": int(page) + 1,
|
||||
"size": self._size,
|
||||
"type": search_type,
|
||||
@@ -69,9 +76,51 @@ class TNodeSpider:
|
||||
"resolution": [],
|
||||
"group": []
|
||||
}
|
||||
|
||||
def __parse_result(self, results: List[dict]) -> List[dict]:
|
||||
"""
|
||||
解析搜索结果
|
||||
"""
|
||||
torrents = []
|
||||
if not results:
|
||||
return torrents
|
||||
|
||||
for result in results:
|
||||
torrent = {
|
||||
'title': result.get('title'),
|
||||
'description': result.get('subtitle'),
|
||||
'enclosure': self._downloadurl % (self._domain, result.get('id')),
|
||||
'pubdate': StringUtils.format_timestamp(result.get('upload_time')),
|
||||
'size': result.get('size'),
|
||||
'seeders': result.get('seeding'),
|
||||
'peers': result.get('leeching'),
|
||||
'grabs': result.get('complete'),
|
||||
'downloadvolumefactor': result.get('downloadRate'),
|
||||
'uploadvolumefactor': result.get('uploadRate'),
|
||||
'page_url': self._pageurl % (self._domain, result.get('id')),
|
||||
'imdbid': result.get('imdb')
|
||||
}
|
||||
torrents.append(torrent)
|
||||
|
||||
return torrents
|
||||
|
||||
def search(self, keyword: str, page: Optional[int] = 0) -> Tuple[bool, List[dict]]:
|
||||
"""
|
||||
搜索
|
||||
"""
|
||||
# 获取token
|
||||
_token = self.__get_token()
|
||||
if not _token:
|
||||
logger.warn(f"{self._name} 未获取到token,无法搜索")
|
||||
return True, []
|
||||
|
||||
# 获取请求参数
|
||||
params = self.__get_params(keyword, page)
|
||||
|
||||
# 发送请求
|
||||
res = RequestUtils(
|
||||
headers={
|
||||
'X-CSRF-TOKEN': self._token,
|
||||
'X-CSRF-TOKEN': _token,
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"User-Agent": f"{self._ua}"
|
||||
},
|
||||
@@ -79,29 +128,46 @@ class TNodeSpider:
|
||||
proxies=self._proxy,
|
||||
timeout=self._timeout
|
||||
).post_res(url=self._searchurl, json=params)
|
||||
torrents = []
|
||||
if res and res.status_code == 200:
|
||||
results = res.json().get('data', {}).get("torrents") or []
|
||||
for result in results:
|
||||
torrent = {
|
||||
'title': result.get('title'),
|
||||
'description': result.get('subtitle'),
|
||||
'enclosure': self._downloadurl % (self._domain, result.get('id')),
|
||||
'pubdate': StringUtils.format_timestamp(result.get('upload_time')),
|
||||
'size': result.get('size'),
|
||||
'seeders': result.get('seeding'),
|
||||
'peers': result.get('leeching'),
|
||||
'grabs': result.get('complete'),
|
||||
'downloadvolumefactor': result.get('downloadRate'),
|
||||
'uploadvolumefactor': result.get('uploadRate'),
|
||||
'page_url': self._pageurl % (self._domain, result.get('id')),
|
||||
'imdbid': result.get('imdb')
|
||||
}
|
||||
torrents.append(torrent)
|
||||
return False, self.__parse_result(results)
|
||||
elif res is not None:
|
||||
logger.warn(f"{self._name} 搜索失败,错误码:{res.status_code}")
|
||||
return True, []
|
||||
else:
|
||||
logger.warn(f"{self._name} 搜索失败,无法连接 {self._domain}")
|
||||
return True, []
|
||||
|
||||
async def async_search(self, keyword: str, page: Optional[int] = 0) -> Tuple[bool, List[dict]]:
|
||||
"""
|
||||
异步搜索
|
||||
"""
|
||||
# 获取token
|
||||
_token = await self.__async_get_token()
|
||||
if not _token:
|
||||
logger.warn(f"{self._name} 未获取到token,无法搜索")
|
||||
return True, []
|
||||
|
||||
# 获取请求参数
|
||||
params = self.__get_params(keyword, page)
|
||||
|
||||
# 发送请求
|
||||
res = await AsyncRequestUtils(
|
||||
headers={
|
||||
'X-CSRF-TOKEN': _token,
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"User-Agent": f"{self._ua}"
|
||||
},
|
||||
cookies=self._cookie,
|
||||
proxies=self._proxy,
|
||||
timeout=self._timeout
|
||||
).post_res(url=self._searchurl, json=params)
|
||||
if res and res.status_code == 200:
|
||||
results = res.json().get('data', {}).get("torrents") or []
|
||||
return False, self.__parse_result(results)
|
||||
elif res is not None:
|
||||
logger.warn(f"{self._name} 搜索失败,错误码:{res.status_code}")
|
||||
return True, []
|
||||
else:
|
||||
logger.warn(f"{self._name} 搜索失败,无法连接 {self._domain}")
|
||||
return True, []
|
||||
return False, torrents
|
||||
|
||||
Reference in New Issue
Block a user