Code refactoring
This commit is contained in:
+33
-48
@@ -1,13 +1,11 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/cmd/app"
|
"github.com/AlexxIT/go2rtc/cmd/app"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func configHandler(w http.ResponseWriter, r *http.Request) {
|
func configHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -22,42 +20,27 @@ func configHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Warn().Err(err).Caller().Send()
|
log.Warn().Err(err).Caller().Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
case "POST":
|
case "POST", "PATCH":
|
||||||
data, err := io.ReadAll(r.Body)
|
data, err := io.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate config
|
if r.Method == "PATCH" {
|
||||||
var tmp struct{}
|
// no need to validate after merge
|
||||||
if err = yaml.Unmarshal(data, &tmp); err != nil {
|
data, err = mergeYAML(app.ConfigPath, data)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
if err != nil {
|
||||||
return
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
}
|
return
|
||||||
|
}
|
||||||
if err = os.WriteFile(app.ConfigPath, data, 0644); err != nil {
|
} else {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
// validate config
|
||||||
return
|
var tmp struct{}
|
||||||
}
|
if err = yaml.Unmarshal(data, &tmp); err != nil {
|
||||||
case "PATCH":
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
rawdata, err := io.ReadAll(r.Body)
|
return
|
||||||
if err != nil {
|
}
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := mergeYAML(app.ConfigPath, rawdata)
|
|
||||||
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 {
|
if err = os.WriteFile(app.ConfigPath, data, 0644); err != nil {
|
||||||
@@ -69,44 +52,46 @@ func configHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func mergeYAML(file1 string, yaml2 []byte) ([]byte, error) {
|
func mergeYAML(file1 string, yaml2 []byte) ([]byte, error) {
|
||||||
// Read the contents of the first YAML file
|
// Read the contents of the first YAML file
|
||||||
data1, err := ioutil.ReadFile(file1)
|
data1, err := os.ReadFile(file1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal the first YAML file into a map
|
// Unmarshal the first YAML file into a map
|
||||||
var config1 map[string]interface{}
|
var config1 map[string]interface{}
|
||||||
err = yaml.Unmarshal(data1, &config1)
|
if err = yaml.Unmarshal(data1, &config1); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal the second YAML document into a map
|
// Unmarshal the second YAML document into a map
|
||||||
var config2 map[string]interface{}
|
var config2 map[string]interface{}
|
||||||
err = yaml.Unmarshal(yaml2, &config2)
|
if err = yaml.Unmarshal(yaml2, &config2); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge the two maps
|
// Merge the two maps
|
||||||
config1 = merge(config1, config2)
|
config1 = merge(config1, config2)
|
||||||
|
|
||||||
// Marshal the merged map into YAML
|
// Marshal the merged map into YAML
|
||||||
return yaml.Marshal(&config1)
|
return yaml.Marshal(&config1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func merge(a, b map[string]interface{}) map[string]interface{} {
|
func merge(dst, src map[string]interface{}) map[string]interface{} {
|
||||||
for k, v := range b {
|
for k, v := range src {
|
||||||
if vv, ok := a[k]; ok {
|
if vv, ok := dst[k]; ok {
|
||||||
switch vv := vv.(type) {
|
switch vv := vv.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
v := v.(map[string]interface{})
|
v := v.(map[string]interface{})
|
||||||
a[k] = merge(vv, v)
|
dst[k] = merge(vv, v)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
v := v.([]interface{})
|
v := v.([]interface{})
|
||||||
a[k] = v
|
dst[k] = v
|
||||||
default:
|
default:
|
||||||
a[k] = v
|
dst[k] = v
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
a[k] = v
|
dst[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return a
|
return dst
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user