package main import ( "encoding/json" "strings" ) type fileListing struct { Files map[string]interface{} `json:"files"` Dirs map[string]interface{} `json:"dirs"` Path string `json:"path"` } func toStringJoin(in []interface{}, sep string) string { s := []string{} for _, a := range in { s = append(s, a.(string)) } return strings.Join(s, sep) } func listFiles(path string, includeMeta bool, depth int) (fileListing, error) { emptyObject := &(json.RawMessage{'{', '}'}) viewRes := struct { Rows []struct { Key []interface{} Value struct { Count, Sum, Min, Max int64 } } }{} // use the requested path to build our view query parameters endKey := []interface{}{} if path != "" { for _, k := range strings.Split(path, "/") { endKey = append(endKey, k) } } endKey = append(endKey, emptyObject) startKey := endKey[:len(endKey)-1] groupLevel := len(startKey) + depth // query the view err := couchbase.ViewCustom("cbfs", "file_browse", map[string]interface{}{ "group_level": groupLevel, "start_key": startKey, "end_key": endKey, }, &viewRes) if err != nil { return fileListing{}, err } // use the view result to build a list of keys keys := make([]string, len(viewRes.Rows), len(viewRes.Rows)) for i, r := range viewRes.Rows { keys[i] = shortName(toStringJoin(r.Key, "/")) } // do a multi-get on the all the keys returned bulkResult, _, err := couchbase.GetBulk(keys) if err != nil { return fileListing{}, err } // divide items up into files and directories files := map[string]interface{}{} dirs := map[string]interface{}{} for _, r := range viewRes.Rows { key := shortName(toStringJoin(r.Key, "/")) subkey := r.Key if len(r.Key) > depth { subkey = r.Key[len(r.Key)-depth:] } name := toStringJoin(subkey, "/") res, ok := bulkResult[key] if ok == true { // this means we have a file if includeMeta { rm := json.RawMessage(res.Body) files[name] = &rm } else { files[name] = emptyObject } } else { // no record in the multi-get means this is a directory dirs[name] = struct { Count int64 `json:"descendants"` Sum int64 `json:"size"` Min int64 `json:"smallest"` Max int64 `json:"largest"` }{r.Value.Count, r.Value.Sum, r.Value.Min, r.Value.Max} } } rv := fileListing{ Path: "/" + path, Dirs: dirs, Files: files, } return rv, nil }