Compare commits

..

6 Commits

Author SHA1 Message Date
jxxghp
607eb4b4aa v2.1.8
- 修复已知问题,优化UI细节
2025-01-04 14:20:57 +08:00
jxxghp
846b4e645c Merge pull request #3664 from Aqr-K/feature/log 2025-01-03 13:38:18 +08:00
Aqr-K
3775e99b02 Remove: del Todo 2025-01-03 13:17:46 +08:00
Aqr-K
cea77bddee feat(log): log supports hot update. 2025-01-03 06:08:29 +08:00
jxxghp
8ac0d169d2 fix 目录监控蓝光原盘 2025-01-02 13:30:59 +08:00
jxxghp
d5ac9f65f6 fix bug 2025-01-01 10:50:14 +08:00
6 changed files with 75 additions and 14 deletions

View File

@@ -527,8 +527,8 @@ class DownloadChain(ChainBase):
downloaded_list.append(context)
# 电视剧整季匹配
logger.info(f"开始匹配电视剧整季:{no_exists}")
if no_exists:
logger.info(f"开始匹配电视剧整季:{no_exists}")
# 先把整季缺失的拿出来,看是否刚好有所有季都满足的种子 {tmdbid: [seasons]}
need_seasons: Dict[int, list] = {}
for need_mid, need_tv in no_exists.items():
@@ -631,8 +631,8 @@ class DownloadChain(ChainBase):
# 全部下载完成
break
# 电视剧季内的集匹配
logger.info(f"开始电视剧完整集匹配:{no_exists}")
if no_exists:
logger.info(f"开始电视剧完整集匹配:{no_exists}")
# TMDBID列表
need_tv_list = list(no_exists)
for need_mid in need_tv_list:
@@ -701,8 +701,8 @@ class DownloadChain(ChainBase):
logger.info(f"{need_season} 剩余需要集:{need_episodes}")
# 仍然缺失的剧集从整季中选择需要的集数文件下载仅支持QB和TR
logger.info(f"开始电视剧多集拆包匹配:{no_exists}")
if no_exists:
logger.info(f"开始电视剧多集拆包匹配:{no_exists}")
# TMDBID列表
no_exists_list = list(no_exists)
for need_mid in no_exists_list:

View File

@@ -1010,7 +1010,8 @@ class TransferChain(ChainBase, metaclass=Singleton):
if not force:
transferd = self.transferhis.get_by_src(file_item.path, storage=file_item.storage)
if transferd:
all_success = False
if not transferd.status:
all_success = False
logger.info(f"{file_item.path} 已整理过,如需重新处理,请删除整理记录。")
err_msgs.append(f"{file_item.name} 已整理过")
fail_num += 1

View File

