Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 0daa01a

Browse files
committed
Merge branch 'ipfs-files-get' of https://github.com/noffle/js-ipfs-api into noffle-ipfs-files-get
2 parents a0ec626 + 5dcc4a0 commit 0daa01a

File tree

6 files changed

+210
-12
lines changed

6 files changed

+210
-12
lines changed

src/api/cat.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
'use strict'
22

3-
const bs58 = require('bs58')
4-
const isIPFS = require('is-ipfs')
53
const promisify = require('promisify-es6')
4+
const cleanMultihash = require('../clean-multihash')
65

76
module.exports = (send) => {
87
const cat = promisify((multihash, callback) => {
@@ -15,13 +14,3 @@ module.exports = (send) => {
1514
})
1615
return cat
1716
}
18-
19-
function cleanMultihash (multihash) {
20-
if (!isIPFS.multihash(multihash)) {
21-
throw new Error('not valid multihash')
22-
}
23-
if (Buffer.isBuffer(multihash)) {
24-
return bs58.encode(multihash)
25-
}
26-
return multihash
27-
}

src/api/get.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict'
2+
3+
const tarStreamToObjects = require('../tar-stream-to-objects')
4+
const cleanMultihash = require('../clean-multihash')
5+
const promisify = require('promisify-es6')
6+
7+
module.exports = (send) => {
8+
return promisify(function get (path, opts, cb) {
9+
if (typeof opts === 'function' && !cb) {
10+
cb = opts
11+
opts = {}
12+
}
13+
14+
// opts is the real callback -- 'cb' is being injected by promisify
15+
if (typeof opts === 'function' && typeof cb === 'function') {
16+
cb = opts
17+
opts = {}
18+
}
19+
20+
try {
21+
path = cleanMultihash(path)
22+
} catch (err) {
23+
return cb(err)
24+
}
25+
26+
var sendWithTransform = send.withTransform(tarStreamToObjects)
27+
28+
return sendWithTransform('get', path, opts, null, cb)
29+
})
30+
}

src/clean-multihash.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict'
2+
3+
const bs58 = require('bs58')
4+
const isIPFS = require('is-ipfs')
5+
6+
module.exports = function (multihash) {
7+
if (!isIPFS.multihash(multihash)) {
8+
throw new Error('not valid multihash')
9+
}
10+
if (Buffer.isBuffer(multihash)) {
11+
return bs58.encode(multihash)
12+
}
13+
return multihash
14+
}
15+

src/load-commands.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function requireCommands () {
1313
dht: require('./api/dht'),
1414
diag: require('./api/diag'),
1515
id: require('./api/id'),
16+
get: require('./api/get'),
1617
log: require('./api/log'),
1718
ls: require('./api/ls'),
1819
mount: require('./api/mount'),
@@ -33,6 +34,12 @@ function requireCommands () {
3334
const files = require('./api/files')(send)
3435
files.add = require('./api/add')(send)
3536
files.createAddStream = require('./api/add-stream.js')(send)
37+
files.get = require('./api/get')(send)
38+
39+
// aliases
40+
cmds.add = files.add
41+
cmds.createAddStream = files.createAddStream
42+
cmds.get = files.get
3643

3744
return files
3845
}

src/tar-stream-to-objects.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict'
2+
3+
const tar = require('tar-stream')
4+
const Readable = require('readable-stream')
5+
const through = require('through2')
6+
7+
// transform tar stream into readable stream of
8+
// { path: 'string', content: Readable }
9+
module.exports = function (err, res, send, done) {
10+
11+
if (err) return done(err)
12+
13+
var ex = tar.extract()
14+
res.pipe(ex)
15+
16+
var objStream = new Readable({ objectMode: true })
17+
objStream._read = function noop () {}
18+
19+
ex.on('entry', function (header, stream, next) {
20+
objStream.push({
21+
path: header.name,
22+
content: header.type !== 'directory' ? stream : null
23+
})
24+
next()
25+
})
26+
ex.on('finish', () => {
27+
objStream.push(null)
28+
})
29+
30+
done(null, objStream)
31+
}
32+

test/api/get.spec.js

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/* eslint-env mocha */
2+
/* globals apiClients */
3+
'use strict'
4+
5+
const expect = require('chai').expect
6+
const isNode = require('detect-node')
7+
const fs = require('fs')
8+
const bl = require('bl')
9+
const concat = require('concat-stream')
10+
const through = require('through2')
11+
12+
const path = require('path')
13+
const streamEqual = require('stream-equal')
14+
15+
const extract = require('tar-stream').extract
16+
17+
let testfile
18+
let testfileBig
19+
20+
if (isNode) {
21+
testfile = fs.readFileSync(path.join(__dirname, '/../testfile.txt'))
22+
testfileBig = fs.createReadStream(path.join(__dirname, '/../15mb.random'), { bufferSize: 128 })
23+
} else {
24+
testfile = require('raw!../testfile.txt')
25+
}
26+
27+
describe('.get', () => {
28+
it('get with no compression args', (done) => {
29+
apiClients.a
30+
.get('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', (err, res) => {
31+
32+
// accumulate the files and their content
33+
var files = []
34+
res.pipe(through.obj((file, enc, next) => {
35+
file.content.pipe(concat((content) => {
36+
files.push({
37+
path: file.path,
38+
content: content
39+
})
40+
next()
41+
}))
42+
}, () => {
43+
expect(files).to.be.length(1)
44+
expect(files[0].content.toString()).to.contain(testfile.toString())
45+
done()
46+
}))
47+
})
48+
})
49+
50+
it('get with archive true', (done) => {
51+
apiClients.a
52+
.get('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', {archive: true}, (err, res) => {
53+
54+
// accumulate the files and their content
55+
var files = []
56+
res.pipe(through.obj((file, enc, next) => {
57+
file.content.pipe(concat((content) => {
58+
files.push({
59+
path: file.path,
60+
content: content
61+
})
62+
next()
63+
}))
64+
}, () => {
65+
expect(files).to.be.length(1)
66+
expect(files[0].content.toString()).to.contain(testfile.toString())
67+
done()
68+
}))
69+
})
70+
})
71+
72+
it('get err with out of range compression level', (done) => {
73+
apiClients.a
74+
.get('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', {compress: true, 'compression-level': 10}, (err, res) => {
75+
expect(err).to.exist
76+
expect(err.toString()).to.equal('Error: Compression level must be between 1 and 9')
77+
done()
78+
})
79+
})
80+
81+
it('get with compression level', (done) => {
82+
apiClients.a
83+
.get('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', {compress: true, 'compression-level': 1}, (err, res) => {
84+
expect(err).to.not.exist
85+
done()
86+
})
87+
})
88+
89+
it.skip('get BIG file', (done) => {
90+
if (!isNode) {
91+
return done()
92+
}
93+
94+
apiClients.a.get('Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq', (err, res) => {
95+
expect(err).to.not.exist
96+
97+
// Do not blow out the memory of nodejs :)
98+
streamEqual(res, testfileBig, (err, equal) => {
99+
expect(err).to.not.exist
100+
expect(equal).to.be.true
101+
done()
102+
})
103+
})
104+
})
105+
106+
describe('promise', () => {
107+
it.skip('get', (done) => {
108+
return apiClients.a.get('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
109+
.then((res) => {
110+
let buf = ''
111+
res
112+
.on('error', (err) => {
113+
throw err
114+
})
115+
.on('data', (data) => {
116+
buf += data
117+
})
118+
.on('end', () => {
119+
expect(buf).to.contain(testfile.toString())
120+
done()
121+
})
122+
})
123+
})
124+
})
125+
})

0 commit comments

Comments
 (0)