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

Commit 3751be4

Browse files
committed
Merge pull request #25 from nginnever/master
Data Exporting
2 parents 94daa32 + 9585a9f commit 3751be4

File tree

63 files changed

+238
-321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+238
-321
lines changed

src/index.js

+113-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const FixedSizeChunker = require('./chunker-fixed-size')
99
const through2 = require('through2')
1010
const UnixFS = require('ipfs-unixfs')
1111
const async = require('async')
12+
const events = require('events')
13+
const Readable = require('stream').Readable
14+
const pathj = require('path')
1215

1316
exports = module.exports
1417

@@ -206,7 +209,6 @@ exports.import = (target, dagService, options, callback) => {
206209
leafSize: raw.fileSize(),
207210
Name: ''
208211
})
209-
210212
cb()
211213
})
212214
}, (cb) => {
@@ -249,6 +251,114 @@ exports.import = (target, dagService, options, callback) => {
249251
// function streamImporter (stream, callback) {}
250252
}
251253

252-
exports.export = function () {
253-
// export into files by hash
254+
exports.export = function (hash, dagService, options, callback) {
255+
if (typeof options === 'function') {
256+
callback = options
257+
options = {}
258+
}
259+
260+
const ee = new events.EventEmitter()
261+
dagService.get(hash, (err, fetchedNode) => {
262+
if (err) {
263+
if (callback) {
264+
return callback(err)
265+
}
266+
return
267+
}
268+
const data = UnixFS.unmarshal(fetchedNode.data)
269+
const type = data.type
270+
if (type === 'directory') {
271+
dirExporter(fetchedNode, hash, callback)
272+
}
273+
if (type === 'file') {
274+
fileExporter(fetchedNode, hash, false, callback)
275+
}
276+
})
277+
return ee
278+
279+
function fileExporter (node, name, dir, callback) {
280+
if (typeof dir === 'function') { callback = dir; dir = {} }
281+
var rs = new Readable()
282+
if (node.links.length === 0) {
283+
const unmarshaledData = UnixFS.unmarshal(node.data)
284+
ee.emit('file', { stream: rs, path: name, dir: dir })
285+
rs.push(unmarshaledData.data)
286+
rs.push(null)
287+
if (callback) {
288+
callback()
289+
}
290+
return
291+
} else {
292+
ee.emit('file', { stream: rs, path: name, dir: dir })
293+
var init = false
294+
rs._read = () => {
295+
if (init) {
296+
return
297+
}
298+
init = true
299+
async.forEachSeries(node.links, (link, callback) => {
300+
dagService.get(link.hash, (err, res) => {
301+
if (err) {
302+
callback(err)
303+
}
304+
var unmarshaledData = UnixFS.unmarshal(res.data)
305+
rs.push(unmarshaledData.data)
306+
callback()
307+
})
308+
}, (err) => {
309+
if (err) {
310+
if (callback) {
311+
return callback(err)
312+
}
313+
return
314+
}
315+
rs.push(null)
316+
if (callback) {
317+
callback()
318+
}
319+
return
320+
})
321+
}
322+
}
323+
}
324+
325+
function dirExporter (node, name, callback) {
326+
var rs = new Readable()
327+
if (node.links.length === 0) {
328+
rs.push(node.data)
329+
rs.push(null)
330+
ee.emit('file', {stream: rs, path: name})
331+
if (callback) {
332+
callback()
333+
}
334+
return
335+
} else {
336+
async.forEachSeries(node.links, (link, callback) => {
337+
dagService.get(link.hash, (err, res) => {
338+
if (err) {
339+
callback(err)
340+
}
341+
var unmarshaledData = UnixFS.unmarshal(res.data)
342+
if (unmarshaledData.type === 'file') {
343+
return (fileExporter(res, pathj.join(name, link.name), callback))
344+
}
345+
if (unmarshaledData.type === 'directory') {
346+
return (dirExporter(res, pathj.join(name, link.name), callback))
347+
}
348+
callback()
349+
})
350+
}, (err) => {
351+
if (err) {
352+
if (callback) {
353+
return callback(err)
354+
}
355+
return
356+
}
357+
if (callback) {
358+
callback()
359+
}
360+
return
361+
})
362+
}
363+
}
254364
}

test/buffer-test.js

+55
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,60 @@ module.exports = function (repo) {
8282
})
8383
})
8484
})
85+
86+
it('export a file with no links', (done) => {
87+
const hash = 'QmQmZQxSKQppbsWfVzBvg59Cn3DKtsNVQ94bjAxg2h3Lb8'
88+
const bs = new BlockService(repo)
89+
const ds = new DAGService(bs)
90+
const testExport = importer.export(hash, ds)
91+
testExport.on('file', (data) => {
92+
ds.get(hash, (err, fetchedNode) => {
93+
expect(err).to.not.exist
94+
const unmarsh = UnixFS.unmarshal(fetchedNode.data)
95+
expect(unmarsh.data).to.deep.equal(data.stream._readableState.buffer[0])
96+
done()
97+
})
98+
})
99+
})
100+
101+
it('export a small file with links', (done) => {
102+
const hash = 'QmW7BDxEbGqxxSYVtn3peNPQgdDXbWkoQ6J1EFYAEuQV3Q'
103+
const bs = new BlockService(repo)
104+
const ds = new DAGService(bs)
105+
const testExport = importer.export(hash, ds)
106+
testExport.on('file', (data) => {
107+
expect(data.stream).to.exist
108+
done()
109+
})
110+
})
111+
112+
it('export a large file > 5mb', (done) => {
113+
const hash = 'QmRQgufjp9vLE8XK2LGKZSsPCFCF6e4iynCQtNB5X2HBKE'
114+
const bs = new BlockService(repo)
115+
const ds = new DAGService(bs)
116+
const testExport = importer.export(hash, ds)
117+
testExport.on('file', (data) => {
118+
expect(data.stream).to.exist
119+
done()
120+
})
121+
})
122+
123+
it('export a directory', (done) => {
124+
const hash = 'QmWChcSFMNcFkfeJtNd8Yru1rE6PhtCRfewi1tMwjkwKjN'
125+
const bs = new BlockService(repo)
126+
const ds = new DAGService(bs)
127+
const testExport = importer.export(hash, ds)
128+
var fs = []
129+
testExport.on('file', (data) => {
130+
fs.push(data)
131+
})
132+
setTimeout(() => {
133+
expect(fs[0].path).to.equal('QmWChcSFMNcFkfeJtNd8Yru1rE6PhtCRfewi1tMwjkwKjN/200Bytes.txt')
134+
expect(fs[1].path).to.equal('QmWChcSFMNcFkfeJtNd8Yru1rE6PhtCRfewi1tMwjkwKjN/dir-another')
135+
expect(fs[2].path).to.equal('QmWChcSFMNcFkfeJtNd8Yru1rE6PhtCRfewi1tMwjkwKjN/level-1/200Bytes.txt')
136+
expect(fs[3].path).to.equal('QmWChcSFMNcFkfeJtNd8Yru1rE6PhtCRfewi1tMwjkwKjN/level-1/level-2')
137+
done()
138+
}, 1000)
139+
})
85140
})
86141
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
5
2+
" $��G�,�A�4{���x�Z/.����D`� 200Bytes.txt�/
3+
" Y��9_)a���˹2�R�m�Ŗke�9��level-2
4+


