Compare commits

...

4 Commits

Author SHA1 Message Date
Koha9
8fa0189a1d
Merge pull request #2 from Koha9/codex/add-token-based-authentication-for-plex-server
Implement Plex token login
2025-06-20 22:36:54 +09:00
Koha9
83c5780c57 Remove library selection and default theme 2025-06-20 22:32:05 +09:00
Koha9
75a413667d Set default Plex port 2025-06-20 22:27:01 +09:00
Koha9
aa4223b413 Refactor Plex interaction into separate module 2025-06-20 21:54:55 +09:00
6 changed files with 53 additions and 16 deletions

View File

@ -12,6 +12,11 @@ PlexPlaylistSync 是一个用于同步 Plex 播放列表和本地 `.m3u`/`.m3u8`
- **低功耗运行**: 适合 NAS 或服务器 24 小时运行,优化资源使用,减少能耗。 - **低功耗运行**: 适合 NAS 或服务器 24 小时运行,优化资源使用,减少能耗。
- **Docker 部署**: 可通过 Docker 轻松部署和运行。 - **Docker 部署**: 可通过 Docker 轻松部署和运行。
### Token 登录
首次登录时使用用户名和密码连接 Plex 服务器,成功后程序会将获得的 `token` 保存在配置文件中,后续通信仅使用该 `token`,不再保存明文密码。
默认情况下 Plex 服务器使用 `32400` 端口,可在未修改服务器端口时直接使用该默认值。
## 安装 ## 安装
首先安装依赖: 首先安装依赖:

View File

@ -1,3 +1,6 @@
{ {
"theme": "light" "theme": "auto",
"token": "",
"server_url": "",
"server_port": "32400"
} }

View File

@ -4,6 +4,7 @@ from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from app.utils.plex_client import connect_plex
app = FastAPI() app = FastAPI()
templates = Jinja2Templates(directory=os.path.join(os.path.dirname(__file__), "templates")) templates = Jinja2Templates(directory=os.path.join(os.path.dirname(__file__), "templates"))
@ -31,16 +32,34 @@ async def login(
user: str = Form(...), user: str = Form(...),
pw: str = Form(...), pw: str = Form(...),
url: str = Form(...), url: str = Form(...),
port: str = Form(...), port: str = Form("32400")
library: str = Form(...)
): ):
config = load_config() config = load_config()
theme = config.get("theme", "auto") theme = config.get("theme", "auto")
# demo假装连接成功 try:
if user == "admin": connect_plex(config, user, pw, url, port)
return templates.TemplateResponse("login.html", {"request": request, "message": "连接成功", "success": True, "theme": theme, "path": "/login"}) save_config(config)
else: return templates.TemplateResponse(
return templates.TemplateResponse("login.html", {"request": request, "message": "连接失败:用户名错误", "success": False, "theme": theme, "path": "/login"}) "login.html",
{
"request": request,
"message": "连接成功",
"success": True,
"theme": theme,
"path": "/login",
},
)
except Exception as e:
return templates.TemplateResponse(
"login.html",
{
"request": request,
"message": f"连接失败:{str(e)}",
"success": False,
"theme": theme,
"path": "/login",
},
)
@app.get("/playlist", response_class=HTMLResponse) @app.get("/playlist", response_class=HTMLResponse)
async def get_playlist(request: Request): async def get_playlist(request: Request):

View File

@ -19,14 +19,7 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="port" class="form-label">端口</label> <label for="port" class="form-label">端口</label>
<input type="text" class="form-control" id="port" name="port" placeholder="32400"> <input type="text" class="form-control" id="port" name="port" value="32400">
</div>
<div class="mb-3">
<label for="library" class="form-label">选择库</label>
<select class="form-select" id="library" name="library">
<option>Music</option>
<option>Podcast</option>
</select>
</div> </div>
<button type="submit" class="btn btn-primary">连接</button> <button type="submit" class="btn btn-primary">连接</button>
</form> </form>

16
app/utils/plex_client.py Normal file
View File

@ -0,0 +1,16 @@
from plexapi.myplex import MyPlexAccount
from plexapi.server import PlexServer
def connect_plex(config, username, password, url, port="32400"):
"""Return a connected PlexServer instance and update config with token and server info."""
token = config.get("token")
if not token:
account = MyPlexAccount(username, password)
token = account.authenticationToken
config["token"] = token
base_url = f"http://{url}:{port}"
server = PlexServer(base_url, token)
config.update({"server_url": url, "server_port": port})
return server

View File

@ -2,3 +2,4 @@ fastapi
uvicorn[standard] uvicorn[standard]
jinja2 jinja2
python-multipart python-multipart
plexapi