diff --git a/main.go b/main.go index 7620957..8453cd7 100644 --- a/main.go +++ b/main.go @@ -28,24 +28,58 @@ func init() { func main() { latestBooks := map[string]*storygraph.Book{} - go func() { - var err error - for { - latestBooks, err = storygraph.GetLatestBooks() - if err != nil { - fmt.Println("Error fetching latest books:", err) - return + refreshingBooks := true + var lastUpdated *time.Time + + updateBooks := func() { + refreshingBooks = true + defer func() { refreshingBooks = false }() + newBookList, err := storygraph.GetLatestBooks() + if err != nil { + fmt.Println("Error fetching latest books:", err) + return + } + + // Update each category individually with books we have managed to find + for cat, book := range newBookList { + if b, ok := newBookList[cat]; ok && b != nil { + latestBooks[cat] = book } + } + now := time.Now() + lastUpdated = &now + fmt.Println("Updated latest book recommendations") + } - fmt.Println("Updated latest book recommendations") - + go func() { + for { + updateBooks() time.Sleep(1 * time.Hour) } }() http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + type data struct { + Books map[string]*storygraph.Book + LastUpdated string + Refreshing bool + } + d := data{ + Books: latestBooks, + LastUpdated: "", + Refreshing: refreshingBooks, + } + if lastUpdated != nil { + d.LastUpdated = lastUpdated.Format(time.RFC1123) + } tmpl := template.Must(template.ParseFiles("templates/index.html")) - tmpl.Execute(w, latestBooks) + tmpl.Execute(w, d) + }) + http.HandleFunc("/refresh", func(w http.ResponseWriter, r *http.Request) { + go updateBooks() + w.Header().Set("Location", "/") + w.Header().Set("Refresh", "0; url=/") + w.Write([]byte("Refreshing...")) }) http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets")))) http.ListenAndServe(fmt.Sprintf(":%s", port), nil) diff --git a/pkg/storygraph/http.go b/pkg/storygraph/http.go index 4c1f55f..de80fc0 100644 --- a/pkg/storygraph/http.go +++ b/pkg/storygraph/http.go @@ -23,7 +23,7 @@ func New(cookie string) *HTTPClient { Cookie: cookie, client: &http.Client{}, - rl: rate.NewLimiter(rate.Every(1*time.Second), 15), + rl: rate.NewLimiter(rate.Every(1*time.Second), 10), ctx: context.Background(), retries: 3, } @@ -52,7 +52,7 @@ func (h *HTTPClient) Get(url string) (*http.Response, error) { if resp.StatusCode == 429 { fmt.Println("Rate limit exceeded, retrying...") h.retries-- - time.Sleep(30 * time.Second) + time.Sleep(15 * time.Second) continue } diff --git a/templates/index.html b/templates/index.html index de9deb8..4144ccf 100644 --- a/templates/index.html +++ b/templates/index.html @@ -54,11 +54,19 @@

Next Book

Suggestions for the next book to read from your Storygraph to-read pile

+ {{ if .Refreshing }} +
Refreshing recommendations...
+ {{ else if .LastUpdated }} +
+ Last Update: {{ .LastUpdated }} + Refresh recommendations +
+ {{ end }}
- {{ if index . "Fiction" }} + {{ if index .Books "Fiction" }}
{{ $cat := "Fiction" }} - {{ $book := index . $cat }} + {{ $book := index .Books $cat }}

{{ $cat }}

@@ -68,7 +76,7 @@
⭐ {{ $book.Rating }}
{{ $cat := "Non-Fiction" }} - {{ $book := index . $cat }} + {{ $book := index .Books $cat }}

{{ $cat }}

@@ -78,7 +86,7 @@
⭐ {{ $book.Rating }}
{{ $cat := "Comics" }} - {{ $book := index . $cat }} + {{ $book := index .Books $cat }}

{{ $cat }}

@@ -88,7 +96,7 @@
⭐ {{ $book.Rating }}
- {{ range $cat, $book := .}} + {{ range $cat, $book := .Books }} {{ if or (eq $cat "Fiction") (eq $cat "Non-Fiction") (eq $cat "Comics") }} {{ continue }} {{ end }}