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("name") == "" { indexTemplate, err := template.ParseFiles(indexHTML, baseHTML) if err != nil { log.Fatal(err) } indexTemplate.Execute(w, server.Streams) return } name := r.FormValue("name") stream, exists := server.Streams[name] if !exists { return } 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) go server.Streams[name].UpdateInterval() 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("name") == "" { return } w.Header().Set("Content-Type", "image/jpeg") name := r.FormValue("name") stream, exists := server.Streams[name] 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:", name) } w.Write(jpg) } func (server Server) previous(w http.ResponseWriter, r *http.Request) { if r.FormValue("name") == "" { return } w.Header().Set("Content-Type", "image/jpeg") name := r.FormValue("name") stream, exists := server.Streams[name] 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:", name) } w.Write(jpg) } func (server Server) currentColor(w http.ResponseWriter, r *http.Request) { if r.FormValue("name") == "" { return } w.Header().Set("Content-Type", "image/jpeg") name := r.FormValue("name") stream, exists := server.Streams[name] 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:", name) } w.Write(jpg) } func (server Server) debug(w http.ResponseWriter, r *http.Request) { if r.FormValue("name") == "" { return } w.Header().Set("Content-Type", "image/jpeg") name := r.FormValue("name") stream, exists := server.Streams[name] 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:", name) } w.Write(jpg) } func (server Server) current(w http.ResponseWriter, r *http.Request) { if r.FormValue("name") == "" { return } w.Header().Set("Content-Type", "image/jpeg") name := r.FormValue("name") stream, exists := server.Streams[name] 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:", name) } 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.Name] = 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)) }