From 67c5678062b12a857c524d2f3dbfd1617fc71609 Mon Sep 17 00:00:00 2001 From: mpl Date: Wed, 9 Jan 2013 16:58:20 +0100 Subject: [PATCH] Index directories with "fileinfo", and use this to find their name in a search request. Fixes http://code.google.com/p/camlistore/issues/detail?id=79 Change-Id: I755afd8f52dbd2f8a48ba72bed0a6b0192d1dd71 --- pkg/index/receive.go | 27 ++++++++++++++++++++++++ pkg/search/handler.go | 17 +++++++++++++++ pkg/search/search.go | 3 ++- server/camlistored/ui/camli.js | 4 ++++ server/camlistored/ui/zembed_camli.js.go | 9 ++++++-- 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/pkg/index/receive.go b/pkg/index/receive.go index c21b87fee..8a3102676 100644 --- a/pkg/index/receive.go +++ b/pkg/index/receive.go @@ -101,6 +101,10 @@ func (ix *Index) populateMutation(br *blobref.BlobRef, sniffer *BlobSniffer, bm if err := ix.populateFile(br, camli, bm); err != nil { return err } + case "directory": + if err := ix.populateDir(br, camli, bm); err != nil { + return err + } } } return nil @@ -168,6 +172,29 @@ func (ix *Index) populateFile(blobRef *blobref.BlobRef, ss *schema.Superset, bm return nil } +// blobref: of the file or schema blob +// ss: the parsed file schema blob +// bm: keys to populate +func (ix *Index) populateDir(blobRef *blobref.BlobRef, ss *schema.Superset, bm BatchMutation) error { + seekFetcher := blobref.SeekerFromStreamingFetcher(ix.BlobSource) + dr, err := ss.NewDirReader(seekFetcher) + if err != nil { + // TODO(bradfitz): propagate up a transient failure + // error type, so we can retry indexing files in the + // future if blobs are only temporarily unavailable. + log.Printf("index: error indexing directory, creating NewDirReader %s: %v", blobRef, err) + return nil + } + sts, err := dr.StaticSet() + if err != nil { + log.Printf("index: error indexing directory: can't get StaticSet: %v\n", err) + return nil + } + + bm.Set(keyFileInfo.Key(blobRef), keyFileInfo.Val(len(sts), ss.FileName, "")) + return nil +} + func (ix *Index) populateClaim(br *blobref.BlobRef, ss *schema.Superset, sniffer *BlobSniffer, bm BatchMutation) error { pnbr := blobref.Parse(ss.Permanode) if pnbr == nil { diff --git a/pkg/search/handler.go b/pkg/search/handler.go index 368469c37..846c0a53a 100644 --- a/pkg/search/handler.go +++ b/pkg/search/handler.go @@ -317,6 +317,8 @@ type DescribedBlob struct { // if camliType "file" File *FileInfo + // if camliType "directory" + Dir *FileInfo Stub bool // if not loaded, but referenced } @@ -357,6 +359,9 @@ func (b *DescribedBlob) Title() string { if b.File != nil { return b.File.FileName } + if b.Dir != nil { + return b.Dir.FileName + } return "" } @@ -494,6 +499,9 @@ func (b *DescribedBlob) thumbnail(thumbSize int) (path string, width, height int // TODO: different thumbnails based on peer.File.MimeType. return "file.png", thumbSize, thumbSize, true } + if peer.Dir != nil { + return "folder.png", thumbSize, thumbSize, true + } } return "node.png", thumbSize, thumbSize, true @@ -515,6 +523,9 @@ func (b *DescribedBlob) jsonMap() map[string]interface{} { if b.File != nil { m["file"] = b.File } + if b.Dir != nil { + m["dir"] = b.Dir + } return m } @@ -712,6 +723,12 @@ func (dr *DescribeRequest) describeReally(br *blobref.BlobRef, depth int) { if err != nil { dr.addError(br, err) } + case "directory": + var err error + des.Dir, err = dr.sh.index.GetFileInfo(br) + if err != nil { + dr.addError(br, err) + } } } diff --git a/pkg/search/search.go b/pkg/search/search.go index 315cb5aec..a59f65804 100644 --- a/pkg/search/search.go +++ b/pkg/search/search.go @@ -91,7 +91,8 @@ func (cl ClaimList) String() string { type FileInfo struct { Size int64 `json:"size"` FileName string `json:"fileName"` - MimeType string `json:"mimeType"` + // MimeType may be set for files, but never for directories. + MimeType string `json:"mimeType,omitempty"` } func (fi *FileInfo) IsImage() bool { diff --git a/server/camlistored/ui/camli.js b/server/camlistored/ui/camli.js index 836d7cb5f..4ebf8092a 100644 --- a/server/camlistored/ui/camli.js +++ b/server/camlistored/ui/camli.js @@ -466,6 +466,7 @@ function _camliBlobTitleOrThumb(pn, des, w, h) { } if (d.camliType == "file" && d.file && d.file.fileName) { var fileName = d.file.fileName + // TODO(mpl): check whether this is ever used anywhere, now that search requests directly give the thumbnailSrc. if (w != 0 && h != 0 && d.file.mimeType && d.file.mimeType.indexOf("image/") == 0) { var img = "\?&]/g, "") + "?mw=" + w + "&mh=" + h + "'>"; @@ -473,6 +474,9 @@ function _camliBlobTitleOrThumb(pn, des, w, h) { } return fileName; } + if (d.camliType == "directory" && d.dir && d.dir.fileName) { + return d.dir.fileName + } if (d.permanode) { var attr = d.permanode.attr; if (!attr) { diff --git a/server/camlistored/ui/zembed_camli.js.go b/server/camlistored/ui/zembed_camli.js.go index 89696dc33..e32442868 100644 --- a/server/camlistored/ui/zembed_camli.js.go +++ b/server/camlistored/ui/zembed_camli.js.go @@ -7,7 +7,7 @@ import "time" import "camlistore.org/pkg/fileembed" func init() { - Files.Add("camli.js", 17159, fileembed.String("/*\n"+ + Files.Add("camli.js", 17381, fileembed.String("/*\n"+ "Copyright 2011 Google Inc.\n"+ "\n"+ "Licensed under the Apache License, Version 2.0 (the \"License\");\n"+ @@ -495,6 +495,8 @@ func init() { " }\n"+ " if (d.camliType == \"file\" && d.file && d.file.fileName) {\n"+ " var fileName = d.file.fileName\n"+ + " // TODO(mpl): check whether this is ever used anywhere, now that search r"+ + "equests directly give the thumbnailSrc.\n"+ " if (w != 0 && h != 0 && d.file.mimeType && d.file.mimeType.indexOf(\"image"+ "/\") == 0) {\n"+ " var img = \"