mirror of
https://github.com/gojp/goreportcard.git
synced 2026-01-29 06:49:05 +08:00
start recent list
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
25
handlers/recent_heap.go
Normal 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
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user