This commit is contained in:
jxxghp 2023-09-07 14:59:32 +08:00
parent 1c07b306c3
commit 7efcde89b9
8 changed files with 218 additions and 201 deletions

View File

@ -242,12 +242,14 @@ class TransferChain(ChainBase):
f"回复:```\n/redo {his.id} [tmdbid]|[类型]\n``` 手动识别转移。"
))
continue
# 如果未开启新增已入库媒体是否跟随TMDB信息变化则根据tmdbid查询之前的title
if not settings.SCRAP_FOLLOW_TMDB:
transfer_historys = self.transferhis.get_by(tmdbid=file_mediainfo.tmdb_id,
type=file_mediainfo.type.value)
mtype=file_mediainfo.type.value)
if transfer_historys:
file_mediainfo.title = transfer_historys[0].title
logger.info(f"{file_path.name} 识别为:{file_mediainfo.type.value} {file_mediainfo.title_year}")
# 电视剧没有集无法转移
@ -338,6 +340,8 @@ class TransferChain(ChainBase):
mediainfo=file_mediainfo,
transferinfo=transferinfo
)
# 刮削单个文件
self.scrape_metadata(path=transferinfo.target_path, mediainfo=file_mediainfo)
# 更新进度
processed_num += 1
self.progress.update(value=processed_num / total_num * 100,
@ -356,8 +360,6 @@ class TransferChain(ChainBase):
# 媒体目录
if transfer_info.target_path.is_file():
transfer_info.target_path = transfer_info.target_path.parent
# 刮削
self.scrape_metadata(path=transfer_info.target_path, mediainfo=media)
# 刷新媒体库,根目录或季目录
self.refresh_mediaserver(mediainfo=media, file_path=transfer_info.target_path)
# 发送通知
@ -586,7 +588,6 @@ class TransferChain(ChainBase):
"""
logger.info(f"开始删除文件以及空目录:{path} ...")
if not path.exists():
logger.error(f"{path} 不存在")
return
elif path.is_file():
# 删除文件

View File

@ -15,9 +15,9 @@ class MetaBase(object):
"""
# 是否处理的文件
isfile: bool = False
# 原标题字符串
# 原标题字符串(未经过识别词处理)
title: str = ""
# 识别用字符串
# 识别用字符串(经过识别词处理后)
org_string: Optional[str] = None
# 副标题
subtitle: Optional[str] = None

View File

@ -85,38 +85,48 @@ class TransferHistory(Base):
return db.query(func.count(TransferHistory.id)).filter(TransferHistory.title.like(f'%{title}%')).first()[0]
@staticmethod
def list_by(db: Session, type: str = None, title: str = None, year: int = None, season: str = None,
def list_by(db: Session, mtype: str = None, title: str = None, year: str = None, season: str = None,
episode: str = None, tmdbid: int = None):
"""
据tmdbidseasonseason_episode查询转移记录
tmdbid + mtype title + year 必输
"""
if tmdbid and type:
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid,
TransferHistory.type == type).all()
if tmdbid and not season and not episode:
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid).all()
if tmdbid and season and not episode:
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid,
TransferHistory.seasons == season).all()
if tmdbid and season and episode:
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid,
TransferHistory.seasons == season,
TransferHistory.episodes == episode).all()
# 电视剧所有季集|电影
if not season and not episode:
return db.query(TransferHistory).filter(TransferHistory.title == title,
TransferHistory.year == year).all()
# 电视剧某季
if season and not episode:
return db.query(TransferHistory).filter(TransferHistory.title == title,
TransferHistory.year == year,
TransferHistory.seasons == season).all()
# 电视剧某季某集
if season and episode:
return db.query(TransferHistory).filter(TransferHistory.title == title,
TransferHistory.year == year,
TransferHistory.seasons == season,
TransferHistory.episodes == episode).all()
# TMDBID + 类型
if tmdbid and mtype:
if season and episode:
# 查询一集
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid,
TransferHistory.type == mtype,
TransferHistory.seasons == season,
TransferHistory.episodes == episode).all()
elif season:
# 查询一季
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid,
TransferHistory.type == mtype,
TransferHistory.seasons == season).all()
else:
# 查询所有
return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid,
TransferHistory.type == mtype).all()
# 标题 + 年份
elif title and year:
# 电视剧某季某集
if season and episode:
return db.query(TransferHistory).filter(TransferHistory.title == title,
TransferHistory.year == year,
TransferHistory.seasons == season,
TransferHistory.episodes == episode).all()
# 电视剧某季
elif season:
return db.query(TransferHistory).filter(TransferHistory.title == title,
TransferHistory.year == year,
TransferHistory.seasons == season).all()
# 电视剧所有季集|电影
else:
return db.query(TransferHistory).filter(TransferHistory.title == title,
TransferHistory.year == year).all()
return []
@staticmethod
def update_download_hash(db: Session, historyid: int = None, download_hash: str = None):

