fix:优化emby、jellyfin用户匹配

This commit is contained in:
jxxghp
2024-01-07 11:46:29 +08:00
parent 87111c8736
commit bf8a75b201
10 changed files with 90 additions and 47 deletions

View File

@ -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",

View File

@ -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 []

View File

@ -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]:
"""

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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)

View File

@ -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:

View File

@ -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]:
"""
获取媒体服务器最新入库条目
"""

View File

@ -14,3 +14,7 @@ class Token(BaseModel):
class TokenPayload(BaseModel):
# 用户ID
sub: Optional[int] = None
# 用户名
username: Optional[str] = None
# 超级用户
super_user: Optional[bool] = None