Skip to content

Commit

Permalink
Add the POST /files/_all_docs route
Browse files Browse the repository at this point in the history
  • Loading branch information
nono committed Oct 24, 2024
1 parent 05cdffd commit cda83ee
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
128 changes: 128 additions & 0 deletions docs/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,134 @@ Content-Type: application/vnd.api+json
}
```

### POST `/files/_all_docs`

This route allows to fetch several files in one request. It is the same as the
`_all_docs` request for CouchDB, except the response is in the JSON-API format,
(with thumbnails and path for the files).

### Request

```http
POST /files/_all_docs HTTP/1.1
```

```json
{
"keys": ["e8c1561846c730428180a5f6c6107914", "e8c1561846c730428180a5f6c6109007"]
}
```

### Response

```http
HTTP/1.1 200 OK
Date: Mon, 27 Sept 2016 12:28:53 GMT
Content-Length: ...
Content-Type: application/json
```

```json
{
"data": [
{
"type": "io.cozy.files",
"id": "e8c1561846c730428180a5f6c6107914",
"attributes": {
"type": "file",
"name": "nicepic1.jpg",
"dir_id": "f49b4087cbf946dfc759214394009a6c",
"created_at": "2020-02-13T16:35:47.568155477+01:00",
"updated_at": "2020-02-13T16:35:47.568155477+01:00",
"size": "345385",
"md5sum": "12cGYwT+RiNjFxf4f7AmzQ==",
"mime": "image/jpeg",
"class": "image",
"executable": false,
"trashed": false,
"tags": [],
"path": "/Pictures/nicepic1.jpg",
"metadata": {
"datetime": "2020-02-13T16:35:47.568155477+01:00",
"extractor_version": 2,
"height": 1080,
"width": 1920
}
},
"meta": {
"rev": "2-235e715b1d82a93285be1b0bd691b779"
},
"links": {
"self": "/files/e8c1561846c730428180a5f6c6107914",
"tiny": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/tiny",
"small": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/small",
"medium": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/medium",
"large": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/large"
},
"relationships": {
"parent": {
"links": {
"related": "/files/f49b4087cbf946dfc759214394009a6c"
},
"data": {
"id": "f49b4087cbf946dfc759214394009a6c",
"type": "io.cozy.files"
}
}
}
},
{
"type": "io.cozy.files",
"id": "e8c1561846c730428180a5f6c6109007",
"attributes": {
"type": "file",
"name": "nicepic2.jpg",
"dir_id": "f49b4087cbf946dfc759214394009a6c",
"created_at": "2020-02-13T16:35:47.845049743+01:00",
"updated_at": "2020-02-13T16:35:47.845049743+01:00",
"size": "323009",
"md5sum": "Fla3ucNXuW2Xw/TK8pfsPA==",
"mime": "image/jpeg",
"class": "image",
"executable": false,
"trashed": false,
"tags": [],
"path": "/Pictures/nicepic2.jpg",
"metadata": {
"datetime": "2020-02-13T16:35:47.845049743+01:00",
"extractor_version": 2,
"height": 1080,
"width": 1920
}
},
"meta": {
"rev": "2-4883d6b8ccad32f8fb056af9b7f8b37f"
},
"links": {
"self": "/files/e8c1561846c730428180a5f6c6109007",
"tiny": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/tiny",
"small": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/small",
"medium": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/medium",
"large": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/large"
},
"relationships": {
"parent": {
"links": {
"related": "/files/f49b4087cbf946dfc759214394009a6c"
},
"data": {
"id": "f49b4087cbf946dfc759214394009a6c",
"type": "io.cozy.files"
}
}
}
}
]
}
```



### GET `/files/_changes`

This endpoint is similar to the changes feed of CouchDB for io.cozy.files.
Expand Down
38 changes: 38 additions & 0 deletions web/files/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,43 @@ func DestroyFileHandler(c echo.Context) error {
return c.NoContent(204)
}

// GetAllDocs is the handler for POST /files/_all_docs
func GetAllDocs(c echo.Context) error {
inst := middlewares.GetInstance(c)
if err := middlewares.AllowWholeType(c, permission.GET, consts.Files); err != nil {
return err
}
var allDocsReq struct {
Keys []string `json:"keys"`
}
if err := json.NewDecoder(c.Request().Body).Decode(&allDocsReq); err != nil {
return jsonapi.Errorf(http.StatusBadRequest, "%s", err)
}

req := &couchdb.AllDocsRequest{Keys: allDocsReq.Keys}
var results []vfs.DirOrFileDoc
if err := couchdb.GetAllDocs(inst, consts.Files, req, &results); err != nil {
return err
}

out := make([]jsonapi.Object, 0)
fp := vfs.NewFilePatherWithCache(inst.VFS())
for _, result := range results {
if result.ID() == consts.TrashDirID {
continue
}
d, f := result.Refine()
if d != nil {
out = append(out, newDir(d))
} else {
file := NewFile(f, inst)
file.IncludePath(fp)
out = append(out, file)
}
}
return jsonapi.DataList(c, http.StatusOK, out, nil)
}

// FindFilesMango is the route POST /files/_find
// used to retrieve files and their metadata from a mango query.
func FindFilesMango(c echo.Context) error {
Expand Down Expand Up @@ -1938,6 +1975,7 @@ func Routes(router *echo.Group) {
router.POST("/:file-id/versions", CopyVersionHandler)
router.DELETE("/versions", ClearOldVersions)

router.POST("/_all_docs", GetAllDocs)
router.POST("/_find", FindFilesMango)
router.GET("/_changes", ChangesFeed)

Expand Down
27 changes: 27 additions & 0 deletions web/files/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3305,6 +3305,33 @@ func TestFiles(t *testing.T) {
})
})

t.Run("GetAllDocs", func(t *testing.T) {
e := testutils.CreateTestClient(t, ts.URL)

obj := e.POST("/files/_all_docs").
WithHeader("Content-Type", "application/json").
WithHeader("Authorization", "Bearer "+token).
WithBytes([]byte(fmt.Sprintf(`{
"keys": ["io.cozy.files.root-dir", "%s"]
}`, fileID))).
Expect().Status(200).
JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}).
Object()

data := obj.Value("data").Array()
data.Length().IsEqual(2)

elem := data.Value(0).Object()
attrs := elem.Value("attributes").Object()
attrs.HasValue("path", "/")

elem = data.Value(1).Object()
attrs = elem.Value("attributes").Object()
attrs.Value("path").String().NotEmpty()
links := elem.Value("links").Object()
links.Value("tiny").String().NotEmpty()
})

t.Run("Find", func(t *testing.T) {
e := testutils.CreateTestClient(t, ts.URL)

Expand Down

0 comments on commit cda83ee

Please sign in to comment.