View File

@ -51,13 +51,13 @@ class TransferHistoryOper(DbOper):
"""
return TransferHistory.statistic(self._db, days)
def get_by(self, title: str = None, year: str = None, type: str = None,
def get_by(self, title: str = None, year: str = None, mtype: str = None,
season: str = None, episode: str = None, tmdbid: int = None) -> List[TransferHistory]:
"""
按类型标题年份季集查询转移记录
"""
return TransferHistory.list_by(db=self._db,
type=type,
mtype=mtype,
title=title,
year=year,
season=season,

View File

@ -264,7 +264,7 @@ class DirMonitor(_PluginBase):
# 如果未开启新增已入库媒体是否跟随TMDB信息变化则根据tmdbid查询之前的title
if not settings.SCRAP_FOLLOW_TMDB:
transfer_historys = self.transferhis.get_by(tmdbid=mediainfo.tmdb_id,
type=mediainfo.type.value)
mtype=mediainfo.type.value)
if transfer_historys:
mediainfo.title = transfer_historys[0].title
logger.info(f"{file_path.name} 识别为:{mediainfo.type.value} {mediainfo.title_year}")
@ -315,8 +315,8 @@ class DirMonitor(_PluginBase):
transferinfo=transferinfo
)
# 刮削元数据,根目录或季目录
self.chain.scrape_metadata(path=transferinfo.target_path.parent,
# 刮削单个文件
self.chain.scrape_metadata(path=transferinfo.target_path,
mediainfo=mediainfo)
"""

View File

@ -353,7 +353,7 @@ class LibraryScraper(_PluginBase):
# 如果未开启新增已入库媒体是否跟随TMDB信息变化则根据tmdbid查询之前的title
if not settings.SCRAP_FOLLOW_TMDB:
transfer_historys = self.transferhis.get_by(tmdbid=mediainfo.tmdb_id,
type=mediainfo.type.value)
mtype=mediainfo.type.value)
if transfer_historys:
mediainfo.title = transfer_historys[0].title
@ -379,7 +379,7 @@ class LibraryScraper(_PluginBase):
except Exception as err:
print(str(err))
# 开始刮削
# 刮削单个文件
self.chain.scrape_metadata(path=file, mediainfo=mediainfo)
@staticmethod

View File