test/repo-example/blocks/122074d4/122074d42168a1c62b4796e77a9591d8f1fab4685f6674eabecc7773913363b45301.data

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
5
2+
" $��G�,�A�4{���x�Z/.����D`� 200Bytes.txt�3
3+
" Y��9_)a���˹2�R�m�Ŗke�9�� dir-another0
4+
" Ty�5;_9Yf�q��F�Lhyl���/��level-1�
5+


test/repo-tests1457120896998/blocks/1220120f/1220120f6af601d46e10b2d2e11ed71c55d25f3042c22501e41d1246e7a1e9d3d8ec.data

-28
This file was deleted.

test/repo-tests1457120896998/blocks/122031e7/122031e7a41c15d03feb8cd793c3348ea3b310512d7767a9abfbd7a928a85e977173.data

-4
This file was deleted.

test/repo-tests1457120896998/blocks/12204a5a/12204a5a95586f52e25811cf214677160e64383755a8c5163ba3c053c3b65777ed16.data

-4
This file was deleted.

test/repo-tests1457120896998/blocks/122052c6/122052c63c7775396b3f82c639977a7223c2d96a9f70b5fd8b1d513f8c5b69dcaed4.data

-23
This file was deleted.

test/repo-tests1457120896998/blocks/12205994/122059948439065f29619ef41280cbb932be52c56d99c5966b65e0111239f098bbef.data

-2
This file was deleted.

test/repo-tests1457120896998/blocks/122062ce/122062ce1f2c91a13a97b596e873b5a3346a644605d7614dca53cd3a59f7385a8abb.data

-114
This file was deleted.

0 commit comments

Comments
 (0)