diff --git a/db_fileutil.go b/db_fileutil.go
index b00ed5d..897312b 100644
--- a/db_fileutil.go
+++ b/db_fileutil.go
@@ -3,6 +3,7 @@ package main
import (
"github.com/vbatts/imgsrv/hash"
"github.com/vbatts/imgsrv/types"
+ "labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
)
@@ -58,3 +59,34 @@ func HasFileByKeyword(keyword string) (exists bool, err error) {
exists = (c > 0)
return exists, nil
}
+
+func GetKeywords() (kp []types.KeywordCount, err error) {
+ job := &mgo.MapReduce{
+ Map: `
+ function() {
+ if (!this.metadata.keywords) {
+ return;
+ }
+
+ for (index in this.metadata.keywords) {
+ emit(this.metadata.keywords[index], 1);
+ }
+ }
+ `,
+ Reduce: `
+ function(previous, current) {
+ var count = 0;
+
+ for (index in current) {
+ count += current[index];
+ }
+
+ return count;
+ }
+ `,
+ }
+ if _, err := gfs.Find(nil).MapReduce(job, &kp); err != nil {
+ return kp, err
+ }
+ return kp, nil
+}
diff --git a/layouts.go b/layouts.go
index fa7e6f3..0127c60 100644
--- a/layouts.go
+++ b/layouts.go
@@ -2,9 +2,10 @@ package main
import (
"fmt"
- "github.com/vbatts/imgsrv/types"
"io"
"text/template"
+
+ "github.com/vbatts/imgsrv/types"
)
var emptyInterface interface{}
@@ -164,6 +165,28 @@ var listTemplateHTML = `
{{end}}
`
+var tagcloudTemplate = template.Must(template.New("tagcloud").Parse(tagcloudTemplateHTML))
+var tagcloudTemplateHTML = `
+{{if .}}
+
+{{end}}
+
+
+`
+
var fileViewImageTemplate = template.Must(template.New("file").Parse(fileViewImageTemplateHTML))
var fileViewImageTemplateHTML = `
{{if .}}
@@ -359,3 +382,30 @@ func ListFilesPage(w io.Writer, files []types.File) (err error) {
}
return
}
+
+func ListKeywordsPage(w io.Writer, kc []types.KeywordCount) (err error) {
+ err = headTemplate.Execute(w, map[string]string{"title": "FileSrv"})
+ if err != nil {
+ return err
+ }
+ err = navbarTemplate.Execute(w, nil)
+ if err != nil {
+ return err
+ }
+ err = containerBeginTemplate.Execute(w, nil)
+ if err != nil {
+ return err
+ }
+
+ // main context of this page
+ err = tagcloudTemplate.Execute(w, kc)
+ if err != nil {
+ return err
+ }
+
+ err = tailTemplate.Execute(w, map[string]string{"footer": fmt.Sprintf("Version: %s", VERSION)})
+ if err != nil {
+ return err
+ }
+ return
+}
diff --git a/server.go b/server.go
index a7c87d5..a246e1f 100644
--- a/server.go
+++ b/server.go
@@ -441,7 +441,17 @@ func routeKeywords(w http.ResponseWriter, r *http.Request) {
http.NotFound(w, r)
return
} else if len(uriChunks) == 1 || (len(uriChunks) == 2 && len(uriChunks[1]) == 0) {
- routeRoot(w, r)
+ // Path: /k/
+ // show a tag cloud!
+ kc, err := GetKeywords()
+ if err != nil {
+ serverErr(w, r, err)
+ return
+ }
+ err = ListKeywordsPage(w, kc)
+ if err != nil {
+ serverErr(w, r, err)
+ }
return
}
@@ -449,11 +459,13 @@ func routeKeywords(w http.ResponseWriter, r *http.Request) {
var iter *mgo.Iter
if uriChunks[len(uriChunks)-1] == "r" {
+ // Path: /k/
// TODO determine how to show a random image by keyword ...
log.Println("random isn't built yet")
httplog.LogRequest(r, 404)
return
} else if len(uriChunks) == 2 {
+ // Path: /k/:name
log.Println(uriChunks[1])
iter = gfs.Find(bson.M{"metadata.keywords": uriChunks[1]}).Sort("-metadata.timestamp").Limit(defaultPageLimit).Iter()
}
diff --git a/types/types.go b/types/types.go
index f04c7b7..3d11826 100644
--- a/types/types.go
+++ b/types/types.go
@@ -42,3 +42,12 @@ func (f *File) IsAudio() bool {
f.SetContentType()
return strings.HasPrefix(f.ContentType, "audio")
}
+
+/*
+Structure used for collecting the keyword usage for the tag cloud
+*/
+type KeywordCount struct {
+ Id string "_id"
+ Value int
+}
+