Clean up REST JSON a little further

This commit is contained in:
Jakob Borg 2015-04-20 22:37:04 +09:00
parent 34c691087e
commit bf7d84c12a
3 changed files with 69 additions and 44 deletions

View File

@ -109,7 +109,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
// The GET handlers
getRestMux := http.NewServeMux()
getRestMux.HandleFunc("/rest/db/completion", withModel(m, restGetDBCompletion)) // device folder
getRestMux.HandleFunc("/rest/db/file", withModel(m, restGetDBFile)) // folder file [blocks]
getRestMux.HandleFunc("/rest/db/file", withModel(m, restGetDBFile)) // folder file
getRestMux.HandleFunc("/rest/db/ignores", withModel(m, restGetDBIgnores)) // folder
getRestMux.HandleFunc("/rest/db/need", withModel(m, restGetDBNeed)) // folder
getRestMux.HandleFunc("/rest/db/status", withModel(m, restGetDBStatus)) // folder
@ -384,7 +384,7 @@ func restGetDBNeed(m *model.Model, w http.ResponseWriter, r *http.Request) {
progress, queued, rest := m.NeedFolderFiles(folder, 100)
// Convert the struct to a more loose structure, and inject the size.
output := map[string][]map[string]interface{}{
output := map[string][]jsonDBFileInfo{
"progress": toNeedSlice(progress),
"queued": toNeedSlice(queued),
"rest": toNeedSlice(rest),
@ -416,19 +416,13 @@ func restGetDBFile(m *model.Model, w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
folder := qs.Get("folder")
file := qs.Get("file")
withBlocks := qs.Get("blocks") != ""
gf, _ := m.CurrentGlobalFile(folder, file)
lf, _ := m.CurrentFolderFile(folder, file)
if !withBlocks {
gf.Blocks = nil
lf.Blocks = nil
}
av := m.Availability(folder, file)
json.NewEncoder(w).Encode(map[string]interface{}{
"global": gf,
"local": lf,
"global": jsonFileInfo(gf),
"local": jsonFileInfo(lf),
"availability": av,
})
}
@ -910,17 +904,49 @@ func mimeTypeForFile(file string) string {
}
}
func toNeedSlice(fs []db.FileInfoTruncated) []map[string]interface{} {
output := make([]map[string]interface{}, len(fs))
for i, file := range fs {
output[i] = map[string]interface{}{
"name": file.Name,
"flags": file.Flags,
"modified": file.Modified,
"version": file.Version,
"localVersion": file.LocalVersion,
"size": file.Size(),
}
func toNeedSlice(fs []db.FileInfoTruncated) []jsonDBFileInfo {
res := make([]jsonDBFileInfo, len(fs))
for i, f := range fs {
res[i] = jsonDBFileInfo(f)
}
return output
return res
}
// Type wrappers for nice JSON serialization
type jsonFileInfo protocol.FileInfo
func (f jsonFileInfo) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"name": f.Name,
"size": protocol.FileInfo(f).Size(),
"flags": fmt.Sprintf("%#o", f.Flags),
"modified": time.Unix(f.Modified, 0),
"localVersion": f.LocalVersion,
"numBlocks": len(f.Blocks),
"version": jsonVersionVector(f.Version),
})
}
type jsonDBFileInfo db.FileInfoTruncated
func (f jsonDBFileInfo) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"name": f.Name,
"size": db.FileInfoTruncated(f).Size(),
"flags": fmt.Sprintf("%#o", f.Flags),
"modified": time.Unix(f.Modified, 0),
"localVersion": f.LocalVersion,
"version": jsonVersionVector(f.Version),
})
}
type jsonVersionVector protocol.Vector
func (v jsonVersionVector) MarshalJSON() ([]byte, error) {
res := make([]string, len(v))
for i, c := range v {
res[i] = fmt.Sprintf("%d:%d", c.ID, c.Value)
}
return json.Marshal(res)
}

View File

@ -1482,8 +1482,8 @@ func (m *Model) GlobalDirectoryTree(folder, prefix string, levels int, dirsonly
}
if !dirsonly && base != "" {
last[base] = []int64{
f.Modified, f.Size(),
last[base] = []interface{}{
time.Unix(f.Modified, 0), f.Size(),
}
}

View File

@ -14,7 +14,6 @@ import (
"math/rand"
"os"
"path/filepath"
"reflect"
"strconv"
"testing"
"time"
@ -775,7 +774,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
}
}
filedata := []int64{0x666, 0xa}
filedata := []interface{}{time.Unix(0x666, 0), 0xa}
testdata := []protocol.FileInfo{
b(false, "another"),
@ -847,13 +846,13 @@ func TestGlobalDirectoryTree(t *testing.T) {
result := m.GlobalDirectoryTree("default", "", -1, false)
if !reflect.DeepEqual(result, expectedResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(expectedResult))
if mm(result) != mm(expectedResult) {
t.Errorf("Does not match:\n%#v\n%#v", result, expectedResult)
}
result = m.GlobalDirectoryTree("default", "another", -1, false)
if !reflect.DeepEqual(result, expectedResult["another"]) {
if mm(result) != mm(expectedResult["another"]) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(expectedResult["another"]))
}
@ -865,7 +864,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"rootfile": filedata,
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -886,7 +885,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"rootfile": filedata,
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -916,7 +915,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -935,7 +934,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -945,7 +944,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"file": filedata,
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -954,7 +953,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"with": map[string]interface{}{},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -965,7 +964,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -978,7 +977,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -991,7 +990,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -999,7 +998,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
result = m.GlobalDirectoryTree("default", "som", -1, false)
currentResult = map[string]interface{}{}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
}
@ -1024,7 +1023,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
}
}
filedata := []int64{0x666, 0xa}
filedata := []interface{}{time.Unix(0x666, 0).Format(time.RFC3339), 0xa}
testdata := []protocol.FileInfo{
b(true, "another", "directory", "afile"),
@ -1105,7 +1104,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
result := m.GlobalDirectoryTree("default", "", -1, false)
if !reflect.DeepEqual(result, expectedResult) {
if mm(result) != mm(expectedResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(expectedResult))
}
@ -1116,7 +1115,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -1125,7 +1124,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
"invalid": map[string]interface{}{},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@ -1134,7 +1133,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
result = m.GlobalDirectoryTree("default", "xthis", 1, false)
currentResult = map[string]interface{}{}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
}