diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62c8935 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/README.md b/README.md index fc9af46..3302719 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,38 @@ # minimap_renderer_web + minimap_renderer项目的web服务支持 + +本项目为 https://github.com/benx1n/HikariBot 的扩展支持 + +请先安装好python环境 python版本大于等于3.10 + +# 部署流程 + +请吾 + +首先 把 https://github.com/WoWs-Builder-Team/minimap_renderer 项目克隆到本地 + +把本项目的以下文件复制到minimap_renderer根目录下 + +`src` 文件夹 + +`temp` 文件夹 + +`token.json` 文件 + +`安装依赖.bat` 文件 + +`运行.bat` 文件 + +复制后的根目录有以下文件 + +![257368cc83c92fe8dcd18558b2644816.png](temp%2F257368cc83c92fe8dcd18558b2644816.png) + +src目录里面 + +![00b17fe4ce2e4966dbed620093b66f79.png](temp%2F00b17fe4ce2e4966dbed620093b66f79.png) + + +先执行 `安装依赖.bat` 然后执行 `运行.bat` + +如果是conda环境部署,请自行复制.bat文件的内容执行 \ No newline at end of file diff --git a/src/render_web.py b/src/render_web.py new file mode 100644 index 0000000..25b3bbd --- /dev/null +++ b/src/render_web.py @@ -0,0 +1,92 @@ +import hashlib +import io +import json +import os +import secrets +from typing import Annotated + +from fastapi import FastAPI, UploadFile, Depends, HTTPException, status +from fastapi.responses import FileResponse +from fastapi.security import HTTPBasic, HTTPBasicCredentials + +from renderer.render import Renderer +from replay_parser import ReplayParser + +app = FastAPI() +security = HTTPBasic() + + +def get_current_username( + credentials: Annotated[HTTPBasicCredentials, Depends(security)], +): + with open(os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + "/token.json", 'r', encoding='utf8') as json_f: + json_data = json.load(json_f) + + current_username_bytes = credentials.username.encode("utf8") + correct_username_bytes = str(json_data['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 = str(json_data['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 credentials.username + + +@app.post("/upload_replays_video", summary="上传rep文件返回视频流") +async def upload_replays_video(file: UploadFile, username: Annotated[str, Depends(get_current_username)]): + binary_bytes = file.file.read() + binary_stream = io.BytesIO(binary_bytes) + uuid_str_mp4 = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + '/temp/' + hashlib.sha256(binary_bytes).hexdigest() + '.mp4' + if not os.path.exists(uuid_str_mp4): + replay_info = ReplayParser( + binary_stream, strict=True, raw_data_output=False + ).get_info() + renderer = Renderer( + replay_info["hidden"]["replay_data"], + logs=True, + enable_chat=True, + use_tqdm=True, + ) + renderer.start(str(uuid_str_mp4)) + return FileResponse(uuid_str_mp4, media_type="video/mp4") + + +@app.post("/upload_replays_video_url", summary="上传rep文件返回视频名称") +async def upload_replays_video_url(file: UploadFile, username: Annotated[str, Depends(get_current_username)]): + binary_bytes = file.file.read() + binary_stream = io.BytesIO(binary_bytes) + video_name = hashlib.sha256(binary_bytes).hexdigest() + '.mp4' + uuid_str_mp4 = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + '/temp/' + video_name + if not os.path.exists(uuid_str_mp4): + replay_info = ReplayParser( + binary_stream, strict=True, raw_data_output=False + ).get_info() + renderer = Renderer( + replay_info["hidden"]["replay_data"], + logs=True, + enable_chat=True, + use_tqdm=True, + ) + renderer.start(str(uuid_str_mp4)) + return video_name + + +@app.get("/video_url", summary="上传rep文件返回视频地址") +async def video_url(file_name: str): + file = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + '/temp/' + file_name + if os.path.exists(file): + return FileResponse(file, media_type="video/mp4") + return HTTPException(status_code=404, detail="文件不存在") + + +def del_file(file_name): + os.remove(file_name) diff --git a/temp/00b17fe4ce2e4966dbed620093b66f79.png b/temp/00b17fe4ce2e4966dbed620093b66f79.png new file mode 100644 index 0000000..b9bb9e4 Binary files /dev/null and b/temp/00b17fe4ce2e4966dbed620093b66f79.png differ diff --git a/temp/257368cc83c92fe8dcd18558b2644816.png b/temp/257368cc83c92fe8dcd18558b2644816.png new file mode 100644 index 0000000..7b8cddd Binary files /dev/null and b/temp/257368cc83c92fe8dcd18558b2644816.png differ diff --git "a/temp/\347\274\223\345\255\230\347\233\256\345\275\225.txt" "b/temp/\347\274\223\345\255\230\347\233\256\345\275\225.txt" new file mode 100644 index 0000000..e69de29 diff --git a/token.json b/token.json new file mode 100644 index 0000000..9822ad0 --- /dev/null +++ b/token.json @@ -0,0 +1,4 @@ +{ + "username": "yuyuko", + "password": "yuyuko" +} \ No newline at end of file diff --git "a/\345\256\211\350\243\205\344\276\235\350\265\226.bat" "b/\345\256\211\350\243\205\344\276\235\350\265\226.bat" new file mode 100644 index 0000000..53d96d5 --- /dev/null +++ "b/\345\256\211\350\243\205\344\276\235\350\265\226.bat" @@ -0,0 +1,6 @@ +pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com + +pip install fastapi~=0.110.2 -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com + +pip install python-multipart~=0.0.9 -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com + diff --git "a/\350\277\220\350\241\214.bat" "b/\350\277\220\350\241\214.bat" new file mode 100644 index 0000000..566fc76 --- /dev/null +++ "b/\350\277\220\350\241\214.bat" @@ -0,0 +1,7 @@ +chcp 65001 + +cd src + +uvicorn render_web:app --host "0.0.0.0" --port 9876 + +pause \ No newline at end of file