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

Lines changed: 113 additions & 3 deletions
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

Lines changed: 55 additions & 0 deletions
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
}

0 commit comments

Comments
 (0)