recipe-card/main.go

145 lines
3.6 KiB
Go

package main
import (
"fmt"
"net"
"net/http"
"os"
"path"
"path/filepath"
"time"
log "github.com/sirupsen/logrus"
open "github.com/skratchdot/open-golang/open"
flag "github.com/spf13/pflag"
)
// Mux is the http servemux for this server
type Mux struct {
mux *http.ServeMux
}
// NewMux creates a new mux instance
func NewMux() *Mux {
return &Mux{
mux: http.NewServeMux(),
}
}
// Handle registers the handler for the given pattern
func (mux *Mux) Handle(pattern string, handler http.Handler) {
mux.mux.Handle(pattern, handler)
}
// HandleFunc registers the handler func for the given pattern
func (mux *Mux) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
mux.mux.HandleFunc(pattern, handler)
}
// ServeHTTP dispatches the request to the handler whose pattern most closely matches the request URL
func (mux *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.WithFields(log.Fields{
"remoteAddr": r.RemoteAddr,
"userAgent": r.UserAgent(),
"requestURI": r.RequestURI,
"method": r.Method,
}).Debug()
mux.mux.ServeHTTP(w, r)
}
func main() {
// only output >= info by default
log.SetLevel(log.InfoLevel)
// get good timestamps for logs
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
})
// get the path relative to the executble
recipePath, err := os.Executable()
if err != nil {
log.WithError(err).Errorln("Failed to get executable path")
recipePath = ""
}
debug := false
listenAddr := "127.0.0.1"
listenPort := uint16(0)
indexPath := filepath.Join(path.Dir(recipePath), "search_idx")
recipePath = filepath.Join(path.Dir(recipePath), "Recipes")
recipePath, err = filepath.Abs(recipePath)
if err != nil {
log.WithError(err).Errorln("Failed to get absolute path for default recipe path")
recipePath = ""
}
indexPath, err = filepath.Abs(indexPath)
if err != nil {
log.WithError(err).Errorln("Failed to get absolute path for default index path")
indexPath = ""
}
flag.StringVarP(&listenAddr, "host", "h", listenAddr, "HTTP listen address")
flag.Uint16VarP(&listenPort, "port", "p", listenPort, "HTTP listen port")
flag.StringVarP(&recipePath, "recipes", "r", recipePath, "Path to recipes")
flag.StringVarP(&indexPath, "index", "i", indexPath, "Path for search index")
flag.BoolVarP(&debug, "debug", "d", debug, "Enable debug mode")
flag.Parse()
if debug {
log.SetLevel(log.DebugLevel)
}
log.WithFields(log.Fields{
"host": listenAddr,
"port": listenPort,
"recipes": recipePath,
"index": indexPath,
"debug": debug,
}).Debugln("Options received")
log.Debugln("Creating new handler")
handler, err := NewHandler(recipePath, indexPath, log.StandardLogger())
if err != nil {
log.WithError(err).Errorln("Failed to create new handler")
os.Exit(1)
}
log.Debugln("Successfully created new handler")
defer handler.Close()
log.Debugln("Creating TCP listening port")
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", listenAddr, listenPort))
if err != nil {
log.WithError(err).Errorln("Failed to listen on new TCP port")
os.Exit(1)
}
defer listener.Close()
mux := NewMux()
log.Debugln("Associating handler funcs with http server")
for pattern, handlerFunc := range handler.GetHandlerFuncs() {
mux.HandleFunc(pattern, handlerFunc)
}
go func() {
log.Infoln("Waiting before opening web browser")
time.Sleep(time.Second)
url := "http://" + listener.Addr().String()
err = open.Run(url)
if err == nil {
log.Infoln("Opened", url, "in your web browser")
} else {
log.Infoln("Open", url, "in your web browser")
}
}()
err = http.Serve(listener, mux)
if err != nil {
log.WithError(err).Fatalln("HTTP server died")
}
}