A simple website to serve a list of books currently in my possession.
https://library.yetaga.in/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.0 KiB
90 lines
2.0 KiB
package main |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"io/fs" |
|
"log" |
|
"net/http" |
|
|
|
"git.yetaga.in/alazyreader/library/book" |
|
"git.yetaga.in/alazyreader/library/config" |
|
"git.yetaga.in/alazyreader/library/database" |
|
"git.yetaga.in/alazyreader/library/frontend" |
|
"github.com/kelseyhightower/envconfig" |
|
) |
|
|
|
type Library interface { |
|
GetAllBooks(context.Context) ([]book.Book, error) |
|
} |
|
|
|
type Router struct { |
|
static fs.FS |
|
lib Library |
|
} |
|
|
|
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
|
if req.URL.Path == "/api" { |
|
APIHandler(r.lib).ServeHTTP(w, req) |
|
return |
|
} |
|
StaticHandler(r.static).ServeHTTP(w, req) |
|
return |
|
} |
|
|
|
func APIHandler(l Library) http.Handler { |
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
books, err := l.GetAllBooks(r.Context()) |
|
if err != nil { |
|
http.Error(w, err.Error(), http.StatusInternalServerError) |
|
return |
|
} |
|
b, err := json.Marshal(books) |
|
if err != nil { |
|
http.Error(w, err.Error(), http.StatusInternalServerError) |
|
return |
|
} |
|
w.Header().Set("Content-Type", "application/json") |
|
w.WriteHeader(http.StatusOK) |
|
w.Write(b) |
|
w.Write([]byte("\n")) |
|
}) |
|
} |
|
|
|
func StaticHandler(f fs.FS) http.Handler { |
|
return http.FileServer(http.FS(f)) |
|
} |
|
|
|
func main() { |
|
var c config.Config |
|
err := envconfig.Process("library", &c) |
|
if err != nil { |
|
log.Fatalln(err) |
|
} |
|
f, err := frontend.Root() |
|
if err != nil { |
|
log.Fatalln(err) |
|
} |
|
if c.DBUser == "" || c.DBPass == "" || c.DBHost == "" || c.DBPort == "" || c.DBName == "" { |
|
log.Fatalf("vars: %+v", c) |
|
} |
|
lib, err := database.NewMySQLConnection(c.DBUser, c.DBPass, c.DBHost, c.DBPort, c.DBName) |
|
if err != nil { |
|
log.Fatalln(err) |
|
} |
|
err = lib.PrepareDatabase(context.Background()) |
|
if err != nil { |
|
log.Fatalln(err) |
|
} |
|
latest, run, err := lib.RunMigrations(context.Background()) |
|
if err != nil { |
|
log.Fatalln(err) |
|
} |
|
log.Printf("latest migration: %d; migrations run: %d", latest, run) |
|
r := &Router{ |
|
static: f, |
|
lib: lib, |
|
} |
|
log.Println("Listening on http://localhost:8080/") |
|
log.Fatalln(http.ListenAndServe(":8080", r)) |
|
}
|
|
|