@@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple, Type
from dotenv import set_key
from pydantic import BaseModel, BaseSettings, validator, Field
from app.log import logger
from app.log import logger, log_settings, LogConfigModel
from app.utils.system import SystemUtils
from app.utils.url import UrlUtils
@@ -244,7 +244,7 @@ class ConfigModel(BaseModel):
TOKENIZED_SEARCH: bool = False
class Settings(BaseSettings, ConfigModel):
class Settings(BaseSettings, ConfigModel, LogConfigModel):
"""
系统配置类
"""
@@ -406,6 +406,8 @@ class Settings(BaseSettings, ConfigModel):
# 仅成功更新配置时,才更新内存
if success:
setattr(self, key, converted_value)
if hasattr(log_settings, key):
setattr(log_settings, key, converted_value)
return success, message
return True, ""
except Exception as e:
@@ -416,8 +418,14 @@ class Settings(BaseSettings, ConfigModel):
更新多个配置项
"""
results = {}
log_updated = False
for k, v in env.items():
results[k] = self.update_setting(k, v)
if hasattr(log_settings, k):
log_updated = True
# 本次更新存在日志配置项更新,需要重新加载日志配置
if log_updated:
logger.update_loggers()
return results
@property

View File

@@ -5,15 +5,19 @@ from pathlib import Path
from typing import Dict, Any, Optional
import click
from pydantic import BaseSettings
from pydantic import BaseSettings, BaseModel
from app.utils.system import SystemUtils
class LogSettings(BaseSettings):
class LogConfigModel(BaseModel):
"""
日志设置
Pydantic 配置模型,描述所有配置项及其类型和默认值
"""
class Config:
extra = "ignore" # 忽略未定义的配置项
# 配置文件目录
CONFIG_DIR: Optional[str] = None
# 是否为调试模式
@@ -29,6 +33,12 @@ class LogSettings(BaseSettings):
# 文件日志格式
LOG_FILE_FORMAT: str = "%(levelname)s%(asctime)s - %(message)s"
class LogSettings(BaseSettings, LogConfigModel):
"""
日志设置类
"""
@property
def CONFIG_PATH(self):
return SystemUtils.get_config_path(self.CONFIG_DIR)
@@ -124,7 +134,8 @@ class LoggerManager:
def __setup_logger(log_file: str):
"""
设置日志
log_file日志文件相对路径
:param log_file日志文件相对路径
"""
log_file_path = log_settings.LOG_PATH / log_file
log_file_path.parent.mkdir(parents=True, exist_ok=True)
@@ -134,6 +145,8 @@ class LoggerManager:
if log_settings.DEBUG:
_logger.setLevel(logging.DEBUG)
# 全局日志等级
else:
loglevel = getattr(logging, log_settings.LOG_LEVEL.upper(), logging.INFO)
_logger.setLevel(loglevel)
@@ -162,6 +175,21 @@ class LoggerManager:
return _logger
def update_loggers(self):
"""
更新日志实例
"""
_new_loggers: Dict[str, Any] = {}
for log_file, _logger in self._loggers.items():
# 移除已有的 handler避免重复添加
for handler in _logger.handlers:
_logger.removeHandler(handler)
# 重新设置日志实例
_new_logger = self.__setup_logger(log_file=log_file)
_new_loggers[log_file] = _new_logger
self._loggers = _new_loggers
def logger(self, method: str, msg: str, *args, **kwargs):
"""
获取模块的logger
@@ -181,7 +209,7 @@ class LoggerManager:
# 获取调用者的模块的logger
_logger = self._loggers.get(logfile)
if not _logger:
_logger = self.__setup_logger(logfile)
_logger = self.__setup_logger(log_file=logfile)
self._loggers[logfile] = _logger
# 调用logger的方法打印日志
if hasattr(_logger, method):

View File

@@ -1,9 +1,10 @@
import platform
import re
import threading
import traceback
from pathlib import Path
from threading import Lock
from typing import Any
from typing import Any, Optional
from apscheduler.schedulers.background import BackgroundScheduler
from cachetools import TTLCache
@@ -217,12 +218,35 @@ class Monitor(metaclass=Singleton):
:param event_path: 事件文件路径
:param file_size: 文件大小
"""
def __is_bluray_sub(_path: Path) -> bool:
"""
判断是否蓝光原盘目录内的子目录或文件
"""
return True if re.search(r"BDMV[/\\]STREAM", str(_path), re.IGNORECASE) else False
def __get_bluray_dir(_path: Path) -> Optional[Path]:
"""
获取蓝光原盘BDMV目录的上级目录
"""
for p in _path.parents:
if p.name == "BDMV":
return p.parent
return None
# 全程加锁
with lock:
# 蓝光原盘文件处理
if __is_bluray_sub(event_path):
event_path = __get_bluray_dir(event_path)
if not event_path:
return
# TTL缓存控重
if self._cache.get(str(event_path)):
return
self._cache[str(event_path)] = True
try:
# 开始整理
self.transferchain.do_transfer(

View File

@@ -1,2 +1,2 @@
APP_VERSION = 'v2.1.7'
FRONTEND_VERSION = 'v2.1.7'
APP_VERSION = 'v2.1.8'
FRONTEND_VERSION = 'v2.1.8'