fix:优化emby、jellyfin用户匹配
This commit is contained in:
@ -56,7 +56,9 @@ async def login_access_token(
|
||||
logger.info(f"用户 {user.name} 登录成功!")
|
||||
return schemas.Token(
|
||||
access_token=security.create_access_token(
|
||||
user.id,
|
||||
userid=user.id,
|
||||
username=user.name,
|
||||
super_user=user.is_superuser,
|
||||
expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
),
|
||||
token_type="bearer",
|
||||
|
@ -8,7 +8,6 @@ from app.chain.download import DownloadChain
|
||||
from app.chain.media import MediaChain
|
||||
from app.chain.mediaserver import MediaServerChain
|
||||
from app.core.config import settings
|
||||
from app.core.context import MediaInfo
|
||||
from app.core.metainfo import MetaInfo
|
||||
from app.core.security import verify_token
|
||||
from app.db import get_db
|
||||
@ -123,25 +122,25 @@ def not_exists(media_in: schemas.MediaInfo,
|
||||
|
||||
@router.get("/latest", summary="最新入库条目", response_model=List[schemas.MediaServerPlayItem])
|
||||
def latest(count: int = 18,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
获取媒体服务器最新入库条目
|
||||
"""
|
||||
return MediaServerChain().latest(count=count) or []
|
||||
return MediaServerChain().latest(count=count, username=userinfo.username) or []
|
||||
|
||||
|
||||
@router.get("/playing", summary="正在播放条目", response_model=List[schemas.MediaServerPlayItem])
|
||||
def playing(count: int = 12,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
获取媒体服务器正在播放条目
|
||||
"""
|
||||
return MediaServerChain().playing(count=count) or []
|
||||
return MediaServerChain().playing(count=count, username=userinfo.username) or []
|
||||
|
||||
|
||||
@router.get("/library", summary="媒体库列表", response_model=List[schemas.MediaServerLibrary])
|
||||
def library(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
def library(userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
获取媒体服务器媒体库列表
|
||||
"""
|
||||
return MediaServerChain().librarys() or []
|
||||
return MediaServerChain().librarys(userinfo.username) or []
|
||||
|
@ -20,11 +20,11 @@ class MediaServerChain(ChainBase):
|
||||
super().__init__()
|
||||
self.dboper = MediaServerOper()
|
||||
|
||||
def librarys(self, server: str = None) -> List[schemas.MediaServerLibrary]:
|
||||
def librarys(self, server: str = None, username: str = None) -> List[schemas.MediaServerLibrary]:
|
||||
"""
|
||||
获取媒体服务器所有媒体库
|
||||
"""
|
||||
return self.run_module("mediaserver_librarys", server=server)
|
||||
return self.run_module("mediaserver_librarys", server=server, username=username)
|
||||
|
||||
def items(self, server: str, library_id: Union[str, int]) -> List[schemas.MediaServerItem]:
|
||||
"""
|
||||
@ -44,17 +44,17 @@ class MediaServerChain(ChainBase):
|
||||
"""
|
||||
return self.run_module("mediaserver_tv_episodes", server=server, item_id=item_id)
|
||||
|
||||
def playing(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def playing(self, count: int = 20, server: str = None, username: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器正在播放信息
|
||||
"""
|
||||
return self.run_module("mediaserver_playing", count=count, server=server)
|
||||
return self.run_module("mediaserver_playing", count=count, server=server, username=username)
|
||||
|
||||
def latest(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def latest(self, count: int = 20, server: str = None, username: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器最新入库条目
|
||||
"""
|
||||
return self.run_module("mediaserver_latest", count=count, server=server)
|
||||
return self.run_module("mediaserver_latest", count=count, server=server, username=username)
|
||||
|
||||
def get_play_url(self, server: str, item_id: Union[str, int]) -> Optional[str]:
|
||||
"""
|
||||
|
@ -26,7 +26,8 @@ reusable_oauth2 = OAuth2PasswordBearer(
|
||||
|
||||
|
||||
def create_access_token(
|
||||
subject: Union[str, Any], expires_delta: timedelta = None
|
||||
userid: Union[str, Any], username: str, super_user: bool = False,
|
||||
expires_delta: timedelta = None
|
||||
) -> str:
|
||||
if expires_delta:
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
@ -34,7 +35,12 @@ def create_access_token(
|
||||
expire = datetime.utcnow() + timedelta(
|
||||
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
|
||||
)
|
||||
to_encode = {"exp": expire, "sub": str(subject)}
|
||||
to_encode = {
|
||||
"exp": expire,
|
||||
"sub": str(userid),
|
||||
"username": username,
|
||||
"super_user": super_user
|
||||
}
|
||||
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
|
||||
return encoded_jwt
|
||||
|
||||
|
@ -103,13 +103,13 @@ class EmbyModule(_ModuleBase):
|
||||
media_statistic.user_count = self.emby.get_user_count()
|
||||
return [media_statistic]
|
||||
|
||||
def mediaserver_librarys(self, server: str = None) -> Optional[List[schemas.MediaServerLibrary]]:
|
||||
def mediaserver_librarys(self, server: str = None, username: str = None) -> Optional[List[schemas.MediaServerLibrary]]:
|
||||
"""
|
||||
媒体库列表
|
||||
"""
|
||||
if server and server != "emby":
|
||||
return None
|
||||
return self.emby.get_librarys()
|
||||
return self.emby.get_librarys(username)
|
||||
|
||||
def mediaserver_items(self, server: str, library_id: str) -> Optional[Generator]:
|
||||
"""
|
||||
@ -142,13 +142,14 @@ class EmbyModule(_ModuleBase):
|
||||
episodes=episodes
|
||||
) for season, episodes in seasoninfo.items()]
|
||||
|
||||
def mediaserver_playing(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def mediaserver_playing(self, count: int = 20,
|
||||
server: str = None, username: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器正在播放信息
|
||||
"""
|
||||
if server and server != "emby":
|
||||
return []
|
||||
return self.emby.get_resume(count)
|
||||
return self.emby.get_resume(num=count, username=username)
|
||||
|
||||
def mediaserver_play_url(self, server: str, item_id: Union[str, int]) -> Optional[str]:
|
||||
"""
|
||||
@ -158,10 +159,11 @@ class EmbyModule(_ModuleBase):
|
||||
return None
|
||||
return self.emby.get_play_url(item_id)
|
||||
|
||||
def mediaserver_latest(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def mediaserver_latest(self, count: int = 20,
|
||||
server: str = None, username: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器最新入库条目
|
||||
"""
|
||||
if server and server != "emby":
|
||||
return []
|
||||
return self.emby.get_latest(count)
|
||||
return self.emby.get_latest(num=count, username=username)
|
||||
|
@ -66,13 +66,17 @@ class Emby(metaclass=Singleton):
|
||||
logger.error(f"连接Library/SelectableMediaFolders 出错:" + str(e))
|
||||
return []
|
||||
|
||||
def __get_emby_librarys(self) -> List[dict]:
|
||||
def __get_emby_librarys(self, username: str = None) -> List[dict]:
|
||||
"""
|
||||
获取Emby媒体库列表
|
||||
"""
|
||||
if not self._host or not self._apikey:
|
||||
return []
|
||||
req_url = f"{self._host}emby/Users/{self.user}/Views?api_key={self._apikey}"
|
||||
if username:
|
||||
user = self.get_user(username)
|
||||
else:
|
||||
user = self.user
|
||||
req_url = f"{self._host}emby/Users/{user}/Views?api_key={self._apikey}"
|
||||
try:
|
||||
res = RequestUtils().get_res(req_url)
|
||||
if res:
|
||||
@ -84,7 +88,7 @@ class Emby(metaclass=Singleton):
|
||||
logger.error(f"连接User/Views 出错:" + str(e))
|
||||
return []
|
||||
|
||||
def get_librarys(self) -> List[schemas.MediaServerLibrary]:
|
||||
def get_librarys(self, username: str = None) -> List[schemas.MediaServerLibrary]:
|
||||
"""
|
||||
获取媒体服务器所有媒体库列表
|
||||
"""
|
||||
@ -92,7 +96,7 @@ class Emby(metaclass=Singleton):
|
||||
return []
|
||||
libraries = []
|
||||
black_list = (settings.MEDIASERVER_SYNC_BLACKLIST or '').split(",")
|
||||
for library in self.__get_emby_librarys() or []:
|
||||
for library in self.__get_emby_librarys(username) or []:
|
||||
if library.get("Name") in black_list:
|
||||
continue
|
||||
match library.get("CollectionType"):
|
||||
@ -956,13 +960,18 @@ class Emby(metaclass=Singleton):
|
||||
return ""
|
||||
return "%sItems/%s/Images/Primary" % (self._host, item_id)
|
||||
|
||||
def get_resume(self, num: int = 12) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
def get_resume(self, num: int = 12, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
"""
|
||||
获得继续观看
|
||||
"""
|
||||
if not self._host or not self._apikey:
|
||||
return None
|
||||
req_url = f"{self._host}Users/{self.user}/Items/Resume?Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear"
|
||||
if username:
|
||||
user = self.get_user(username)
|
||||
else:
|
||||
user = self.user
|
||||
req_url = (f"{self._host}Users/{user}/Items/Resume?"
|
||||
f"Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear")
|
||||
try:
|
||||
res = RequestUtils().get_res(req_url)
|
||||
if res:
|
||||
@ -1006,13 +1015,18 @@ class Emby(metaclass=Singleton):
|
||||
logger.error(f"连接Users/Items/Resume出错:" + str(e))
|
||||
return []
|
||||
|
||||
def get_latest(self, num: int = 20) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
def get_latest(self, num: int = 20, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
"""
|
||||
获得最近更新
|
||||
"""
|
||||
if not self._host or not self._apikey:
|
||||
return None
|
||||
req_url = f"{self._host}Users/{self.user}/Items/Latest?Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear"
|
||||
if username:
|
||||
user = self.get_user(username)
|
||||
else:
|
||||
user = self.user
|
||||
req_url = (f"{self._host}Users/{user}/Items/Latest?"
|
||||
f"Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear")
|
||||
try:
|
||||
res = RequestUtils().get_res(req_url)
|
||||
if res:
|
||||
|
@ -101,13 +101,13 @@ class JellyfinModule(_ModuleBase):
|
||||
media_statistic.user_count = self.jellyfin.get_user_count()
|
||||
return [media_statistic]
|
||||
|
||||
def mediaserver_librarys(self, server: str = None) -> Optional[List[schemas.MediaServerLibrary]]:
|
||||
def mediaserver_librarys(self, server: str = None, username: str = None) -> Optional[List[schemas.MediaServerLibrary]]:
|
||||
"""
|
||||
媒体库列表
|
||||
"""
|
||||
if server and server != "jellyfin":
|
||||
return None
|
||||
return self.jellyfin.get_librarys()
|
||||
return self.jellyfin.get_librarys(username)
|
||||
|
||||
def mediaserver_items(self, server: str, library_id: str) -> Optional[Generator]:
|
||||
"""
|
||||
@ -140,13 +140,14 @@ class JellyfinModule(_ModuleBase):
|
||||
episodes=episodes
|
||||
) for season, episodes in seasoninfo.items()]
|
||||
|
||||
def mediaserver_playing(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def mediaserver_playing(self, count: int = 20,
|
||||
server: str = None, username: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器正在播放信息
|
||||
"""
|
||||
if server and server != "jellyfin":
|
||||
return []
|
||||
return self.jellyfin.get_resume(count)
|
||||
return self.jellyfin.get_resume(num=count, username=username)
|
||||
|
||||
def mediaserver_play_url(self, server: str, item_id: Union[str, int]) -> Optional[str]:
|
||||
"""
|
||||
@ -156,10 +157,11 @@ class JellyfinModule(_ModuleBase):
|
||||
return None
|
||||
return self.jellyfin.get_play_url(item_id)
|
||||
|
||||
def mediaserver_latest(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def mediaserver_latest(self, count: int = 20,
|
||||
server: str = None, username: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器最新入库条目
|
||||
"""
|
||||
if server and server != "jellyfin":
|
||||
return []
|
||||
return self.jellyfin.get_latest(count)
|
||||
return self.jellyfin.get_latest(num=count, username=username)
|
||||
|
@ -45,13 +45,17 @@ class Jellyfin(metaclass=Singleton):
|
||||
self.user = self.get_user()
|
||||
self.serverid = self.get_server_id()
|
||||
|
||||
def __get_jellyfin_librarys(self) -> List[dict]:
|
||||
def __get_jellyfin_librarys(self, username: str = None) -> List[dict]:
|
||||
"""
|
||||
获取Jellyfin媒体库的信息
|
||||
"""
|
||||
if not self._host or not self._apikey:
|
||||
return []
|
||||
req_url = f"{self._host}Users/{self.user}/Views?api_key={self._apikey}"
|
||||
if username:
|
||||
user = self.get_user(username)
|
||||
else:
|
||||
user = self.user
|
||||
req_url = f"{self._host}Users/{user}/Views?api_key={self._apikey}"
|
||||
try:
|
||||
res = RequestUtils().get_res(req_url)
|
||||
if res:
|
||||
@ -63,7 +67,7 @@ class Jellyfin(metaclass=Singleton):
|
||||
logger.error(f"连接Users/Views 出错:" + str(e))
|
||||
return []
|
||||
|
||||
def get_librarys(self):
|
||||
def get_librarys(self, username: str = None) -> List[schemas.MediaServerLibrary]:
|
||||
"""
|
||||
获取媒体服务器所有媒体库列表
|
||||
"""
|
||||
@ -71,7 +75,7 @@ class Jellyfin(metaclass=Singleton):
|
||||
return []
|
||||
libraries = []
|
||||
black_list = (settings.MEDIASERVER_SYNC_BLACKLIST or '').split(",")
|
||||
for library in self.__get_jellyfin_librarys() or []:
|
||||
for library in self.__get_jellyfin_librarys(username) or []:
|
||||
if library.get("Name") in black_list:
|
||||
continue
|
||||
match library.get("CollectionType"):
|
||||
@ -639,13 +643,18 @@ class Jellyfin(metaclass=Singleton):
|
||||
return f"{self._host}Items/{item_id}/" \
|
||||
f"Images/Backdrop?tag={image_tag}&fillWidth=666&api_key={self._apikey}"
|
||||
|
||||
def get_resume(self, num: int = 12) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
def get_resume(self, num: int = 12, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
"""
|
||||
获得继续观看
|
||||
"""
|
||||
if not self._host or not self._apikey:
|
||||
return None
|
||||
req_url = f"{self._host}Users/{self.user}/Items/Resume?Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear"
|
||||
if username:
|
||||
user = self.get_user(username)
|
||||
else:
|
||||
user = self.user
|
||||
req_url = (f"{self._host}Users/{user}/Items/Resume?"
|
||||
f"Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear")
|
||||
try:
|
||||
res = RequestUtils().get_res(req_url)
|
||||
if res:
|
||||
@ -683,13 +692,18 @@ class Jellyfin(metaclass=Singleton):
|
||||
logger.error(f"连接Users/Items/Resume出错:" + str(e))
|
||||
return []
|
||||
|
||||
def get_latest(self, num=20) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
def get_latest(self, num=20, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]:
|
||||
"""
|
||||
获得最近更新
|
||||
"""
|
||||
if not self._host or not self._apikey:
|
||||
return None
|
||||
req_url = f"{self._host}Users/{self.user}/Items/Latest?Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear"
|
||||
if username:
|
||||
user = self.get_user(username)
|
||||
else:
|
||||
user = self.user
|
||||
req_url = (f"{self._host}Users/{user}/Items/Latest?"
|
||||
f"Limit={num}&MediaTypes=Video&api_key={self._apikey}&Fields=ProductionYear")
|
||||
try:
|
||||
res = RequestUtils().get_res(req_url)
|
||||
if res:
|
||||
|
@ -95,7 +95,7 @@ class PlexModule(_ModuleBase):
|
||||
media_statistic.user_count = 1
|
||||
return [media_statistic]
|
||||
|
||||
def mediaserver_librarys(self, server: str = None) -> Optional[List[schemas.MediaServerLibrary]]:
|
||||
def mediaserver_librarys(self, server: str = None, **kwargs) -> Optional[List[schemas.MediaServerLibrary]]:
|
||||
"""
|
||||
媒体库列表
|
||||
"""
|
||||
@ -134,7 +134,7 @@ class PlexModule(_ModuleBase):
|
||||
episodes=episodes
|
||||
) for season, episodes in seasoninfo.items()]
|
||||
|
||||
def mediaserver_playing(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def mediaserver_playing(self, count: int = 20, server: str = None, **kwargs) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器正在播放信息
|
||||
"""
|
||||
@ -142,7 +142,7 @@ class PlexModule(_ModuleBase):
|
||||
return []
|
||||
return self.plex.get_resume(count)
|
||||
|
||||
def mediaserver_latest(self, count: int = 20, server: str = None) -> List[schemas.MediaServerPlayItem]:
|
||||
def mediaserver_latest(self, count: int = 20, server: str = None, **kwargs) -> List[schemas.MediaServerPlayItem]:
|
||||
"""
|
||||
获取媒体服务器最新入库条目
|
||||
"""
|
||||
|
@ -14,3 +14,7 @@ class Token(BaseModel):
|
||||
class TokenPayload(BaseModel):
|
||||
# 用户ID
|
||||
sub: Optional[int] = None
|
||||
# 用户名
|
||||
username: Optional[str] = None
|
||||
# 超级用户
|
||||
super_user: Optional[bool] = None
|
||||
|
Reference in New Issue
Block a user