mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
fix: 修复变更默认下载器不生效的问题
- 配置模块迁移到 `SettingsConfigDict` 以支持 Pydantic v2 的配置方式 - 在 `MediaInfo` 中新增 `release_dates` 字段,用于存储多地区发行日期信息 - 修改 `MetaVideo` 类中的 token 传递逻辑,以修复搜索站点资源序列化错误的问题
This commit is contained in:
+1
-1
@@ -215,7 +215,7 @@ class Command(metaclass=Singleton):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error occurred during command initialization in background: {e}", exc_info=True)
|
logger.error(f"Error occurred during command initialization in background: {e}", exc_info=True)
|
||||||
|
|
||||||
def __trigger_register_commands_event(self) -> (Optional[Event], dict):
|
def __trigger_register_commands_event(self) -> tuple[Optional[Event], dict]:
|
||||||
"""
|
"""
|
||||||
触发事件,允许调整命令数据
|
触发事件,允许调整命令数据
|
||||||
"""
|
"""
|
||||||
|
|||||||
+3
-3
@@ -12,7 +12,7 @@ from urllib.parse import urlparse
|
|||||||
|
|
||||||
from dotenv import set_key
|
from dotenv import set_key
|
||||||
from pydantic import BaseModel, Field, ConfigDict, model_validator
|
from pydantic import BaseModel, Field, ConfigDict, model_validator
|
||||||
from pydantic_settings import BaseSettings
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
from app.log import logger, log_settings, LogConfigModel
|
from app.log import logger, log_settings, LogConfigModel
|
||||||
from app.schemas import MediaType
|
from app.schemas import MediaType
|
||||||
@@ -438,10 +438,10 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel):
|
|||||||
系统配置类
|
系统配置类
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model_config = ConfigDict(
|
model_config = SettingsConfigDict(
|
||||||
case_sensitive=True,
|
case_sensitive=True,
|
||||||
env_file=SystemUtils.get_env_path(),
|
env_file=SystemUtils.get_env_path(),
|
||||||
env_file_encoding="utf-8"
|
env_file_encoding="utf-8",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
|||||||
@@ -250,6 +250,8 @@ class MediaInfo:
|
|||||||
production_countries: list = field(default_factory=list)
|
production_countries: list = field(default_factory=list)
|
||||||
# 语种
|
# 语种
|
||||||
spoken_languages: list = field(default_factory=list)
|
spoken_languages: list = field(default_factory=list)
|
||||||
|
# 所有发行日期
|
||||||
|
release_dates: list = field(default_factory=list)
|
||||||
# 状态
|
# 状态
|
||||||
status: str = None
|
status: str = None
|
||||||
# 标签
|
# 标签
|
||||||
@@ -433,6 +435,18 @@ class MediaInfo:
|
|||||||
if self.release_date:
|
if self.release_date:
|
||||||
# 年份
|
# 年份
|
||||||
self.year = self.release_date[:4]
|
self.year = self.release_date[:4]
|
||||||
|
# 所有发行日期
|
||||||
|
self.release_dates = [
|
||||||
|
{
|
||||||
|
"date": release_date.get("release_date"),
|
||||||
|
"iso_code": result.get("iso_3166_1"),
|
||||||
|
"note": release_date.get("note"),
|
||||||
|
"type": release_date.get("type"),
|
||||||
|
}
|
||||||
|
for result in info.get("release_dates", {}).get("results", [])
|
||||||
|
for release_date in result.get("release_dates", [])
|
||||||
|
if release_date.get("release_date")
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
# 电视剧
|
# 电视剧
|
||||||
self.title = info.get('name')
|
self.title = info.get('name')
|
||||||
|
|||||||
+12
-13
@@ -94,7 +94,6 @@ class MetaVideo(MetaBase):
|
|||||||
title = re.sub(r'\d{4}[\s._-]\d{1,2}[\s._-]\d{1,2}', "", title)
|
title = re.sub(r'\d{4}[\s._-]\d{1,2}[\s._-]\d{1,2}', "", title)
|
||||||
# 拆分tokens
|
# 拆分tokens
|
||||||
tokens = Tokens(title)
|
tokens = Tokens(title)
|
||||||
self.tokens = tokens
|
|
||||||
# 实例化StreamingPlatforms对象
|
# 实例化StreamingPlatforms对象
|
||||||
streaming_platforms = StreamingPlatforms()
|
streaming_platforms = StreamingPlatforms()
|
||||||
# 解析名称、年份、季、集、资源类型、分辨率等
|
# 解析名称、年份、季、集、资源类型、分辨率等
|
||||||
@@ -102,7 +101,7 @@ class MetaVideo(MetaBase):
|
|||||||
while token:
|
while token:
|
||||||
self._index += 1 # 更新当前处理的token索引
|
self._index += 1 # 更新当前处理的token索引
|
||||||
# Part
|
# Part
|
||||||
self.__init_part(token)
|
self.__init_part(token, tokens)
|
||||||
# 标题
|
# 标题
|
||||||
if self._continue_flag:
|
if self._continue_flag:
|
||||||
self.__init_name(token)
|
self.__init_name(token)
|
||||||
@@ -123,7 +122,7 @@ class MetaVideo(MetaBase):
|
|||||||
self.__init_resource_type(token)
|
self.__init_resource_type(token)
|
||||||
# 流媒体平台
|
# 流媒体平台
|
||||||
if self._continue_flag:
|
if self._continue_flag:
|
||||||
self.__init_web_source(token, streaming_platforms)
|
self.__init_web_source(token, tokens, streaming_platforms)
|
||||||
# 视频编码
|
# 视频编码
|
||||||
if self._continue_flag:
|
if self._continue_flag:
|
||||||
self.__init_video_encode(token)
|
self.__init_video_encode(token)
|
||||||
@@ -311,7 +310,7 @@ class MetaVideo(MetaBase):
|
|||||||
self.en_name = token
|
self.en_name = token
|
||||||
self._last_token_type = "enname"
|
self._last_token_type = "enname"
|
||||||
|
|
||||||
def __init_part(self, token: str):
|
def __init_part(self, token: str, tokens: Tokens):
|
||||||
"""
|
"""
|
||||||
识别Part
|
识别Part
|
||||||
"""
|
"""
|
||||||
@@ -327,12 +326,12 @@ class MetaVideo(MetaBase):
|
|||||||
if re_res:
|
if re_res:
|
||||||
if not self.part:
|
if not self.part:
|
||||||
self.part = re_res.group(1)
|
self.part = re_res.group(1)
|
||||||
nextv = self.tokens.cur()
|
nextv = tokens.cur()
|
||||||
if nextv \
|
if nextv \
|
||||||
and ((nextv.isdigit() and (len(nextv) == 1 or len(nextv) == 2 and nextv.startswith('0')))
|
and ((nextv.isdigit() and (len(nextv) == 1 or len(nextv) == 2 and nextv.startswith('0')))
|
||||||
or nextv.upper() in ['A', 'B', 'C', 'I', 'II', 'III']):
|
or nextv.upper() in ['A', 'B', 'C', 'I', 'II', 'III']):
|
||||||
self.part = "%s%s" % (self.part, nextv)
|
self.part = "%s%s" % (self.part, nextv)
|
||||||
self.tokens.get_next()
|
tokens.get_next()
|
||||||
self._last_token_type = "part"
|
self._last_token_type = "part"
|
||||||
self._continue_flag = False
|
self._continue_flag = False
|
||||||
# self._stop_name_flag = False
|
# self._stop_name_flag = False
|
||||||
@@ -582,7 +581,7 @@ class MetaVideo(MetaBase):
|
|||||||
self._effect.append(effect)
|
self._effect.append(effect)
|
||||||
self._last_token = effect.upper()
|
self._last_token = effect.upper()
|
||||||
|
|
||||||
def __init_web_source(self, token: str, streaming_platforms: StreamingPlatforms):
|
def __init_web_source(self, token: str, tokens: Tokens, streaming_platforms: StreamingPlatforms):
|
||||||
"""
|
"""
|
||||||
识别流媒体平台
|
识别流媒体平台
|
||||||
"""
|
"""
|
||||||
@@ -594,10 +593,10 @@ class MetaVideo(MetaBase):
|
|||||||
|
|
||||||
prev_token = None
|
prev_token = None
|
||||||
prev_idx = self._index - 2
|
prev_idx = self._index - 2
|
||||||
if 0 <= prev_idx < len(self.tokens.tokens):
|
if 0 <= prev_idx < len(tokens.tokens):
|
||||||
prev_token = self.tokens.tokens[prev_idx]
|
prev_token = tokens.tokens[prev_idx]
|
||||||
|
|
||||||
next_token = self.tokens.peek()
|
next_token = tokens.peek()
|
||||||
|
|
||||||
if streaming_platforms.is_streaming_platform(token):
|
if streaming_platforms.is_streaming_platform(token):
|
||||||
platform_name = streaming_platforms.get_streaming_platform_name(token)
|
platform_name = streaming_platforms.get_streaming_platform_name(token)
|
||||||
@@ -616,7 +615,7 @@ class MetaVideo(MetaBase):
|
|||||||
platform_name = streaming_platforms.get_streaming_platform_name(combined_token)
|
platform_name = streaming_platforms.get_streaming_platform_name(combined_token)
|
||||||
query_range = 2
|
query_range = 2
|
||||||
if is_next:
|
if is_next:
|
||||||
self.tokens.get_next()
|
tokens.get_next()
|
||||||
break
|
break
|
||||||
|
|
||||||
if not platform_name:
|
if not platform_name:
|
||||||
@@ -626,8 +625,8 @@ class MetaVideo(MetaBase):
|
|||||||
match_start_idx = self._index - query_range
|
match_start_idx = self._index - query_range
|
||||||
match_end_idx = self._index - 1
|
match_end_idx = self._index - 1
|
||||||
start_index = max(0, match_start_idx - query_range)
|
start_index = max(0, match_start_idx - query_range)
|
||||||
end_index = min(len(self.tokens.tokens), match_end_idx + 1 + query_range)
|
end_index = min(len(tokens.tokens), match_end_idx + 1 + query_range)
|
||||||
tokens_to_check = self.tokens.tokens[start_index:end_index]
|
tokens_to_check = tokens.tokens[start_index:end_index]
|
||||||
|
|
||||||
if any(tok and tok.upper() in web_tokens for tok in tokens_to_check):
|
if any(tok and tok.upper() in web_tokens for tok in tokens_to_check):
|
||||||
self.web_source = platform_name
|
self.web_source = platform_name
|
||||||
|
|||||||
@@ -232,6 +232,19 @@ class _DownloaderBase(ServiceBase[TService, DownloaderConf]):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self._default_config_name: Optional[str] = None
|
self._default_config_name: Optional[str] = None
|
||||||
|
|
||||||
|
def init_service(self, service_name: str,
|
||||||
|
service_type: Optional[Union[Type[TService], Callable[..., TService]]] = None):
|
||||||
|
"""
|
||||||
|
初始化服务,获取配置并实例化对应服务
|
||||||
|
|
||||||
|
:param service_name: 服务名称,作为配置匹配的依据
|
||||||
|
:param service_type: 服务的类型,可以是类类型(Type[TService])、工厂函数(Callable)或 None 来跳过实例化
|
||||||
|
"""
|
||||||
|
# 重置默认配置名称
|
||||||
|
self.reset_default_config_name()
|
||||||
|
# 初始化服务
|
||||||
|
super().init_service(service_name, service_type)
|
||||||
|
|
||||||
def get_default_config_name(self) -> Optional[str]:
|
def get_default_config_name(self) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
获取默认服务配置的名称
|
获取默认服务配置的名称
|
||||||
@@ -263,6 +276,12 @@ class _DownloaderBase(ServiceBase[TService, DownloaderConf]):
|
|||||||
return {}
|
return {}
|
||||||
return {conf.name: conf for conf in configs if conf.type == self._service_name and conf.enabled}
|
return {conf.name: conf for conf in configs if conf.type == self._service_name and conf.enabled}
|
||||||
|
|
||||||
|
def reset_default_config_name(self):
|
||||||
|
"""
|
||||||
|
重置默认配置名称
|
||||||
|
"""
|
||||||
|
self._default_config_name = None
|
||||||
|
|
||||||
|
|
||||||
class _MediaServerBase(ServiceBase[TService, MediaServerConf]):
|
class _MediaServerBase(ServiceBase[TService, MediaServerConf]):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ class MediaInfo(BaseModel):
|
|||||||
production_countries: Optional[list] = Field(default_factory=list)
|
production_countries: Optional[list] = Field(default_factory=list)
|
||||||
# 语种
|
# 语种
|
||||||
spoken_languages: Optional[list] = Field(default_factory=list)
|
spoken_languages: Optional[list] = Field(default_factory=list)
|
||||||
|
# 所有发行日期
|
||||||
|
release_dates: list = Field(default_factory=list)
|
||||||
# 状态
|
# 状态
|
||||||
status: Optional[str] = None
|
status: Optional[str] = None
|
||||||
# 标签
|
# 标签
|
||||||
|
|||||||
Reference in New Issue
Block a user