mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-11 08:35:58 +08:00
feat: 支持豆瓣识别缓存管理
This commit is contained in:
@@ -6,11 +6,61 @@ from app import schemas
|
||||
from app.chain.douban import DoubanChain
|
||||
from app.core.context import MediaInfo
|
||||
from app.core.security import verify_token
|
||||
from app.db.models.user import User
|
||||
from app.db.user_oper import get_current_active_superuser_async
|
||||
from app.modules.douban.douban_cache import DoubanCache
|
||||
from app.schemas import MediaType
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get(
|
||||
"/cache", summary="查询豆瓣识别缓存", response_model=schemas.Response
|
||||
)
|
||||
async def douban_recognition_cache(
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
) -> schemas.Response:
|
||||
"""查询可管理的豆瓣识别缓存。"""
|
||||
cache_items = DoubanCache().list_items()
|
||||
recognized_count = sum(1 for item in cache_items if item["douban_id"])
|
||||
return schemas.Response(
|
||||
success=True,
|
||||
data={
|
||||
"count": len(cache_items),
|
||||
"recognized": recognized_count,
|
||||
"unrecognized": len(cache_items) - recognized_count,
|
||||
"data": cache_items,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.delete(
|
||||
"/cache/{cache_key:path}",
|
||||
summary="删除指定豆瓣识别缓存",
|
||||
response_model=schemas.Response,
|
||||
)
|
||||
async def delete_douban_recognition_cache(
|
||||
cache_key: str,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
) -> schemas.Response:
|
||||
"""按缓存键删除单条豆瓣识别缓存。"""
|
||||
deleted_item = DoubanCache().delete(cache_key)
|
||||
if not deleted_item:
|
||||
return schemas.Response(success=False, message="豆瓣识别缓存不存在")
|
||||
return schemas.Response(success=True, message="豆瓣识别缓存删除成功")
|
||||
|
||||
|
||||
@router.delete(
|
||||
"/cache", summary="清空豆瓣识别缓存", response_model=schemas.Response
|
||||
)
|
||||
async def clear_douban_recognition_cache(
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
) -> schemas.Response:
|
||||
"""清空全部豆瓣识别缓存。"""
|
||||
DoubanCache().clear()
|
||||
return schemas.Response(success=True, message="豆瓣识别缓存清理完成")
|
||||
|
||||
|
||||
@router.get(
|
||||
"/person/{person_id}", summary="人物详情", response_model=schemas.MediaPerson
|
||||
)
|
||||
|
||||
@@ -179,6 +179,9 @@
|
||||
"TheMovieDb 识别缓存不存在": "TheMovieDb recognition cache does not exist",
|
||||
"TheMovieDb 识别缓存删除成功": "TheMovieDb recognition cache deleted successfully",
|
||||
"TheMovieDb 识别缓存清理完成": "TheMovieDb recognition cache cleanup completed",
|
||||
"豆瓣识别缓存不存在": "Douban recognition cache does not exist",
|
||||
"豆瓣识别缓存删除成功": "Douban recognition cache deleted successfully",
|
||||
"豆瓣识别缓存清理完成": "Douban recognition cache cleanup completed",
|
||||
"重新识别完成": "Re-recognition completed",
|
||||
"未识别到新名称": "Unable to recognize new name",
|
||||
"缺少参数": "Missing parameters",
|
||||
|
||||
@@ -108,7 +108,10 @@
|
||||
"Redis连接失败,请检查配置": "Redis连接失败,请检查配置",
|
||||
"TheMovieDb 识别缓存不存在": "TheMovieDb 识别缓存不存在",
|
||||
"TheMovieDb 识别缓存删除成功": "TheMovieDb 识别缓存删除成功",
|
||||
"TheMovieDb 识别缓存清理完成": "TheMovieDb 识别缓存清理完成"
|
||||
"TheMovieDb 识别缓存清理完成": "TheMovieDb 识别缓存清理完成",
|
||||
"豆瓣识别缓存不存在": "豆瓣识别缓存不存在",
|
||||
"豆瓣识别缓存删除成功": "豆瓣识别缓存删除成功",
|
||||
"豆瓣识别缓存清理完成": "豆瓣识别缓存清理完成"
|
||||
},
|
||||
"message_patterns": [
|
||||
{
|
||||
|
||||
@@ -179,6 +179,9 @@
|
||||
"TheMovieDb 识别缓存不存在": "TheMovieDb 識別快取不存在",
|
||||
"TheMovieDb 识别缓存删除成功": "TheMovieDb 識別快取刪除成功",
|
||||
"TheMovieDb 识别缓存清理完成": "TheMovieDb 識別快取清理完成",
|
||||
"豆瓣识别缓存不存在": "豆瓣識別快取不存在",
|
||||
"豆瓣识别缓存删除成功": "豆瓣識別快取刪除成功",
|
||||
"豆瓣识别缓存清理完成": "豆瓣識別快取清理完成",
|
||||
"重新识别完成": "重新識別完成",
|
||||
"未识别到新名称": "未識別到新名稱",
|
||||
"缺少参数": "缺少參數",
|
||||
|
||||
@@ -25,10 +25,11 @@ class DoubanCache(metaclass=WeakSingleton):
|
||||
"type": MediaType
|
||||
}
|
||||
"""
|
||||
# TMDB缓存过期
|
||||
# 豆瓣缓存过期
|
||||
_douban_cache_expire: bool = True
|
||||
|
||||
def __init__(self):
|
||||
"""初始化豆瓣识别缓存并恢复本地持久化数据。"""
|
||||
self.maxsize = settings.CONF.douban
|
||||
self.ttl = settings.CONF.meta
|
||||
self.region = "__douban_cache__"
|
||||
@@ -46,6 +47,30 @@ class DoubanCache(metaclass=WeakSingleton):
|
||||
"""
|
||||
with lock:
|
||||
self._cache.clear()
|
||||
self.save(force=True)
|
||||
|
||||
def list_items(self) -> list[dict]:
|
||||
"""返回可供管理界面展示的豆瓣识别缓存列表。"""
|
||||
with lock:
|
||||
cache_items = []
|
||||
for key, value in self._cache.items():
|
||||
if not isinstance(value, dict):
|
||||
continue
|
||||
media_type = value.get("type")
|
||||
if not isinstance(media_type, MediaType):
|
||||
try:
|
||||
media_type = MediaType(media_type)
|
||||
except (TypeError, ValueError):
|
||||
media_type = None
|
||||
cache_items.append({
|
||||
"key": key,
|
||||
"douban_id": value.get("id") or 0,
|
||||
"title": value.get("title") or "",
|
||||
"year": value.get("year") or "",
|
||||
"media_type": media_type.to_agent() if media_type else "unknown",
|
||||
"poster_path": value.get("poster_path") or "",
|
||||
})
|
||||
return sorted(cache_items, key=lambda item: item["key"])
|
||||
|
||||
@staticmethod
|
||||
def __get_key(meta: MetaBase) -> str:
|
||||
@@ -73,6 +98,7 @@ class DoubanCache(metaclass=WeakSingleton):
|
||||
redis_data = self._cache.get(key)
|
||||
if redis_data:
|
||||
self._cache.delete(key)
|
||||
self.save(force=True)
|
||||
return redis_data
|
||||
return {}
|
||||
|
||||
@@ -169,4 +195,5 @@ class DoubanCache(metaclass=WeakSingleton):
|
||||
pickle.dump(new_meta_data, f, pickle.HIGHEST_PROTOCOL) # noqa
|
||||
|
||||
def __del__(self):
|
||||
"""实例释放前保存非 Redis 缓存。"""
|
||||
self.save()
|
||||
|
||||
Reference in New Issue
Block a user