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 .}} +
+{{range .}} +{{.Id}} +{{end}} +
+{{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 +} +