Skip to content

Commit

Permalink
Merge pull request #57 from aenario/download2steps
Browse files Browse the repository at this point in the history
Add 2 steps download
  • Loading branch information
nono authored Feb 6, 2017
2 parents 156ee79 + a69c2bc commit b86b94e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 10 deletions.
39 changes: 37 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ const trashed = await cozy.files.trash("1234567")

### `cozy.files.downloadById(id)`

`cozy.files.downloadById(id)` is used to download a file identified by the given id.
`cozy.files.downloadById(id)` is used to download a file identified by the given id. The file is downloaded through the browser fetch method, use this if you plan to use the file in javascript after.

It returns a promise of a fetch `Response` object. This response object can be used to extract the information in the wanted form.

Expand All @@ -410,7 +410,7 @@ const buff = await response.arrayBuffer()

### `cozy.files.downloadByPath(path)`

`cozy.files.downloadByPath(path)` is used to download a file identified by the given path.
`cozy.files.downloadByPath(path)` is used to download a file identified by the given path. The file is downloaded through the browser fetch method, use this if you plan to use the file in javascript after.

It returns a promise of a fetch `Response` object. This response object can be used to extract the information in the wanted form.

Expand All @@ -423,6 +423,41 @@ const text = await response.text()
const buff = await response.arrayBuffer()
```

### `cozy.files.getDowloadLink(path)`

`cozy.files.getDowloadLink(path)` is used to get a download link for the file identified by the given path.

It returns a promise for the download link.
Download link are only valid for a short while (default 1 hour)
You can use this link to start a browser download like this:

```javascript
const href = await cozy.files.getDowloadLink("/foo/hello.txt")
const link = document.createElement('a')
link.href = href
link.download = fileName
document.body.appendChild(link) && link.click()
```

- `path` is a string specying the path of the file


### `cozy.files.getArchiveLink(paths)`

`cozy.files.getArchiveLink(paths)` is used to get a download link for a zip file containing all the files identified by the given paths.

It returns a promise for the download link.
Download link are only valid for a short while (default 1 hour)
You can use this link to start a browser download (see code in getDowloadLink)

```javascript
const href = await cozy.files.getArchiveLink("/foo/hello.txt")
```

- `path` is a string specying the path of the file


- `ids` is an array of file ids.

## Settings

Expand Down
23 changes: 23 additions & 0 deletions src/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,29 @@ export function downloadByPath (cozy, path) {
return cozyFetch(cozy, `/files/download?Path=${encodeURIComponent(path)}`)
}

function extractResponseLinkRelated (res) {
let href = res.links && res.links.related
if (!href) throw new Error('No related link in server response')
return href
}

export function getDowloadLink (cozy, path) {
return cozyFetchJSON(cozy, 'POST', `/files/downloads?Path=${encodeURIComponent(path)}`)
.then(extractResponseLinkRelated)
}

export function getArchiveLink (cozy, paths, name = 'files') {
const archive = {
type: 'io.cozy.archives',
attributes: {
name: name,
files: paths
}
}
return cozyFetchJSON(cozy, 'POST', `/files/archive`, {data: archive})
.then(extractResponseLinkRelated)
}

export function listTrash (cozy) {
return cozyFetchJSON(cozy, 'GET', `/files/trash`)
}
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const filesProto = {
statByPath: files.statByPath,
downloadById: files.downloadById,
downloadByPath: files.downloadByPath,
getDowloadLink: files.getDowloadLink,
getArchiveLink: files.getArchiveLink,
listTrash: files.listTrash,
clearTrash: files.clearTrash,
restoreById: files.restoreById,
Expand Down
9 changes: 5 additions & 4 deletions src/jsonapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ function findByRef (resources, ref) {
return resources[indexKey(ref)]
}

function handleResource (rawResource, resources) {
function handleResource (rawResource, resources, links) {
let resource = {
_id: rawResource.id,
_type: rawResource.type,
_rev: rawResource.meta.rev,
links: Object.assign({}, rawResource.links, links),
attributes: rawResource.attributes,
relations: (name) => {
let rels = rawResource.relationships[name]
Expand All @@ -31,13 +32,13 @@ function handleTopLevel (doc, resources = {}) {
const included = doc.included

if (Array.isArray(included)) {
included.forEach((r) => handleResource(r, resources))
included.forEach((r) => handleResource(r, resources, doc.links))
}

if (Array.isArray(doc.data)) {
return doc.data.map((r) => handleResource(r, resources))
return doc.data.map((r) => handleResource(r, resources, doc.links))
} else {
return handleResource(doc.data, resources)
return handleResource(doc.data, resources, doc.links)
}
}

Expand Down
42 changes: 41 additions & 1 deletion test/integration/files.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-env mocha */
/* global fetch */

// eslint-disable-next-line no-unused-vars
import should from 'should'
Expand Down Expand Up @@ -171,6 +172,45 @@ describe('files API', async function () {
trashed.should.have.length(0)
})

it('creates download link for 1 file', async function () {
const filename = 'foo_' + random()
const created = await cozy.files.create('foo', {
name: filename,
contentType: 'application/json'
})
const path = '/' + created.attributes.name
console.log(path)
let link = await cozy.files.getDowloadLink(path)
let downloaded = await fetch(COZY_STACK_URL + link)
const txt1 = await downloaded.text()
txt1.should.equal('foo')
})

it('creates download link for archive', async function () {
const filename = 'foo_' + random()
const created = await cozy.files.create('foo', {
name: filename,
contentType: 'application/json'
})

const filename2 = 'bar_' + random()
const created2 = await cozy.files.create('bar', {
name: filename2,
contentType: 'application/json'
})
const toDownload = [
'/' + created.attributes.name,
'/' + created2.attributes.name
]
console.log(toDownload)
let link = await cozy.files.getArchiveLink(toDownload, 'foobar')
let downloaded = await fetch(COZY_STACK_URL + link)
downloaded.ok.should.be.true
downloaded.headers.get('Content-Type').should.equal('application/zip')
const disp = downloaded.headers.get('Content-Disposition')
disp.indexOf('foobar').should.not.equal(-1)
})

describe('offline', async () => {
beforeEach(() => {
cozy = new Cozy({
Expand All @@ -188,7 +228,7 @@ describe('files API', async function () {
await cozy.offline.replicateFromCozy('io.cozy.files')
const offline = await cozy.files.statById(folder._id)
const online = await cozy.files.statById(folder._id, false)
Object.keys(online).forEach(key => { offline.should.have.keys(key) })
Object.keys(online).forEach(key => { key === 'links' || offline.should.have.keys(key) })
Object.keys(offline).forEach(key => { online.should.have.keys(key) })
Object.keys(online.attributes).forEach(key => { offline.attributes.should.have.keys(key) })
Object.keys(offline.attributes).forEach(key => { online.attributes.should.have.keys(key) })
Expand Down
6 changes: 3 additions & 3 deletions test/unit/jsonapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import jsonapiUnpack from '../../src/jsonapi'
describe('unpacking', function () {
it('simple data', function () {
let result = jsonapiUnpack({
'links': {
'self': '/io.cozy.testobject/42'
},
'data': {
'attributes': {
'test': 'value'
},
'type': 'io.cozy.testobject',
'id': '42',
'links': {
'self': '/io.cozy.testobject/42'
},
'meta': {
'rev': '1-24'
}
Expand Down

0 comments on commit b86b94e

Please sign in to comment.