fix(#2755): refactor pagination and fix media sync DB issue

This commit is contained in:
InfinityPacer
2024-09-28 00:57:13 +08:00
parent 48122d8d9a
commit 1add203c0e
8 changed files with 134 additions and 75 deletions

View File

@@ -173,14 +173,21 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]):
return server.get_librarys(username=username, hidden=hidden)
return None
def mediaserver_items(self, server: str, library_id: str, start_index: int = 0, limit: int = 100) \
-> Optional[Generator]:
def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: int = 0,
limit: Optional[int] = -1) -> Optional[Generator]:
"""
媒体库项目列表
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
:param server: 媒体服务器名称
:param library_id: 媒体库ID用于标识要获取的媒体库
:param start_index: 起始索引,用于分页获取数据。默认为 0即从第一个项目开始获取
:param limit: 每次请求的最大项目数,用于分页。如果为 None 或 -1则表示一次性获取所有数据默认为 -1
:return: 返回一个生成器对象,用于逐步获取媒体服务器中的项目
"""
server: Emby = self.get_instance(server)
if server:
return server.get_items(library_id, start_index, limit)
yield from server.get_items(library_id, start_index, limit)
return None
def mediaserver_iteminfo(self, server: str, item_id: str) -> Optional[schemas.MediaServerItem]:

View File

@@ -313,7 +313,7 @@ class Emby:
if not self._host or not self._apikey:
return None
url = f"{self._host}emby/Items"
params={
params = {
"IncludeItemTypes": "Series",
"Fields": "ProductionYear",
"StartIndex": 0,
@@ -601,7 +601,8 @@ class Emby:
# 刷新根目录
return "/"
def __format_item_info(self, item) -> Optional[schemas.MediaServerItem]:
@staticmethod
def __format_item_info(item) -> Optional[schemas.MediaServerItem]:
"""
格式化item
"""
@@ -610,7 +611,8 @@ class Emby:
if not user_data:
user_state = None
else:
resume = item.get("UserData", {}).get("PlaybackPositionTicks") and item.get("UserData", {}).get("PlaybackPositionTicks") > 0
resume = item.get("UserData", {}).get("PlaybackPositionTicks") and item.get("UserData", {}).get(
"PlaybackPositionTicks") > 0
last_played_date = item.get("UserData", {}).get("LastPlayedDate")
if last_played_date is not None and "." in last_played_date:
last_played_date = last_played_date.split(".")[0]
@@ -624,7 +626,6 @@ class Emby:
)
tmdbid = item.get("ProviderIds", {}).get("Tmdb")
return schemas.MediaServerItem(
id=item.get("Id"),
server="emby",
library=item.get("ParentId"),
item_id=item.get("Id"),
@@ -664,26 +665,30 @@ class Emby:
logger.error(f"连接/Users/{self.user}/Items/{itemid}出错:" + str(e))
return None
def get_items(self, parent: str, start_index: int = 0, limit: int = 100) -> Generator:
def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \
-> Optional[Generator]:
"""
获取媒体服务器所有媒体库列表
:param parent: 父媒体库ID
:param start_index: 开始索引,用于分页
:param limit: 每次请求返回的项目数量
:return: 生成器 schemas.MediaServerItem
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
:param parent: 媒体库ID用于标识要获取的媒体库
:param start_index: 起始索引,用于分页获取数据。默认为 0即从第一个项目开始获取
:param limit: 每次请求的最大项目数,用于分页。如果为 None 或 -1则表示一次性获取所有数据默认为 -1
:return: 返回一个生成器对象,用于逐步获取媒体服务器中的项目
"""
if not parent:
yield None
if not self._host or not self._apikey:
yield None
if not parent or not self._host or not self._apikey:
return None
url = f"{self._host}emby/Users/{self.user}/Items"
params = {
"ParentId": parent,
"api_key": self._apikey,
"Fields": "ProviderIds,OriginalTitle,ProductionYear,Path,UserDataPlayCount,UserDataLastPlayedDate,ParentId",
"StartIndex": start_index,
"Limit": limit
"Fields": "ProviderIds,OriginalTitle,ProductionYear,Path,UserDataPlayCount,UserDataLastPlayedDate,ParentId"
}
if limit is not None and limit != -1:
params.update({
"StartIndex": start_index,
"Limit": limit
})
try:
res = RequestUtils().get_res(url, params)
if not res or res.status_code != 200:
@@ -700,7 +705,6 @@ class Emby:
except Exception as e:
logger.error(f"连接Users/Items出错" + str(e))
yield None
def get_webhook_message(self, form: any, args: dict) -> Optional[schemas.WebhookEventInfo]:
"""

View File

@@ -171,14 +171,21 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]):
return server.get_librarys(username=username, hidden=hidden)
return None
def mediaserver_items(self, server: str, library_id: str, start_index: int = 0, limit: int = 100) \
-> Optional[Generator]:
def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: int = 0,
limit: Optional[int] = -1) -> Optional[Generator]:
"""
媒体库项目列表
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
:param server: 媒体服务器名称
:param library_id: 媒体库ID用于标识要获取的媒体库
:param start_index: 起始索引,用于分页获取数据。默认为 0即从第一个项目开始获取
:param limit: 每次请求的最大项目数,用于分页。如果为 None 或 -1则表示一次性获取所有数据默认为 -1
:return: 返回一个生成器对象,用于逐步获取媒体服务器中的项目
"""
server: Jellyfin = self.get_instance(server)
if server:
return server.get_items(library_id, start_index, limit)
yield from server.get_items(library_id, start_index, limit)
return None
def mediaserver_iteminfo(self, server: str, item_id: str) -> Optional[schemas.MediaServerItem]:

View File

@@ -662,8 +662,8 @@ class Jellyfin:
return eventItem
def __format_item_info(self, item) -> Optional[schemas.MediaServerItem]:
@staticmethod
def __format_item_info(item) -> Optional[schemas.MediaServerItem]:
"""
格式化item
"""
@@ -672,7 +672,8 @@ class Jellyfin:
if not user_data:
user_state = None
else:
resume = item.get("UserData", {}).get("PlaybackPositionTicks") and item.get("UserData", {}).get("PlaybackPositionTicks") > 0
resume = item.get("UserData", {}).get("PlaybackPositionTicks") and item.get("UserData", {}).get(
"PlaybackPositionTicks") > 0
last_played_date = item.get("UserData", {}).get("LastPlayedDate")
if last_played_date is not None and "." in last_played_date:
last_played_date = last_played_date.split(".")[0]
@@ -687,7 +688,6 @@ class Jellyfin:
tmdbid = item.get("ProviderIds", {}).get("Tmdb")
return schemas.MediaServerItem(
server="jellyfin",
id=item.get("Id"),
library=item.get("ParentId"),
item_id=item.get("Id"),
item_type=item.get("Type"),
@@ -725,26 +725,30 @@ class Jellyfin:
logger.error(f"连接Users/{self.user}/Items/{itemid}" + str(e))
return None
def get_items(self, parent: str, start_index: int = 0, limit: int = 100) -> Generator:
def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \
-> Optional[Generator]:
"""
获取媒体服务器所有媒体库列表
:param parent: 父媒体库ID
:param start_index: 开始索引,用于分页
:param limit: 每次请求返回的项目数量
:return: 生成器 schemas.MediaServerItem
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
:param parent: 媒体库ID用于标识要获取的媒体库
:param start_index: 起始索引,用于分页获取数据。默认为 0即从第一个项目开始获取
:param limit: 每次请求的最大项目数,用于分页。如果为 None 或 -1则表示一次性获取所有数据默认为 -1
:return: 返回一个生成器对象,用于逐步获取媒体服务器中的项目
"""
if not parent:
yield None
if not self._host or not self._apikey:
yield None
if not parent or not self._host or not self._apikey:
return None
url = f"{self._host}Users/{self.user}/Items"
params = {
"parentId": parent,
"ParentId": parent,
"api_key": self._apikey,
"Fields": "ProviderIds,OriginalTitle,ProductionYear,Path,UserDataPlayCount,UserDataLastPlayedDate,ParentId",
"StartIndex": start_index,
"Limit": limit,
}
if limit is not None and limit != -1:
params.update({
"StartIndex": start_index,
"Limit": limit
})
try:
res = RequestUtils().get_res(url, params)
if not res or res.status_code != 200:
@@ -760,7 +764,6 @@ class Jellyfin:
yield self.__format_item_info(item)
except Exception as e:
logger.error(f"连接Users/Items出错" + str(e))
yield None
def get_data(self, url: str) -> Optional[Response]:
"""

View File

@@ -159,14 +159,21 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]):
return server.get_librarys(hidden)
return None
def mediaserver_items(self, server: str, library_id: str, start_index: int = 0, limit: int = 100) \
-> Optional[Generator]:
def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: int = 0,
limit: Optional[int] = -1) -> Optional[Generator]:
"""
媒体库项目列表
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
:param server: 媒体服务器名称
:param library_id: 媒体库ID用于标识要获取的媒体库
:param start_index: 起始索引,用于分页获取数据。默认为 0即从第一个项目开始获取
:param limit: 每次请求的最大项目数,用于分页。如果为 None 或 -1则表示一次性获取所有数据默认为 -1
:return: 返回一个生成器对象,用于逐步获取媒体服务器中的项目
"""
server: Plex = self.get_instance(server)
if server:
return server.get_items(library_id, start_index, limit)
yield from server.get_items(library_id, start_index, limit)
return None
def mediaserver_iteminfo(self, server: str, item_id: str) -> Optional[schemas.MediaServerItem]:

