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

feat/ipfs.files.get #337

Merged
merged 6 commits into from
Aug 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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