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

Commit

Permalink
Merge pull request #337 from ipfs/feat/ipfs.files.get
Browse files Browse the repository at this point in the history
feat/ipfs.files.get
  • Loading branch information
daviddias authored Aug 10, 2016
2 parents a0ec626 + 248cd13 commit ff667a7
Show file tree
Hide file tree
Showing 16 changed files with 260 additions and 27 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
"url": "https://github.com/ipfs/js-ipfs-api"
},
"devDependencies": {
"aegir": "^5.0.1",
"aegir": "^6.0.0",
"chai": "^3.5.0",
"gulp": "^3.9.1",
"interface-ipfs-core": "^0.5.0",
"interface-ipfs-core": "^0.6.0",
"ipfsd-ctl": "^0.14.0",
"passthrough-counter": "^1.0.0",
"pre-commit": "^1.1.3",
"stream-equal": "^0.1.8",
"stream-http": "^2.3.1",
Expand Down
1 change: 1 addition & 0 deletions src/add-to-dagnode-transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = function (err, res, send, done) {
if (err) {
return done(err)
}

async.map(res, function map (entry, next) {
getDagNode(send, entry.Hash, function (err, node) {
if (err) {
Expand Down
5 changes: 5 additions & 0 deletions src/api/add-files.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const isNode = require('detect-node')
const addToDagNodesTransform = require('../add-to-dagnode-transform')

module.exports = (send) => {
Expand All @@ -9,6 +10,10 @@ module.exports = (send) => {
opts = {}
}

if (!isNode) {
return cb(new Error('Recursive uploads are not supported in the browser'))
}

if (typeof (path) !== 'string') {
return cb(new Error('"path" must be a string'))
}
Expand Down
13 changes: 1 addition & 12 deletions src/api/cat.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict'

const bs58 = require('bs58')
const isIPFS = require('is-ipfs')
const promisify = require('promisify-es6')
const cleanMultihash = require('../clean-multihash')

module.exports = (send) => {
const cat = promisify((multihash, callback) => {
Expand All @@ -15,13 +14,3 @@ module.exports = (send) => {
})
return cat
}

function cleanMultihash (multihash) {
if (!isIPFS.multihash(multihash)) {
throw new Error('not valid multihash')
}
if (Buffer.isBuffer(multihash)) {
return bs58.encode(multihash)
}
return multihash
}
30 changes: 30 additions & 0 deletions src/api/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'

const tarStreamToObjects = require('../tar-stream-to-objects')
const cleanMultihash = require('../clean-multihash')
const promisify = require('promisify-es6')

module.exports = (send) => {
return promisify(function get (path, opts, cb) {
if (typeof opts === 'function' && !cb) {
cb = opts
opts = {}
}

// opts is the real callback -- 'cb' is being injected by promisify
if (typeof opts === 'function' && typeof cb === 'function') {
cb = opts
opts = {}
}

try {
path = cleanMultihash(path)
} catch (err) {
return cb(err)
}

var sendWithTransform = send.withTransform(tarStreamToObjects)

return sendWithTransform('get', path, opts, null, cb)
})
}
15 changes: 15 additions & 0 deletions src/clean-multihash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict'

const bs58 = require('bs58')
const isIPFS = require('is-ipfs')

module.exports = function (multihash) {
if (!isIPFS.multihash(multihash)) {
throw new Error('not valid multihash')
}
if (Buffer.isBuffer(multihash)) {
return bs58.encode(multihash)
}
return multihash
}

7 changes: 7 additions & 0 deletions src/load-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function requireCommands () {
dht: require('./api/dht'),
diag: require('./api/diag'),
id: require('./api/id'),
get: require('./api/get'),
log: require('./api/log'),
ls: require('./api/ls'),
mount: require('./api/mount'),
Expand All @@ -33,6 +34,12 @@ function requireCommands () {
const files = require('./api/files')(send)
files.add = require('./api/add')(send)
files.createAddStream = require('./api/add-stream.js')(send)
files.get = require('./api/get')(send)

// aliases
cmds.add = files.add
cmds.createAddStream = files.createAddStream
cmds.get = files.get

return files
}
Expand Down
38 changes: 25 additions & 13 deletions src/request-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@ const Wreck = require('wreck')
const Qs = require('qs')
const ndjson = require('ndjson')
const getFilesStream = require('./get-files-stream')
const Counter = require('passthrough-counter')

const isNode = require('detect-node')

// -- Internal

function parseChunkedJson (res, cb) {
const parsed = []
const c = new Counter()
res
.pipe(c)
.pipe(ndjson.parse())
.on('data', parsed.push.bind(parsed))
.on('end', () => cb(null, parsed))
.on('data', (obj) => {
parsed.push(obj)
})
.on('end', () => {
cb(null, parsed)
})
}

function onRes (buffer, cb) {
function onRes (buffer, cb, uri) {
return (err, res) => {
if (err) {
return cb(err)
Expand All @@ -42,10 +49,14 @@ function onRes (buffer, cb) {
})
}

if (stream && !buffer) return cb(null, res)
if (stream && !buffer) {
return cb(null, res)
}

if (chunkedObjects) {
if (isJson) return parseChunkedJson(res, cb)
if (isJson) {
return parseChunkedJson(res, cb)
}

return Wreck.read(res, null, cb)
}
Expand All @@ -56,6 +67,11 @@ function onRes (buffer, cb) {

function requestAPI (config, path, args, qs, files, buffer, cb) {
qs = qs || {}

if (Array.isArray(files)) {
qs.recursive = true
}

if (Array.isArray(path)) path = path.join('/')
if (args && !Array.isArray(args)) args = [args]
if (args) qs.arg = args
Expand All @@ -67,10 +83,6 @@ function requestAPI (config, path, args, qs, files, buffer, cb) {
delete qs.r
}

if (!isNode && qs.recursive && path === 'add') {
return cb(new Error('Recursive uploads are not supported in the browser'))
}

qs['stream-channels'] = true

let stream
Expand Down Expand Up @@ -104,7 +116,7 @@ function requestAPI (config, path, args, qs, files, buffer, cb) {
opts.payload = stream
}

return Wreck.request(opts.method, opts.uri, opts, onRes(buffer, cb))
return Wreck.request(opts.method, opts.uri, opts, onRes(buffer, cb, opts.uri))
}

// -- Interface
Expand All @@ -128,9 +140,9 @@ exports = module.exports = function getRequestAPI (config) {
return requestAPI(config, path, args, qs, files, buffer, cb)
}

// Wraps the 'send' function such that an asynchronous transform may be
// applied to its result before passing it on to either its callback or
// promise.
// Wraps the 'send' function such that an asynchronous
// transform may be applied to its result before
// passing it on to either its callback or promise.
send.withTransform = function (transform) {
return function (path, args, qs, files, buffer, cb) {
if (typeof buffer === 'function') {
Expand Down
32 changes: 32 additions & 0 deletions src/tar-stream-to-objects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict'

const tar = require('tar-stream')
const Readable = require('readable-stream')

// transform tar stream into readable stream of
// { path: 'string', content: Readable }
module.exports = function (err, res, send, done) {
if (err) {
return done(err)
}

var ex = tar.extract()
res.pipe(ex)

var objStream = new Readable({ objectMode: true })
objStream._read = function noop () {}

ex.on('entry', function (header, stream, next) {
objStream.push({
path: header.name,
content: header.type !== 'directory' ? stream : null
})
next()
})
ex.on('finish', () => {
objStream.push(null)
})

done(null, objStream)
}

1 change: 1 addition & 0 deletions tasks/daemons.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
'use strict'
/* eslint max-nested-callbacks: ["error", 8] */ // TODO reduce nesteness

const gulp = require('gulp')
const fs = require('fs')
Expand Down
1 change: 1 addition & 0 deletions test/api/block.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-env mocha */
/* eslint max-nested-callbacks: ["error", 8] */
/* globals apiClients */
'use strict'

Expand Down
1 change: 1 addition & 0 deletions test/api/bootstrap.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-env mocha */
/* eslint max-nested-callbacks: ["error", 8] */
/* globals apiClients */
'use strict'

Expand Down
1 change: 1 addition & 0 deletions test/api/config.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-env mocha */
/* eslint max-nested-callbacks: ["error", 8] */
/* globals apiClients */
'use strict'

Expand Down
1 change: 1 addition & 0 deletions test/api/files.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-env mocha */
/* eslint max-nested-callbacks: ["error", 8] */
/* globals apiClients */
'use strict'

Expand Down
Loading

0 comments on commit ff667a7

Please sign in to comment.