This commit is contained in:
jxxghp 2023-11-09 21:15:36 +08:00
parent b7448232e6
commit 01fb6e8772
11 changed files with 67 additions and 31 deletions

View File

@ -78,7 +78,6 @@ MoviePilot需要配套下载器和媒体服务器配合使用。
- **TMDB_API_DOMAIN** TMDB API地址默认`api.themoviedb.org`,也可配置为`api.tmdb.org`或其它中转代理服务地址,能连通即可 - **TMDB_API_DOMAIN** TMDB API地址默认`api.themoviedb.org`,也可配置为`api.tmdb.org`或其它中转代理服务地址,能连通即可
- **TMDB_IMAGE_DOMAIN** TMDB图片地址默认`image.tmdb.org`可配置为其它中转代理以加速TMDB图片显示`static-mdb.v.geilijiasu.com` - **TMDB_IMAGE_DOMAIN** TMDB图片地址默认`image.tmdb.org`可配置为其它中转代理以加速TMDB图片显示`static-mdb.v.geilijiasu.com`
- **WALLPAPER** 登录首页电影海报,`tmdb`/`bing`,默认`tmdb` - **WALLPAPER** 登录首页电影海报,`tmdb`/`bing`,默认`tmdb`
- **SEARCH_SOURCE** 媒体信息搜索来源,`themoviedb`/`douban`,默认`themoviedb`
- **RECOGNIZE_SOURCE** 媒体信息识别来源,`themoviedb`/`douban`,默认`themoviedb` - **RECOGNIZE_SOURCE** 媒体信息识别来源,`themoviedb`/`douban`,默认`themoviedb`
- **SCRAP_SOURCE** 刮削元数据及图片使用的数据源,`themoviedb`/`douban`,默认`themoviedb` - **SCRAP_SOURCE** 刮削元数据及图片使用的数据源,`themoviedb`/`douban`,默认`themoviedb`
--- ---

View File

