Initial commit trying to turn bot to have RESTful JSON endpoint

This commit is contained in:
Scott
2016-05-23 22:18:42 +10:00
parent 3b0e4c98a8
commit 4b2a336e1b
8 changed files with 172 additions and 135 deletions

27
anxroutes.go Normal file
View File

@@ -0,0 +1,27 @@
package main
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
)
func getLatestAnxTicker(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
currency := vars["currency"]
response := bot.exchange.anx.GetTicker(currency)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(response); err != nil {
panic(err)
}
}
var anxRoutes = Routes{
Route{
"Index",
"GET",
"/exchanges/anx/latest/{currency}",
getLatestAnxTicker,
},
}

39
main.go
View File

@@ -8,6 +8,7 @@ import (
"runtime"
"strconv"
"syscall"
"net/http"
)
type Exchange struct {
@@ -80,29 +81,11 @@ func main() {
} else {
log.Printf("SMS support enabled. Number of SMS contacts %d.\n", GetEnabledSMSContacts())
}
}
if !bot.config.SMS.Enabled {
} else {
log.Println("SMS support disabled.")
}
if bot.config.Webserver.Enabled {
err := CheckWebserverValues()
if err != nil {
log.Println(err) // non fatal event
bot.config.Webserver.Enabled = false
} else {
log.Println("HTTP Webserver support enabled.")
err = StartWebserver()
if err != nil {
log.Println("Unable to start Webserver: ", err)
} else {
log.Printf("HTTP server enabled and running at http://%s:%d\n", GetWebserverHost(), GetWebserverPort())
}
}
}
if !bot.config.Webserver.Enabled {
log.Println("HTTP Webserver support disabled.")
}
log.Printf("Available Exchanges: %d. Enabled Exchanges: %d.\n", len(bot.config.Exchanges), GetEnabledExchanges())
log.Println("Bot Exchange support:")
@@ -150,6 +133,22 @@ func main() {
}
}
}
if bot.config.Webserver.Enabled {
err := CheckWebserverValues()
if err != nil {
log.Println(err) // non fatal event
bot.config.Webserver.Enabled = false
} else {
log.Println("HTTP Webserver support enabled.")
router := NewRouter(bot.exchanges)
log.Fatal(http.ListenAndServe(":8080", router))
}
}
if !bot.config.Webserver.Enabled {
log.Println("HTTP Webserver support disabled.")
}
<-bot.shutdown
Shutdown()
}

34
restfulHandlers.go Normal file
View File

@@ -0,0 +1,34 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w,bot.exchanges[0].GetName())
}
func TodoIndex(w http.ResponseWriter, r *http.Request) {
todos := Todos{
Todo{Name: "Write presentation"},
Todo{Name: "Host meetup"},
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(todos); err != nil {
panic(err)
}
}
func TodoShow(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
todoId := vars["todoId"]
fmt.Fprintln(w, "Todo show:", todoId)
}

23
restfulLogger.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"log"
"net/http"
"time"
)
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s\t%s\t%s\t%s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}

25
restfulRouter.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"net/http"
"github.com/gorilla/mux"
)
func NewRouter(exchanges []IBotExchange) *mux.Router {
router := mux.NewRouter().StrictSlash(true)
allRoutes := append(routes,anxRoutes...)
for _, route := range allRoutes {
var handler http.Handler
handler = route.HandlerFunc
handler = Logger(handler, route.Name)
router.
Methods(route.Method).
Path(route.Pattern).
Name(route.Name).
Handler(handler)
}
return router
}

33
restfulRoutes.go Normal file
View File

@@ -0,0 +1,33 @@
package main
import "net/http"
type Route struct {
Name string
Method string
Pattern string
HandlerFunc http.HandlerFunc
}
type Routes []Route
var routes = Routes{
Route{
"Index",
"GET",
"/",
Index,
},
Route{
"TodoIndex",
"GET",
"/todos",
TodoIndex,
},
Route{
"TodoShow",
"GET",
"/todos/{todoId}",
TodoShow,
},
}

11
restfulTodo.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "time"
type Todo struct {
Name string `json:"name"`
Completed bool `json:"completed"`
Due time.Time `json:"due"`
}
type Todos []Todo

View File

@@ -1,115 +0,0 @@
package main
import (
"html/template"
"io/ioutil"
"log"
"net/http"
"strconv"
)
type Page struct {
Title string
StaticStylesheet template.HTML
Body []byte
Error string
}
const (
coverCSS = `<link rel="stylesheet" href="web/static/css/cover.css">`
dashboardCSS = `<link rel="stylesheet" href="web/static/css/dashboard.css">`
)
func GetWebserverHost() string {
host := SplitStrings(bot.config.Webserver.ListenAddress, ":")[0]
if host == "" {
return "localhost"
}
return host
}
func GetWebserverPort() int {
portStr := SplitStrings(bot.config.Webserver.ListenAddress, ":")[1]
port, _ := strconv.Atoi(portStr)
return port
}
func StartWebserver() error {
fs := http.FileServer(http.Dir("web"))
http.Handle("/web/", http.StripPrefix("/web/", fs))
http.HandleFunc("/", index)
var err error
go func() {
err = http.ListenAndServe(bot.config.Webserver.ListenAddress, nil)
}()
return err
}
func ServerHTTPError(w http.ResponseWriter, err error) {
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
}
func index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
switch r.URL.Path {
case "/":
renderTemplate(w, "index.html", readPage("/index"))
case "/login":
renderTemplate(w, "login.html", readPage(r.URL.Path))
case "/logout":
renderTemplate(w, "index.html", readPage("/index"))
case "/dashboard-marketdepth":
renderTemplate(w, "dashboard-marketdepth.html", readPage(r.URL.Path))
case "/dashboard-ordermanagement":
renderTemplate(w, "dashboard-ordermanagement.html", readPage(r.URL.Path))
case "/dashboard-contact":
renderTemplate(w, "dashboard-contact.html", readPage(r.URL.Path))
case "/dashboard-settings":
renderTemplate(w, "dashboard-settings.html", readPage(r.URL.Path))
case "/dashboard-reports":
renderTemplate(w, "dashboard-reports.html", readPage(r.URL.Path))
default:
w.WriteHeader(http.StatusNotFound)
renderTemplate(w, "error.html", readPage("/error"))
}
}
func readPage(client string) *Page {
filename := "web/" + client[1:] + ".html"
body, err := ioutil.ReadFile(filename)
if err != nil {
log.Println("Webserver: Failed to open file -- ", err, "client string is: ", client)
return nil
}
stylesheet := setStylesheet(client)
return &Page{Title: client[1:], StaticStylesheet: stylesheet, Body: body}
}
func setStylesheet(client string) template.HTML {
if len(client) >= 10 {
if client[:10] == "/dashboard" {
return template.HTML(dashboardCSS)
}
}
return template.HTML(coverCSS)
}
func renderTemplate(w http.ResponseWriter, pageName string, p *Page) {
tmpl, err := template.ParseFiles("web/index.html", "web/header.html",
"web/footer.html", "web/dashboard-marketdepth.html", "web/login.html",
"web/dashboard-ordermanagement.html", "web/dashboard-reports.html",
"web/dashboard-settings.html", "web/dashboard-contact.html", "web/error.html")
if err != nil {
log.Println("Webserver: Could not parsefile -- ", err)
ServerHTTPError(w, err)
return
}
err = tmpl.ExecuteTemplate(w, pageName, p)
if err != nil {
log.Println("Webserver: Could not execute template -- ", err)
}
}