mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-16 05:10:59 +08:00
Add web config editor #153
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
|||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -35,6 +37,8 @@ func Init() {
|
|||||||
initStatic(cfg.Mod.StaticDir)
|
initStatic(cfg.Mod.StaticDir)
|
||||||
initWS(cfg.Mod.Origin)
|
initWS(cfg.Mod.Origin)
|
||||||
|
|
||||||
|
HandleFunc("api/config", configHandler)
|
||||||
|
HandleFunc("api/exit", exitHandler)
|
||||||
HandleFunc("api/streams", streamsHandler)
|
HandleFunc("api/streams", streamsHandler)
|
||||||
HandleFunc("api/ws", apiWS)
|
HandleFunc("api/ws", apiWS)
|
||||||
|
|
||||||
@@ -96,6 +100,17 @@ func middlewareCORS(next http.Handler) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func exitHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s := r.URL.Query().Get("code")
|
||||||
|
code, _ := strconv.Atoi(s)
|
||||||
|
os.Exit(code)
|
||||||
|
}
|
||||||
|
|
||||||
func streamsHandler(w http.ResponseWriter, r *http.Request) {
|
func streamsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
src := r.URL.Query().Get("src")
|
src := r.URL.Query().Get("src")
|
||||||
name := r.URL.Query().Get("name")
|
name := r.URL.Query().Get("name")
|
||||||
|
42
cmd/api/config.go
Normal file
42
cmd/api/config.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/AlexxIT/go2rtc/cmd/app"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func configHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.Method {
|
||||||
|
case "GET":
|
||||||
|
data, err := os.ReadFile(app.ConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err = w.Write(data); err != nil {
|
||||||
|
log.Warn().Err(err).Caller().Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
case "POST":
|
||||||
|
data, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate config
|
||||||
|
var tmp struct{}
|
||||||
|
if err = yaml.Unmarshal(data, &tmp); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.WriteFile(app.ConfigPath, data, 0644); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -13,16 +13,17 @@ import (
|
|||||||
var Version = "0.1-rc.8"
|
var Version = "0.1-rc.8"
|
||||||
var UserAgent = "go2rtc/" + Version
|
var UserAgent = "go2rtc/" + Version
|
||||||
|
|
||||||
|
var ConfigPath string
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
config := flag.String(
|
flag.StringVar(
|
||||||
"config",
|
&ConfigPath, "config", "go2rtc.yaml",
|
||||||
"go2rtc.yaml",
|
|
||||||
"Path to go2rtc configuration file",
|
"Path to go2rtc configuration file",
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
data, _ = os.ReadFile(*config)
|
data, _ = os.ReadFile(ConfigPath)
|
||||||
|
|
||||||
var cfg struct {
|
var cfg struct {
|
||||||
Mod map[string]string `yaml:"log"`
|
Mod map[string]string `yaml:"log"`
|
||||||
|
@@ -4,24 +4,14 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/cmd/api"
|
"github.com/AlexxIT/go2rtc/cmd/api"
|
||||||
"github.com/AlexxIT/go2rtc/cmd/streams"
|
"github.com/AlexxIT/go2rtc/cmd/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
api.HandleFunc("api/stack", stackHandler)
|
api.HandleFunc("api/stack", stackHandler)
|
||||||
api.HandleFunc("api/exit", exitHandler)
|
|
||||||
|
|
||||||
streams.HandleFunc("null", nullHandler)
|
streams.HandleFunc("null", nullHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func exitHandler(_ http.ResponseWriter, r *http.Request) {
|
|
||||||
s := r.URL.Query().Get("code")
|
|
||||||
code, _ := strconv.Atoi(s)
|
|
||||||
os.Exit(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func nullHandler(string) (streamer.Producer, error) {
|
func nullHandler(string) (streamer.Producer, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
59
www/editor.html
Normal file
59
www/editor.html
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>File Editor</title>
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.14.0/ace.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body, #config {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="main.js"></script>
|
||||||
|
<div>
|
||||||
|
<button id="save">Save & Restart</button>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div id="config"></div>
|
||||||
|
<script>
|
||||||
|
ace.config.set('basePath', 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.14.0/');
|
||||||
|
const editor = ace.edit("config", {
|
||||||
|
mode: "ace/mode/yaml",
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('save').addEventListener('click', () => {
|
||||||
|
fetch('api/config', {
|
||||||
|
method: 'POST', body: editor.getValue()
|
||||||
|
}).then(r => {
|
||||||
|
if (r.ok) {
|
||||||
|
alert("OK");
|
||||||
|
fetch('api/exit', {method: 'POST'});
|
||||||
|
} else {
|
||||||
|
r.text().then(alert);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
fetch('api/config').then(r => r.text()).then(data => {
|
||||||
|
editor.setValue(data);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -47,6 +47,7 @@ nav li {
|
|||||||
<li><a href="index.html">Streams</a></li>
|
<li><a href="index.html">Streams</a></li>
|
||||||
<li><a href="devices.html">Devices</a></li>
|
<li><a href="devices.html">Devices</a></li>
|
||||||
<li><a href="homekit.html">HomeKit</a></li>
|
<li><a href="homekit.html">HomeKit</a></li>
|
||||||
|
<li><a href="editor.html">Config</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
` + document.body.innerHTML;
|
` + document.body.innerHTML;
|
||||||
|
Reference in New Issue
Block a user