package main import ( "database/sql" "encoding/json" "log" "net/http" "os" _ "github.com/mattn/go-sqlite3" . "meutel.net/meutel/go-bouquins/bouquins" ) type BouquinsConf struct { BindAddress string `json:"bind-address"` DbPath string `json:"db-path"` CalibrePath string `json:"calibre-path"` } var db *sql.DB // load config func ReadConfig() (*BouquinsConf, error) { conf := new(BouquinsConf) confPath := "bouquins.json" if len(os.Args) > 1 { confPath = os.Args[1] } confFile, err := os.Open(confPath) if err == nil { defer confFile.Close() err = json.NewDecoder(confFile).Decode(conf) } else { log.Println("no conf file, using defaults") err = nil } // default values if conf.CalibrePath == "" { conf.CalibrePath = "." } if conf.DbPath == "" { conf.DbPath = conf.CalibrePath + "/metadata.db" } if conf.BindAddress == "" { conf.BindAddress = ":9000" } return conf, err } func initApp() *BouquinsConf { log.SetFlags(log.LstdFlags | log.Lshortfile) conf, err := ReadConfig() if err != nil { log.Fatalln(err) } tpl, err := TemplatesFunc().ParseGlob("templates/*.html") if err != nil { log.Fatalln(err) } db, err = sql.Open("sqlite3", conf.DbPath) if err != nil { log.Fatalln(err) } app := &Bouquins{tpl, db} err = app.PrepareAll() if err != nil { log.Fatalln(err) } assets(conf.CalibrePath) router(app) return conf } func assets(calibre string) { http.Handle(URL_JS, http.FileServer(http.Dir("assets"))) http.Handle(URL_CSS, http.FileServer(http.Dir("assets"))) http.Handle(URL_FONTS, http.FileServer(http.Dir("assets"))) http.Handle(URL_CALIBRE, http.StripPrefix(URL_CALIBRE, http.FileServer(http.Dir(calibre)))) } func handle(f func(res http.ResponseWriter, req *http.Request) error) func(res http.ResponseWriter, req *http.Request) { return func(res http.ResponseWriter, req *http.Request) { err := f(res, req) if err != nil { log.Println(err) http.Error(res, err.Error(), 500) } } } func handleUrl(url string, f func(res http.ResponseWriter, req *http.Request) error) { http.HandleFunc(url, handle(f)) } func router(app *Bouquins) { handleUrl(URL_INDEX, app.IndexPage) handleUrl(URL_BOOKS, app.BooksPage) handleUrl(URL_AUTHORS, app.AuthorsPage) handleUrl(URL_SERIES, app.SeriesPage) handleUrl(URL_SEARCH, app.SearchPage) handleUrl(URL_ABOUT, app.AboutPage) } func main() { conf := initApp() defer db.Close() http.ListenAndServe(conf.BindAddress, nil) }