Working on server app

This commit is contained in:
2016-02-22 21:23:53 -06:00
parent 32f6cf6e1d
commit 0f75137097
6 changed files with 315 additions and 13 deletions

View File

@@ -0,0 +1,21 @@
package main
import (
"github.com/br0xen/termbox-util"
"github.com/nsf/termbox-go"
)
// AboutScreen is the about screen
type AboutScreen struct{}
func (screen *AboutScreen) handleEvent(event termbox.Event) int {
return ServerScreenIndex
}
func (screen *AboutScreen) performLayout(style Style) {}
func (screen *AboutScreen) drawScreen(style Style) {
width, height := termbox.Size()
exitTxt := "Press any key to exit help"
termboxUtil.DrawStringAtPoint(exitTxt, (width-len(exitTxt))/2, height-1, style.titleFg, style.titleBg)
}

View File

@@ -4,8 +4,11 @@ import (
"errors"
"math/rand"
"os"
"syscall"
"time"
"github.com/br0xen/boltrest"
"github.com/nsf/termbox-go"
)
var adminDB *boltrest.DB
@@ -13,10 +16,60 @@ var adminDB *boltrest.DB
func main() {
initialize()
adminDB = boltrest.Open("admin.db")
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
stl := getDefaultStyle()
termbox.SetOutputMode(termbox.Output256)
mainLoop(stl)
}
func mainLoop() {
screens := defaultScreens()
displayScreen := screens[NasomiScreenIndex]
layoutAndDrawScreen(displayScreen, stl)
eventChan := make(chan termbox.Event)
go readUserInput(eventChan)
go sendNoneEvent(eventChan)
for {
event := <-eventChan
if event.Type == termbox.EventKey {
if event.Key == termbox.KeyCtrlZ {
process, _ := os.FindProcess(os.Getpid())
termbox.Close()
process.Signal(syscall.SIGSTOP)
termbox.Init()
} else if event.Key == termbox.KeyCtrlC {
termbox.Close()
os.Exit(0)
}
newScreenIndex := displayScreen.handleKeyEvent(event)
if newScreenIndex < len(screens) {
displayScreen = screens[newScreenIndex]
layoutAndDrawScreen(displayScreen, stl)
} else {
termbox.Close()
break
}
}
if event.Type == termbox.EventResize || event.Type == termbox.EventNone {
layoutAndDrawScreen(displayScreen, stl)
}
}
}
func readUserInput(e chan termbox.Event) {
for {
e <- termbox.PollEvent()
}
}
func sendNoneEvent(e chan termbox.Event) {
for {
time.Sleep(time.Second)
e <- termbox.Event{Type: termbox.EventNone}
}
}
func initialize() error {
@@ -42,6 +95,25 @@ func initialize() error {
return nil
}
const (
// ServerScreenIndex is the index
ServerScreenIndex = iota
// AboutScreenIndex The idx number for the 'About' Screen
AboutScreenIndex
// ExitScreenIndex The idx number for Exiting
ExitScreenIndex
)
func defaultScreens() []Screen {
serverScreen := ServerScreen{}
aboutScreen := AboutScreen{}
screens := []Screen{
&serverScreen,
&aboutScreen,
}
return screens
}
const keyChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
func generateAPIKey() string {

42
boltrest-server/screen.go Normal file
View File

@@ -0,0 +1,42 @@
package main
import "github.com/nsf/termbox-go"
// Screen is a basic structure for all of the applications screens
type Screen interface {
handleKeyEvent(event termbox.Event) int
performLayout(style Style)
drawScreen(style Style)
}
func drawBackground(bg termbox.Attribute) {
termbox.Clear(0, bg)
}
func layoutAndDrawScreen(screen Screen, style Style) {
screen.performLayout(style)
drawBackground(style.defaultBg)
screen.drawScreen(style)
termbox.Flush()
}
// Style defines style for a screen
type Style struct {
defaultBg termbox.Attribute
defaultFg termbox.Attribute
titleFg termbox.Attribute
titleBg termbox.Attribute
cursorFg termbox.Attribute
cursorBg termbox.Attribute
}
func getDefaultStyle() Style {
return Style{
defaultBg: termbox.ColorBlack,
defaultFg: termbox.ColorWhite,
titleBg: termbox.ColorBlack,
titleFg: termbox.ColorGreen,
cursorBg: termbox.ColorWhite,
cursorFg: termbox.ColorBlack,
}
}

View File

@@ -0,0 +1,75 @@
package main
import (
"time"
"github.com/br0xen/termbox-util"
"github.com/nsf/termbox-go"
)
// ServerScreen holds all that's going on :D
type ServerScreen struct {
initialized bool
message string
messageTime time.Time
messageTimeout time.Duration
tabIdx int
}
func (screen *ServerScreen) handleEvent(event termbox.Event) int {
_, h := termbox.Size()
if event.Type == termbox.EventKey {
}
return ServerScreenIndex
}
func (screen *ServerScreen) performLayout(style Style) {
w, h := termbox.Size()
if !screen.initialized {
}
if screen.messageTimeout > 0 && time.Since(screen.messageTime) > screen.messageTimeout {
screen.clearMessage()
msgString := ""
msgString = termboxUtil.AlignText(msgString, w, termboxUtil.AlignLeft)
screen.setMessage(msgString)
}
}
func (screen *ServerScreen) drawScreen(style Style) {
w, h := termbox.Size()
screen.drawHeader(style)
screen.drawFooter(style)
}
func (screen *ServerScreen) drawHeader(style Style) {
w, _ := termbox.Size()
ttl := termboxUtil.AlignTextWithFill("Boltrest Server", w+1, termboxUtil.AlignCenter, '=')
termboxUtil.DrawStringAtPoint(ttl, 0, 0, style.defaultBg, style.defaultFg)
}
func (screen *ServerScreen) drawFooter(style Style) {
_, height := termbox.Size()
termboxUtil.DrawStringAtPoint(screen.message, 0, height-1, style.defaultBg, style.defaultFg)
}
func (screen *ServerScreen) setMessage(msg string) {
screen.message = msg
screen.messageTime = time.Now()
screen.messageTimeout = -1
}
/* setMessageWithTimeout lets you specify the timeout for the message
* setting it to -1 means it won't timeout
*/
func (screen *ServerScreen) setMessageWithTimeout(msg string, timeout time.Duration) {
screen.message = msg
screen.messageTime = time.Now()
screen.messageTimeout = timeout
}
func (screen *ServerScreen) clearMessage() {
screen.message = ""
screen.messageTimeout = -1
}

View File

@@ -0,0 +1,77 @@
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/devict/magopie"
"github.com/devict/magopie/vendor/github.com/gorilla/mux"
"github.com/devict/magopie/vendor/github.com/justinas/alice"
)
// WebServer ...
type WebServer struct {
addr string
tlsCert string
tlsKey string
adminMode bool
}
// Listen makes it listen for connetions
func (s *WebServer) Listen() {
if s.tlsCert != "" && s.tlsKey != "" {
log.Printf("Listening for HTTPS on %s with key %s and cert %s", s.addr, s.tlsKey, s.tlsCert)
log.Fatal(http.ListenAndServeTLS(s.addr, s.tlsCert, s.tlsKey, s.router(a)))
} else {
log.Printf("Listening for HTTP on %s", *addr)
log.Fatal(http.ListenAndServe(*addr, s.router(a)))
}
}
// Router defines all of the routes
func (s *WebServer) Router() http.Handler {
r := mux.NewRouter()
r.HandleFunc("/", s.handleAllSites).Methods("GET")
r.HandleFunc("/genAPIKey/{db}", s.genAPIKey).Methods("POST")
chain := alice.New(mwLogger, mwAuthenticationCheck(a.key)).Then(r)
return chain
}
func (s *WebServer) handleRequest(w http.ResponseWriter, r *http.Request) {
err := json.NewEncoder(w).Encode()
if err != nil {
log.Println(err)
}
}
func (s *WebServer) genAPIKey(w http.ResponseWriter, r *http.Request) {
err := json.NewEncoder(w).Encode()
if err != nil {
log.Println(err)
}
}
func (s *WebServer) mwLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Serving", r.Method, r.URL.String(), "to", r.RemoteAddr)
next.ServeHTTP(w, r)
})
}
func (s *WebServer) mwAuthenticationCheck(key string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !magopie.CheckMAC(r.Header.Get("X-Request-ID"), r.Header.Get("X-HMAC"), key) {
log.Println("Request failed HMAC")
w.WriteHeader(http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
}