feat: 优化后台网络设置,同时支持ipv4和ipv6
This commit is contained in:
parent
514bf9b8b2
commit
6d7d90d642
@ -77,7 +77,7 @@ def main():
|
|||||||
xiaomusic = XiaoMusic(config)
|
xiaomusic = XiaoMusic(config)
|
||||||
HttpInit(xiaomusic)
|
HttpInit(xiaomusic)
|
||||||
|
|
||||||
uvicorn.run(HttpApp, host="0.0.0.0", port=config.port)
|
uvicorn.run(HttpApp, host=["::", "0.0.0.0"], port=config.port)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import secrets
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from dataclasses import asdict
|
from dataclasses import asdict
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import Depends, FastAPI, HTTPException, Request, status
|
from fastapi import Depends, FastAPI, HTTPException, Request, status
|
||||||
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||||
@ -29,10 +31,49 @@ async def app_lifespan(app):
|
|||||||
task.cancel()
|
task.cancel()
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(lifespan=app_lifespan)
|
|
||||||
security = HTTPBasic()
|
security = HTTPBasic()
|
||||||
|
|
||||||
|
|
||||||
|
def verification(
|
||||||
|
credentials: Annotated[HTTPBasicCredentials, Depends(security)],
|
||||||
|
):
|
||||||
|
current_username_bytes = credentials.username.encode("utf8")
|
||||||
|
correct_username_bytes = config.httpauth_username.encode("utf8")
|
||||||
|
is_correct_username = secrets.compare_digest(
|
||||||
|
current_username_bytes, correct_username_bytes
|
||||||
|
)
|
||||||
|
current_password_bytes = credentials.password.encode("utf8")
|
||||||
|
correct_password_bytes = config.httpauth_password.encode("utf8")
|
||||||
|
is_correct_password = secrets.compare_digest(
|
||||||
|
current_password_bytes, correct_password_bytes
|
||||||
|
)
|
||||||
|
if not (is_correct_username and is_correct_password):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Incorrect username or password",
|
||||||
|
headers={"WWW-Authenticate": "Basic"},
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def no_verification():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
lifespan=app_lifespan,
|
||||||
|
version=__version__,
|
||||||
|
dependencies=[Depends(verification)],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def reset_dependency():
|
||||||
|
if not config.disable_httpauth:
|
||||||
|
app.dependency_overrides[verification] = no_verification
|
||||||
|
else:
|
||||||
|
app.dependency_overrides = {}
|
||||||
|
|
||||||
|
|
||||||
def HttpInit(_xiaomusic):
|
def HttpInit(_xiaomusic):
|
||||||
global xiaomusic, config, log
|
global xiaomusic, config, log
|
||||||
xiaomusic = _xiaomusic
|
xiaomusic = _xiaomusic
|
||||||
@ -41,22 +82,7 @@ def HttpInit(_xiaomusic):
|
|||||||
|
|
||||||
app.mount("/static", StaticFiles(directory="xiaomusic/static"), name="static")
|
app.mount("/static", StaticFiles(directory="xiaomusic/static"), name="static")
|
||||||
app.mount("/music", StaticFiles(directory=config.music_path), name="music")
|
app.mount("/music", StaticFiles(directory=config.music_path), name="music")
|
||||||
|
reset_dependency()
|
||||||
|
|
||||||
def verification(creds: HTTPBasicCredentials = Depends(security)):
|
|
||||||
username = creds.username
|
|
||||||
password = creds.password
|
|
||||||
|
|
||||||
if config.disable_httpauth:
|
|
||||||
return True
|
|
||||||
if config.httpauth_username == username and config.httpauth_password == password:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail="Incorrect email or password",
|
|
||||||
headers={"WWW-Authenticate": "Basic"},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@ -71,7 +97,7 @@ def getversion():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/getvolume")
|
@app.get("/getvolume")
|
||||||
async def getvolume(did: str = "", Verifcation=Depends(verification)):
|
async def getvolume(did: str = ""):
|
||||||
if not xiaomusic.did_exist(did):
|
if not xiaomusic.did_exist(did):
|
||||||
return {"volume": 0}
|
return {"volume": 0}
|
||||||
|
|
||||||
@ -85,7 +111,7 @@ class DidVolume(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/setvolume")
|
@app.post("/setvolume")
|
||||||
async def setvolume(data: DidVolume, Verifcation=Depends(verification)):
|
async def setvolume(data: DidVolume):
|
||||||
did = data.did
|
did = data.did
|
||||||
volume = data.volume
|
volume = data.volume
|
||||||
if not xiaomusic.did_exist(did):
|
if not xiaomusic.did_exist(did):
|
||||||
@ -97,12 +123,12 @@ async def setvolume(data: DidVolume, Verifcation=Depends(verification)):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/searchmusic")
|
@app.get("/searchmusic")
|
||||||
def searchmusic(name: str = "", Verifcation=Depends(verification)):
|
def searchmusic(name: str = ""):
|
||||||
return xiaomusic.searchmusic(name)
|
return xiaomusic.searchmusic(name)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/playingmusic")
|
@app.get("/playingmusic")
|
||||||
def playingmusic(did: str = "", Verifcation=Depends(verification)):
|
def playingmusic(did: str = ""):
|
||||||
if not xiaomusic.did_exist(did):
|
if not xiaomusic.did_exist(did):
|
||||||
return {"ret": "Did not exist"}
|
return {"ret": "Did not exist"}
|
||||||
|
|
||||||
@ -121,7 +147,7 @@ class DidCmd(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/cmd")
|
@app.post("/cmd")
|
||||||
async def do_cmd(data: DidCmd, Verifcation=Depends(verification)):
|
async def do_cmd(data: DidCmd):
|
||||||
did = data.did
|
did = data.did
|
||||||
cmd = data.cmd
|
cmd = data.cmd
|
||||||
log.info(f"docmd. did:{did} cmd:{cmd}")
|
log.info(f"docmd. did:{did} cmd:{cmd}")
|
||||||
@ -135,7 +161,7 @@ async def do_cmd(data: DidCmd, Verifcation=Depends(verification)):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/getsetting")
|
@app.get("/getsetting")
|
||||||
async def getsetting(need_device_list: bool = False, Verifcation=Depends(verification)):
|
async def getsetting(need_device_list: bool = False):
|
||||||
config = xiaomusic.getconfig()
|
config = xiaomusic.getconfig()
|
||||||
data = asdict(config)
|
data = asdict(config)
|
||||||
if need_device_list:
|
if need_device_list:
|
||||||
@ -146,13 +172,14 @@ async def getsetting(need_device_list: bool = False, Verifcation=Depends(verific
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/savesetting")
|
@app.post("/savesetting")
|
||||||
async def savesetting(request: Request, Verifcation=Depends(verification)):
|
async def savesetting(request: Request):
|
||||||
try:
|
try:
|
||||||
data_json = await request.body()
|
data_json = await request.body()
|
||||||
data = json.loads(data_json.decode("utf-8"))
|
data = json.loads(data_json.decode("utf-8"))
|
||||||
debug_data = deepcopy_data_no_sensitive_info(data)
|
debug_data = deepcopy_data_no_sensitive_info(data)
|
||||||
log.info(f"saveconfig: {debug_data}")
|
log.info(f"saveconfig: {debug_data}")
|
||||||
await xiaomusic.saveconfig(data)
|
await xiaomusic.saveconfig(data)
|
||||||
|
reset_dependency()
|
||||||
return "save success"
|
return "save success"
|
||||||
except json.JSONDecodeError as err:
|
except json.JSONDecodeError as err:
|
||||||
raise HTTPException(status_code=400, detail="Invalid JSON") from err
|
raise HTTPException(status_code=400, detail="Invalid JSON") from err
|
||||||
@ -164,7 +191,7 @@ async def musiclist(Verifcation=Depends(verification)):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/curplaylist")
|
@app.get("/curplaylist")
|
||||||
async def curplaylist(did: str = "", Verifcation=Depends(verification)):
|
async def curplaylist(did: str = ""):
|
||||||
if not xiaomusic.did_exist(did):
|
if not xiaomusic.did_exist(did):
|
||||||
return ""
|
return ""
|
||||||
return xiaomusic.get_cur_play_list(did)
|
return xiaomusic.get_cur_play_list(did)
|
||||||
@ -175,7 +202,7 @@ class MusicItem(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/delmusic")
|
@app.post("/delmusic")
|
||||||
def delmusic(data: MusicItem, Verifcation=Depends(verification)):
|
def delmusic(data: MusicItem):
|
||||||
log.info(data)
|
log.info(data)
|
||||||
xiaomusic.del_music(data.name)
|
xiaomusic.del_music(data.name)
|
||||||
return "success"
|
return "success"
|
||||||
@ -186,7 +213,7 @@ class UrlInfo(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/downloadjson")
|
@app.post("/downloadjson")
|
||||||
async def downloadjson(data: UrlInfo, Verifcation=Depends(verification)):
|
async def downloadjson(data: UrlInfo):
|
||||||
log.info(data)
|
log.info(data)
|
||||||
url = data.url
|
url = data.url
|
||||||
content = ""
|
content = ""
|
||||||
@ -212,7 +239,7 @@ def downloadlog(Verifcation=Depends(verification)):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/playurl")
|
@app.get("/playurl")
|
||||||
async def playurl(did: str, url: str, Verifcation=Depends(verification)):
|
async def playurl(did: str, url: str):
|
||||||
if not xiaomusic.did_exist(did):
|
if not xiaomusic.did_exist(did):
|
||||||
return {"ret": "Did not exist"}
|
return {"ret": "Did not exist"}
|
||||||
|
|
||||||
@ -223,7 +250,7 @@ async def playurl(did: str, url: str, Verifcation=Depends(verification)):
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/debug_play_by_music_url")
|
@app.post("/debug_play_by_music_url")
|
||||||
async def debug_play_by_music_url(request: Request, Verifcation=Depends(verification)):
|
async def debug_play_by_music_url(request: Request):
|
||||||
try:
|
try:
|
||||||
data = await request.body()
|
data = await request.body()
|
||||||
data_dict = json.loads(data.decode("utf-8"))
|
data_dict = json.loads(data.decode("utf-8"))
|
||||||
|
Loading…
Reference in New Issue
Block a user