fix module close

This commit is contained in:
jxxghp
2025-06-03 17:11:44 +08:00
parent 90f113a292
commit 5d188e3877
8 changed files with 65 additions and 34 deletions

View File

@@ -18,7 +18,7 @@ class BangumiModule(_ModuleBase):
self.bangumiapi = BangumiApi()
def stop(self):
pass
self.bangumiapi.close()
def test(self) -> Tuple[bool, str]:
"""

View File

@@ -25,19 +25,18 @@ class BangumiApi(object):
"person_credits": "v0/persons/%s/subjects",
}
_base_url = "https://api.bgm.tv/"
_req = RequestUtils(session=requests.Session())
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"])
def __invoke(cls, url, key: Optional[str] = None, **kwargs):
req_url = cls._base_url + url
def __invoke(self, url, key: Optional[str] = None, **kwargs):
req_url = self._base_url + url
params = {}
if 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:
if not resp:
return None
@@ -207,3 +206,7 @@ class BangumiApi(object):
return self.__invoke(self._urls["discover"],
key="data",
_ts=datetime.strftime(datetime.now(), '%Y%m%d'), **kwargs)
def close(self):
if self._session:
self._session.close()

View File

@@ -3,6 +3,7 @@ from datetime import datetime
from pathlib import Path
from typing import Optional, List, Dict
import requests
from requests import Response
from app import schemas
@@ -529,20 +530,19 @@ class Alist(StorageBase, metaclass=Singleton):
if 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:
new_path = settings.TEMP_PATH / fileitem.name
local_path = settings.TEMP_PATH / fileitem.name
else:
new_path = path / fileitem.name
local_path = path / fileitem.name
with open(new_path, "wb") as f:
f.write(resp.content)
with requests.get(download_url, headers=self.__get_header_with_token(), stream=True) as r:
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():
return new_path
if local_path.exists():
return local_path
return None
def upload(

View File

@@ -45,7 +45,12 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]):
return 3
def stop(self):
pass
"""
停止模块服务
"""
for server in self.get_instances().values():
if server:
server.close()
def test(self) -> Optional[Tuple[bool, str]]:
"""
@@ -273,7 +278,8 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]):
episodes=episodes
) 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]:
"""
获取媒体服务器正在播放信息
"""

View File

@@ -14,7 +14,7 @@ from app.log import logger
from app.schemas import MediaType
from app.utils.http import RequestUtils
from app.utils.url import UrlUtils
from schemas import MediaServerItem
from app.schemas import MediaServerItem
class Plex:
@@ -890,3 +890,7 @@ class Plex:
session = Session()
session.headers = headers
return session
def close(self):
if self._session:
self._session.close()

View File

@@ -111,6 +111,7 @@ class Api:
"_api_path",
"_request_utils",
"_version",
"_session"
)
@property
@@ -138,7 +139,8 @@ class Api:
self._apikey = apikey
self._token: Optional[str] = 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]:
"""
@@ -352,7 +354,7 @@ class Api:
def del_item(self, guid: str, delete_file: bool) -> bool:
"""
删除媒体
:param guid: 媒体GUID
:param delete_file: True删除媒体文件False仅从媒体库移除
"""
if (
@@ -491,3 +493,10 @@ class Api:
if not suppress_log:
logger.error(f"请求接口 {url} 异常:" + str(e))
return None
def close(self):
"""
关闭API会话
"""
if self._session:
self._session.close()

View File

@@ -55,7 +55,8 @@ class TrimeMedia:
"""
return self._api
def __create_api(self, host: Optional[str]) -> Optional[fnapi.Api]:
@staticmethod
def __create_api(host: Optional[str]) -> Optional[fnapi.Api]:
"""
创建一个飞牛API
@@ -76,7 +77,7 @@ class TrimeMedia:
api = fnapi.Api(host, api_key)
return api if api.sys_version() else None
def __del__(self):
def close(self):
self.disconnect()
def is_configured(self) -> bool:
@@ -118,6 +119,7 @@ class TrimeMedia:
"""
if self.is_authenticated():
self._api.logout()
self._api.close()
self._userinfo = None
logger.debug(f"{self._username} 已断开飞牛影视")

View File

@@ -1,4 +1,5 @@
import re
from contextlib import contextmanager
from typing import Any, Optional, Union
import chardet
@@ -143,6 +144,22 @@ class RequestUtils:
raise_exception=raise_exception,
**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,
url: str,
data: Any = None,
@@ -343,11 +360,6 @@ class RequestUtils:
content_type = response.headers.get("Content-Type", "")
if re.search(r"charset=[\"']?utf-8[\"']?", content_type, re.IGNORECASE):
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
if response.content[:3] == b"\xef\xbb\xbf":
return "utf-8"
@@ -355,11 +367,6 @@ class RequestUtils:
# 3. 如果是 HTML 响应体,检查其中的 <meta charset="..."> 标签
if re.search(r"charset=[\"']?utf-8[\"']?", response.text, re.IGNORECASE):
return "utf-8"
# 暂不支持直接提取字符集仅提取UTF8
# match = re.search(r"<meta[^>]+charset=[\"']?([^\"'>\s]+)", response.text, re.IGNORECASE)
# if match:
# return match.group(1)
# 4. 使用 chardet 库进一步分析内容
detection = chardet.detect(response.content)
if detection.get("confidence", 0) > confidence_threshold: