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
This commit is contained in:
mpl 2013-01-09 16:58:20 +01:00
parent 360f63a64b
commit 67c5678062
5 changed files with 57 additions and 3 deletions

View File

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

View File

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

View File

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

View File

@ -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 = "<img src='./thumbnail/" + pn + "/" +
fileName.replace(/['"<>\?&]/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) {

View File

@ -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 = \"<img src='./thumbnail/\" + pn + \"/\" +\n"+
@ -503,6 +505,9 @@ func init() {
" }\n"+
" return fileName;\n"+
" }\n"+
" if (d.camliType == \"directory\" && d.dir && d.dir.fileName) {\n"+
" return d.dir.fileName\n"+
" }\n"+
" if (d.permanode) {\n"+
" var attr = d.permanode.attr;\n"+
" if (!attr) {\n"+
@ -540,5 +545,5 @@ func init() {
" }\n"+
" fn.apply(null, Array.prototype.slice.call(arguments, 1));\n"+
"}\n"+
""), time.Unix(0, 1357701658000000000))
""), time.Unix(0, 1357746813011715782))
}