mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
@@ -19,7 +19,7 @@ class GzipRequest(Request):
|
|||||||
body = await super().body()
|
body = await super().body()
|
||||||
if "gzip" in self.headers.getlist("Content-Encoding"):
|
if "gzip" in self.headers.getlist("Content-Encoding"):
|
||||||
body = gzip.decompress(body)
|
body = gzip.decompress(body)
|
||||||
self._body = body
|
self._body = body # noqa
|
||||||
return self._body
|
return self._body
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class ChainBase(metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with open(settings.TEMP_PATH / filename, 'wb') as f:
|
with open(settings.TEMP_PATH / filename, 'wb') as f:
|
||||||
pickle.dump(cache, f)
|
pickle.dump(cache, f) # noqa
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.error(f"保存缓存 {filename} 出错:{str(err)}")
|
logger.error(f"保存缓存 {filename} 出错:{str(err)}")
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
+2
-2
@@ -96,7 +96,7 @@ class SiteChain(ChainBase):
|
|||||||
))
|
))
|
||||||
return userdata
|
return userdata
|
||||||
|
|
||||||
def refresh_userdatas(self) -> Dict[str, SiteUserData]:
|
def refresh_userdatas(self) -> Optional[Dict[str, SiteUserData]]:
|
||||||
"""
|
"""
|
||||||
刷新所有站点的用户数据
|
刷新所有站点的用户数据
|
||||||
"""
|
"""
|
||||||
@@ -105,7 +105,7 @@ class SiteChain(ChainBase):
|
|||||||
result = {}
|
result = {}
|
||||||
for site in sites:
|
for site in sites:
|
||||||
if global_vars.is_system_stopped:
|
if global_vars.is_system_stopped:
|
||||||
return
|
return None
|
||||||
if site.get("is_active"):
|
if site.get("is_active"):
|
||||||
userdata = self.refresh_userdata(site)
|
userdata = self.refresh_userdata(site)
|
||||||
if userdata:
|
if userdata:
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import time
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Dict, List, Optional, Union, Tuple
|
from typing import Dict, List, Optional, Union, Tuple
|
||||||
|
|
||||||
|
from cachetools import TTLCache
|
||||||
|
|
||||||
from app.chain import ChainBase
|
from app.chain import ChainBase
|
||||||
from app.chain.download import DownloadChain
|
from app.chain.download import DownloadChain
|
||||||
from app.chain.media import MediaChain
|
from app.chain.media import MediaChain
|
||||||
@@ -508,7 +510,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# 记录重新识别过的种子
|
# 记录重新识别过的种子
|
||||||
_recognize_cached = []
|
_recognize_cached = TTLCache(maxsize=1024, ttl=6 * 3600)
|
||||||
|
|
||||||
with self._rlock:
|
with self._rlock:
|
||||||
logger.debug(f"match lock acquired at {datetime.now()}")
|
logger.debug(f"match lock acquired at {datetime.now()}")
|
||||||
@@ -572,14 +574,15 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
|
|
||||||
# 有自定义识别词时,需要判断是否需要重新识别
|
# 有自定义识别词时,需要判断是否需要重新识别
|
||||||
if subscribe.custom_words:
|
if subscribe.custom_words:
|
||||||
|
custom_words_list = subscribe.custom_words.split("\n")
|
||||||
_, apply_words = WordsMatcher().prepare(torrent_info.title,
|
_, apply_words = WordsMatcher().prepare(torrent_info.title,
|
||||||
custom_words=subscribe.custom_words.split("\n"))
|
custom_words=custom_words_list)
|
||||||
if apply_words:
|
if apply_words:
|
||||||
logger.info(
|
logger.info(
|
||||||
f'{torrent_info.site_name} - {torrent_info.title} 因订阅存在自定义识别词,重新识别元数据...')
|
f'{torrent_info.site_name} - {torrent_info.title} 因订阅存在自定义识别词,重新识别元数据...')
|
||||||
# 重新识别元数据
|
# 重新识别元数据
|
||||||
torrent_meta = MetaInfo(title=torrent_info.title, subtitle=torrent_info.description,
|
torrent_meta = MetaInfo(title=torrent_info.title, subtitle=torrent_info.description,
|
||||||
custom_words=subscribe.custom_words)
|
custom_words=custom_words_list)
|
||||||
# 媒体信息需要重新识别
|
# 媒体信息需要重新识别
|
||||||
torrent_mediainfo = None
|
torrent_mediainfo = None
|
||||||
|
|
||||||
@@ -588,8 +591,8 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
or (not torrent_mediainfo.tmdb_id and not torrent_mediainfo.douban_id):
|
or (not torrent_mediainfo.tmdb_id and not torrent_mediainfo.douban_id):
|
||||||
# 避免重复处理
|
# 避免重复处理
|
||||||
_cache_key = f"{torrent_meta.org_string}_{torrent_info.description}"
|
_cache_key = f"{torrent_meta.org_string}_{torrent_info.description}"
|
||||||
if _cache_key not in _recognize_cached:
|
if not _recognize_cached.get(_cache_key):
|
||||||
_recognize_cached.append(_cache_key)
|
_recognize_cached[_cache_key] = True
|
||||||
# 重新识别媒体信息
|
# 重新识别媒体信息
|
||||||
torrent_mediainfo = self.recognize_media(meta=torrent_meta)
|
torrent_mediainfo = self.recognize_media(meta=torrent_meta)
|
||||||
if torrent_mediainfo:
|
if torrent_mediainfo:
|
||||||
|
|||||||
+1
-1
@@ -293,7 +293,7 @@ class EventManager(metaclass=Singleton):
|
|||||||
|
|
||||||
# 对于类实例(实现了 __call__ 方法)
|
# 对于类实例(实现了 __call__ 方法)
|
||||||
if not inspect.isfunction(handler) and hasattr(handler, "__call__"):
|
if not inspect.isfunction(handler) and hasattr(handler, "__call__"):
|
||||||
handler_cls = handler.__class__
|
handler_cls = handler.__class__ # noqa
|
||||||
return cls.__get_handler_identifier(handler_cls)
|
return cls.__get_handler_identifier(handler_cls)
|
||||||
|
|
||||||
# 对于未绑定方法、静态方法、类方法,使用 __qualname__ 提取类信息
|
# 对于未绑定方法、静态方法、类方法,使用 __qualname__ 提取类信息
|
||||||
|
|||||||
+1
-1
@@ -225,7 +225,7 @@ class Base:
|
|||||||
return list(result)
|
return list(result)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
|
return {c.name: getattr(self, c.name, None) for c in self.__table__.columns} # noqa
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def __tablename__(self) -> str:
|
def __tablename__(self) -> str:
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ def init_db():
|
|||||||
初始化数据库
|
初始化数据库
|
||||||
"""
|
"""
|
||||||
# 全量建表
|
# 全量建表
|
||||||
Base.metadata.create_all(bind=Engine)
|
Base.metadata.create_all(bind=Engine) # noqa
|
||||||
|
|
||||||
|
|
||||||
def update_db():
|
def update_db():
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class MessageOper(DbOper):
|
|||||||
|
|
||||||
# 从kwargs中去掉Message中没有的字段
|
# 从kwargs中去掉Message中没有的字段
|
||||||
for k in list(kwargs.keys()):
|
for k in list(kwargs.keys()):
|
||||||
if k not in Message.__table__.columns.keys():
|
if k not in Message.__table__.columns.keys(): # noqa
|
||||||
kwargs.pop(k)
|
kwargs.pop(k)
|
||||||
|
|
||||||
Message(**kwargs).create(self._db)
|
Message(**kwargs).create(self._db)
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ class LoggerManager:
|
|||||||
plugin_name = None
|
plugin_name = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
frame = sys._getframe(3)
|
frame = sys._getframe(3) # noqa
|
||||||
except (AttributeError, ValueError):
|
except (AttributeError, ValueError):
|
||||||
# 如果无法获取帧,返回默认值
|
# 如果无法获取帧,返回默认值
|
||||||
return "log.py", None
|
return "log.py", None
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ class DoubanCache(metaclass=Singleton):
|
|||||||
return
|
return
|
||||||
|
|
||||||
with open(self._meta_path, 'wb') as f:
|
with open(self._meta_path, 'wb') as f:
|
||||||
pickle.dump(new_meta_data, f, pickle.HIGHEST_PROTOCOL)
|
pickle.dump(new_meta_data, f, pickle.HIGHEST_PROTOCOL) # noqa
|
||||||
|
|
||||||
def _random_sample(self, new_meta_data: dict) -> bool:
|
def _random_sample(self, new_meta_data: dict) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class DoubanScraper:
|
|||||||
# 电视剧元数据文件
|
# 电视剧元数据文件
|
||||||
doc = self.__gen_tv_nfo_file(mediainfo=mediainfo)
|
doc = self.__gen_tv_nfo_file(mediainfo=mediainfo)
|
||||||
if doc:
|
if doc:
|
||||||
return doc.toprettyxml(indent=" ", encoding="utf-8")
|
return doc.toprettyxml(indent=" ", encoding="utf-8") # noqa
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ class Emby:
|
|||||||
year: str = None,
|
year: str = None,
|
||||||
tmdb_id: int = None,
|
tmdb_id: int = None,
|
||||||
season: int = None
|
season: int = None
|
||||||
) -> Tuple[Optional[str], Optional[Dict[int, List[Dict[int, list]]]]]:
|
) -> Tuple[Optional[str], Optional[Dict[int, List[int]]]]:
|
||||||
"""
|
"""
|
||||||
根据标题和年份和季,返回Emby中的剧集列表
|
根据标题和年份和季,返回Emby中的剧集列表
|
||||||
:param item_id: Emby中的ID
|
:param item_id: Emby中的ID
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class AliPan(StorageBase, metaclass=Singleton):
|
|||||||
refresh_token = self.__auth_params.get("refreshToken")
|
refresh_token = self.__auth_params.get("refreshToken")
|
||||||
if refresh_token:
|
if refresh_token:
|
||||||
try:
|
try:
|
||||||
self.aligo = Aligo(refresh_token=refresh_token, show=show_qrcode, use_aria2=self._has_aria2c,
|
self.aligo = Aligo(refresh_token=refresh_token, show=show_qrcode, use_aria2=self._has_aria2c, # noqa
|
||||||
name="MoviePilot V2", level=logging.ERROR, re_login=False)
|
name="MoviePilot V2", level=logging.ERROR, re_login=False)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.error(f"初始化阿里云盘失败:{str(err)}")
|
logger.error(f"初始化阿里云盘失败:{str(err)}")
|
||||||
@@ -327,7 +327,7 @@ class AliPan(StorageBase, metaclass=Singleton):
|
|||||||
return None
|
return None
|
||||||
item = self.aligo.get_file_by_path(path=str(path))
|
item = self.aligo.get_file_by_path(path=str(path))
|
||||||
if item:
|
if item:
|
||||||
return self.__get_fileitem(item, parent=path.parent)
|
return self.__get_fileitem(item, parent=str(path.parent))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def delete(self, fileitem: schemas.FileItem) -> bool:
|
def delete(self, fileitem: schemas.FileItem) -> bool:
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class TmdbScraper:
|
|||||||
# 电视剧元数据文件
|
# 电视剧元数据文件
|
||||||
doc = self.__gen_tv_nfo_file(mediainfo=mediainfo)
|
doc = self.__gen_tv_nfo_file(mediainfo=mediainfo)
|
||||||
if doc:
|
if doc:
|
||||||
return doc.toprettyxml(indent=" ", encoding="utf-8")
|
return doc.toprettyxml(indent=" ", encoding="utf-8") # noqa
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -45,4 +45,4 @@ class StorageUsage(BaseModel):
|
|||||||
|
|
||||||
class StorageTransType(BaseModel):
|
class StorageTransType(BaseModel):
|
||||||
# 传输类型
|
# 传输类型
|
||||||
transtype: Optional[dict] = Field(default_factory=dict)
|
transtype: Optional[str] = None
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from pydantic import BaseModel, Field
|
|||||||
from app.schemas import TmdbEpisode, DownloadHistory
|
from app.schemas import TmdbEpisode, DownloadHistory
|
||||||
from app.schemas.file import FileItem
|
from app.schemas.file import FileItem
|
||||||
from app.schemas.system import TransferDirectoryConf
|
from app.schemas.system import TransferDirectoryConf
|
||||||
from schemas import MediaInfo, MetaInfo
|
|
||||||
|
|
||||||
|
|
||||||
class TransferTorrent(BaseModel):
|
class TransferTorrent(BaseModel):
|
||||||
|
|||||||
+1
-1
@@ -227,7 +227,7 @@ class StringUtils:
|
|||||||
size = float(size)
|
size = float(size)
|
||||||
d = [(1024 - 1, 'K'), (1024 ** 2 - 1, 'M'), (1024 ** 3 - 1, 'G'), (1024 ** 4 - 1, 'T')]
|
d = [(1024 - 1, 'K'), (1024 ** 2 - 1, 'M'), (1024 ** 3 - 1, 'G'), (1024 ** 4 - 1, 'T')]
|
||||||
s = [x[0] for x in d]
|
s = [x[0] for x in d]
|
||||||
index = bisect.bisect_left(s, size) - 1
|
index = bisect.bisect_left(s, size) - 1 # noqa
|
||||||
if index == -1:
|
if index == -1:
|
||||||
return str(size) + "B"
|
return str(size) + "B"
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user