Added frontend code
authorvolpol <volpol@packet-gain.de>
Sat, 18 Aug 2018 10:20:24 +0000 (12:20 +0200)
committervolpol <volpol@packet-gain.de>
Sat, 18 Aug 2018 10:20:24 +0000 (12:20 +0200)
frontend/TODO [new file with mode: 0644]
frontend/barbot.go [new file with mode: 0644]
frontend/build [new file with mode: 0755]

diff --git a/frontend/TODO b/frontend/TODO
new file mode 100644 (file)
index 0000000..fd336c6
--- /dev/null
@@ -0,0 +1,13 @@
+error handling:
+1 pumping over certain amount of time and not reaching target weight - DONE, if weight gain < 5 gr over 10 seconds
+2 refuse (or queue) mixing requests when already mixing? - DONE, refuse
+
+status display in backend via LED
+
+maintainance mode:
+cleaning
+startconfig
+
+support alternative styles /style hooks: partially done (example)
+
+Use NULL-Aware String types!!!
diff --git a/frontend/barbot.go b/frontend/barbot.go
new file mode 100644 (file)
index 0000000..937b82b
--- /dev/null
@@ -0,0 +1,221 @@
+package main
+
+import (
+       "bufio"
+       "database/sql"
+       "fmt"
+       _ "github.com/mattn/go-sqlite3"
+       "io"
+       "log"
+       "net/http"
+       "os"
+       "net"
+       "strconv"
+       "strings"
+       "time"
+)
+
+const (
+       BASE       = "Barbot 3.4"
+       DB         = BASE + "/data/database"
+       barbot_db  = DB + "/barbot.sqlite"
+       barbot_ini = DB + "/database.ini"
+)
+
+func styleHF(w http.ResponseWriter, r *http.Request) {
+       log.Print(r.RemoteAddr, " ", r.Method, " ", r.URL.Path)
+       log.Print("Serving:", BASE+r.URL.Path)
+       http.ServeFile(w, r, BASE+r.URL.Path)
+}
+
+func imgHF(w http.ResponseWriter, r *http.Request) {
+       log.Print(r.RemoteAddr, " ", r.Method, " ", r.URL.Path)
+       log.Print("Serving:", DB+r.URL.Path)
+       http.ServeFile(w, r, DB+r.URL.Path)
+}
+
+func holler(w http.ResponseWriter, err error) {
+       log.Print(err)
+       http.Error(w, err.Error(), http.StatusInternalServerError)
+}
+
+func rootHF(w http.ResponseWriter, r *http.Request) {
+
+       log.Print(r.RemoteAddr, " ", r.Method, " ", r.URL.Path)
+       if r.URL.Path == "/favicon.ico" {
+               http.Error(w, "404 Seek, and you shall find", http.StatusNotFound)
+               return
+       }
+       db, err := sql.Open("sqlite3", barbot_db)
+
+       if err != nil {
+               holler(w, err)
+               return
+       }
+
+       defer db.Close()
+       html := "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"
+       html += "<html>\n"
+       html += "<head>\n"
+       html += "<link rel=\"stylesheet\" type=\"text/css\" href=\"/style/main.css\">"
+       html += "<title>Barbot: Cocktails</title>"
+       html += "<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">"
+       html += "</head>\n"
+       html += "<body>\n"
+
+       q := r.URL.Query()
+       var selected_cocktails string
+       var installed_bottles string
+       single_mode := false
+
+       bbi, err := os.Open(barbot_ini)
+
+       if err != nil {
+               holler(w, err)
+               return
+       }
+
+       defer bbi.Close()
+
+       scanner := bufio.NewScanner(bbi)
+
+       if !scanner.Scan() {
+               holler(w, scanner.Err())
+               return
+       }
+
+       installed_bottles = scanner.Text()
+       ib_slice := strings.Split(installed_bottles, "|")
+
+       log.Print(installed_bottles)
+
+       if len(q["cid"]) != 1 {
+
+               if !scanner.Scan() {
+                       holler(w, scanner.Err())
+                       return
+               }
+
+               selected_cocktails = scanner.Text()
+       } else {
+               selected_cocktails = q["cid"][0]
+               single_mode = true
+       }
+
+       for _, ctl := range strings.Split(selected_cocktails, "|") {
+               ct, err := db.Query("SELECT * FROM cocktails WHERE ct_ID=?", ctl)
+               if err != nil {
+                       holler(w, err)
+                       return
+               }
+
+               defer ct.Close()
+               for ct.Next() {
+                       var ct_ID string
+                       var ct_Name string
+                       var ct_Kurzinfo string
+                       var ct_Beschreibung string
+                       err := ct.Scan(&ct_ID, &ct_Name, &ct_Kurzinfo, &ct_Beschreibung)
+                       if nil != err {
+                               log.Print(err)
+                               continue
+                       }
+
+                       html += fmt.Sprintf("<h1>%s</h1>\n", ct_Name)
+                       img := "/images/ct" + ct_ID + ".jpg"
+                       _, err = os.Stat(DB + img)
+                       if nil != err {
+                               img = "/images/ctdefault.jpg"
+                       }
+
+                       if !single_mode {
+                               html += fmt.Sprintf("<a href=\"?cid=%s\">", ct_ID)
+                               html += fmt.Sprintf("<img class=\"img_overview\" title=\"%s\" alt=\"%s\" src=\"%s\" width=\"150\">\n", ct_Name, ct_Name, img)
+                               html += "</a>"
+                       } else {
+                               html += fmt.Sprintf("<img class=\"img_detail\" title=\"%s\" alt=\"%s\" src=\"%s\" width=\"150\">\n", ct_Name, ct_Name, img)
+                       }
+
+                       html += "<p>\n"
+                       if single_mode {
+                               bbd := "MIX:"
+                               html += "<span class=\"long_descr\">"
+                               html += ct_Beschreibung
+                               html += "</span>"
+                               html += "<hr>\n"
+                               html += "<h2>Zutaten:</h2>\n"
+                               bt, err := db.Query("SELECT bottles.bt_ID, bottles.bt_Name, mixdefinition.bt_Menge FROM bottles, mixdefinition WHERE bottles.bt_ID = mixdefinition.bt_ID AND mixdefinition.ct_ID = ?", ct_ID)
+
+                               for nil == err && bt.Next() {
+                                       var bt_ID string
+                                       var bt_Name string
+                                       var bt_Menge string
+                                       err := bt.Scan(&bt_ID, &bt_Name, &bt_Menge)
+                                       if nil != err {
+                                               log.Print(err)
+                                               continue
+                                       }
+                                       i := 0
+                                       for i < len(ib_slice) {
+                                               if ib_slice[i] == bt_ID {
+                                                       bbd += strconv.Itoa(i+1) + "," + bt_Menge + ","
+                                                       log.Println("Found", bt_ID, "at index", i)
+                                               }
+                                               i++
+                                       }
+                                       img := "/images/bt" + bt_ID + ".jpg"
+                                       _, err = os.Stat(DB + img)
+                                       if nil != err {
+                                               img = "/images/btdefault.jpg"
+                                       }
+                                       html += fmt.Sprintf("<img class=\"img_bottle\" title=\"%s\" alt=\"%s\" src=\"%s\" width=\"50\">\n", bt_Name, bt_Name, img)
+                                       html += fmt.Sprintf("%s: %sml.\n", bt_Name, bt_Menge)
+                               }
+                               html += "<hr>\n"
+
+                               html += "<input id=\"btnBack\" type=\"button\" onclick=\"location.href='../'\" value=\"Zur&uuml;ck\"/> "
+                               html += "<input id=\"btnStart\" type=\"button\" onclick=\"location.href='?cid=" + selected_cocktails + "&mix=1'\"  value=\"Mischen\"/>"
+                               bbd = strings.TrimSuffix(bbd, ",")
+                               log.Println(bbd)
+                               status := "Backend: "
+
+                               conn, err := net.DialTimeout("tcp", "localhost:3005", time.Second*60)
+                               if nil == err {
+                                       defer conn.Close()
+                                       rr := bufio.NewReader(conn)
+                                       greet, err := rr.ReadString('\n')
+                                       if nil == err {
+                                               greet = strings.TrimSpace(greet)
+                                               log.Println(greet)
+                                               if greet == "READY" && 1 == len(q["mix"]) {
+                                                       conn.Write([]byte(bbd))
+                                                       conn.Write([]byte("\n"))
+                                                       status += "OK"
+                                               } else {
+                                                       status += greet
+                                               }
+                                       } else {
+                                               status = err.Error()
+                                       }
+
+                               } else {
+                                       status = err.Error()
+                               }
+                               html += "<p><div class=\"status\">" + status + "</div>"
+                       } else {
+                               html += "<span class=\"short_descr\">"
+                               html += ct_Kurzinfo
+                               html += "</span>"
+                       }
+               }
+       }
+       html += "</body>\n</html>\n"
+       io.WriteString(w, html)
+}
+
+func main() {
+       http.HandleFunc("/", rootHF)
+       http.HandleFunc("/images/", imgHF)
+       http.HandleFunc("/style/", styleHF)
+       log.Fatal(http.ListenAndServe(":8080", nil))
+}
diff --git a/frontend/build b/frontend/build
new file mode 100755 (executable)
index 0000000..0531e16
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+what=`basename $0`
+case $1 in
+       arm)
+               GOOS=linux
+               GOARCH=arm
+               GOARM=5
+               export CC GOOS GOARCH GOARM 
+               ;;
+       armcc)
+               GOOS=linux
+               GOARCH=arm
+               GOARM=5
+               CGO_ENABLED=1
+               CC=arm-linux-gnueabi-gcc
+               export CGO_ENABLED CC GOOS GOARCH GOARM 
+               ;;
+       android)
+               CGO_ENABLED=1
+               CC=/usr/local/android/bin/arm-linux-androideabi-gcc
+               GOOS=android
+               GOARCH=arm
+               GOARM=7
+               export CGO_ENABLED CC GOOS GOARCH GOARM
+               ;;
+       win64)
+               GOOS=windows
+               GOARCH=amd64
+               export GOOS GOARCH
+               ;;
+       win32)
+               GOOS=windows
+               GOARCH=386
+               export GOOS GOARCH
+               ;;
+esac
+go $what