From 269be4a9784f07a824169f87e8bc787e59893b56 Mon Sep 17 00:00:00 2001 From: Shawn Smith Date: Sun, 28 Feb 2016 15:03:54 +0900 Subject: [PATCH] start recent list --- handlers/check.go | 47 +++++++++++++++++++++++++++++++++++++++++ handlers/home.go | 44 +++++++++++++++++++++++++++++++++++++- handlers/recent_heap.go | 25 ++++++++++++++++++++++ templates/home.html | 14 ++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 handlers/recent_heap.go diff --git a/handlers/check.go b/handlers/check.go index 549e45d..a3a8d07 100644 --- a/handlers/check.go +++ b/handlers/check.go @@ -123,8 +123,19 @@ func CheckHandler(w http.ResponseWriter, r *http.Request) { if err != nil { log.Println("Bolt writing error:", err) } + } + err = db.Update(func(tx *bolt.Tx) error { + // fetch meta-bucket + mb := tx.Bucket([]byte(MetaBucket)) + if mb == nil { + return fmt.Errorf("high score bucket not found") + } + + return updateRecentlyViewed(mb, repo) + }) + b, err := json.Marshal(map[string]string{"redirect": "/report/" + repo}) if err != nil { log.Println("JSON marshal error:", err) @@ -203,3 +214,39 @@ func updateReposCount(mb *bolt.Bucket, resp checksResp, repo string) (err error) log.Println("Repo count is now", totalInt) return nil } + +func updateRecentlyViewed(mb *bolt.Bucket, repo string) error { + b := mb.Get([]byte("recent")) + if b == nil { + b, _ = json.Marshal([]recentHeap{}) + } + recent := &recentHeap{} + json.Unmarshal(b, recent) + + heap.Init(recent) + // if this repo is already in the list, remove the original entry: + for i := range *recent { + if (*recent)[i].Repo == repo { + heap.Remove(recent, i) + break + } + } + // now we can safely push it onto the heap + heap.Push(recent, recentItem{ + Repo: repo, + }) + if len(*recent) > 5 { + // trim heap if it's grown to over 5 + *recent = (*recent)[1:6] + } + b, err := json.Marshal(&recent) + if err != nil { + return err + } + err = mb.Put([]byte("recent"), b) + if err != nil { + return err + } + + return nil +} diff --git a/handlers/home.go b/handlers/home.go index ac33b56..84feac2 100644 --- a/handlers/home.go +++ b/handlers/home.go @@ -1,8 +1,15 @@ package handlers import ( + "container/heap" + "encoding/json" + "fmt" + "html/template" "log" "net/http" + "time" + + "github.com/boltdb/bolt" ) // HomeHandler handles the homepage @@ -10,7 +17,42 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) { log.Println("Serving home page") if r.URL.Path[1:] == "" { - http.ServeFile(w, r, "templates/home.html") + db, err := bolt.Open(DBPath, 0755, &bolt.Options{Timeout: 1 * time.Second}) + if err != nil { + log.Println("Failed to open bolt database: ", err) + return + } + defer db.Close() + + recent := &recentHeap{} + err = db.View(func(tx *bolt.Tx) error { + rb := tx.Bucket([]byte(MetaBucket)) + if rb == nil { + return fmt.Errorf("meta bucket not found") + } + b := rb.Get([]byte("recent")) + if b == nil { + b, err = json.Marshal([]recentHeap{}) + if err != nil { + return err + } + } + json.Unmarshal(b, recent) + + heap.Init(recent) + + return nil + }) + + var recentRepos []string + for _, r := range *recent { + recentRepos = append(recentRepos, r.Repo) + } + + t := template.Must(template.New("home.html").Delims("[[", "]]").ParseFiles("templates/home.html")) + t.Execute(w, map[string]interface{}{"Recent": recentRepos}) + + return } else { http.NotFound(w, r) } diff --git a/handlers/recent_heap.go b/handlers/recent_heap.go new file mode 100644 index 0000000..2ee086e --- /dev/null +++ b/handlers/recent_heap.go @@ -0,0 +1,25 @@ +package handlers + +type recentItem struct { + Repo string `json:"repo"` +} + +type recentHeap []recentItem + +func (h recentHeap) Len() int { return len(h) } +func (h recentHeap) Less(i, j int) bool { return true } +func (h recentHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *recentHeap) Push(x interface{}) { + // Push and Pop use pointer receivers because they modify the slice's length, + // not just its contents. + *h = append(*h, x.(recentItem)) +} + +func (h *recentHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} diff --git a/templates/home.html b/templates/home.html index 38e7921..bd018ba 100644 --- a/templates/home.html +++ b/templates/home.html @@ -100,6 +100,20 @@ + + + + + + + + [[ range .Recent ]] + + + + [[ end ]] + +
Recently Viewed