fix #655
This commit is contained in:
@ -131,130 +131,130 @@ class BestFilmVersion(_PluginBase):
|
|||||||
拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构
|
拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'component': 'VForm',
|
'component': 'VForm',
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VRow',
|
'component': 'VRow',
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 3
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VSwitch',
|
'component': 'VSwitch',
|
||||||
'props': {
|
'props': {
|
||||||
'model': 'enabled',
|
'model': 'enabled',
|
||||||
'label': '启用插件',
|
'label': '启用插件',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 3
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VSwitch',
|
'component': 'VSwitch',
|
||||||
'props': {
|
'props': {
|
||||||
'model': 'notify',
|
'model': 'notify',
|
||||||
'label': '发送通知',
|
'label': '发送通知',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 3
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VSwitch',
|
'component': 'VSwitch',
|
||||||
'props': {
|
'props': {
|
||||||
'model': 'only_once',
|
'model': 'only_once',
|
||||||
'label': '立即运行一次',
|
'label': '立即运行一次',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 3
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VSwitch',
|
'component': 'VSwitch',
|
||||||
'props': {
|
'props': {
|
||||||
'model': 'webhook_enabled',
|
'model': 'webhook_enabled',
|
||||||
'label': 'Webhook',
|
'label': 'Webhook',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'component': 'VRow',
|
'component': 'VRow',
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VTextField',
|
'component': 'VTextField',
|
||||||
'props': {
|
'props': {
|
||||||
'model': 'cron',
|
'model': 'cron',
|
||||||
'label': '执行周期',
|
'label': '执行周期',
|
||||||
'placeholder': '5位cron表达式,留空自动'
|
'placeholder': '5位cron表达式,留空自动'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'component': 'VRow',
|
'component': 'VRow',
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
'component': 'VAlert',
|
'component': 'VAlert',
|
||||||
'props': {
|
'props': {
|
||||||
'text': '支持主动定时获取媒体库数据和Webhook实时触发两种方式,两者只能选其一,'
|
'text': '支持主动定时获取媒体库数据和Webhook实时触发两种方式,两者只能选其一,'
|
||||||
'Webhook需要在媒体服务器设置发送Webhook报文。'
|
'Webhook需要在媒体服务器设置发送Webhook报文。'
|
||||||
'Plex使用主动获取时,建议执行周期设置大于1小时,'
|
'Plex使用主动获取时,建议执行周期设置大于1小时,'
|
||||||
'收藏Api调用Plex官网接口,有频率限制。'
|
'收藏Api调用Plex官网接口,有频率限制。'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
], {
|
], {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"notify": False,
|
"notify": False,
|
||||||
"cron": "*/30 * * * *",
|
"cron": "*/30 * * * *",
|
||||||
"webhook_enabled": False,
|
"webhook_enabled": False,
|
||||||
"only_once": False
|
"only_once": False
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_page(self) -> List[dict]:
|
def get_page(self) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
@ -386,81 +386,85 @@ class BestFilmVersion(_PluginBase):
|
|||||||
# 读取历史记录
|
# 读取历史记录
|
||||||
history = self.get_data('history') or []
|
history = self.get_data('history') or []
|
||||||
|
|
||||||
all_item = []
|
# 媒体服务器类型,多个以,分隔
|
||||||
|
if not settings.MEDIASERVER:
|
||||||
|
return
|
||||||
|
media_servers = settings.MEDIASERVER.split(',')
|
||||||
|
|
||||||
# 读取收藏
|
# 读取收藏
|
||||||
if settings.MEDIASERVER == 'jellyfin':
|
all_items = {}
|
||||||
self.jellyfin_get_items(all_item)
|
for media_server in media_servers:
|
||||||
elif settings.MEDIASERVER == 'emby':
|
if media_server == 'jellyfin':
|
||||||
self.emby_get_items(all_item)
|
all_items['jellyfin'] = self.jellyfin_get_items()
|
||||||
else:
|
elif media_server == 'emby':
|
||||||
resp = self.plex_get_watchlist()
|
all_items['emby'] = self.emby_get_items()
|
||||||
if not resp:
|
else:
|
||||||
return
|
all_items['plex'] = self.plex_get_watchlist()
|
||||||
all_item.extend(resp)
|
|
||||||
|
|
||||||
def function(y, x):
|
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]
|
return y if (x['Name'] in [i['Name'] for i in y]) else (lambda z, u: (z.append(u), z))(y, x)[1]
|
||||||
|
|
||||||
# all_item 根据电影名去重
|
# 处理所有结果
|
||||||
result = reduce(function, all_item, [])
|
for server, all_item in all_items.items():
|
||||||
|
# all_item 根据电影名去重
|
||||||
for data in result:
|
result = reduce(function, all_item, [])
|
||||||
# 检查缓存
|
for data in result:
|
||||||
if data.get('Name') in caches:
|
# 检查缓存
|
||||||
continue
|
if data.get('Name') in caches:
|
||||||
|
|
||||||
# 获取详情
|
|
||||||
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')
|
|
||||||
if not media_info_ids:
|
|
||||||
continue
|
|
||||||
for media_info_id in media_info_ids:
|
|
||||||
if 'TheMovieDb' != media_info_id.get('Name'):
|
|
||||||
continue
|
continue
|
||||||
tmdb_find_id = str(media_info_id.get('Url')).split('/')
|
|
||||||
tmdb_find_id.reverse()
|
# 获取详情
|
||||||
tmdb_id = tmdb_find_id[0]
|
if server == 'jellyfin':
|
||||||
# 识别媒体信息
|
item_info_resp = Jellyfin().get_iteminfo(itemid=data.get('Id'))
|
||||||
mediainfo: MediaInfo = self.chain.recognize_media(tmdbid=tmdb_id, mtype=MediaType.MOVIE)
|
elif server == 'emby':
|
||||||
if not mediainfo:
|
item_info_resp = Emby().get_iteminfo(itemid=data.get('Id'))
|
||||||
logger.warn(f'未识别到媒体信息,标题:{data.get("Name")},tmdbID:{tmdb_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
|
continue
|
||||||
# 添加订阅
|
|
||||||
self.subscribechain.add(mtype=MediaType.MOVIE,
|
# 只接受Movie类型
|
||||||
title=mediainfo.title,
|
if data.get('Type') != 'Movie':
|
||||||
year=mediainfo.year,
|
continue
|
||||||
tmdbid=mediainfo.tmdb_id,
|
|
||||||
best_version=True,
|
# 获取tmdb_id
|
||||||
username="收藏洗版",
|
media_info_ids = item_info_resp.get('ExternalUrls')
|
||||||
exist_ok=True)
|
if not media_info_ids:
|
||||||
# 加入缓存
|
continue
|
||||||
caches.append(data.get('Name'))
|
for media_info_id in media_info_ids:
|
||||||
# 存储历史记录
|
if 'TheMovieDb' != media_info_id.get('Name'):
|
||||||
if mediainfo.tmdb_id not in [h.get("tmdbid") for h in history]:
|
continue
|
||||||
history.append({
|
tmdb_find_id = str(media_info_id.get('Url')).split('/')
|
||||||
"title": mediainfo.title,
|
tmdb_find_id.reverse()
|
||||||
"type": mediainfo.type.value,
|
tmdb_id = tmdb_find_id[0]
|
||||||
"year": mediainfo.year,
|
# 识别媒体信息
|
||||||
"poster": mediainfo.get_poster_image(),
|
mediainfo: MediaInfo = self.chain.recognize_media(tmdbid=tmdb_id, mtype=MediaType.MOVIE)
|
||||||
"overview": mediainfo.overview,
|
if not mediainfo:
|
||||||
"tmdbid": mediainfo.tmdb_id,
|
logger.warn(f'未识别到媒体信息,标题:{data.get("Name")},tmdbID:{tmdb_id}')
|
||||||
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
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.save_data('history', history)
|
||||||
# 保存缓存
|
# 保存缓存
|
||||||
@ -468,13 +472,14 @@ class BestFilmVersion(_PluginBase):
|
|||||||
finally:
|
finally:
|
||||||
lock.release()
|
lock.release()
|
||||||
|
|
||||||
def jellyfin_get_items(self, all_item):
|
def jellyfin_get_items(self) -> List[dict]:
|
||||||
# 获取所有user
|
# 获取所有user
|
||||||
users_url = "{HOST}Users?&apikey={APIKEY}"
|
users_url = "{HOST}Users?&apikey={APIKEY}"
|
||||||
users = self.get_users(Jellyfin().get_data(users_url))
|
users = self.get_users(Jellyfin().get_data(users_url))
|
||||||
if not users:
|
if not users:
|
||||||
logger.info(f"bestfilmversion/users_url: {users_url}")
|
logger.info(f"bestfilmversion/users_url: {users_url}")
|
||||||
return
|
return []
|
||||||
|
all_items = []
|
||||||
for user in users:
|
for user in users:
|
||||||
# 根据加入日期 降序排序
|
# 根据加入日期 降序排序
|
||||||
url = "{HOST}Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
url = "{HOST}Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
||||||
@ -490,14 +495,16 @@ class BestFilmVersion(_PluginBase):
|
|||||||
resp = self.get_items(Jellyfin().get_data(url))
|
resp = self.get_items(Jellyfin().get_data(url))
|
||||||
if not resp:
|
if not resp:
|
||||||
continue
|
continue
|
||||||
all_item.extend(resp)
|
all_items.extend(resp)
|
||||||
|
return all_items
|
||||||
|
|
||||||
def emby_get_items(self, all_item):
|
def emby_get_items(self) -> List[dict]:
|
||||||
# 获取所有user
|
# 获取所有user
|
||||||
get_users_url = "{HOST}Users?&api_key={APIKEY}"
|
get_users_url = "{HOST}Users?&api_key={APIKEY}"
|
||||||
users = self.get_users(Emby().get_data(get_users_url))
|
users = self.get_users(Emby().get_data(get_users_url))
|
||||||
if not users:
|
if not users:
|
||||||
return
|
return []
|
||||||
|
all_items = []
|
||||||
for user in users:
|
for user in users:
|
||||||
# 根据加入日期 降序排序
|
# 根据加入日期 降序排序
|
||||||
url = "{HOST}emby/Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
url = "{HOST}emby/Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
|
||||||
@ -512,7 +519,8 @@ class BestFilmVersion(_PluginBase):
|
|||||||
resp = self.get_items(Emby().get_data(url))
|
resp = self.get_items(Emby().get_data(url))
|
||||||
if not resp:
|
if not resp:
|
||||||
continue
|
continue
|
||||||
all_item.extend(resp)
|
all_items.extend(resp)
|
||||||
|
return all_items
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_items(resp: Response):
|
def get_items(resp: Response):
|
||||||
@ -538,7 +546,7 @@ class BestFilmVersion(_PluginBase):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def plex_get_watchlist():
|
def plex_get_watchlist() -> List[dict]:
|
||||||
# 根据加入日期 降序排序
|
# 根据加入日期 降序排序
|
||||||
url = f"https://metadata.provider.plex.tv/library/sections/watchlist/all?type=1&sort=addedAt%3Adesc" \
|
url = f"https://metadata.provider.plex.tv/library/sections/watchlist/all?type=1&sort=addedAt%3Adesc" \
|
||||||
f"&X-Plex-Container-Start=0&X-Plex-Container-Size=50" \
|
f"&X-Plex-Container-Start=0&X-Plex-Container-Size=50" \
|
||||||
|
@ -598,7 +598,7 @@ class DirMonitor(_PluginBase):
|
|||||||
'rows': 5,
|
'rows': 5,
|
||||||
'placeholder': '每一行一个目录,支持两种配置方式:\n'
|
'placeholder': '每一行一个目录,支持两种配置方式:\n'
|
||||||
'监控目录\n'
|
'监控目录\n'
|
||||||
'监控目录:转移目的目录'
|
'监控目录:转移目的目录(需同时在媒体库目录中配置该目的目录)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -718,19 +718,21 @@ class MediaSyncDel(_PluginBase):
|
|||||||
"""
|
"""
|
||||||
# 读取历史记录
|
# 读取历史记录
|
||||||
history = self.get_data('history') or []
|
history = self.get_data('history') or []
|
||||||
|
|
||||||
# 媒体服务器类型
|
|
||||||
media_server = settings.MEDIASERVER
|
|
||||||
|
|
||||||
last_time = self.get_data("last_time")
|
last_time = self.get_data("last_time")
|
||||||
del_medias = []
|
del_medias = []
|
||||||
if media_server == 'emby':
|
|
||||||
del_medias = self.parse_emby_log(last_time)
|
# 媒体服务器类型,多个以,分隔
|
||||||
elif media_server == 'jellyfin':
|
if not settings.MEDIASERVER:
|
||||||
del_medias = self.parse_jellyfin_log(last_time)
|
|
||||||
elif media_server == 'plex':
|
|
||||||
# TODO plex解析日志
|
|
||||||
return
|
return
|
||||||
|
media_servers = settings.MEDIASERVER.split(',')
|
||||||
|
for media_server in media_servers:
|
||||||
|
if media_server == 'emby':
|
||||||
|
del_medias.extend(self.parse_emby_log(last_time))
|
||||||
|
elif media_server == 'jellyfin':
|
||||||
|
del_medias.extend(self.parse_jellyfin_log(last_time))
|
||||||
|
elif media_server == 'plex':
|
||||||
|
# TODO plex解析日志
|
||||||
|
return
|
||||||
|
|
||||||
if not del_medias:
|
if not del_medias:
|
||||||
logger.error("未解析到已删除媒体信息")
|
logger.error("未解析到已删除媒体信息")
|
||||||
|
@ -383,78 +383,86 @@ class SpeedLimiter(_PluginBase):
|
|||||||
return
|
return
|
||||||
# 当前播放的总比特率
|
# 当前播放的总比特率
|
||||||
total_bit_rate = 0
|
total_bit_rate = 0
|
||||||
# 查询播放中会话
|
# 媒体服务器类型,多个以,分隔
|
||||||
playing_sessions = []
|
if not settings.MEDIASERVER:
|
||||||
if settings.MEDIASERVER == "emby":
|
return
|
||||||
req_url = "{HOST}emby/Sessions?api_key={APIKEY}"
|
media_servers = settings.MEDIASERVER.split(',')
|
||||||
try:
|
# 查询所有媒体服务器状态
|
||||||
res = Emby().get_data(req_url)
|
for media_server in media_servers:
|
||||||
if res and res.status_code == 200:
|
# 查询播放中会话
|
||||||
sessions = res.json()
|
playing_sessions = []
|
||||||
for session in sessions:
|
if media_server == "emby":
|
||||||
if session.get("NowPlayingItem") and not session.get("PlayState", {}).get("IsPaused"):
|
req_url = "{HOST}emby/Sessions?api_key={APIKEY}"
|
||||||
playing_sessions.append(session)
|
try:
|
||||||
except Exception as e:
|
res = Emby().get_data(req_url)
|
||||||
logger.error(f"获取Emby播放会话失败:{str(e)}")
|
if res and res.status_code == 200:
|
||||||
# 计算有效比特率
|
sessions = res.json()
|
||||||
for session in playing_sessions:
|
for session in sessions:
|
||||||
# 设置了不限速范围则判断session ip是否在不限速范围内
|
if session.get("NowPlayingItem") and not session.get("PlayState", {}).get("IsPaused"):
|
||||||
if self._unlimited_ips["ipv4"] or self._unlimited_ips["ipv6"]:
|
playing_sessions.append(session)
|
||||||
if not self.__allow_access(self._unlimited_ips, session.get("RemoteEndPoint")) \
|
except Exception as e:
|
||||||
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
logger.error(f"获取Emby播放会话失败:{str(e)}")
|
||||||
total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0)
|
continue
|
||||||
# 未设置不限速范围,则默认不限速内网ip
|
|
||||||
elif not IpUtils.is_private_ip(session.get("RemoteEndPoint")) \
|
|
||||||
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
|
||||||
total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0)
|
|
||||||
elif settings.MEDIASERVER == "jellyfin":
|
|
||||||
req_url = "{HOST}Sessions?api_key={APIKEY}"
|
|
||||||
try:
|
|
||||||
res = Jellyfin().get_data(req_url)
|
|
||||||
if res and res.status_code == 200:
|
|
||||||
sessions = res.json()
|
|
||||||
for session in sessions:
|
|
||||||
if session.get("NowPlayingItem") and not session.get("PlayState", {}).get("IsPaused"):
|
|
||||||
playing_sessions.append(session)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"获取Jellyfin播放会话失败:{str(e)}")
|
|
||||||
# 计算有效比特率
|
|
||||||
for session in playing_sessions:
|
|
||||||
# 设置了不限速范围则判断session ip是否在不限速范围内
|
|
||||||
if self._unlimited_ips["ipv4"] or self._unlimited_ips["ipv6"]:
|
|
||||||
if not self.__allow_access(self._unlimited_ips, session.get("RemoteEndPoint")) \
|
|
||||||
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
|
||||||
media_streams = session.get("NowPlayingItem", {}).get("MediaStreams") or []
|
|
||||||
for media_stream in media_streams:
|
|
||||||
total_bit_rate += int(media_stream.get("BitRate") or 0)
|
|
||||||
# 未设置不限速范围,则默认不限速内网ip
|
|
||||||
elif not IpUtils.is_private_ip(session.get("RemoteEndPoint")) \
|
|
||||||
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
|
||||||
media_streams = session.get("NowPlayingItem", {}).get("MediaStreams") or []
|
|
||||||
for media_stream in media_streams:
|
|
||||||
total_bit_rate += int(media_stream.get("BitRate") or 0)
|
|
||||||
elif settings.MEDIASERVER == "plex":
|
|
||||||
_plex = Plex().get_plex()
|
|
||||||
if _plex:
|
|
||||||
sessions = _plex.sessions()
|
|
||||||
for session in sessions:
|
|
||||||
bitrate = sum([m.bitrate or 0 for m in session.media])
|
|
||||||
playing_sessions.append({
|
|
||||||
"type": session.TAG,
|
|
||||||
"bitrate": bitrate,
|
|
||||||
"address": session.player.address
|
|
||||||
})
|
|
||||||
# 计算有效比特率
|
# 计算有效比特率
|
||||||
for session in playing_sessions:
|
for session in playing_sessions:
|
||||||
# 设置了不限速范围则判断session ip是否在不限速范围内
|
# 设置了不限速范围则判断session ip是否在不限速范围内
|
||||||
if self._unlimited_ips["ipv4"] or self._unlimited_ips["ipv6"]:
|
if self._unlimited_ips["ipv4"] or self._unlimited_ips["ipv6"]:
|
||||||
if not self.__allow_access(self._unlimited_ips, session.get("address")) \
|
if not self.__allow_access(self._unlimited_ips, session.get("RemoteEndPoint")) \
|
||||||
|
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
||||||
|
total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0)
|
||||||
|
# 未设置不限速范围,则默认不限速内网ip
|
||||||
|
elif not IpUtils.is_private_ip(session.get("RemoteEndPoint")) \
|
||||||
|
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
||||||
|
total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0)
|
||||||
|
elif media_server == "jellyfin":
|
||||||
|
req_url = "{HOST}Sessions?api_key={APIKEY}"
|
||||||
|
try:
|
||||||
|
res = Jellyfin().get_data(req_url)
|
||||||
|
if res and res.status_code == 200:
|
||||||
|
sessions = res.json()
|
||||||
|
for session in sessions:
|
||||||
|
if session.get("NowPlayingItem") and not session.get("PlayState", {}).get("IsPaused"):
|
||||||
|
playing_sessions.append(session)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取Jellyfin播放会话失败:{str(e)}")
|
||||||
|
continue
|
||||||
|
# 计算有效比特率
|
||||||
|
for session in playing_sessions:
|
||||||
|
# 设置了不限速范围则判断session ip是否在不限速范围内
|
||||||
|
if self._unlimited_ips["ipv4"] or self._unlimited_ips["ipv6"]:
|
||||||
|
if not self.__allow_access(self._unlimited_ips, session.get("RemoteEndPoint")) \
|
||||||
|
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
||||||
|
media_streams = session.get("NowPlayingItem", {}).get("MediaStreams") or []
|
||||||
|
for media_stream in media_streams:
|
||||||
|
total_bit_rate += int(media_stream.get("BitRate") or 0)
|
||||||
|
# 未设置不限速范围,则默认不限速内网ip
|
||||||
|
elif not IpUtils.is_private_ip(session.get("RemoteEndPoint")) \
|
||||||
|
and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
|
||||||
|
media_streams = session.get("NowPlayingItem", {}).get("MediaStreams") or []
|
||||||
|
for media_stream in media_streams:
|
||||||
|
total_bit_rate += int(media_stream.get("BitRate") or 0)
|
||||||
|
elif media_server == "plex":
|
||||||
|
_plex = Plex().get_plex()
|
||||||
|
if _plex:
|
||||||
|
sessions = _plex.sessions()
|
||||||
|
for session in sessions:
|
||||||
|
bitrate = sum([m.bitrate or 0 for m in session.media])
|
||||||
|
playing_sessions.append({
|
||||||
|
"type": session.TAG,
|
||||||
|
"bitrate": bitrate,
|
||||||
|
"address": session.player.address
|
||||||
|
})
|
||||||
|
# 计算有效比特率
|
||||||
|
for session in playing_sessions:
|
||||||
|
# 设置了不限速范围则判断session ip是否在不限速范围内
|
||||||
|
if self._unlimited_ips["ipv4"] or self._unlimited_ips["ipv6"]:
|
||||||
|
if not self.__allow_access(self._unlimited_ips, session.get("address")) \
|
||||||
|
and session.get("type") == "Video":
|
||||||
|
total_bit_rate += int(session.get("bitrate") or 0)
|
||||||
|
# 未设置不限速范围,则默认不限速内网ip
|
||||||
|
elif not IpUtils.is_private_ip(session.get("address")) \
|
||||||
and session.get("type") == "Video":
|
and session.get("type") == "Video":
|
||||||
total_bit_rate += int(session.get("bitrate") or 0)
|
total_bit_rate += int(session.get("bitrate") or 0)
|
||||||
# 未设置不限速范围,则默认不限速内网ip
|
|
||||||
elif not IpUtils.is_private_ip(session.get("address")) \
|
|
||||||
and session.get("type") == "Video":
|
|
||||||
total_bit_rate += int(session.get("bitrate") or 0)
|
|
||||||
|
|
||||||
if total_bit_rate:
|
if total_bit_rate:
|
||||||
# 开启智能限速计算上传限速
|
# 开启智能限速计算上传限速
|
||||||
|
Reference in New Issue
Block a user