1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16
17 package server
18
19 import (
20 "log"
21 "net/http"
22
23 "perkeep.org/internal/httputil"
24 "perkeep.org/pkg/blob"
25 "perkeep.org/pkg/schema"
26 )
27
28 type FileTreeHandler struct {
29 Fetcher blob.Fetcher
30 file blob.Ref
31 }
32
33
34
35 type FileTreeNode struct {
36
37 Name string `json:"name"`
38
39
40 Type schema.CamliType `json:"type"`
41
42 BlobRef blob.Ref `json:"blobRef"`
43 }
44
45
46 type FileTreeResponse struct {
47
48 Children []FileTreeNode `json:"children"`
49 }
50
51 func (fth *FileTreeHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
52 ctx := req.Context()
53 if req.Method != "GET" && req.Method != "HEAD" {
54 http.Error(rw, "Invalid method", http.StatusBadRequest)
55 return
56 }
57
58 de, err := schema.NewDirectoryEntryFromBlobRef(ctx, fth.Fetcher, fth.file)
59 if err != nil {
60 http.Error(rw, "Error reading directory", 500)
61 log.Printf("Error reading directory from blobref %s: %v\n", fth.file, err)
62 return
63 }
64 dir, err := de.Directory(ctx)
65 if err != nil {
66 http.Error(rw, "Error reading directory", 500)
67 log.Printf("Error reading directory from blobref %s: %v\n", fth.file, err)
68 return
69 }
70 entries, err := dir.Readdir(ctx, -1)
71 if err != nil {
72 http.Error(rw, "Error reading directory", 500)
73 log.Printf("reading dir from blobref %s: %v\n", fth.file, err)
74 return
75 }
76
77 var ret = FileTreeResponse{
78 Children: make([]FileTreeNode, 0, len(entries)),
79 }
80 for _, v := range entries {
81 ret.Children = append(ret.Children, FileTreeNode{
82 Name: v.FileName(),
83 Type: v.CamliType(),
84 BlobRef: v.BlobRef(),
85 })
86 }
87 httputil.ReturnJSON(rw, ret)
88 }