@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
from app import schemas from app import schemas
from app.chain.subscribe import SubscribeChain from app.chain.subscribe import SubscribeChain
from app.core.config import settings from app.core.config import settings
from app.core.metainfo import MetaInfo
from app.core.security import verify_token from app.core.security import verify_token
from app.db import get_db from app.db import get_db
from app.db.models.subscribe import Subscribe from app.db.models.subscribe import Subscribe
@ -55,6 +56,11 @@ def create_subscribe(
mtype = MediaType(subscribe_in.type) mtype = MediaType(subscribe_in.type)
else: else:
mtype = None mtype = None
# 豆瓣标理
if subscribe_in.doubanid:
meta = MetaInfo(subscribe_in.name)
subscribe_in.name = meta.name
subscribe_in.season = meta.begin_season
# 标题转换 # 标题转换
if subscribe_in.name: if subscribe_in.name:
title = subscribe_in.name title = subscribe_in.name
@ -117,7 +123,7 @@ def subscribe_mediaid(
tmdbid = mediaid[5:] tmdbid = mediaid[5:]
if not tmdbid or not str(tmdbid).isdigit(): if not tmdbid or not str(tmdbid).isdigit():
return Subscribe() return Subscribe()
result = Subscribe.exists(db, int(tmdbid), season) result = Subscribe.exists(db, tmdbid=int(tmdbid), season=season)
elif mediaid.startswith("douban:"): elif mediaid.startswith("douban:"):
doubanid = mediaid[7:] doubanid = mediaid[7:]
if not doubanid: if not doubanid:

View File

@ -94,6 +94,9 @@ class SearchChain(ChainBase):
:param filter_rule: 过滤规则为空是使用默认过滤规则 :param filter_rule: 过滤规则为空是使用默认过滤规则
:param area: 搜索范围title or imdbid :param area: 搜索范围title or imdbid
""" """
# 豆瓣标题处理
if mediainfo.douban_id:
mediainfo.title = MetaInfo(title=mediainfo.title).name
logger.info(f'开始搜索资源,关键词:{keyword or mediainfo.title} ...') logger.info(f'开始搜索资源,关键词:{keyword or mediainfo.title} ...')
# 补充媒体信息 # 补充媒体信息
if not mediainfo.names: if not mediainfo.names:

View File

@ -75,6 +75,9 @@ class SubscribeChain(ChainBase):
else: else:
# 豆瓣识别模式 # 豆瓣识别模式
mediainfo = self.recognize_media(meta=metainfo, mtype=mtype, doubanid=doubanid) mediainfo = self.recognize_media(meta=metainfo, mtype=mtype, doubanid=doubanid)
if mediainfo:
# 豆瓣标题处理
mediainfo.title = MetaInfo(mediainfo.title).name
# 识别失败 # 识别失败
if not mediainfo: if not mediainfo:
logger.warn(f'未识别到媒体信息,标题:{title}tmdbid{tmdbid}doubanid{doubanid}') logger.warn(f'未识别到媒体信息,标题:{title}tmdbid{tmdbid}doubanid{doubanid}')
@ -143,6 +146,7 @@ class SubscribeChain(ChainBase):
判断订阅是否已存在 判断订阅是否已存在
""" """
if self.subscribeoper.exists(tmdbid=mediainfo.tmdb_id, if self.subscribeoper.exists(tmdbid=mediainfo.tmdb_id,
doubanid=mediainfo.douban_id,
season=meta.begin_season if meta else None): season=meta.begin_season if meta else None):
return True return True
return False return False

View File

@ -45,8 +45,6 @@ class Settings(BaseSettings):
PROXY_HOST: str = None PROXY_HOST: str = None
# 媒体识别来源 themoviedb/douban # 媒体识别来源 themoviedb/douban
RECOGNIZE_SOURCE: str = "themoviedb" RECOGNIZE_SOURCE: str = "themoviedb"
# 媒体信息搜索来源 themoviedb/douban
SEARCH_SOURCE: str = "themoviedb"
# 刮削来源 themoviedb/douban # 刮削来源 themoviedb/douban
SCRAP_SOURCE: str = "themoviedb" SCRAP_SOURCE: str = "themoviedb"
# 刮削入库的媒体文件 # 刮削入库的媒体文件

View File

@ -417,20 +417,28 @@ class MediaInfo:
if not self.type: if not self.type:
if isinstance(info.get('media_type'), MediaType): if isinstance(info.get('media_type'), MediaType):
self.type = info.get('media_type') self.type = info.get('media_type')
else: elif info.get("type"):
self.type = MediaType.MOVIE if info.get("type") == "movie" else MediaType.TV self.type = MediaType.MOVIE if info.get("type") == "movie" else MediaType.TV
elif info.get("type_name"):
self.type = MediaType(info.get("type_name"))
# 标题 # 标题
if not self.title: if not self.title:
# 识别标题中的季 self.title = info.get("title")
meta = MetaInfo(info.get("title"))
self.season = meta.begin_season
self.title = meta.name
# 原语种标题 # 原语种标题
if not self.original_title: if not self.original_title:
self.original_title = info.get("original_title") self.original_title = info.get("original_title")
# 年份 # 年份
if not self.year: if not self.year:
self.year = info.get("year")[:4] if info.get("year") else None self.year = info.get("year")[:4] if info.get("year") else None
# 识别标题中的季
meta = MetaInfo(info.get("title"))
# 季
if not self.season:
self.season = meta.begin_season
if self.season:
self.type = MediaType.TV
else:
self.type = MediaType.MOVIE
# 评分 # 评分
if not self.vote_average: if not self.vote_average:
rating = info.get("rating") rating = info.get("rating")

View File

@ -69,11 +69,15 @@ class Subscribe(Base):
@staticmethod @staticmethod
@db_query @db_query
def exists(db: Session, tmdbid: int, season: int = None): def exists(db: Session, tmdbid: int = None, doubanid: str = None, season: int = None):
if tmdbid:
if season: if season:
return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid, return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid,
Subscribe.season == season).first() Subscribe.season == season).first()
return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid).first() return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid).first()
elif doubanid:
return db.query(Subscribe).filter(Subscribe.doubanid == doubanid).first()
return None
@staticmethod @staticmethod
@db_query @db_query

View File

