fix BestFilmVersion 短时间内连续触发插件 造成的重复订阅
This commit is contained in:
parent
271ab494a9
commit
9e37068b75
@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from threading import RLock
|
||||||
from typing import Optional, Any, List, Dict, Tuple
|
from typing import Optional, Any, List, Dict, Tuple
|
||||||
from xml.dom.minidom import parseString
|
from xml.dom.minidom import parseString
|
||||||
|
|
||||||
@ -22,6 +23,8 @@ from app.schemas import WebhookEventInfo
|
|||||||
from app.schemas.types import MediaType, EventType
|
from app.schemas.types import MediaType, EventType
|
||||||
from app.utils.http import RequestUtils
|
from app.utils.http import RequestUtils
|
||||||
|
|
||||||
|
lock = RLock()
|
||||||
|
|
||||||
|
|
||||||
class BestFilmVersion(_PluginBase):
|
class BestFilmVersion(_PluginBase):
|
||||||
# 插件名称
|
# 插件名称
|
||||||
@ -373,128 +376,143 @@ class BestFilmVersion(_PluginBase):
|
|||||||
"""
|
"""
|
||||||
通过流媒体管理工具收藏,自动洗版
|
通过流媒体管理工具收藏,自动洗版
|
||||||
"""
|
"""
|
||||||
|
# 获取锁
|
||||||
|
_is_lock: bool = lock.acquire(timeout=60)
|
||||||
|
if not _is_lock:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
# 读取缓存
|
||||||
|
caches = self._cache_path.read_text().split("\n") if self._cache_path.exists() else []
|
||||||
|
# 读取历史记录
|
||||||
|
history = self.get_data('history') or []
|
||||||
|
|
||||||
# 读取缓存
|
all_item = []
|
||||||
caches = self._cache_path.read_text().split("\n") if self._cache_path.exists() else []
|
# 读取收藏
|
||||||
# 读取历史记录
|
if settings.MEDIASERVER == 'jellyfin':
|
||||||
history = self.get_data('history') or []
|
self.jellyfin_get_items(all_item)
|
||||||
|
elif settings.MEDIASERVER == 'emby':
|
||||||
|
self.emby_get_items(all_item)
|
||||||
|
else:
|
||||||
|
resp = self.plex_get_watchlist()
|
||||||
|
if not resp:
|
||||||
|
return
|
||||||
|
all_item.extend(resp)
|
||||||
|
|
||||||
all_item = []
|
def function(y, x):
|
||||||
# 读取收藏
|
return y if (x['Name'] in [i['Name'] for i in y]) else (lambda z, u: (z.append(u), z))(y, x)[1]
|
||||||
if settings.MEDIASERVER == 'jellyfin':
|
|
||||||
# 获取所有user
|
# all_item 根据电影名去重
|
||||||
users_url = "{HOST}Users?&apikey={APIKEY}"
|
result = reduce(function, all_item, [])
|
||||||
users = self.get_users(Jellyfin().get_data(users_url))
|
|
||||||
if not users:
|
for data in result:
|
||||||
logger.info(f"bestfilmversion/users_url: {users_url}")
|
# 检查缓存
|
||||||
return
|
if data.get('Name') in caches:
|
||||||
for user in users:
|
|
||||||
# 根据加入日期 降序排序
|
|
||||||
url = "{HOST}Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
|
||||||
"&SortOrder=Descending" \
|
|
||||||
"&Filters=IsFavorite" \
|
|
||||||
"&Recursive=true" \
|
|
||||||
"&Fields=PrimaryImageAspectRatio%2CBasicSyncInfo" \
|
|
||||||
"&CollapseBoxSetItems=false" \
|
|
||||||
"&ExcludeLocationTypes=Virtual" \
|
|
||||||
"&EnableTotalRecordCount=false" \
|
|
||||||
"&Limit=20" \
|
|
||||||
"&apikey={APIKEY}"
|
|
||||||
resp = self.get_items(Jellyfin().get_data(url))
|
|
||||||
if not resp:
|
|
||||||
continue
|
continue
|
||||||
all_item.extend(resp)
|
|
||||||
elif settings.MEDIASERVER == 'emby':
|
# 获取详情
|
||||||
# 获取所有user
|
if settings.MEDIASERVER == 'jellyfin':
|
||||||
get_users_url = "{HOST}Users?&api_key={APIKEY}"
|
item_info_resp = Jellyfin().get_iteminfo(itemid=data.get('Id'))
|
||||||
users = self.get_users(Emby().get_data(get_users_url))
|
elif settings.MEDIASERVER == 'emby':
|
||||||
if not users:
|
item_info_resp = Emby().get_iteminfo(itemid=data.get('Id'))
|
||||||
return
|
else:
|
||||||
for user in users:
|
item_info_resp = self.plex_get_iteminfo(itemid=data.get('Id'))
|
||||||
# 根据加入日期 降序排序
|
|
||||||
url = "{HOST}emby/Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
logger.info(f'BestFilmVersion插件 item打印 {item_info_resp}')
|
||||||
"&SortOrder=Descending" \
|
if not item_info_resp:
|
||||||
"&Filters=IsFavorite" \
|
|
||||||
"&Recursive=true" \
|
|
||||||
"&Fields=PrimaryImageAspectRatio%2CBasicSyncInfo" \
|
|
||||||
"&CollapseBoxSetItems=false" \
|
|
||||||
"&ExcludeLocationTypes=Virtual" \
|
|
||||||
"&EnableTotalRecordCount=false" \
|
|
||||||
"&Limit=20&api_key={APIKEY}"
|
|
||||||
resp = self.get_items(Emby().get_data(url))
|
|
||||||
if not resp:
|
|
||||||
continue
|
continue
|
||||||
all_item.extend(resp)
|
|
||||||
else:
|
# 只接受Movie类型
|
||||||
resp = self.plex_get_watchlist()
|
if data.get('Type') != 'Movie':
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 获取tmdb_id
|
||||||
|
media_info_ids = item_info_resp.get('ExternalUrls')
|
||||||
|
if not media_info_ids:
|
||||||
|
continue
|
||||||
|
for media_info_id in media_info_ids:
|
||||||
|
if 'TheMovieDb' != media_info_id.get('Name'):
|
||||||
|
continue
|
||||||
|
tmdb_find_id = str(media_info_id.get('Url')).split('/')
|
||||||
|
tmdb_find_id.reverse()
|
||||||
|
tmdb_id = tmdb_find_id[0]
|
||||||
|
# 识别媒体信息
|
||||||
|
mediainfo: MediaInfo = self.chain.recognize_media(tmdbid=tmdb_id, mtype=MediaType.MOVIE)
|
||||||
|
if not mediainfo:
|
||||||
|
logger.warn(f'未识别到媒体信息,标题:{data.get("Name")},tmdbID:{tmdb_id}')
|
||||||
|
continue
|
||||||
|
# 添加订阅
|
||||||
|
self.subscribechain.add(mtype=MediaType.MOVIE,
|
||||||
|
title=mediainfo.title,
|
||||||
|
year=mediainfo.year,
|
||||||
|
tmdbid=mediainfo.tmdb_id,
|
||||||
|
best_version=True,
|
||||||
|
username="收藏洗版",
|
||||||
|
exist_ok=True)
|
||||||
|
# 加入缓存
|
||||||
|
caches.append(data.get('Name'))
|
||||||
|
# 存储历史记录
|
||||||
|
if mediainfo.tmdb_id not in [h.get("tmdbid") for h in history]:
|
||||||
|
history.append({
|
||||||
|
"title": mediainfo.title,
|
||||||
|
"type": mediainfo.type.value,
|
||||||
|
"year": mediainfo.year,
|
||||||
|
"poster": mediainfo.get_poster_image(),
|
||||||
|
"overview": mediainfo.overview,
|
||||||
|
"tmdbid": mediainfo.tmdb_id,
|
||||||
|
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
})
|
||||||
|
# 保存历史记录
|
||||||
|
self.save_data('history', history)
|
||||||
|
# 保存缓存
|
||||||
|
self._cache_path.write_text("\n".join(caches))
|
||||||
|
finally:
|
||||||
|
lock.release()
|
||||||
|
|
||||||
|
def jellyfin_get_items(self, all_item):
|
||||||
|
# 获取所有user
|
||||||
|
users_url = "{HOST}Users?&apikey={APIKEY}"
|
||||||
|
users = self.get_users(Jellyfin().get_data(users_url))
|
||||||
|
if not users:
|
||||||
|
logger.info(f"bestfilmversion/users_url: {users_url}")
|
||||||
|
return
|
||||||
|
for user in users:
|
||||||
|
# 根据加入日期 降序排序
|
||||||
|
url = "{HOST}Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
||||||
|
"&SortOrder=Descending" \
|
||||||
|
"&Filters=IsFavorite" \
|
||||||
|
"&Recursive=true" \
|
||||||
|
"&Fields=PrimaryImageAspectRatio%2CBasicSyncInfo" \
|
||||||
|
"&CollapseBoxSetItems=false" \
|
||||||
|
"&ExcludeLocationTypes=Virtual" \
|
||||||
|
"&EnableTotalRecordCount=false" \
|
||||||
|
"&Limit=20" \
|
||||||
|
"&apikey={APIKEY}"
|
||||||
|
resp = self.get_items(Jellyfin().get_data(url))
|
||||||
if not resp:
|
if not resp:
|
||||||
return
|
continue
|
||||||
all_item.extend(resp)
|
all_item.extend(resp)
|
||||||
|
|
||||||
def function(y, x):
|
def emby_get_items(self, all_item):
|
||||||
return y if (x['Name'] in [i['Name'] for i in y]) else (lambda z, u: (z.append(u), z))(y, x)[1]
|
# 获取所有user
|
||||||
# all_item 根据电影名去重
|
get_users_url = "{HOST}Users?&api_key={APIKEY}"
|
||||||
result = reduce(function, all_item, [])
|
users = self.get_users(Emby().get_data(get_users_url))
|
||||||
|
if not users:
|
||||||
for data in result:
|
return
|
||||||
# 检查缓存
|
for user in users:
|
||||||
if data.get('Name') in caches:
|
# 根据加入日期 降序排序
|
||||||
|
url = "{HOST}emby/Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
||||||
|
"&SortOrder=Descending" \
|
||||||
|
"&Filters=IsFavorite" \
|
||||||
|
"&Recursive=true" \
|
||||||
|
"&Fields=PrimaryImageAspectRatio%2CBasicSyncInfo" \
|
||||||
|
"&CollapseBoxSetItems=false" \
|
||||||
|
"&ExcludeLocationTypes=Virtual" \
|
||||||
|
"&EnableTotalRecordCount=false" \
|
||||||
|
"&Limit=20&api_key={APIKEY}"
|
||||||
|
resp = self.get_items(Emby().get_data(url))
|
||||||
|
if not resp:
|
||||||
continue
|
continue
|
||||||
|
all_item.extend(resp)
|
||||||
# 获取详情
|
|
||||||
if settings.MEDIASERVER == 'jellyfin':
|
|
||||||
item_info_resp = Jellyfin().get_iteminfo(itemid=data.get('Id'))
|
|
||||||
elif settings.MEDIASERVER == 'emby':
|
|
||||||
item_info_resp = Emby().get_iteminfo(itemid=data.get('Id'))
|
|
||||||
else:
|
|
||||||
item_info_resp = self.plex_get_iteminfo(itemid=data.get('Id'))
|
|
||||||
|
|
||||||
logger.info(f'BestFilmVersion插件 item打印 {item_info_resp}')
|
|
||||||
if not item_info_resp:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 只接受Movie类型
|
|
||||||
if data.get('Type') != 'Movie':
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 获取tmdb_id
|
|
||||||
media_info_ids = item_info_resp.get('ExternalUrls')
|
|
||||||
for media_info_id in media_info_ids:
|
|
||||||
if 'TheMovieDb' != media_info_id.get('Name'):
|
|
||||||
continue
|
|
||||||
tmdb_find_id = str(media_info_id.get('Url')).split('/')
|
|
||||||
tmdb_find_id.reverse()
|
|
||||||
tmdb_id = tmdb_find_id[0]
|
|
||||||
# 识别媒体信息
|
|
||||||
mediainfo: MediaInfo = self.chain.recognize_media(tmdbid=tmdb_id, mtype=MediaType.MOVIE)
|
|
||||||
if not mediainfo:
|
|
||||||
logger.warn(f'未识别到媒体信息,标题:{data.get("Name")},tmdbID:{tmdb_id}')
|
|
||||||
continue
|
|
||||||
# 添加订阅
|
|
||||||
self.subscribechain.add(mtype=MediaType.MOVIE,
|
|
||||||
title=mediainfo.title,
|
|
||||||
year=mediainfo.year,
|
|
||||||
tmdbid=mediainfo.tmdb_id,
|
|
||||||
best_version=True,
|
|
||||||
username="收藏洗版",
|
|
||||||
exist_ok=True)
|
|
||||||
# 加入缓存
|
|
||||||
caches.append(data.get('Name'))
|
|
||||||
# 存储历史记录
|
|
||||||
if mediainfo.tmdb_id not in [h.get("tmdbid") for h in history]:
|
|
||||||
history.append({
|
|
||||||
"title": mediainfo.title,
|
|
||||||
"type": mediainfo.type.value,
|
|
||||||
"year": mediainfo.year,
|
|
||||||
"poster": mediainfo.get_poster_image(),
|
|
||||||
"overview": mediainfo.overview,
|
|
||||||
"tmdbid": mediainfo.tmdb_id,
|
|
||||||
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
})
|
|
||||||
# 保存历史记录
|
|
||||||
self.save_data('history', history)
|
|
||||||
# 保存缓存
|
|
||||||
self._cache_path.write_text("\n".join(caches))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_items(resp: Response):
|
def get_items(resp: Response):
|
||||||
@ -594,83 +612,98 @@ class BestFilmVersion(_PluginBase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
data: WebhookEventInfo = event.event_data
|
data: WebhookEventInfo = event.event_data
|
||||||
|
# 排除不是收藏调用
|
||||||
|
if data.channel not in ['jellyfin', 'emby', 'plex']:
|
||||||
|
return
|
||||||
|
if data.channel in ['emby', 'plex'] and data.event != 'item.rate':
|
||||||
|
return
|
||||||
|
if data.channel == 'jellyfin' and data.save_reason != 'UpdateUserRating':
|
||||||
|
return
|
||||||
logger.info(f'BestFilmVersion/webhook_message_action WebhookEventInfo打印:{data}')
|
logger.info(f'BestFilmVersion/webhook_message_action WebhookEventInfo打印:{data}')
|
||||||
|
|
||||||
mediainfo: Optional[MediaInfo] = None
|
# 获取锁
|
||||||
if not data.tmdb_id:
|
_is_lock: bool = lock.acquire(timeout=60)
|
||||||
info = None
|
if not _is_lock:
|
||||||
if data.channel == 'jellyfin' and data.save_reason == 'UpdateUserRating' and data.item_favorite:
|
|
||||||
info = Jellyfin().get_iteminfo(itemid=data.item_id)
|
|
||||||
if data.channel == 'emby' and data.event == 'item.rate':
|
|
||||||
info = Emby().get_iteminfo(itemid=data.item_id)
|
|
||||||
if data.channel == 'plex' and data.event == 'item.rate':
|
|
||||||
info = Plex().get_iteminfo(itemid=data.item_id)
|
|
||||||
logger.info(f'BestFilmVersion/webhook_message_action item打印:{info}')
|
|
||||||
|
|
||||||
if not info:
|
|
||||||
return
|
|
||||||
if info['Type'] not in ['Movie', 'MOV', 'movie']:
|
|
||||||
return
|
|
||||||
|
|
||||||
# 获取tmdb_id
|
|
||||||
media_info_ids = info.get('ExternalUrls')
|
|
||||||
for media_info_id in media_info_ids:
|
|
||||||
|
|
||||||
if 'TheMovieDb' != media_info_id.get('Name'):
|
|
||||||
continue
|
|
||||||
|
|
||||||
tmdb_find_id = str(media_info_id.get('Url')).split('/')
|
|
||||||
tmdb_find_id.reverse()
|
|
||||||
tmdb_id = tmdb_find_id[0]
|
|
||||||
|
|
||||||
mediainfo = self.chain.recognize_media(tmdbid=tmdb_id, mtype=MediaType.MOVIE)
|
|
||||||
if not mediainfo:
|
|
||||||
logger.warn(f'未识别到媒体信息,标题:{data.item_name},tmdbID:{tmdb_id}')
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
if data.channel == 'jellyfin' and (data.save_reason != 'UpdateUserRating' or not data.item_favorite):
|
|
||||||
return
|
|
||||||
if data.channel == 'emby' and data.event != 'item.rate':
|
|
||||||
return
|
|
||||||
if data.channel == 'plex' and data.event != 'item.rate':
|
|
||||||
return
|
|
||||||
if data.item_type not in ['Movie', 'MOV', 'movie']:
|
|
||||||
return
|
|
||||||
|
|
||||||
mediainfo = self.chain.recognize_media(tmdbid=data.tmdb_id, mtype=MediaType.MOVIE)
|
|
||||||
if not mediainfo:
|
|
||||||
logger.warn(f'未识别到媒体信息,标题:{data.item_name},tmdbID:{data.tmdb_id}')
|
|
||||||
return
|
|
||||||
|
|
||||||
# 读取缓存
|
|
||||||
caches = self._cache_path.read_text().split("\n") if self._cache_path.exists() else []
|
|
||||||
# 检查缓存
|
|
||||||
if mediainfo.title in caches:
|
|
||||||
return
|
return
|
||||||
# 读取历史记录
|
try:
|
||||||
history = self.get_data('history') or []
|
|
||||||
# 添加订阅
|
mediainfo: Optional[MediaInfo] = None
|
||||||
self.subscribechain.add(mtype=MediaType.MOVIE,
|
if not data.tmdb_id:
|
||||||
title=mediainfo.title,
|
info = None
|
||||||
year=mediainfo.year,
|
if data.channel == 'jellyfin' and data.save_reason == 'UpdateUserRating' and data.item_favorite:
|
||||||
tmdbid=mediainfo.tmdb_id,
|
info = Jellyfin().get_iteminfo(itemid=data.item_id)
|
||||||
best_version=True,
|
elif data.channel == 'emby' and data.event == 'item.rate':
|
||||||
username="收藏洗版",
|
info = Emby().get_iteminfo(itemid=data.item_id)
|
||||||
exist_ok=True)
|
elif data.channel == 'plex' and data.event == 'item.rate':
|
||||||
# 加入缓存
|
info = Plex().get_iteminfo(itemid=data.item_id)
|
||||||
caches.append(data.item_name)
|
logger.info(f'BestFilmVersion/webhook_message_action item打印:{info}')
|
||||||
# 存储历史记录
|
|
||||||
if mediainfo.tmdb_id not in [h.get("tmdbid") for h in history]:
|
if not info:
|
||||||
history.append({
|
return
|
||||||
"title": mediainfo.title,
|
if info['Type'] not in ['Movie', 'MOV', 'movie']:
|
||||||
"type": mediainfo.type.value,
|
return
|
||||||
"year": mediainfo.year,
|
|
||||||
"poster": mediainfo.get_poster_image(),
|
# 获取tmdb_id
|
||||||
"overview": mediainfo.overview,
|
media_info_ids = info.get('ExternalUrls')
|
||||||
"tmdbid": mediainfo.tmdb_id,
|
if not media_info_ids:
|
||||||
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
return
|
||||||
})
|
for media_info_id in media_info_ids:
|
||||||
# 保存历史记录
|
|
||||||
self.save_data('history', history)
|
if 'TheMovieDb' != media_info_id.get('Name'):
|
||||||
# 保存缓存
|
continue
|
||||||
self._cache_path.write_text("\n".join(caches))
|
|
||||||
|
tmdb_find_id = str(media_info_id.get('Url')).split('/')
|
||||||
|
tmdb_find_id.reverse()
|
||||||
|
tmdb_id = tmdb_find_id[0]
|
||||||
|
|
||||||
|
mediainfo = self.chain.recognize_media(tmdbid=tmdb_id, mtype=MediaType.MOVIE)
|
||||||
|
if not mediainfo:
|
||||||
|
logger.warn(f'未识别到媒体信息,标题:{data.item_name},tmdbID:{tmdb_id}')
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if data.channel == 'jellyfin' and (data.save_reason != 'UpdateUserRating' or not data.item_favorite):
|
||||||
|
return
|
||||||
|
if data.item_type not in ['Movie', 'MOV', 'movie']:
|
||||||
|
return
|
||||||
|
|
||||||
|
mediainfo = self.chain.recognize_media(tmdbid=data.tmdb_id, mtype=MediaType.MOVIE)
|
||||||
|
if not mediainfo:
|
||||||
|
logger.warn(f'未识别到媒体信息,标题:{data.item_name},tmdbID:{data.tmdb_id}')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not mediainfo:
|
||||||
|
return
|
||||||
|
# 读取缓存
|
||||||
|
caches = self._cache_path.read_text().split("\n") if self._cache_path.exists() else []
|
||||||
|
# 检查缓存
|
||||||
|
if mediainfo.title in caches:
|
||||||
|
return
|
||||||
|
# 读取历史记录
|
||||||
|
history = self.get_data('history') or []
|
||||||
|
# 添加订阅
|
||||||
|
self.subscribechain.add(mtype=MediaType.MOVIE,
|
||||||
|
title=mediainfo.title,
|
||||||
|
year=mediainfo.year,
|
||||||
|
tmdbid=mediainfo.tmdb_id,
|
||||||
|
best_version=True,
|
||||||
|
username="收藏洗版",
|
||||||
|
exist_ok=True)
|
||||||
|
# 加入缓存
|
||||||
|
caches.append(data.item_name)
|
||||||
|
# 存储历史记录
|
||||||
|
if mediainfo.tmdb_id not in [h.get("tmdbid") for h in history]:
|
||||||
|
history.append({
|
||||||
|
"title": mediainfo.title,
|
||||||
|
"type": mediainfo.type.value,
|
||||||
|
"year": mediainfo.year,
|
||||||
|
"poster": mediainfo.get_poster_image(),
|
||||||
|
"overview": mediainfo.overview,
|
||||||
|
"tmdbid": mediainfo.tmdb_id,
|
||||||
|
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
})
|
||||||
|
# 保存历史记录
|
||||||
|
self.save_data('history', history)
|
||||||
|
# 保存缓存
|
||||||
|
self._cache_path.write_text("\n".join(caches))
|
||||||
|
finally:
|
||||||
|
lock.release()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user