From 44da8694f0d5be889ca51b34cd70d11f1bdbd697 Mon Sep 17 00:00:00 2001
From: kingmo888 <17401091+kingmo888@users.noreply.github.com>
Date: Wed, 20 Dec 2023 09:22:55 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7V1.4=EF=BC=8C=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0web=20client=EF=BC=8C=E8=AE=A1=E5=88=92=E5=BC=80?=
=?UTF-8?q?=E5=8F=91=E5=86=85=E5=AE=B9=E5=B7=B2=E5=85=A8=E9=83=A8=E5=AE=8C?=
=?UTF-8?q?=E6=88=90=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 14 +-
api/templates/base.html | 1 +
api/templates/share.html | 6 +-
api/util.py | 1 +
db/db.sqlite3 | Bin 155648 -> 155648 bytes
images/webui.png | Bin 0 -> 20898 bytes
rustdesk_server_api/settings.py | 4 +-
rustdesk_server_api/urls.py | 4 +-
static/web_client/assets/AssetManifest.json | 1 +
static/web_client/assets/FontManifest.json | 1 +
static/web_client/assets/assets/android.png | Bin 0 -> 1762 bytes
static/web_client/assets/assets/insecure.png | Bin 0 -> 4126 bytes
.../assets/assets/insecure_relay.png | Bin 0 -> 4616 bytes
static/web_client/assets/assets/linux.png | Bin 0 -> 4247 bytes
static/web_client/assets/assets/mac.png | Bin 0 -> 2885 bytes
static/web_client/assets/assets/secure.png | Bin 0 -> 2509 bytes
.../web_client/assets/assets/secure_relay.png | Bin 0 -> 5147 bytes
static/web_client/assets/assets/win.png | Bin 0 -> 1379 bytes
.../assets/fonts/CupertinoIcons.ttf | Bin 0 -> 283452 bytes
.../assets/fonts/MaterialIcons-Regular.otf | Bin 0 -> 1545172 bytes
static/web_client/assets/fonts/gestures.ttf | Bin 0 -> 7600 bytes
.../web_client/canvaskit@0.33.0/canvaskit.js | 281 +
.../canvaskit@0.33.0/canvaskit.wasm | Bin 0 -> 6953528 bytes
static/web_client/favicon.svg | 1 +
static/web_client/flutter_service_worker.js | 172 +
static/web_client/js/main.dart.js | 94638 ++++++++++++++++
static/web_client/js/no_sleep.js | 230 +
static/web_client/js/vendor.js | 1 +
static/web_client/js/yuv-canvas-1.2.6.js | 1234 +
static/web_client/js/yuv.js | 73 +
static/web_client/js/yuv.wasm | Bin 0 -> 8238 bytes
static/web_client/libopus.js | 5555 +
static/web_client/libopus.wasm | Bin 0 -> 489750 bytes
static/web_client/libs/firebase-analytics.js | 2 +
static/web_client/libs/firebase-app.js | 2 +
static/web_client/manifest.json | 35 +
static/web_client/module/index.b7bb6fa2.js | 22 +
static/web_client/module/vendor.b7bb6fa2.js | 1 +
static/web_client/ogvjs-1.8.6/COPYING | 21 +
.../web_client/ogvjs-1.8.6/COPYING-dav1d.txt | 23 +
static/web_client/ogvjs-1.8.6/COPYING-ogg.txt | 28 +
.../web_client/ogvjs-1.8.6/COPYING-opus.txt | 44 +
.../web_client/ogvjs-1.8.6/COPYING-theora.txt | 28 +
.../web_client/ogvjs-1.8.6/COPYING-vorbis.txt | 28 +
.../ogvjs-1.8.6/LICENSE-nestegg.txt | 13 +
static/web_client/ogvjs-1.8.6/LICENSE-vpx.txt | 31 +
static/web_client/ogvjs-1.8.6/PATENTS-vpx.txt | 23 +
static/web_client/ogvjs-1.8.6/README.md | 391 +
.../ogv-decoder-audio-opus-wasm.js | 39 +
.../ogv-decoder-audio-opus-wasm.wasm | Bin 0 -> 143417 bytes
.../ogv-decoder-audio-vorbis-wasm.js | 40 +
.../ogv-decoder-audio-vorbis-wasm.wasm | Bin 0 -> 155787 bytes
.../ogv-decoder-video-av1-mt-wasm.js | 21 +
.../ogv-decoder-video-av1-mt-wasm.wasm | Bin 0 -> 418335 bytes
.../ogv-decoder-video-av1-mt-wasm.worker.js | 1 +
.../ogv-decoder-video-av1-simd-mt-wasm.js | 21 +
.../ogv-decoder-video-av1-simd-mt-wasm.wasm | Bin 0 -> 495935 bytes
...v-decoder-video-av1-simd-mt-wasm.worker.js | 1 +
.../ogv-decoder-video-av1-simd-wasm.js | 43 +
.../ogv-decoder-video-av1-simd-wasm.wasm | Bin 0 -> 484008 bytes
.../ogvjs-1.8.6/ogv-decoder-video-av1-wasm.js | 43 +
.../ogv-decoder-video-av1-wasm.wasm | Bin 0 -> 406454 bytes
.../ogv-decoder-video-theora-wasm.js | 42 +
.../ogv-decoder-video-theora-wasm.wasm | Bin 0 -> 48923 bytes
.../ogv-decoder-video-vp8-mt-wasm.js | 21 +
.../ogv-decoder-video-vp8-mt-wasm.wasm | Bin 0 -> 139143 bytes
.../ogv-decoder-video-vp8-mt-wasm.worker.js | 1 +
.../ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.js | 44 +
.../ogv-decoder-video-vp8-wasm.wasm | Bin 0 -> 113790 bytes
.../ogv-decoder-video-vp9-mt-wasm.js | 21 +
.../ogv-decoder-video-vp9-mt-wasm.wasm | Bin 0 -> 259095 bytes
.../ogv-decoder-video-vp9-mt-wasm.worker.js | 1 +
.../ogv-decoder-video-vp9-simd-mt-wasm.js | 21 +
.../ogv-decoder-video-vp9-simd-mt-wasm.wasm | Bin 0 -> 277701 bytes
...v-decoder-video-vp9-simd-mt-wasm.worker.js | 1 +
.../ogv-decoder-video-vp9-simd-wasm.js | 45 +
.../ogv-decoder-video-vp9-simd-wasm.wasm | Bin 0 -> 260523 bytes
.../ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.js | 45 +
.../ogv-decoder-video-vp9-wasm.wasm | Bin 0 -> 241857 bytes
.../ogvjs-1.8.6/ogv-demuxer-ogg-wasm.js | 43 +
.../ogvjs-1.8.6/ogv-demuxer-ogg-wasm.wasm | Bin 0 -> 39042 bytes
.../ogvjs-1.8.6/ogv-demuxer-webm-wasm.js | 46 +
.../ogvjs-1.8.6/ogv-demuxer-webm-wasm.wasm | Bin 0 -> 43838 bytes
static/web_client/ogvjs-1.8.6/ogv-es2017.js | 2 +
static/web_client/ogvjs-1.8.6/ogv-support.js | 1 +
static/web_client/ogvjs-1.8.6/ogv-version.js | 1 +
.../ogvjs-1.8.6/ogv-worker-audio.js | 1 +
.../ogvjs-1.8.6/ogv-worker-video.js | 1 +
static/web_client/ogvjs-1.8.6/ogv.js | 2 +
webui/__init__.py | 0
webui/admin.py | 3 +
webui/apps.py | 5 +
webui/migrations/__init__.py | 0
webui/models.py | 3 +
webui/templates/webui.html | 172 +
webui/tests.py | 3 +
webui/urls.py | 22 +
webui/views.py | 13 +
98 files changed, 103669 insertions(+), 9 deletions(-)
create mode 100644 images/webui.png
create mode 100644 static/web_client/assets/AssetManifest.json
create mode 100644 static/web_client/assets/FontManifest.json
create mode 100644 static/web_client/assets/assets/android.png
create mode 100644 static/web_client/assets/assets/insecure.png
create mode 100644 static/web_client/assets/assets/insecure_relay.png
create mode 100644 static/web_client/assets/assets/linux.png
create mode 100644 static/web_client/assets/assets/mac.png
create mode 100644 static/web_client/assets/assets/secure.png
create mode 100644 static/web_client/assets/assets/secure_relay.png
create mode 100644 static/web_client/assets/assets/win.png
create mode 100644 static/web_client/assets/fonts/CupertinoIcons.ttf
create mode 100644 static/web_client/assets/fonts/MaterialIcons-Regular.otf
create mode 100644 static/web_client/assets/fonts/gestures.ttf
create mode 100644 static/web_client/canvaskit@0.33.0/canvaskit.js
create mode 100644 static/web_client/canvaskit@0.33.0/canvaskit.wasm
create mode 100644 static/web_client/favicon.svg
create mode 100644 static/web_client/flutter_service_worker.js
create mode 100644 static/web_client/js/main.dart.js
create mode 100644 static/web_client/js/no_sleep.js
create mode 100644 static/web_client/js/vendor.js
create mode 100644 static/web_client/js/yuv-canvas-1.2.6.js
create mode 100644 static/web_client/js/yuv.js
create mode 100644 static/web_client/js/yuv.wasm
create mode 100644 static/web_client/libopus.js
create mode 100644 static/web_client/libopus.wasm
create mode 100644 static/web_client/libs/firebase-analytics.js
create mode 100644 static/web_client/libs/firebase-app.js
create mode 100644 static/web_client/manifest.json
create mode 100644 static/web_client/module/index.b7bb6fa2.js
create mode 100644 static/web_client/module/vendor.b7bb6fa2.js
create mode 100644 static/web_client/ogvjs-1.8.6/COPYING
create mode 100644 static/web_client/ogvjs-1.8.6/COPYING-dav1d.txt
create mode 100644 static/web_client/ogvjs-1.8.6/COPYING-ogg.txt
create mode 100644 static/web_client/ogvjs-1.8.6/COPYING-opus.txt
create mode 100644 static/web_client/ogvjs-1.8.6/COPYING-theora.txt
create mode 100644 static/web_client/ogvjs-1.8.6/COPYING-vorbis.txt
create mode 100644 static/web_client/ogvjs-1.8.6/LICENSE-nestegg.txt
create mode 100644 static/web_client/ogvjs-1.8.6/LICENSE-vpx.txt
create mode 100644 static/web_client/ogvjs-1.8.6/PATENTS-vpx.txt
create mode 100644 static/web_client/ogvjs-1.8.6/README.md
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-audio-opus-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-audio-opus-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-audio-vorbis-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-audio-vorbis-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.worker.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-simd-mt-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-simd-mt-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-simd-mt-wasm.worker.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-simd-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-simd-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-av1-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-theora-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-theora-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.worker.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.worker.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-simd-mt-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-simd-mt-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-simd-mt-wasm.worker.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-simd-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-simd-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-demuxer-ogg-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-demuxer-ogg-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-demuxer-webm-wasm.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-demuxer-webm-wasm.wasm
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-es2017.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-support.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-version.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-worker-audio.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv-worker-video.js
create mode 100644 static/web_client/ogvjs-1.8.6/ogv.js
create mode 100644 webui/__init__.py
create mode 100644 webui/admin.py
create mode 100644 webui/apps.py
create mode 100644 webui/migrations/__init__.py
create mode 100644 webui/models.py
create mode 100644 webui/templates/webui.html
create mode 100644 webui/tests.py
create mode 100644 webui/urls.py
create mode 100644 webui/views.py
diff --git a/README.md b/README.md
index 1be259b..3c88fbd 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
一个 python 实现的 Rustdesk API 接口,支持 WebUI 管理
-
+
@@ -35,6 +35,8 @@
- 利用心跳接口自动管理token并保活。
- 支持分享设备给其他用户。

