-
Notifications
You must be signed in to change notification settings - Fork 1.2k
jsipfs block http-api and cli #81
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
**/node_modules/ | ||
**/*.log | ||
tests/repo-tests* | ||
test/repo-tests* | ||
|
||
# Logs | ||
logs | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const Command = require('ronin').Command | ||
const utils = require('../../utils') | ||
const bs58 = require('bs58') | ||
const debug = require('debug') | ||
const log = debug('cli:block') | ||
log.error = debug('cli:block:error') | ||
|
||
module.exports = Command.extend({ | ||
desc: 'Get a raw IPFS block', | ||
|
||
options: {}, | ||
|
||
run: (key) => { | ||
if (!key) { | ||
throw new Error("Argument 'key' is required") | ||
} | ||
|
||
utils.getIPFS((err, ipfs) => { | ||
if (err) { | ||
throw err | ||
} | ||
|
||
const mh = utils.isDaemonOn() | ||
? key | ||
: new Buffer(bs58.decode(key)) | ||
|
||
ipfs.block.get(mh, (err, block) => { | ||
if (err) { | ||
log.error(err) | ||
throw err | ||
} | ||
|
||
if (block.data) { | ||
console.log(block.data.toString()) | ||
return | ||
} | ||
|
||
console.log(block.toString()) | ||
}) | ||
}) | ||
} | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
const Command = require('ronin').Command | ||
const utils = require('../../utils') | ||
const bs58 = require('bs58') | ||
const bl = require('bl') | ||
const fs = require('fs') | ||
const Block = require('ipfs-blocks').Block | ||
const debug = require('debug') | ||
const log = debug('cli:block') | ||
log.error = debug('cli:block:error') | ||
|
||
function addBlock (buf) { | ||
utils.getIPFS((err, ipfs) => { | ||
if (err) { | ||
throw err | ||
} | ||
|
||
if (utils.isDaemonOn()) { | ||
return ipfs.block.put(buf, (err, block) => { | ||
if (err) { | ||
log.error(err) | ||
throw err | ||
} | ||
|
||
console.log(block.Key) | ||
}) | ||
} | ||
|
||
const block = new Block(buf) | ||
|
||
ipfs.block.put(block, (err, obj) => { | ||
if (err) { | ||
log.error(err) | ||
throw err | ||
} | ||
|
||
console.log(bs58.encode(block.key).toString()) | ||
}) | ||
}) | ||
} | ||
|
||
module.exports = Command.extend({ | ||
desc: 'Stores input as an IPFS block', | ||
|
||
options: {}, | ||
|
||
run: (filePath) => { | ||
if (filePath) { | ||
return addBlock(fs.readFileSync(filePath)) | ||
} | ||
|
||
process.stdin.pipe(bl((err, input) => { | ||
if (err) { | ||
log.error(err) | ||
throw err | ||
} | ||
|
||
addBlock(input) | ||
})) | ||
} | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
'use strict' | ||
|
||
const Command = require('ronin').Command | ||
const utils = require('../../utils') | ||
const bs58 = require('bs58') | ||
const debug = require('debug') | ||
const log = debug('cli:block') | ||
log.error = debug('cli:block:error') | ||
|
||
module.exports = Command.extend({ | ||
desc: 'Remove a raw IPFS block', | ||
|
||
options: {}, | ||
|
||
run: (key) => { | ||
if (!key) { | ||
throw new Error("Argument 'key' is required") | ||
} | ||
|
||
utils.getIPFS((err, ipfs) => { | ||
if (err) { | ||
throw err | ||
} | ||
|
||
if (utils.isDaemonOn()) { | ||
// TODO implement this once `js-ipfs-api` supports it | ||
throw new Error('rm block with daemon running is not yet implemented') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why? We have 'del', right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no ipfs block del or rm on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good. We definitely need to push it to be part of the spec (go-ipfs can delete things on disk directly, js-ipfs-api has to interact with disk through the blob-store, always) |
||
} | ||
|
||
const mh = new Buffer(bs58.decode(key)) | ||
|
||
ipfs.block.del(mh, (err) => { | ||
if (err) { | ||
log.error(err) | ||
throw err | ||
} | ||
|
||
console.log('removed', key) | ||
}) | ||
}) | ||
} | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
'use strict' | ||
|
||
const Command = require('ronin').Command | ||
const utils = require('../../utils') | ||
const bs58 = require('bs58') | ||
const debug = require('debug') | ||
const log = debug('cli:block') | ||
log.error = debug('cli:block:error') | ||
|
||
module.exports = Command.extend({ | ||
desc: 'Print information of a raw IPFS block', | ||
|
||
options: {}, | ||
|
||
run: (key) => { | ||
if (!key) { | ||
throw new Error("Argument 'key' is required") | ||
} | ||
|
||
utils.getIPFS((err, ipfs) => { | ||
if (err) { | ||
throw err | ||
} | ||
|
||
const mh = utils.isDaemonOn() | ||
? key | ||
: new Buffer(bs58.decode(key)) | ||
|
||
ipfs.block.stat(mh, (err, block) => { | ||
if (err) { | ||
log.error(err) | ||
throw err | ||
} | ||
|
||
if (typeof block.Key !== 'string') { | ||
block.Key = bs58.encode(block.Key).toString() | ||
} | ||
|
||
Object.keys(block).forEach((key) => { | ||
console.log(`${key}: ${block[key]}`) | ||
}) | ||
}) | ||
}) | ||
} | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
'use strict' | ||
|
||
const ipfs = require('./../index.js').ipfs | ||
const bs58 = require('bs58') | ||
const multipart = require('ipfs-multipart') | ||
const Block = require('ipfs-blocks').Block | ||
const debug = require('debug') | ||
const log = debug('http-api:block') | ||
log.error = debug('http-api:block:error') | ||
|
||
exports = module.exports | ||
|
||
// common pre request handler that parses the args and returns `key` which is assigned to `request.pre.args` | ||
exports.parseKey = (request, reply) => { | ||
if (!request.query.arg) { | ||
return reply("Argument 'key' is required").code(400).takeover() | ||
} | ||
|
||
try { | ||
return reply({ | ||
key: new Buffer(bs58.decode(request.query.arg)) | ||
}) | ||
} catch (err) { | ||
log.error(err) | ||
return reply({ | ||
Message: 'Not a valid hash', | ||
Code: 0 | ||
}).code(500).takeover() | ||
} | ||
} | ||
|
||
exports.get = { | ||
// uses common parseKey method that returns a `key` | ||
parseArgs: exports.parseKey, | ||
|
||
// main route handler which is called after the above `parseArgs`, but only if the args were valid | ||
handler: (request, reply) => { | ||
const key = request.pre.args.key | ||
|
||
ipfs.block.get(key, (err, block) => { | ||
if (err) { | ||
log.error(err) | ||
return reply({ | ||
Message: 'Failed to get block: ' + err, | ||
Code: 0 | ||
}).code(500) | ||
} | ||
|
||
return reply(block.data.toString()) | ||
}) | ||
} | ||
} | ||
|
||
exports.put = { | ||
// pre request handler that parses the args and returns `data` which is assigned to `request.pre.args` | ||
parseArgs: (request, reply) => { | ||
if (!request.payload) { | ||
return reply("File argument 'data' is required").code(400).takeover() | ||
} | ||
|
||
const parser = multipart.reqParser(request.payload) | ||
var file | ||
|
||
parser.on('file', (fileName, fileStream) => { | ||
fileStream.on('data', (data) => { | ||
file = data | ||
}) | ||
}) | ||
|
||
parser.on('end', () => { | ||
if (!file) { | ||
return reply("File argument 'data' is required").code(400).takeover() | ||
} | ||
|
||
return reply({ | ||
data: file.toString() | ||
}) | ||
}) | ||
}, | ||
|
||
// main route handler which is called after the above `parseArgs`, but only if the args were valid | ||
handler: (request, reply) => { | ||
const data = request.pre.args.data | ||
|
||
const block = new Block(data) | ||
|
||
ipfs.block.put(block, (err) => { | ||
if (err) { | ||
log.error(err) | ||
return reply({ | ||
Message: 'Failed to put block: ' + err, | ||
Code: 0 | ||
}).code(500) | ||
} | ||
|
||
return reply({ | ||
Key: bs58.encode(block.key).toString(), | ||
Size: block.data.length | ||
}) | ||
}) | ||
} | ||
} | ||
|
||
exports.del = { | ||
// uses common parseKey method that returns a `key` | ||
parseArgs: exports.parseKey, | ||
|
||
// main route handler which is called after the above `parseArgs`, but only if the args were valid | ||
handler: (request, reply) => { | ||
const key = request.pre.args.key | ||
|
||
ipfs.block.del(key, (err, block) => { | ||
if (err) { | ||
log.error(err) | ||
return reply({ | ||
Message: 'Failed to get block stats: ' + err, | ||
Code: 0 | ||
}).code(500) | ||
} | ||
|
||
return reply() | ||
}) | ||
} | ||
} | ||
|
||
exports.stat = { | ||
// uses common parseKey method that returns a `key` | ||
parseArgs: exports.parseKey, | ||
|
||
// main route handler which is called after the above `parseArgs`, but only if the args were valid | ||
handler: (request, reply) => { | ||
const key = request.pre.args.key | ||
|
||
ipfs.block.stat(key, (err, block) => { | ||
if (err) { | ||
log.error(err) | ||
return reply({ | ||
Message: 'Failed to get block stats: ' + err, | ||
Code: 0 | ||
}).code(500) | ||
} | ||
|
||
return reply({ | ||
Key: bs58.encode(block.Key).toString(), | ||
Size: block.Size | ||
}) | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
soon all these hacks will be gone (once we get core spec \o/)