streamwatcher/main.go
2020-07-12 12:04:44 +00:00

223 lines
5.3 KiB
Go
Executable file

package main
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"path/filepath"
"text/template"
"gocv.io/x/gocv"
)
var baseHTML = filepath.Join("templates", "base.html")
var indexHTML = filepath.Join("templates", "index.html")
var addStreamHTML = filepath.Join("templates", "add_stream.html")
var streamHTML = filepath.Join("templates", "stream.html")
// Server is the main application struct
type Server struct {
Streams map[string]Stream
}
func (server Server) index(w http.ResponseWriter, r *http.Request) {
if r.FormValue("URL") == "" {
indexTemplate, err := template.ParseFiles(indexHTML, baseHTML)
if err != nil {
log.Fatal(err)
}
indexTemplate.Execute(w, server.Streams)
return
}
URL := r.FormValue("URL")
stream, exists := server.Streams[URL]
if !exists {
stream = NewStream("test", URL)
server.Streams[URL] = stream
go stream.UpdateInterval()
}
streamTemplate, err := template.ParseFiles(streamHTML, baseHTML)
if err != nil {
log.Fatal(err)
}
streamTemplate.Execute(w, stream)
}
func (server Server) addStream(w http.ResponseWriter, r *http.Request) {
nameMessage := ""
URLMessage := ""
if r.Method == "POST" {
name := r.FormValue("name")
URL := r.FormValue("URL")
if name == "" {
nameMessage = "Name is required"
}
if URL == "" {
URLMessage = "URL is required"
}
_, exists := server.Streams[name]
if exists {
nameMessage = "Name already used"
}
if !exists && name != "" && URL != "" {
server.Streams[name] = NewStream(name, URL)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}
}
addStreamTemplate, err := template.ParseFiles(addStreamHTML, baseHTML)
if err != nil {
log.Fatal(err)
}
addStreamTemplate.Execute(w, struct {
NameMessage string
URLMessage string
}{
nameMessage,
URLMessage,
})
}
func (server Server) stream(w http.ResponseWriter, r *http.Request) {
if r.FormValue("URL") == "" {
return
}
w.Header().Set("Content-Type", "image/jpeg")
URL := r.FormValue("URL")
stream, exists := server.Streams[URL]
if !exists {
return
}
if !stream.CurrentColorInstantPathExists() {
return
}
mat := stream.IMReadCurrentColor()
jpg, err := gocv.IMEncode(".jpg", mat)
if err != nil {
log.Fatal("Could not encode Mat to jpg:", URL)
}
w.Write(jpg)
}
func (server Server) previous(w http.ResponseWriter, r *http.Request) {
if r.FormValue("URL") == "" {
return
}
w.Header().Set("Content-Type", "image/jpeg")
URL := r.FormValue("URL")
stream, exists := server.Streams[URL]
if !exists {
return
}
if !stream.PreviousInstantPathExists() {
return
}
jpg, err := gocv.IMEncode(".jpg", stream.IMReadPrevious())
if err != nil {
log.Fatal("Could not encode Mat to jpg:", URL)
}
w.Write(jpg)
}
func (server Server) currentColor(w http.ResponseWriter, r *http.Request) {
if r.FormValue("URL") == "" {
return
}
w.Header().Set("Content-Type", "image/jpeg")
URL := r.FormValue("URL")
stream, exists := server.Streams[URL]
if !exists {
return
}
if !stream.CurrentColorInstantPathExists() {
return
}
jpg, err := gocv.IMEncode(".jpg", stream.IMReadCurrentColor())
if err != nil {
log.Fatal("Could not encode Mat to jpg:", URL)
}
w.Write(jpg)
}
func (server Server) debug(w http.ResponseWriter, r *http.Request) {
if r.FormValue("URL") == "" {
return
}
w.Header().Set("Content-Type", "image/jpeg")
URL := r.FormValue("URL")
stream, exists := server.Streams[URL]
if !exists {
return
}
if !stream.DebugInstantPathExists() {
return
}
jpg, err := gocv.IMEncode(".jpg", stream.IMReadDebug())
if err != nil {
log.Fatal("Could not encode Mat to jpg:", URL)
}
w.Write(jpg)
}
func (server Server) current(w http.ResponseWriter, r *http.Request) {
if r.FormValue("URL") == "" {
return
}
w.Header().Set("Content-Type", "image/jpeg")
URL := r.FormValue("URL")
stream, exists := server.Streams[URL]
if !exists {
return
}
if !stream.CurrentInstantPathExists() {
return
}
jpg, err := gocv.IMEncode(".jpg", stream.IMReadCurrent())
if err != nil {
log.Fatal("Could not encode Mat to jpg:", URL)
}
w.Write(jpg)
}
func main() {
staticFileServer := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", staticFileServer))
server := Server{
Streams: make(map[string]Stream),
}
streams, err := ioutil.ReadDir(GetStreamDirPath())
if err != nil {
log.Fatal("Could not read Streamdir")
}
for _, streamStoreDir := range streams {
if !streamStoreDir.IsDir() {
continue
}
streamJSONPath := filepath.Join(GetStreamDirPath(), streamStoreDir.Name(), "stream.json")
streamJSONFile, _ := ioutil.ReadFile(streamJSONPath)
stream := Stream{}
json.Unmarshal([]byte(streamJSONFile), &stream)
server.Streams[stream.URL] = stream
go stream.UpdateInterval()
}
http.HandleFunc("/", server.index)
http.HandleFunc("/stream", server.stream)
http.HandleFunc("/addStream", server.addStream)
http.HandleFunc("/previous", server.previous)
http.HandleFunc("/current_color", server.currentColor)
http.HandleFunc("/current", server.current)
http.HandleFunc("/debug", server.debug)
log.Fatal(http.ListenAndServe(":8080", nil))
}