View File

@@ -465,7 +465,6 @@ class Plex:
)
return schemas.MediaServerItem(
id=item.ratingKey,
server="plex",
library=item.librarySectionID,
item_id=item.key,
@@ -480,22 +479,27 @@ class Plex:
user_state=user_state,
)
def get_items(self, parent: str, start_index: int = 0, limit: int = 100) -> Generator:
def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \
-> Optional[Generator]:
"""
获取媒体服务器所有媒体库列表
:param parent: 父媒体库ID
:param start_index: 开始索引,用于分页
:param limit: 每次请求返回的项目数量
:return: 生成器 schemas.MediaServerItem
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
:param parent: 媒体库ID用于标识要获取的媒体库
:param start_index: 起始索引,用于分页获取数据。默认为 0即从第一个项目开始获取
:param limit: 每次请求的最大项目数,用于分页。如果为 None 或 -1则表示一次性获取所有数据默认为 -1
:return: 返回一个生成器对象,用于逐步获取媒体服务器中的项目
"""
if not parent:
yield None
if not self._plex:
yield None
if not parent or not self._plex:
return None
try:
section = self._plex.library.sectionByID(int(parent))
if section:
for item in section.all(container_start=start_index, limit=limit):
if limit is None or limit == -1:
items = section.all()
else:
items = section.all(container_start=start_index, container_size=limit, maxresults=limit)
for item in items:
try:
if not item:
continue
@@ -505,7 +509,6 @@ class Plex:
continue
except Exception as err:
logger.error(f"获取媒体库列表出错:{str(err)}")
yield None
def get_webhook_message(self, form: any) -> Optional[schemas.WebhookEventInfo]:
"""