start recent list

This commit is contained in:
Shawn Smith
2016-02-28 15:03:54 +09:00
parent 87ab879c0d
commit 269be4a978
4 changed files with 129 additions and 1 deletions

View File

@@ -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
}

View File

@@ -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)
}

25
handlers/recent_heap.go Normal file
View File

@@ -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
}

View File

@@ -100,6 +100,20 @@
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th>Recently Viewed</th>
</tr>
</thead>
<tbody>
[[ range .Recent ]]
<tr>
<td class="table-link"><a href="/report/[[ . ]]">[[ . ]]</td>
</tr>
[[ end ]]
</tbody>
</table>
</div>
<div class="column is-quarter">
</div>