@ -15,7 +15,10 @@ class SubscribeOper(DbOper):
""" """
新增订阅 新增订阅
""" """
subscribe = Subscribe.exists(self._db, tmdbid=mediainfo.tmdb_id, season=kwargs.get('season')) subscribe = Subscribe.exists(self._db,
tmdbid=mediainfo.tmdb_id,
doubanid=mediainfo.douban_id,
season=kwargs.get('season'))
if not subscribe: if not subscribe:
subscribe = Subscribe(name=mediainfo.title, subscribe = Subscribe(name=mediainfo.title,
year=mediainfo.year, year=mediainfo.year,
@ -32,19 +35,26 @@ class SubscribeOper(DbOper):
**kwargs) **kwargs)
subscribe.create(self._db) subscribe.create(self._db)
# 查询订阅 # 查询订阅
subscribe = Subscribe.exists(self._db, tmdbid=mediainfo.tmdb_id, season=kwargs.get('season')) subscribe = Subscribe.exists(self._db,
tmdbid=mediainfo.tmdb_id,
doubanid=mediainfo.douban_id,
season=kwargs.get('season'))
return subscribe.id, "新增订阅成功" return subscribe.id, "新增订阅成功"
else: else:
return subscribe.id, "订阅已存在" return subscribe.id, "订阅已存在"
def exists(self, tmdbid: int, season: int) -> bool: def exists(self, tmdbid: int = None, doubanid: str = None, season: int = None) -> bool:
""" """
判断是否存在 判断是否存在
""" """
if tmdbid:
if season: if season:
return True if Subscribe.exists(self._db, tmdbid=tmdbid, season=season) else False return True if Subscribe.exists(self._db, tmdbid=tmdbid, season=season) else False
else: else:
return True if Subscribe.exists(self._db, tmdbid=tmdbid) else False return True if Subscribe.exists(self._db, tmdbid=tmdbid) else False
elif doubanid:
return True if Subscribe.exists(self._db, doubanid=doubanid) else False
return False
def get(self, sid: int) -> Subscribe: def get(self, sid: int) -> Subscribe:
""" """

View File

@ -484,7 +484,7 @@ class DoubanModule(_ModuleBase):
:reutrn: 媒体信息 :reutrn: 媒体信息
""" """
# 未启用豆瓣搜索时返回None # 未启用豆瓣搜索时返回None
if settings.SEARCH_SOURCE != "douban": if settings.RECOGNIZE_SOURCE != "douban":
return None return None
if not meta.name: if not meta.name:
@ -495,7 +495,7 @@ class DoubanModule(_ModuleBase):
# 返回数据 # 返回数据
ret_medias = [] ret_medias = []
for item_obj in result.get("items"): for item_obj in result.get("items"):
if meta.type and meta.type.value != item_obj.get("type_name"): if meta.type and meta.type != MediaType.UNKNOWN and meta.type.value != item_obj.get("type_name"):
continue continue
if item_obj.get("type_name") not in (MediaType.TV.value, MediaType.MOVIE.value): if item_obj.get("type_name") not in (MediaType.TV.value, MediaType.MOVIE.value):
continue continue

View File

@ -7,6 +7,7 @@ from typing import Optional
from app.core.config import settings from app.core.config import settings
from app.core.meta import MetaBase from app.core.meta import MetaBase
from app.core.metainfo import MetaInfo
from app.utils.singleton import Singleton from app.utils.singleton import Singleton
from app.schemas.types import MediaType from app.schemas.types import MediaType
@ -128,24 +129,27 @@ class DoubanCache(metaclass=Singleton):
with lock: with lock:
if info: if info:
# 缓存标题 # 缓存标题
cache_title = info.get("title") \ cache_title = info.get("title")
if info.get("media_type") == MediaType.MOVIE else info.get("name")
# 缓存年份 # 缓存年份
cache_year = info.get('release_date') \ cache_year = info.get('year')
if info.get("media_type") == MediaType.MOVIE else info.get('first_air_date')
if cache_year:
cache_year = cache_year[:4]
# 类型 # 类型
if isinstance(info.get('media_type'), MediaType): if isinstance(info.get('media_type'), MediaType):
mtype = info.get('media_type') mtype = info.get('media_type')
else: elif info.get("type"):
mtype = MediaType.MOVIE if info.get("type") == "movie" else MediaType.TV mtype = MediaType.MOVIE if info.get("type") == "movie" else MediaType.TV
else:
meta = MetaInfo(cache_title)
if meta.begin_season:
mtype = MediaType.TV
else:
mtype = MediaType.MOVIE
# 海报 # 海报
poster_path = info.get("pic", {}).get("large") poster_path = info.get("pic", {}).get("large")
if not poster_path and info.get("cover_url"): if not poster_path and info.get("cover_url"):
poster_path = info.get("cover_url") poster_path = info.get("cover_url")
if not poster_path and info.get("cover"): if not poster_path and info.get("cover"):
poster_path = info.get("cover").get("url") poster_path = info.get("cover").get("url")
self._meta_data[self.__get_key(meta)] = { self._meta_data[self.__get_key(meta)] = {
"id": info.get("id"), "id": info.get("id"),
"type": mtype, "type": mtype,

View File

@ -188,7 +188,7 @@ class TheMovieDbModule(_ModuleBase):
:reutrn: 媒体信息列表 :reutrn: 媒体信息列表
""" """
# 未启用时返回None # 未启用时返回None
if settings.SEARCH_SOURCE != "themoviedb": if settings.RECOGNIZE_SOURCE != "themoviedb":
return None return None
if not meta.name: if not meta.name: