CLI: Embed WebUI

This commit is contained in:
genteure 2022-06-04 03:39:33 +08:00
parent dfba519e41
commit 89d41742ef
9 changed files with 143 additions and 11 deletions

View File

@ -23,9 +23,17 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v2
- name: Make sure webui can be built
if: "${{ matrix.os == 'windows-latest' }}"
run: ./webui/build.ps1
- name: Make sure webui can be built
if: "${{ matrix.os == 'ubuntu-latest' }}"
run: ./webui/build.sh
- name: Run Tests - Debug - name: Run Tests - Debug
run: dotnet test -v m -c Debug run: dotnet test -v m -c Debug
- name: Run Tests - Release - name: Run Tests - Release
@ -39,6 +47,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v1.1
@ -73,9 +82,13 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v2
- name: Build WebUI
run: ./webui/build.sh
- name: Build CLI - Debug - name: Build CLI - Debug
if: ${{ matrix.rid == 'any' }} if: ${{ matrix.rid == 'any' }}
run: dotnet publish -c Debug BililiveRecorder.Cli/BililiveRecorder.Cli.csproj run: dotnet publish -c Debug BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
@ -113,6 +126,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx - name: Set up Docker Buildx
@ -132,6 +146,8 @@ jobs:
with: with:
images: | images: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build WebUI
run: ./webui/build.sh
- name: Build CLI - name: Build CLI
run: dotnet build -c Release -o ./BililiveRecorder.Cli/bin/docker_out BililiveRecorder.Cli/BililiveRecorder.Cli.csproj run: dotnet build -c Release -o ./BililiveRecorder.Cli/bin/docker_out BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
# Build and push Docker image with Buildx (don't push on PR) # Build and push Docker image with Buildx (don't push on PR)

View File

@ -22,9 +22,17 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v2
- name: Make sure webui can be built
if: "${{ matrix.os == 'windows-latest' }}"
run: ./webui/build.ps1
- name: Make sure webui can be built
if: "${{ matrix.os == 'ubuntu-latest' }}"
run: ./webui/build.sh
- name: Run Tests - Debug - name: Run Tests - Debug
run: dotnet test -v m -c Debug run: dotnet test -v m -c Debug
- name: Run Tests - Release - name: Run Tests - Release
@ -41,6 +49,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2 uses: microsoft/setup-msbuild@v1.0.2
- name: Restore Packages - name: Restore Packages
@ -83,22 +92,31 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v2
- name: Build WebUI
run: ./webui/build.sh
- name: Build CLI - name: Build CLI
if: ${{ matrix.rid == 'any' }} if: ${{ matrix.rid == 'any' }}
run: dotnet publish -c ${{ matrix.build_configuration }} BililiveRecorder.Cli/BililiveRecorder.Cli.csproj run: dotnet publish -c ${{ matrix.build_configuration }} BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
- name: Build CLI - name: Build CLI
if: ${{ matrix.rid != 'any' }} if: ${{ matrix.rid != 'any' }}
run: dotnet publish -c ${{ matrix.build_configuration }} -r ${{ matrix.rid }} BililiveRecorder.Cli/BililiveRecorder.Cli.csproj run: dotnet publish -c ${{ matrix.build_configuration }} -r ${{ matrix.rid }} BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: CLI-${{ matrix.rid }}-${{ matrix.build_configuration }} name: CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}
path: BililiveRecorder.Cli/publish/${{ matrix.rid }} path: BililiveRecorder.Cli/publish/${{ matrix.rid }}
- name: Pack Release Asset - name: Pack Release Asset
run: | run: |
cd BililiveRecorder.Cli/publish cd BililiveRecorder.Cli/publish
zip -r CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}.zip ./${{ matrix.rid }} zip -r CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}.zip ./${{ matrix.rid }}
- name: Upload Release Asset - name: Upload Release Asset
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:
@ -120,6 +138,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx - name: Set up Docker Buildx
@ -148,6 +167,8 @@ jobs:
images: | images: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
bililive/recorder bililive/recorder
- name: Build WebUI
run: ./webui/build.sh
- name: Build CLI - name: Build CLI
run: dotnet build -c Release -o ./BililiveRecorder.Cli/bin/docker_out BililiveRecorder.Cli/BililiveRecorder.Cli.csproj run: dotnet build -c Release -o ./BililiveRecorder.Cli/bin/docker_out BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
# Build and push Docker image with Buildx (don't push on PR) # Build and push Docker image with Buildx (don't push on PR)

1
.gitignore vendored
View File

@ -265,3 +265,4 @@ __pycache__/
BililiveRecorder.Cli/Properties/launchSettings.json BililiveRecorder.Cli/Properties/launchSettings.json
**/*.received.* **/*.received.*
BililiveRecorder.Web/embeded/ui/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "webui-source"]
path = webui/source
url = https://github.com/BililiveRecorder/BililiveRecorder-WebUI.git

View File

@ -135,8 +135,16 @@ namespace BililiveRecorder.Web
var originalPath = context.Request.Path; var originalPath = context.Request.Path;
var originalQueryString = context.Request.QueryString; var originalQueryString = context.Request.QueryString;
try try
{
if (originalPath.StartsWithSegments("/ui"))
{
context.Request.Path = "/ui/";
}
else
{ {
context.Request.Path = PAGE404; context.Request.Path = PAGE404;
}
context.Request.QueryString = new QueryString(); context.Request.QueryString = new QueryString();
await next(context); await next(context);
} }
@ -209,10 +217,10 @@ namespace BililiveRecorder.Web
endpoints.MapGraphQLWebSockets<RecorderSchema>(); endpoints.MapGraphQLWebSockets<RecorderSchema>();
endpoints.MapSwagger(); endpoints.MapSwagger();
endpoints.MapGraphQLPlayground(); endpoints.MapGraphQLPlayground("graphql/playground");
endpoints.MapGraphQLGraphiQL(); endpoints.MapGraphQLGraphiQL("graphql/graphiql");
endpoints.MapGraphQLAltair(); endpoints.MapGraphQLAltair("graphql/altair");
endpoints.MapGraphQLVoyager(); endpoints.MapGraphQLVoyager("graphql/voyager");
}) })
.UseSwaggerUI(c => .UseSwaggerUI(c =>
{ {

View File

@ -1,5 +1,53 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8><meta content="width=device-width,initial-scale=1"name=viewport><title>录播姬</title><style>a{margin:5px}textarea{width:300px;height:200px}</style><h1>录播姬,以后再写管理界面</h1><p><span style=color:red;font-weight:700>API 界面</span> <a href=/ui/graphiql>GraphiQL</a> <a href=/ui/playground>Playground</a> <a href=/ui/altair>Altair</a> <a href=/ui/voyager>Voyager</a><p>说明:录播姬 API 里的 objectId 在重启后会重新生成,是不保存到配置文件里的<div><h2>API 用法示例</h2><p>graphql 的<b>语法</b>请查看官方文档 <a href=https://graphql.org/learn/ >https://graphql.org/learn/</a> ,或中文翻译镜像 <a href=https://graphql.cn/learn/ >https://graphql.cn/learn/</a><div><h3>列出所有直播间和基本信息</h3><textarea> <head>
<meta charset=utf-8>
<meta content="width=device-width,initial-scale=1" name=viewport>
<title>B站录播姬</title>
<style>
a {
margin: 5px
}
textarea {
width: 300px;
height: 200px
}
</style>
</head>
<body>
<h1>B站录播姬</h1>
<p>
<span style="color:red;font-weight:700">录播姬管理界面</span>
<a href="/ui">WebUI</a>
</p>
<p>
<span style="color:red;font-weight:700">REST API 界面</span>
<a href="/swagger">Swagger</a>
</p>
<p>
<span style="color:red;font-weight:700">GraphiQL API 界面</span>
<a href="/graphql/graphiql">GraphiQL</a>
<a href="/graphql/playground">Playground</a>
<a href="/graphql/altair">Altair</a>
<a href="/graphql/voyager">Voyager</a>
</p>
<p>录播姬 API 里的 objectId 在重启后会重新生成,是不保存到配置文件里的</p>
<div>
<hr style="margin-top: 50px;">
<h2>GraphQL API 用法示例</h2>
<p>
graphql 的<b>语法</b>请查看官方文档
<a href="https://graphql.org/learn/">https://graphql.org/learn/</a>
或中文翻译镜像
<a href="https://graphql.cn/learn/">https://graphql.cn/learn/</a>
</p>x
<div>
<h3>列出所有直播间和基本信息</h3>
<textarea>
query { query {
rooms { rooms {
objectId objectId
@ -14,7 +62,11 @@ query {
areaNameParent areaNameParent
areaNameChild areaNameChild
} }
}</textarea></div><div><h3>列出所有直播间的所有信息截至编写此页面时具体最新属性见API界面的文档</h3><textarea> }</textarea>
</div>
<div>
<h3>列出所有直播间的所有信息截至编写此页面时具体最新属性见API界面的文档</h3><textarea>
query { query {
rooms { rooms {
objectId objectId
@ -78,7 +130,10 @@ query {
areaNameChild areaNameChild
} }
} }
</textarea></div><div><h3>添加一个房间</h3><textarea> </textarea>
</div>
<div>
<h3>添加一个房间</h3><textarea>
mutation { mutation {
addRoom(roomId: 3, autoRecord: false) { addRoom(roomId: 3, autoRecord: false) {
objectId objectId
@ -89,7 +144,10 @@ mutation {
} }
} }
} }
</textarea></div><div><h3>添加一个房间,用变量传参版</h3><textarea> </textarea>
</div>
<div>
<h3>添加一个房间,用变量传参版</h3><textarea>
mutation AddRoom($roomid: Int, $autoRecord: Boolean) { mutation AddRoom($roomid: Int, $autoRecord: Boolean) {
addRoom(roomId: $roomid, autoRecord: $autoRecord) { addRoom(roomId: $roomid, autoRecord: $autoRecord) {
objectId objectId
@ -100,7 +158,10 @@ mutation AddRoom($roomid: Int, $autoRecord: Boolean) {
} }
} }
} }
</textarea> <textarea>{'roomid': 4, 'autoRecord': false}</textarea></div><div><h3>启用自动录制</h3><textarea> </textarea> <textarea>{'roomid': 4, 'autoRecord': false}</textarea>
</div>
<div>
<h3>启用自动录制</h3><textarea>
mutation { mutation {
setRoomConfig(roomId: 3, config: { autoRecord: true }) { setRoomConfig(roomId: 3, config: { autoRecord: true }) {
objectId objectId
@ -112,4 +173,10 @@ mutation {
} }
} }
} }
</textarea></div><div>开始录制、结束录制、手动切分,都是 mutation在 graphql 文档页面里可以看到</div></div> </textarea>
</div>
<div>开始录制、结束录制、手动切分,都是 mutation在 graphql 文档页面里可以看到</div>
</div>
</body>
</html>

7
webui/build.ps1 Normal file
View File

@ -0,0 +1,7 @@
Set-PSDebug -Trace 1
Push-Location "$PSScriptRoot/source"
$env:BASE_URL = "/ui/"
npm ci
npx vite build
Copy-Item -Recurse dist ../../BililiveRecorder.Web/embeded/ui
Pop-Location

8
webui/build.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -ex
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-$0}"; )" &> /dev/null && pwd 2> /dev/null; )";
pushd "$SCRIPT_DIR/source"
export BASE_URL="/ui/"
npm ci && npx vite build
cp --recursive dist ../../BililiveRecorder.Web/embeded/ui
popd

1
webui/source Submodule

@ -0,0 +1 @@
Subproject commit 9c058133cd4e88d4b31a00faf6433d1e4e5fb853