+- 支持web控制端(目前仅支持非SSL模式,见下面使用问题说明)
+
后台主页:

@@ -132,17 +134,21 @@ services:
- 连接速度慢
新版本Key模式链接速度慢,可以在服务端启动服务时,不要带参数的-k,此时,客户端也不能配置key。
+
+- Web控制端一直转圈
-## 开发计划
+ web控制端目前仅支持非SSL模式,若webui为https访问,请将s去掉,否则ws连不上一直转圈。如:https://domain.com/webui,改为http://domain.com/webui
+
+## [x] 开发计划
- [x] 分享设备给其他已注册用户(v1.3)
> 说明:类似网盘url分享,url激活后可以获得某个或某组或某个标签下的设备
> 备注:其实web api作为中间件,可做的不多,更多功能还是需要修改客户端来实现,就不太值当了。
-- [ ] 集成Web客户端形式
+- [x] 集成Web客户端形式
- > 将大神的web客户端集成进来(待议)
+ > 将大神的web客户端集成进来,已集成。 [来源](https://www.52pojie.cn/thread-1708319-1-1.html)
## 其他相关工具
diff --git a/api/templates/base.html b/api/templates/base.html
index 0bc6073..d39baa5 100644
--- a/api/templates/base.html
+++ b/api/templates/base.html
@@ -26,6 +26,7 @@ layer.msg(elem.text());
- 首页
- 分享
+- 网页控制
{% if u.is_admin %}
- 管理后台
diff --git a/api/templates/share.html b/api/templates/share.html
index 29cb3dc..6d924da 100644
--- a/api/templates/share.html
+++ b/api/templates/share.html
@@ -20,8 +20,8 @@
-
-
+
+
@@ -35,7 +35,7 @@
{% for one in sharelinks %}
- | {{one.shash}} |
+ {{one.shash}} |
{{one.create_time}} |
{{one.peers}} |
diff --git a/api/util.py b/api/util.py
index 1593586..28089de 100644
--- a/api/util.py
+++ b/api/util.py
@@ -26,6 +26,7 @@ def settings(request):
context['username'] = username
context['is_admin'] = u.is_admin
context['is_active'] = u.is_active
+ context['domain'] = _settings.ID_SERVER
logger.info("set system status variable")
except Exception as e:
diff --git a/db/db.sqlite3 b/db/db.sqlite3
index 2e8cf698ec820c21fb002b5cd1128d6d9dff78a8..442c69d60203f9ee2dec940c4d2f8fa25750c4df 100644
GIT binary patch
delta 513
zcmaixt4;$^6h%vuiW;5)L}xl<2&$9wxUW+T4F-Y05MeMqnsaYFjpZw!njMkIbf+eJuhmRMu-tSC~95G?EC
Z9~&7V;;-T`u>lc)pUanWZBe$5e*tC~b94Xz
delta 513
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