mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 23:47:41 +08:00
fix module close
This commit is contained in:
@@ -18,7 +18,7 @@ class BangumiModule(_ModuleBase):
|
|||||||
self.bangumiapi = BangumiApi()
|
self.bangumiapi = BangumiApi()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
pass
|
self.bangumiapi.close()
|
||||||
|
|
||||||
def test(self) -> Tuple[bool, str]:
|
def test(self) -> Tuple[bool, str]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -25,19 +25,18 @@ class BangumiApi(object):
|
|||||||
"person_credits": "v0/persons/%s/subjects",
|
"person_credits": "v0/persons/%s/subjects",
|
||||||
}
|
}
|
||||||
_base_url = "https://api.bgm.tv/"
|
_base_url = "https://api.bgm.tv/"
|
||||||
_req = RequestUtils(session=requests.Session())
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
self._session = requests.Session()
|
||||||
|
self._req = RequestUtils(session=self._session)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
@cached(maxsize=settings.CACHE_CONF["bangumi"], ttl=settings.CACHE_CONF["meta"])
|
@cached(maxsize=settings.CACHE_CONF["bangumi"], ttl=settings.CACHE_CONF["meta"])
|
||||||
def __invoke(cls, url, key: Optional[str] = None, **kwargs):
|
def __invoke(self, url, key: Optional[str] = None, **kwargs):
|
||||||
req_url = cls._base_url + url
|
req_url = self._base_url + url
|
||||||
params = {}
|
params = {}
|
||||||
if kwargs:
|
if kwargs:
|
||||||
params.update(kwargs)
|
params.update(kwargs)
|
||||||
resp = cls._req.get_res(url=req_url, params=params)
|
resp = self._req.get_res(url=req_url, params=params)
|
||||||
try:
|
try:
|
||||||
if not resp:
|
if not resp:
|
||||||
return None
|
return None
|
||||||
@@ -207,3 +206,7 @@ class BangumiApi(object):
|
|||||||
return self.__invoke(self._urls["discover"],
|
return self.__invoke(self._urls["discover"],
|
||||||
key="data",
|
key="data",
|
||||||
_ts=datetime.strftime(datetime.now(), '%Y%m%d'), **kwargs)
|
_ts=datetime.strftime(datetime.now(), '%Y%m%d'), **kwargs)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._session:
|
||||||
|
self._session.close()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, List, Dict
|
from typing import Optional, List, Dict
|
||||||
|
|
||||||
|
import requests
|
||||||
from requests import Response
|
from requests import Response
|
||||||
|
|
||||||
from app import schemas
|
from app import schemas
|
||||||
@@ -529,20 +530,19 @@ class Alist(StorageBase, metaclass=Singleton):
|
|||||||
if result["data"]["sign"]:
|
if result["data"]["sign"]:
|
||||||
download_url = download_url + "?sign=" + result["data"]["sign"]
|
download_url = download_url + "?sign=" + result["data"]["sign"]
|
||||||
|
|
||||||
resp = RequestUtils(
|
|
||||||
headers=self.__get_header_with_token()
|
|
||||||
).get_res(download_url)
|
|
||||||
|
|
||||||
if not path:
|
if not path:
|
||||||
new_path = settings.TEMP_PATH / fileitem.name
|
local_path = settings.TEMP_PATH / fileitem.name
|
||||||
else:
|
else:
|
||||||
new_path = path / fileitem.name
|
local_path = path / fileitem.name
|
||||||
|
|
||||||
with open(new_path, "wb") as f:
|
with requests.get(download_url, headers=self.__get_header_with_token(), stream=True) as r:
|
||||||
f.write(resp.content)
|
r.raise_for_status()
|
||||||
|
with open(local_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
if new_path.exists():
|
if local_path.exists():
|
||||||
return new_path
|
return local_path
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def upload(
|
def upload(
|
||||||
|
|||||||
@@ -45,7 +45,12 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]):
|
|||||||
return 3
|
return 3
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
pass
|
"""
|
||||||
|
停止模块服务
|
||||||
|
"""
|
||||||
|
for server in self.get_instances().values():
|
||||||
|
if server:
|
||||||
|
server.close()
|
||||||
|
|
||||||
def test(self) -> Optional[Tuple[bool, str]]:
|
def test(self) -> Optional[Tuple[bool, str]]:
|
||||||
"""
|
"""
|
||||||
@@ -273,7 +278,8 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]):
|
|||||||
episodes=episodes
|
episodes=episodes
|
||||||
) for season, episodes in seasoninfo.items()]
|
) for season, episodes in seasoninfo.items()]
|
||||||
|
|
||||||
def mediaserver_playing(self, server: str, count: Optional[int] = 20, **kwargs) -> List[schemas.MediaServerPlayItem]:
|
def mediaserver_playing(self, server: str, count: Optional[int] = 20, **kwargs) -> List[
|
||||||
|
schemas.MediaServerPlayItem]:
|
||||||
"""
|
"""
|
||||||
获取媒体服务器正在播放信息
|
获取媒体服务器正在播放信息
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from app.log import logger
|
|||||||
from app.schemas import MediaType
|
from app.schemas import MediaType
|
||||||
from app.utils.http import RequestUtils
|
from app.utils.http import RequestUtils
|
||||||
from app.utils.url import UrlUtils
|
from app.utils.url import UrlUtils
|
||||||
from schemas import MediaServerItem
|
from app.schemas import MediaServerItem
|
||||||
|
|
||||||
|
|
||||||
class Plex:
|
class Plex:
|
||||||
@@ -890,3 +890,7 @@ class Plex:
|
|||||||
session = Session()
|
session = Session()
|
||||||
session.headers = headers
|
session.headers = headers
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._session:
|
||||||
|
self._session.close()
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ class Api:
|
|||||||
"_api_path",
|
"_api_path",
|
||||||
"_request_utils",
|
"_request_utils",
|
||||||
"_version",
|
"_version",
|
||||||
|
"_session"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -138,7 +139,8 @@ class Api:
|
|||||||
self._apikey = apikey
|
self._apikey = apikey
|
||||||
self._token: Optional[str] = None
|
self._token: Optional[str] = None
|
||||||
self._version: Optional[Version] = None
|
self._version: Optional[Version] = None
|
||||||
self._request_utils = RequestUtils(session=requests.Session())
|
self._session = requests.Session()
|
||||||
|
self._request_utils = RequestUtils(session=self._session)
|
||||||
|
|
||||||
def sys_version(self) -> Optional[Version]:
|
def sys_version(self) -> Optional[Version]:
|
||||||
"""
|
"""
|
||||||
@@ -352,7 +354,7 @@ class Api:
|
|||||||
def del_item(self, guid: str, delete_file: bool) -> bool:
|
def del_item(self, guid: str, delete_file: bool) -> bool:
|
||||||
"""
|
"""
|
||||||
删除媒体
|
删除媒体
|
||||||
|
:param guid: 媒体GUID
|
||||||
:param delete_file: True删除媒体文件,False仅从媒体库移除
|
:param delete_file: True删除媒体文件,False仅从媒体库移除
|
||||||
"""
|
"""
|
||||||
if (
|
if (
|
||||||
@@ -491,3 +493,10 @@ class Api:
|
|||||||
if not suppress_log:
|
if not suppress_log:
|
||||||
logger.error(f"请求接口 {url} 异常:" + str(e))
|
logger.error(f"请求接口 {url} 异常:" + str(e))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""
|
||||||
|
关闭API会话
|
||||||
|
"""
|
||||||
|
if self._session:
|
||||||
|
self._session.close()
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ class TrimeMedia:
|
|||||||
"""
|
"""
|
||||||
return self._api
|
return self._api
|
||||||
|
|
||||||
def __create_api(self, host: Optional[str]) -> Optional[fnapi.Api]:
|
@staticmethod
|
||||||
|
def __create_api(host: Optional[str]) -> Optional[fnapi.Api]:
|
||||||
"""
|
"""
|
||||||
创建一个飞牛API
|
创建一个飞牛API
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ class TrimeMedia:
|
|||||||
api = fnapi.Api(host, api_key)
|
api = fnapi.Api(host, api_key)
|
||||||
return api if api.sys_version() else None
|
return api if api.sys_version() else None
|
||||||
|
|
||||||
def __del__(self):
|
def close(self):
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
def is_configured(self) -> bool:
|
def is_configured(self) -> bool:
|
||||||
@@ -118,6 +119,7 @@ class TrimeMedia:
|
|||||||
"""
|
"""
|
||||||
if self.is_authenticated():
|
if self.is_authenticated():
|
||||||
self._api.logout()
|
self._api.logout()
|
||||||
|
self._api.close()
|
||||||
self._userinfo = None
|
self._userinfo = None
|
||||||
logger.debug(f"{self._username} 已断开飞牛影视")
|
logger.debug(f"{self._username} 已断开飞牛影视")
|
||||||
|
|
||||||
|
|||||||
+17
-10
@@ -1,4 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
|
from contextlib import contextmanager
|
||||||
from typing import Any, Optional, Union
|
from typing import Any, Optional, Union
|
||||||
|
|
||||||
import chardet
|
import chardet
|
||||||
@@ -143,6 +144,22 @@ class RequestUtils:
|
|||||||
raise_exception=raise_exception,
|
raise_exception=raise_exception,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def get_stream(self, url: str, params: dict = None, **kwargs):
|
||||||
|
"""
|
||||||
|
获取流式响应的上下文管理器,适用于大文件下载
|
||||||
|
:param url: 请求的URL
|
||||||
|
:param params: 请求的参数
|
||||||
|
:param kwargs: 其他请求参数
|
||||||
|
"""
|
||||||
|
kwargs['stream'] = True
|
||||||
|
response = self.request(method="get", url=url, params=params, **kwargs)
|
||||||
|
try:
|
||||||
|
yield response
|
||||||
|
finally:
|
||||||
|
if response:
|
||||||
|
response.close()
|
||||||
|
|
||||||
def post_res(self,
|
def post_res(self,
|
||||||
url: str,
|
url: str,
|
||||||
data: Any = None,
|
data: Any = None,
|
||||||
@@ -343,11 +360,6 @@ class RequestUtils:
|
|||||||
content_type = response.headers.get("Content-Type", "")
|
content_type = response.headers.get("Content-Type", "")
|
||||||
if re.search(r"charset=[\"']?utf-8[\"']?", content_type, re.IGNORECASE):
|
if re.search(r"charset=[\"']?utf-8[\"']?", content_type, re.IGNORECASE):
|
||||||
return "utf-8"
|
return "utf-8"
|
||||||
# 暂不支持直接提取字符集,仅提取UTF8
|
|
||||||
# match = re.search(r"charset=[\"']?([^\"';\s]+)", content_type, re.IGNORECASE)
|
|
||||||
# if match:
|
|
||||||
# return match.group(1)
|
|
||||||
|
|
||||||
# 2. 检查响应体中的 BOM 标记(例如 UTF-8 BOM)
|
# 2. 检查响应体中的 BOM 标记(例如 UTF-8 BOM)
|
||||||
if response.content[:3] == b"\xef\xbb\xbf":
|
if response.content[:3] == b"\xef\xbb\xbf":
|
||||||
return "utf-8"
|
return "utf-8"
|
||||||
@@ -355,11 +367,6 @@ class RequestUtils:
|
|||||||
# 3. 如果是 HTML 响应体,检查其中的 <meta charset="..."> 标签
|
# 3. 如果是 HTML 响应体,检查其中的 <meta charset="..."> 标签
|
||||||
if re.search(r"charset=[\"']?utf-8[\"']?", response.text, re.IGNORECASE):
|
if re.search(r"charset=[\"']?utf-8[\"']?", response.text, re.IGNORECASE):
|
||||||
return "utf-8"
|
return "utf-8"
|
||||||
# 暂不支持直接提取字符集,仅提取UTF8
|
|
||||||
# match = re.search(r"<meta[^>]+charset=[\"']?([^\"'>\s]+)", response.text, re.IGNORECASE)
|
|
||||||
# if match:
|
|
||||||
# return match.group(1)
|
|
||||||
|
|
||||||
# 4. 使用 chardet 库进一步分析内容
|
# 4. 使用 chardet 库进一步分析内容
|
||||||
detection = chardet.detect(response.content)
|
detection = chardet.detect(response.content)
|
||||||
if detection.get("confidence", 0) > confidence_threshold:
|
if detection.get("confidence", 0) > confidence_threshold:
|
||||||
|
|||||||
Reference in New Issue
Block a user