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

Commit bc04eba

Browse files
committed
cat
1 parent de2f861 commit bc04eba

File tree

2 files changed

+226
-92
lines changed

2 files changed

+226
-92
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,33 @@ ipfs.files.createAddStream(function (err, stream) {
148148

149149

150150

151+
152+
### `cat`
153+
154+
> Streams the file at the given IPFS multihash..
155+
156+
##### `Go` **WIP**
157+
158+
##### `JavaScript` - ipfs.cat(multihash, [callback])
159+
160+
`multihash` is a [multihash][] which can be passed as
161+
162+
- Buffer, the raw Buffer of the multihash
163+
- String, the base58 encoded version of the multihash
164+
165+
`callback` must follow `function (err, stream) {}` signature, where `err` is an error if the operation was not successful and `stream` is a readable stream of the file.
166+
167+
If no `callback` is passed, a promise is returned.
168+
169+
```js
170+
ipfs.files.cat(multihash, function (err, file) {
171+
// file will be a stream containing the data of the file requested
172+
})
173+
```
174+
175+
176+
177+
151178
## Object
152179

153180
### `object.new`

src/files.js

Lines changed: 199 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ const Readable = require('readable-stream')
77
const path = require('path')
88
const fs = require('fs')
99
const isNode = require('detect-node')
10+
const bl = require('bl')
1011

1112
module.exports = (common) => {
12-
describe('.files/add', () => {
13+
describe('.files', () => {
1314
let smallFile
1415
let bigFile
1516
let ipfs
@@ -31,121 +32,227 @@ module.exports = (common) => {
3132
common.teardown(done)
3233
})
3334

34-
it('stream', (done) => {
35-
const buffered = new Buffer('some data')
36-
const rs = new Readable()
37-
rs.push(buffered)
38-
rs.push(null)
35+
describe('.add', () => {
36+
it('stream', (done) => {
37+
const buffered = new Buffer('some data')
38+
const rs = new Readable()
39+
rs.push(buffered)
40+
rs.push(null)
3941

40-
const arr = []
41-
const filePair = {path: 'data.txt', content: rs}
42-
arr.push(filePair)
42+
const arr = []
43+
const filePair = {path: 'data.txt', content: rs}
44+
arr.push(filePair)
4345

44-
ipfs.files.add(arr, (err, res) => {
45-
expect(err).to.not.exist
46-
expect(res).to.be.length(1)
47-
expect(res[0].path).to.equal('data.txt')
48-
expect(res[0].node.size()).to.equal(17)
49-
const mh = 'QmVv4Wz46JaZJeH5PMV4LGbRiiMKEmszPYY3g6fjGnVXBS'
50-
expect(bs58.encode(res[0].node.multihash()).toString()).to.equal(mh)
51-
done()
46+
ipfs.files.add(arr, (err, res) => {
47+
expect(err).to.not.exist
48+
expect(res).to.be.length(1)
49+
expect(res[0].path).to.equal('data.txt')
50+
expect(res[0].node.size()).to.equal(17)
51+
const mh = 'QmVv4Wz46JaZJeH5PMV4LGbRiiMKEmszPYY3g6fjGnVXBS'
52+
expect(bs58.encode(res[0].node.multihash()).toString()).to.equal(mh)
53+
done()
54+
})
5255
})
53-
})
5456

55-
it('buffer as tuple', (done) => {
56-
const file = {
57-
path: 'testfile.txt',
58-
content: smallFile
59-
}
57+
it('buffer as tuple', (done) => {
58+
const file = {
59+
path: 'testfile.txt',
60+
content: smallFile
61+
}
6062

61-
ipfs.files.add([file], (err, res) => {
62-
expect(err).to.not.exist
63+
ipfs.files.add([file], (err, res) => {
64+
expect(err).to.not.exist
6365

64-
const added = res[0] != null ? res[0] : res
65-
const mh = bs58.encode(added.node.multihash()).toString()
66-
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
67-
expect(added.path).to.equal('testfile.txt')
68-
expect(added.node.links).to.have.length(0)
69-
done()
66+
const added = res[0] != null ? res[0] : res
67+
const mh = bs58.encode(added.node.multihash()).toString()
68+
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
69+
expect(added.path).to.equal('testfile.txt')
70+
expect(added.node.links).to.have.length(0)
71+
done()
72+
})
7073
})
71-
})
7274

73-
it('buffer', (done) => {
74-
ipfs.files.add(smallFile, (err, res) => {
75-
expect(err).to.not.exist
75+
it('buffer', (done) => {
76+
ipfs.files.add(smallFile, (err, res) => {
77+
expect(err).to.not.exist
7678

77-
expect(res).to.have.length(1)
78-
const mh = bs58.encode(res[0].node.multihash()).toString()
79-
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
80-
expect(res[0].path).to.equal(mh)
81-
expect(res[0].node.links).to.have.length(0)
82-
done()
79+
expect(res).to.have.length(1)
80+
const mh = bs58.encode(res[0].node.multihash()).toString()
81+
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
82+
expect(res[0].path).to.equal(mh)
83+
expect(res[0].node.links).to.have.length(0)
84+
done()
85+
})
8386
})
84-
})
8587

86-
it('BIG buffer', (done) => {
87-
ipfs.files.add(bigFile, (err, res) => {
88-
expect(err).to.not.exist
88+
it('BIG buffer', (done) => {
89+
ipfs.files.add(bigFile, (err, res) => {
90+
expect(err).to.not.exist
8991

90-
expect(res).to.have.length(1)
91-
expect(res[0].node.links).to.have.length(58)
92-
const mh = bs58.encode(res[0].node.multihash()).toString()
93-
expect(res[0].path).to.equal(mh)
94-
expect(mh).to.equal('Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq')
95-
done()
92+
expect(res).to.have.length(1)
93+
expect(res[0].node.links).to.have.length(58)
94+
const mh = bs58.encode(res[0].node.multihash()).toString()
95+
expect(res[0].path).to.equal(mh)
96+
expect(mh).to.equal('Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq')
97+
done()
98+
})
99+
})
100+
101+
it('add a nested dir as array', (done) => {
102+
if (!isNode) {
103+
return done()
104+
// can't run this test cause browserify
105+
// can't shim readFileSync in runtime
106+
}
107+
const base = path.join(__dirname, 'data/test-folder')
108+
const content = (name) => ({
109+
path: `test-folder/${name}`,
110+
content: fs.readFileSync(path.join(base, name))
111+
})
112+
const emptyDir = (name) => ({
113+
path: `test-folder/${name}`
114+
})
115+
const dirs = [
116+
content('pp.txt'),
117+
content('holmes.txt'),
118+
content('jungle.txt'),
119+
content('alice.txt'),
120+
emptyDir('empty-folder'),
121+
content('files/hello.txt'),
122+
content('files/ipfs.txt'),
123+
emptyDir('files/empty')
124+
]
125+
126+
ipfs.files.add(dirs, (err, res) => {
127+
expect(err).to.not.exist
128+
129+
const added = res[res.length - 1]
130+
const mh = bs58.encode(added.node.multihash()).toString()
131+
expect(mh).to.equal('QmVvjDy7yF7hdnqE8Hrf4MHo5ABDtb5AbX6hWbD3Y42bXP')
132+
expect(added.path).to.equal('test-folder')
133+
expect(added.node.links).to.have.length(6)
134+
done()
135+
})
136+
})
137+
138+
describe('promise', () => {
139+
it('buffer', () => {
140+
return ipfs.files.add(smallFile)
141+
.then((res) => {
142+
const added = res[0] != null ? res[0] : res
143+
const mh = bs58.encode(added.node.multihash()).toString()
144+
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
145+
expect(added.path).to.equal(mh)
146+
expect(added.node.links).to.have.length(0)
147+
})
148+
.catch((err) => {
149+
expect(err).to.not.exist
150+
})
151+
})
96152
})
97153
})
98154

99-
it('add a nested dir as array', (done) => {
100-
if (!isNode) {
101-
return done()
102-
// can't run this test cause browserify
103-
// can't shim readFileSync in runtime
104-
}
105-
const base = path.join(__dirname, 'data/test-folder')
106-
const content = (name) => ({
107-
path: `test-folder/${name}`,
108-
content: fs.readFileSync(path.join(base, name))
155+
describe('.cat', () => {
156+
it('returns file stream', (done) => {
157+
const hash = 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB'
158+
ipfs.cat(hash, (err, file) => {
159+
expect(err).to.not.exist
160+
file.pipe(bl((err, bldata) => {
161+
expect(err).to.not.exist
162+
expect(bldata.toString()).to.contain('Check out some of the other files in this directory:')
163+
done()
164+
}))
165+
})
109166
})
110-
const emptyDir = (name) => ({
111-
path: `test-folder/${name}`
167+
168+
// This fails on js-ipfs-api
169+
it('takes a buffer input', (done) => {
170+
const mhBuf = new Buffer(bs58.decode('QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB'))
171+
ipfs.cat(mhBuf, (err, file) => {
172+
expect(err).to.not.exist
173+
file.pipe(bl((err, bldata) => {
174+
expect(err).to.not.exist
175+
expect(bldata.toString()).to.contain('Check out some of the other files in this directory:')
176+
done()
177+
}))
178+
})
112179
})
113-
const dirs = [
114-
content('pp.txt'),
115-
content('holmes.txt'),
116-
content('jungle.txt'),
117-
content('alice.txt'),
118-
emptyDir('empty-folder'),
119-
content('files/hello.txt'),
120-
content('files/ipfs.txt'),
121-
emptyDir('files/empty')
122-
]
123-
124-
ipfs.files.add(dirs, (err, res) => {
125-
expect(err).to.not.exist
126180

127-
const added = res[res.length - 1]
128-
const mh = bs58.encode(added.node.multihash()).toString()
129-
expect(mh).to.equal('QmVvjDy7yF7hdnqE8Hrf4MHo5ABDtb5AbX6hWbD3Y42bXP')
130-
expect(added.path).to.equal('test-folder')
131-
expect(added.node.links).to.have.length(6)
132-
done()
181+
// You can add a large file to your ipfs repo and change the hash to the file after installing js-ipfs
182+
it('returns a large file', (done) => {
183+
const hash = 'Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq'
184+
ipfs.cat(hash, (err, file) => {
185+
expect(err).to.not.exist
186+
file.pipe(bl((err, bldata) => {
187+
expect(err).to.not.exist
188+
expect(bldata).to.deep.equal(bigFile)
189+
done()
190+
}))
191+
})
133192
})
134-
})
135193

136-
describe('promise', () => {
137-
it('buffer', () => {
138-
return ipfs.files.add(smallFile)
139-
.then((res) => {
140-
const added = res[0] != null ? res[0] : res
141-
const mh = bs58.encode(added.node.multihash()).toString()
142-
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
143-
expect(added.path).to.equal(mh)
144-
expect(added.node.links).to.have.length(0)
194+
it('returns error on invalid key', (done) => {
195+
const hash = 'somethingNotMultihash'
196+
ipfs.cat(hash, (err, file) => {
197+
expect(err).to.exist
198+
const errString = err.toString()
199+
if (errString === 'Error: invalid ipfs ref path') {
200+
expect(err.toString()).to.contain('Error: invalid ipfs ref path')
201+
}
202+
if (errString === 'Error: Invalid Key') {
203+
expect(err.toString()).to.contain('Error: Invalid Key')
204+
}
205+
done()
206+
})
207+
})
208+
209+
describe('promise', () => {
210+
it('files.cat', (done) => {
211+
const hash = 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB'
212+
ipfs.cat(hash)
213+
.then((stream) => {
214+
stream.pipe(bl((err, bldata) => {
215+
expect(err).to.not.exist
216+
expect(bldata.toString()).to.contain('Check out some of the other files in this directory:')
217+
done()
218+
}))
219+
})
220+
.catch((err) => {
221+
expect(err).to.not.exist
222+
})
223+
})
224+
225+
it('returns error on invalid key', (done) => {
226+
const hash = 'somethingNotMultihash'
227+
ipfs.cat(hash)
228+
.then((stream) => {})
229+
.catch((err) => {
230+
expect(err).to.exist
231+
const errString = err.toString()
232+
if (errString === 'Error: invalid ipfs ref path') {
233+
expect(err.toString()).to.contain('Error: invalid ipfs ref path')
234+
}
235+
if (errString === 'Error: Invalid Key') {
236+
expect(err.toString()).to.contain('Error: Invalid Key')
237+
}
238+
done()
239+
})
240+
})
241+
242+
it('takes a buffer input', (done) => {
243+
const hash = new Buffer(bs58.decode('QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB'))
244+
ipfs.cat(hash)
245+
.then((stream) => {
246+
stream.pipe(bl((err, bldata) => {
247+
expect(err).to.not.exist
248+
expect(bldata.toString()).to.contain('Check out some of the other files in this directory:')
249+
done()
250+
}))
145251
})
146252
.catch((err) => {
147253
expect(err).to.not.exist
148254
})
255+
})
149256
})
150257
})
151258
})

0 commit comments

Comments
 (0)