@ -22,7 +22,7 @@ from app.modules.qbittorrent import Qbittorrent
from app.modules.themoviedb.tmdbv3api import Episode
from app.modules.transmission import Transmission
from app.plugins import _PluginBase
from app.schemas.types import NotificationType, EventType
from app.schemas.types import NotificationType, EventType, MediaType
from app.utils.path_utils import PathUtils
@ -116,154 +116,154 @@ class MediaSyncDel(_PluginBase):
拼装插件配置页面需要返回两块数据1页面配置2数据结构
"""
return [
{
'component': 'VForm',
'content': [
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'enabled',
'label': '启用插件',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'notify',
'label': '发送通知',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'del_source',
'label': '删除源文件',
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSelect',
'props': {
'model': 'sync_type',
'label': '同步方式',
'items': [
{'title': 'webhook', 'value': 'webhook'},
{'title': '日志', 'value': 'log'},
{'title': 'Scripter X', 'value': 'plugin'}
]
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'cron',
'label': '执行周期',
'placeholder': '5位cron表达式留空自动'
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'exclude_path',
'label': '排除路径'
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
},
'content': [
{
'component': 'VAlert',
'props': {
'text': '同步方式分为webhook、日志同步和Scripter X。'
'webhook需要Emby4.8.0.45及以上开启媒体删除的webhook'
'(建议使用媒体库刮削插件覆盖元数据重新刮削剧集路径)。'
'日志同步需要配置执行周期默认30分钟执行一次。'
'Scripter X方式需要emby安装并配置Scripter X插件无需配置执行周期。'
}
}
]
}
]
}
]
}
], {
"enabled": False,
"notify": True,
"del_source": False,
"sync_type": "webhook",
"cron": "*/30 * * * *",
"exclude_path": "",
}
{
'component': 'VForm',
'content': [
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'enabled',
'label': '启用插件',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'notify',
'label': '发送通知',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'del_source',
'label': '删除源文件',
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSelect',
'props': {
'model': 'sync_type',
'label': '同步方式',
'items': [
{'title': 'webhook', 'value': 'webhook'},
{'title': '日志', 'value': 'log'},
{'title': 'Scripter X', 'value': 'plugin'}
]
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'cron',
'label': '执行周期',
'placeholder': '5位cron表达式留空自动'
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'exclude_path',
'label': '排除路径'
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
},
'content': [
{
'component': 'VAlert',
'props': {
'text': '同步方式分为webhook、日志同步和Scripter X。'
'webhook需要Emby4.8.0.45及以上开启媒体删除的webhook'
'(建议使用媒体库刮削插件覆盖元数据重新刮削剧集路径)。'
'日志同步需要配置执行周期默认30分钟执行一次。'
'Scripter X方式需要emby安装并配置Scripter X插件无需配置执行周期。'
}
}
]
}
]
}
]
}
], {
"enabled": False,
"notify": True,
"del_source": False,
"sync_type": "webhook",
"cron": "*/30 * * * *",
"exclude_path": "",
}
def get_page(self) -> List[dict]:
"""
@ -639,29 +639,36 @@ class MediaSyncDel(_PluginBase):
if episode_num:
episode_num = str(episode_num).rjust(2, '0')
# 类型
mtype = MediaType.MOVIE if media_type in ["Movie", "MOV"] else MediaType.TV
# 删除电影
if media_type == "Movie" or media_type == "MOV":
if mtype == MediaType.MOVIE:
msg = f'电影 {media_name} {tmdb_id}'
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id)
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id,
mtype=mtype.value)
# 删除电视剧
elif (media_type == "Series" or media_type == "TV") and not season_num and not episode_num:
elif mtype == MediaType.TV and not season_num and not episode_num:
msg = f'剧集 {media_name} {tmdb_id}'
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id)
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id,
mtype=mtype.value)
# 删除季 S02
elif (media_type == "Season" or media_type == "TV") and season_num and not episode_num:
elif mtype == MediaType.TV and season_num and not episode_num:
if not season_num or not str(season_num).isdigit():
logger.error(f"{media_name} 季同步删除失败,未获取到具体季")
return
msg = f'剧集 {media_name} S{season_num} {tmdb_id}'
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id,
mtype=mtype.value,
season=f'S{season_num}')
# 删除剧集S02E02
elif (media_type == "Episode" or media_type == "TV") and season_num and episode_num:
elif mtype == MediaType.TV and season_num and episode_num:
if not season_num or not str(season_num).isdigit() or not episode_num or not str(episode_num).isdigit():
logger.error(f"{media_name} 集同步删除失败,未获取到具体集")
return
msg = f'剧集 {media_name} S{season_num}E{episode_num} {tmdb_id}'
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id,
mtype=mtype.value,
season=f'S{season_num}',
episode=f'E{episode_num}')
else:

View File

@ -275,8 +275,7 @@ class MessageForward(_PluginBase):
return access_token, appid
def __send_message(self, title: str, text: str = None, userid: str = None, access_token: str = None,
appid: str = None, i: int = None) -> \
Optional[bool]:
appid: str = None, i: int = None) -> Optional[bool]:
"""
发送文本消息
:param title: 消息标题
@ -305,8 +304,8 @@ class MessageForward(_PluginBase):
}
return self.__post_request(message_url=message_url, req_json=req_json, i=i, title=title)
def __send_image_message(self, title: str, text: str, image_url: str, userid: str = None, access_token: str = None,
appid: str = None, i: int = None) -> Optional[bool]:
def __send_image_message(self, title: str, text: str, image_url: str, userid: str = None,
access_token: str = None, appid: str = None, i: int = None) -> Optional[bool]:
"""
发送图文消息
:param title: 消息标题
@ -372,7 +371,7 @@ class MessageForward(_PluginBase):
logger.error(f"转发消息 {title} 异常,错误信息:{err}")
return False
def __get_access_token(self, corpid, appsecret):
def __get_access_token(self, corpid: str, appsecret: str):
"""
获取微信Token
:return 微信Token