308 lines
7.5 KiB
Go
Raw Normal View History

package web
2017-07-26 22:40:21 +09:30
import (
2017-07-27 12:18:02 +09:30
"encoding/json"
2017-07-26 22:40:21 +09:30
"fmt"
2021-02-07 08:10:27 +10:30
"log"
2021-01-31 18:48:48 +10:30
"mime"
2021-02-07 08:10:27 +10:30
"net/http"
"os"
2021-01-31 18:48:48 +10:30
"path/filepath"
"regexp"
2021-02-07 08:10:27 +10:30
"strconv"
2021-01-31 18:48:48 +10:30
"text/template"
"github.com/tardisx/discord-auto-upload/assets"
"github.com/tardisx/discord-auto-upload/config"
daulog "github.com/tardisx/discord-auto-upload/log"
2017-07-26 22:40:21 +09:30
)
2017-07-27 12:18:02 +09:30
// DAUWebServer - stuff for the web server
type DAUWebServer struct {
ConfigChange chan int
}
type valueStringResponse struct {
Success bool `json:"success"`
Value string `json:"value"`
2017-07-27 12:18:02 +09:30
}
2021-02-07 08:10:06 +10:30
type valueBooleanResponse struct {
Success bool `json:"success"`
Value bool `json:"value"`
2021-02-07 08:10:06 +10:30
}
type errorResponse struct {
Success bool `json:"success"`
Error string `json:"error"`
}
2017-07-27 12:18:02 +09:30
2020-03-26 11:40:35 +10:30
func getStatic(w http.ResponseWriter, r *http.Request) {
// haha this is dumb and I should change it
re := regexp.MustCompile(`[^a-zA-Z0-9\.]`)
path := r.URL.Path[1:]
2020-03-26 11:40:35 +10:30
sanitized_path := re.ReplaceAll([]byte(path), []byte("_"))
if string(sanitized_path) == "" {
2021-01-31 18:48:48 +10:30
sanitized_path = []byte("index.html")
}
2020-03-26 11:40:35 +10:30
data, err := assets.Asset(string(sanitized_path))
2017-07-27 22:04:32 +09:30
if err != nil {
// Asset was not found.
fmt.Fprintln(w, err)
}
2021-01-31 18:48:48 +10:30
extension := filepath.Ext(string(sanitized_path))
// is this a HTML file? if so wrap it in the template
if extension == ".html" {
wrapper, _ := assets.Asset("wrapper.tmpl")
t := template.Must(template.New("wrapper").Parse(string(wrapper)))
var b struct {
2021-01-31 18:48:48 +10:30
Body string
Path string
Version string
}
b.Body = string(data)
b.Path = string(sanitized_path)
b.Version = config.CurrentVersion
2021-01-31 18:48:48 +10:30
t.Execute(w, b)
return
}
// otherwise we are a static thing
2021-01-31 18:48:48 +10:30
w.Header().Set("Content-Type", mime.TypeByExtension(extension))
2017-07-27 22:04:32 +09:30
w.Write(data)
2021-01-31 18:48:48 +10:30
//
2017-07-27 12:18:02 +09:30
}
// TODO there should be locks around all these config accesses
2017-07-27 12:18:02 +09:30
func getSetWebhook(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
2020-03-26 11:40:35 +10:30
2021-01-31 18:48:48 +10:30
if r.Method == "GET" {
getResponse := valueStringResponse{Success: true, Value: config.Config.WebHookURL}
// I can't see any way this will fail
2021-01-31 18:48:48 +10:30
js, _ := json.Marshal(getResponse)
w.Write(js)
2021-01-31 18:48:48 +10:30
} else if r.Method == "POST" {
err := r.ParseForm()
2021-01-31 18:48:48 +10:30
if err != nil {
log.Fatal(err)
}
config.Config.WebHookURL = r.PostForm.Get("value")
2021-02-07 11:42:13 +10:30
config.SaveConfig()
2021-01-31 18:48:48 +10:30
postResponse := valueStringResponse{Success: true, Value: config.Config.WebHookURL}
2021-01-31 18:48:48 +10:30
js, _ := json.Marshal(postResponse)
w.Write(js)
}
2017-07-27 12:18:02 +09:30
}
// TODO there should be locks around all these config accesses
func getSetUsername(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method == "GET" {
getResponse := valueStringResponse{Success: true, Value: config.Config.Username}
// I can't see any way this will fail
js, _ := json.Marshal(getResponse)
w.Write(js)
} else if r.Method == "POST" {
err := r.ParseForm()
if err != nil {
log.Fatal(err)
}
config.Config.Username = r.PostForm.Get("value")
2021-02-07 11:42:13 +10:30
config.SaveConfig()
postResponse := valueStringResponse{Success: true, Value: config.Config.Username}
js, _ := json.Marshal(postResponse)
w.Write(js)
}
}
func getSetWatch(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method == "GET" {
getResponse := valueStringResponse{Success: true, Value: strconv.Itoa(config.Config.Watch)}
// I can't see any way this will fail
js, _ := json.Marshal(getResponse)
w.Write(js)
} else if r.Method == "POST" {
err := r.ParseForm()
if err != nil {
log.Fatal(err)
}
2021-02-07 08:10:27 +10:30
i, err := strconv.Atoi(r.PostForm.Get("value"))
if err != nil {
response := errorResponse{Success: false, Error: fmt.Sprintf("Bad value for watch: %v", err)}
js, _ := json.Marshal(response)
w.Write(js)
return
}
if i < 1 {
response := errorResponse{Success: false, Error: "must be > 0"}
js, _ := json.Marshal(response)
w.Write(js)
return
}
config.Config.Watch = i
2021-02-07 11:42:13 +10:30
config.SaveConfig()
postResponse := valueStringResponse{Success: true, Value: strconv.Itoa(config.Config.Watch)}
js, _ := json.Marshal(postResponse)
w.Write(js)
}
}
2021-02-07 08:10:06 +10:30
func getSetNoWatermark(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method == "GET" {
getResponse := valueBooleanResponse{Success: true, Value: config.Config.NoWatermark}
// I can't see any way this will fail
js, _ := json.Marshal(getResponse)
w.Write(js)
} else if r.Method == "POST" {
err := r.ParseForm()
if err != nil {
log.Fatal(err)
}
2021-02-07 08:10:27 +10:30
v := r.PostForm.Get("value")
2021-02-07 08:10:06 +10:30
if v != "0" && v != "1" {
2021-02-07 08:10:27 +10:30
response := errorResponse{Success: false, Error: fmt.Sprintf("Bad value for nowatermark: %v", err)}
js, _ := json.Marshal(response)
w.Write(js)
return
2021-02-07 08:10:06 +10:30
}
if v == "0" {
config.Config.NoWatermark = false
} else {
config.Config.NoWatermark = true
}
2021-02-07 11:42:13 +10:30
config.SaveConfig()
2021-02-07 08:10:27 +10:30
postResponse := valueBooleanResponse{Success: true, Value: config.Config.NoWatermark}
2021-02-07 08:10:06 +10:30
js, _ := json.Marshal(postResponse)
w.Write(js)
}
}
2017-07-27 12:18:02 +09:30
func getSetDirectory(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
2017-07-26 22:40:21 +09:30
2021-01-31 18:48:48 +10:30
if r.Method == "GET" {
getResponse := valueStringResponse{Success: true, Value: config.Config.Path}
// I can't see any way this will fail
2021-01-31 18:48:48 +10:30
js, _ := json.Marshal(getResponse)
w.Write(js)
2021-01-31 18:48:48 +10:30
} else if r.Method == "POST" {
err := r.ParseForm()
2021-01-31 18:48:48 +10:30
if err != nil {
log.Fatal(err)
}
newPath := r.PostForm.Get("value")
// sanity check this path
stat, err := os.Stat(newPath)
if os.IsNotExist(err) {
// not exist
2021-01-31 18:48:48 +10:30
response := errorResponse{Success: false, Error: fmt.Sprintf("Path: %s - does not exist", newPath)}
js, _ := json.Marshal(response)
w.Write(js)
2021-01-31 18:48:48 +10:30
return
} else if !stat.IsDir() {
// not a directory
2021-01-31 18:48:48 +10:30
response := errorResponse{Success: false, Error: fmt.Sprintf("Path: %s - is not a directory", newPath)}
js, _ := json.Marshal(response)
w.Write(js)
2021-01-31 18:48:48 +10:30
return
}
config.Config.Path = newPath
2021-02-07 11:42:13 +10:30
config.SaveConfig()
2021-01-31 18:48:48 +10:30
postResponse := valueStringResponse{Success: true, Value: config.Config.Path}
2021-01-31 18:48:48 +10:30
js, _ := json.Marshal(postResponse)
w.Write(js)
}
2017-07-26 22:40:21 +09:30
}
2021-02-09 22:07:40 +10:30
func getSetExclude(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method == "GET" {
getResponse := valueStringResponse{Success: true, Value: config.Config.Exclude}
// I can't see any way this will fail
js, _ := json.Marshal(getResponse)
w.Write(js)
} else if r.Method == "POST" {
err := r.ParseForm()
if err != nil {
log.Fatal(err)
}
config.Config.Exclude = r.PostForm.Get("value")
config.SaveConfig()
postResponse := valueStringResponse{Success: true, Value: config.Config.Exclude}
js, _ := json.Marshal(postResponse)
w.Write(js)
}
}
func getLogs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
text := ""
for _, log := range daulog.LogEntries {
text = text + fmt.Sprintf(
"%-6s %-19s %s\n", log.Type, log.Timestamp.Format("2006-01-02 15:04:05"), log.Entry,
)
}
// js, _ := json.Marshal(daulog.LogEntries)
w.Write([]byte(text))
}
2021-02-09 22:07:40 +10:30
func StartWebServer() {
2020-03-26 11:40:35 +10:30
http.HandleFunc("/", getStatic)
2017-07-27 12:18:02 +09:30
http.HandleFunc("/rest/config/webhook", getSetWebhook)
http.HandleFunc("/rest/config/username", getSetUsername)
http.HandleFunc("/rest/config/watch", getSetWatch)
2021-02-07 08:10:06 +10:30
http.HandleFunc("/rest/config/nowatermark", getSetNoWatermark)
2017-07-27 12:18:02 +09:30
http.HandleFunc("/rest/config/directory", getSetDirectory)
2021-02-09 22:07:40 +10:30
http.HandleFunc("/rest/config/exclude", getSetExclude)
http.HandleFunc("/rest/logs", getLogs)
go func() {
log.Print("Starting web server on http://localhost:9090")
err := http.ListenAndServe(":9090", nil) // set listen port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}()
}