支持手动token认证
This commit is contained in:
parent
0c2a84f944
commit
a8863f911b
@ -2,5 +2,6 @@
|
|||||||
"theme": "auto",
|
"theme": "auto",
|
||||||
"token": "",
|
"token": "",
|
||||||
"server_url": "",
|
"server_url": "",
|
||||||
"server_port": "32400"
|
"server_port": "",
|
||||||
|
"server_scheme": ""
|
||||||
}
|
}
|
28
app/main.py
28
app/main.py
@ -14,11 +14,12 @@ templates = Jinja2Templates(directory=os.path.join(os.path.dirname(__file__), "t
|
|||||||
app.mount("/static", StaticFiles(directory=os.path.join(os.path.dirname(__file__), "static")), name="static")
|
app.mount("/static", StaticFiles(directory=os.path.join(os.path.dirname(__file__), "static")), name="static")
|
||||||
|
|
||||||
|
|
||||||
|
# 显示主页
|
||||||
@app.get("/", response_class=HTMLResponse)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
async def home(request: Request):
|
async def home(request: Request):
|
||||||
config = load_config()
|
config = load_config()
|
||||||
theme = config.get("theme", "auto")
|
theme = config.get("theme", "auto")
|
||||||
scheme, host, port = get_server_settings(config)
|
token,scheme, host, port = get_server_settings(config)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"login.html",
|
"login.html",
|
||||||
{
|
{
|
||||||
@ -26,22 +27,25 @@ async def home(request: Request):
|
|||||||
"theme": theme,
|
"theme": theme,
|
||||||
"path": "/login",
|
"path": "/login",
|
||||||
"scheme": scheme,
|
"scheme": scheme,
|
||||||
|
"token": token,
|
||||||
"server_url": host,
|
"server_url": host,
|
||||||
"port": port,
|
"port": port,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 登录页面和处理
|
||||||
@app.get("/login", response_class=HTMLResponse)
|
@app.get("/login", response_class=HTMLResponse)
|
||||||
async def login_page(request: Request):
|
async def login_page(request: Request):
|
||||||
config = load_config()
|
config = load_config()
|
||||||
theme = config.get("theme", "auto")
|
theme = config.get("theme", "auto")
|
||||||
scheme, host, port = get_server_settings(config)
|
token, scheme, host, port = get_server_settings(config)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"login.html",
|
"login.html",
|
||||||
{
|
{
|
||||||
"request": request,
|
"request": request,
|
||||||
"theme": theme,
|
"theme": theme,
|
||||||
"path": "/login",
|
"path": "/login",
|
||||||
|
"token": token,
|
||||||
"scheme": scheme,
|
"scheme": scheme,
|
||||||
"server_url": host,
|
"server_url": host,
|
||||||
"port": port,
|
"port": port,
|
||||||
@ -53,19 +57,26 @@ async def login(
|
|||||||
request: Request,
|
request: Request,
|
||||||
user: str = Form(...),
|
user: str = Form(...),
|
||||||
pw: str = Form(...),
|
pw: str = Form(...),
|
||||||
|
token: str = Form(...),
|
||||||
scheme: str = Form("https"),
|
scheme: str = Form("https"),
|
||||||
url: str = Form(...),
|
url: str = Form(...),
|
||||||
port: str = Form("32400")
|
port: str = Form("32400"),
|
||||||
):
|
):
|
||||||
config = load_config()
|
config = load_config()
|
||||||
theme = config.get("theme", "auto")
|
theme = config.get("theme", "auto")
|
||||||
|
# 尝试连接到 Plex 服务器
|
||||||
try:
|
try:
|
||||||
full_url = url
|
# 优先使用 token 连接,如果 token 为空则使用用户名和密码连接
|
||||||
if not full_url.startswith("http://") and not full_url.startswith("https://"):
|
_, token_success = connect_plex(user, pw, token, scheme, url, port)
|
||||||
full_url = f"{scheme}://{url}"
|
# 成功连接后保存配置到配置文件
|
||||||
connect_plex(config, user, pw, full_url, port)
|
config.update({
|
||||||
|
"server_url": url,
|
||||||
|
"server_scheme": scheme,
|
||||||
|
"server_port": port,
|
||||||
|
"token": token_success,
|
||||||
|
})
|
||||||
save_config(config)
|
save_config(config)
|
||||||
scheme, host, port = get_server_settings(config)
|
token, scheme, host, port = get_server_settings(config)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"login.html",
|
"login.html",
|
||||||
{
|
{
|
||||||
@ -74,6 +85,7 @@ async def login(
|
|||||||
"success": True,
|
"success": True,
|
||||||
"theme": theme,
|
"theme": theme,
|
||||||
"path": "/login",
|
"path": "/login",
|
||||||
|
"token": token,
|
||||||
"scheme": scheme,
|
"scheme": scheme,
|
||||||
"server_url": host,
|
"server_url": host,
|
||||||
"port": port,
|
"port": port,
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="pw" class="form-label">密码</label>
|
<label for="pw" class="form-label">密码</label>
|
||||||
<input type="password" class="form-control" id="pw" name="pw">
|
<input type="password" class="form-control" id="pw" name="pw">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="token" class="form-label">Token</label>
|
||||||
|
<input type="text" class="form-control" id="token" name="token" value="{{ token }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="scheme" class="form-label">协议</label>
|
<label for="scheme" class="form-label">协议</label>
|
||||||
|
6
app/utils/common.py
Normal file
6
app/utils/common.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
def str_is_empty(s: str) -> bool:
|
||||||
|
"""Check if a string is empty or contains only whitespace."""
|
||||||
|
if s is None:
|
||||||
|
return True
|
||||||
|
stripped = s.replace(" ", " ")
|
||||||
|
return not bool(stripped)
|
@ -17,7 +17,8 @@ def save_config(new_config):
|
|||||||
|
|
||||||
def get_server_settings(config):
|
def get_server_settings(config):
|
||||||
"""Return (scheme, host, port) using defaults when not configured."""
|
"""Return (scheme, host, port) using defaults when not configured."""
|
||||||
scheme = "https"
|
scheme = config.get("server_scheme", "https")
|
||||||
|
token = config.get("token", "") or ""
|
||||||
host = ""
|
host = ""
|
||||||
port = config.get("server_port", "32400") or "32400"
|
port = config.get("server_port", "32400") or "32400"
|
||||||
|
|
||||||
@ -31,5 +32,5 @@ def get_server_settings(config):
|
|||||||
port = str(parsed.port)
|
port = str(parsed.port)
|
||||||
else:
|
else:
|
||||||
host = url
|
host = url
|
||||||
|
print(f"server_scheme: {scheme}, host: {host}, port: {port}")
|
||||||
return scheme, host, port
|
return token, scheme, host, port
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
from plexapi.myplex import MyPlexAccount
|
from plexapi.myplex import MyPlexAccount
|
||||||
from plexapi.server import PlexServer
|
from plexapi.server import PlexServer
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
from app.utils.common import str_is_empty
|
||||||
|
|
||||||
|
def build_plex_url(scheme, url, port="32400"):
|
||||||
def connect_plex(config, username, password, url, port="32400"):
|
"""Build a full Plex URL from scheme, url, and port."""
|
||||||
"""Return a connected PlexServer instance and update config with token and server info."""
|
# 如果url不以http://或https://开头,则添加scheme
|
||||||
token = config.get("token")
|
full_url = url
|
||||||
if not token:
|
if not full_url.startswith("http://") and not full_url.startswith("https://"):
|
||||||
account = MyPlexAccount(username, password)
|
full_url = f"{scheme}://{url}"
|
||||||
token = account.authenticationToken
|
parsed = urlparse(full_url)
|
||||||
config["token"] = token
|
|
||||||
|
|
||||||
parsed = urlparse(url)
|
|
||||||
|
|
||||||
if parsed.scheme in ("http", "https"):
|
if parsed.scheme in ("http", "https"):
|
||||||
netloc = parsed.netloc or parsed.path
|
netloc = parsed.netloc or parsed.path
|
||||||
@ -20,6 +18,33 @@ def connect_plex(config, username, password, url, port="32400"):
|
|||||||
base_url = f"{parsed.scheme}://{netloc}"
|
base_url = f"{parsed.scheme}://{netloc}"
|
||||||
else:
|
else:
|
||||||
base_url = f"http://{url}:{port}"
|
base_url = f"http://{url}:{port}"
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
def connect_plex(username, password, token, scheme, url, port="32400"):
|
||||||
|
"""Return a connected PlexServer instance and update config with token and server info."""
|
||||||
|
# 如果token存在且不为空,则使用token连接
|
||||||
|
if not str_is_empty(token):
|
||||||
|
return connect_plex_with_token(token, scheme, url, port)
|
||||||
|
else:
|
||||||
|
return connect_plex_with_pw(username, password, scheme, url, port)
|
||||||
|
|
||||||
|
|
||||||
|
def connect_plex_with_pw(username, password, scheme, url, port="32400"):
|
||||||
|
"""Return a connected PlexServer instance and update config with token and server info."""
|
||||||
|
# url 初始化
|
||||||
|
base_url = build_plex_url(scheme, url, port)
|
||||||
|
# account 初始化
|
||||||
|
account = MyPlexAccount(username, password)
|
||||||
|
# token 获取
|
||||||
|
token = account.authenticationToken
|
||||||
|
|
||||||
server = PlexServer(base_url, token)
|
server = PlexServer(base_url, token)
|
||||||
config.update({"server_url": url, "server_port": port})
|
return server, token
|
||||||
return server
|
|
||||||
|
def connect_plex_with_token(token, scheme, url, port="32400"):
|
||||||
|
"""Return a connected PlexServer instance using a token."""
|
||||||
|
# URL 初始化
|
||||||
|
base_url = build_plex_url(scheme, url, port)
|
||||||
|
|
||||||
|
server = PlexServer(base_url, token)
|
||||||
|
return server, token
|
Loading…
Reference in New Issue
Block a user