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

Commit 448ffe8

Browse files
committed
Merge pull request #81 from ipfs/feature/block
jsipfs block http-api and cli
2 parents 2163c4b + 6179d4e commit 448ffe8

File tree

12 files changed

+745
-15
lines changed

12 files changed

+745
-15
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
**/node_modules/
22
**/*.log
3-
tests/repo-tests*
3+
test/repo-tests*
44

55
# Logs
66
logs

src/cli/commands/block/get.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const Command = require('ronin').Command
2+
const utils = require('../../utils')
3+
const bs58 = require('bs58')
4+
const debug = require('debug')
5+
const log = debug('cli:block')
6+
log.error = debug('cli:block:error')
7+
8+
module.exports = Command.extend({
9+
desc: 'Get a raw IPFS block',
10+
11+
options: {},
12+
13+
run: (key) => {
14+
if (!key) {
15+
throw new Error("Argument 'key' is required")
16+
}
17+
18+
utils.getIPFS((err, ipfs) => {
19+
if (err) {
20+
throw err
21+
}
22+
23+
const mh = utils.isDaemonOn()
24+
? key
25+
: new Buffer(bs58.decode(key))
26+
27+
ipfs.block.get(mh, (err, block) => {
28+
if (err) {
29+
log.error(err)
30+
throw err
31+
}
32+
33+
if (block.data) {
34+
console.log(block.data.toString())
35+
return
36+
}
37+
38+
console.log(block.toString())
39+
})
40+
})
41+
}
42+
})

src/cli/commands/block/put.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const Command = require('ronin').Command
2+
const utils = require('../../utils')
3+
const bs58 = require('bs58')
4+
const bl = require('bl')
5+
const fs = require('fs')
6+
const Block = require('ipfs-blocks').Block
7+
const debug = require('debug')
8+
const log = debug('cli:block')
9+
log.error = debug('cli:block:error')
10+
11+
function addBlock (buf) {
12+
utils.getIPFS((err, ipfs) => {
13+
if (err) {
14+
throw err
15+
}
16+
17+
if (utils.isDaemonOn()) {
18+
return ipfs.block.put(buf, (err, block) => {
19+
if (err) {
20+
log.error(err)
21+
throw err
22+
}
23+
24+
console.log(block.Key)
25+
})
26+
}
27+
28+
const block = new Block(buf)
29+
30+
ipfs.block.put(block, (err, obj) => {
31+
if (err) {
32+
log.error(err)
33+
throw err
34+
}
35+
36+
console.log(bs58.encode(block.key).toString())
37+
})
38+
})
39+
}
40+
41+
module.exports = Command.extend({
42+
desc: 'Stores input as an IPFS block',
43+
44+
options: {},
45+
46+
run: (filePath) => {
47+
if (filePath) {
48+
return addBlock(fs.readFileSync(filePath))
49+
}
50+
51+
process.stdin.pipe(bl((err, input) => {
52+
if (err) {
53+
log.error(err)
54+
throw err
55+
}
56+
57+
addBlock(input)
58+
}))
59+
}
60+
})

src/cli/commands/block/rm.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../utils')
5+
const bs58 = require('bs58')
6+
const debug = require('debug')
7+
const log = debug('cli:block')
8+
log.error = debug('cli:block:error')
9+
10+
module.exports = Command.extend({
11+
desc: 'Remove a raw IPFS block',
12+
13+
options: {},
14+
15+
run: (key) => {
16+
if (!key) {
17+
throw new Error("Argument 'key' is required")
18+
}
19+
20+
utils.getIPFS((err, ipfs) => {
21+
if (err) {
22+
throw err
23+
}
24+
25+
if (utils.isDaemonOn()) {
26+
// TODO implement this once `js-ipfs-api` supports it
27+
throw new Error('rm block with daemon running is not yet implemented')
28+
}
29+
30+
const mh = new Buffer(bs58.decode(key))
31+
32+
ipfs.block.del(mh, (err) => {
33+
if (err) {
34+
log.error(err)
35+
throw err
36+
}
37+
38+
console.log('removed', key)
39+
})
40+
})
41+
}
42+
})

src/cli/commands/block/stat.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../utils')
5+
const bs58 = require('bs58')
6+
const debug = require('debug')
7+
const log = debug('cli:block')
8+
log.error = debug('cli:block:error')
9+
10+
module.exports = Command.extend({
11+
desc: 'Print information of a raw IPFS block',
12+
13+
options: {},
14+
15+
run: (key) => {
16+
if (!key) {
17+
throw new Error("Argument 'key' is required")
18+
}
19+
20+
utils.getIPFS((err, ipfs) => {
21+
if (err) {
22+
throw err
23+
}
24+
25+
const mh = utils.isDaemonOn()
26+
? key
27+
: new Buffer(bs58.decode(key))
28+
29+
ipfs.block.stat(mh, (err, block) => {
30+
if (err) {
31+
log.error(err)
32+
throw err
33+
}
34+
35+
if (typeof block.Key !== 'string') {
36+
block.Key = bs58.encode(block.Key).toString()
37+
}
38+
39+
Object.keys(block).forEach((key) => {
40+
console.log(`${key}: ${block[key]}`)
41+
})
42+
})
43+
})
44+
}
45+
})

src/http-api/resources/block.js

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
'use strict'
2+
3+
const ipfs = require('./../index.js').ipfs
4+
const bs58 = require('bs58')
5+
const multipart = require('ipfs-multipart')
6+
const Block = require('ipfs-blocks').Block
7+
const debug = require('debug')
8+
const log = debug('http-api:block')
9+
log.error = debug('http-api:block:error')
10+
11+
exports = module.exports
12+
13+
// common pre request handler that parses the args and returns `key` which is assigned to `request.pre.args`
14+
exports.parseKey = (request, reply) => {
15+
if (!request.query.arg) {
16+
return reply("Argument 'key' is required").code(400).takeover()
17+
}
18+
19+
try {
20+
return reply({
21+
key: new Buffer(bs58.decode(request.query.arg))
22+
})
23+
} catch (err) {
24+
log.error(err)
25+
return reply({
26+
Message: 'Not a valid hash',
27+
Code: 0
28+
}).code(500).takeover()
29+
}
30+
}
31+
32+
exports.get = {
33+
// uses common parseKey method that returns a `key`
34+
parseArgs: exports.parseKey,
35+
36+
// main route handler which is called after the above `parseArgs`, but only if the args were valid
37+
handler: (request, reply) => {
38+
const key = request.pre.args.key
39+
40+
ipfs.block.get(key, (err, block) => {
41+
if (err) {
42+
log.error(err)
43+
return reply({
44+
Message: 'Failed to get block: ' + err,
45+
Code: 0
46+
}).code(500)
47+
}
48+
49+
return reply(block.data.toString())
50+
})
51+
}
52+
}
53+
54+
exports.put = {
55+
// pre request handler that parses the args and returns `data` which is assigned to `request.pre.args`
56+
parseArgs: (request, reply) => {
57+
if (!request.payload) {
58+
return reply("File argument 'data' is required").code(400).takeover()
59+
}
60+
61+
const parser = multipart.reqParser(request.payload)
62+
var file
63+
64+
parser.on('file', (fileName, fileStream) => {
65+
fileStream.on('data', (data) => {
66+
file = data
67+
})
68+
})
69+
70+
parser.on('end', () => {
71+
if (!file) {
72+
return reply("File argument 'data' is required").code(400).takeover()
73+
}
74+
75+
return reply({
76+
data: file.toString()
77+
})
78+
})
79+
},
80+
81+
// main route handler which is called after the above `parseArgs`, but only if the args were valid
82+
handler: (request, reply) => {
83+
const data = request.pre.args.data
84+
85+
const block = new Block(data)
86+
87+
ipfs.block.put(block, (err) => {
88+
if (err) {
89+
log.error(err)
90+
return reply({
91+
Message: 'Failed to put block: ' + err,
92+
Code: 0
93+
}).code(500)
94+
}
95+
96+
return reply({
97+
Key: bs58.encode(block.key).toString(),
98+
Size: block.data.length
99+
})
100+
})
101+
}
102+
}
103+
104+
exports.del = {
105+
// uses common parseKey method that returns a `key`
106+
parseArgs: exports.parseKey,
107+
108+
// main route handler which is called after the above `parseArgs`, but only if the args were valid
109+
handler: (request, reply) => {
110+
const key = request.pre.args.key
111+
112+
ipfs.block.del(key, (err, block) => {
113+
if (err) {
114+
log.error(err)
115+
return reply({
116+
Message: 'Failed to get block stats: ' + err,
117+
Code: 0
118+
}).code(500)
119+
}
120+
121+
return reply()
122+
})
123+
}
124+
}
125+
126+
exports.stat = {
127+
// uses common parseKey method that returns a `key`
128+
parseArgs: exports.parseKey,
129+
130+
// main route handler which is called after the above `parseArgs`, but only if the args were valid
131+
handler: (request, reply) => {
132+
const key = request.pre.args.key
133+
134+
ipfs.block.stat(key, (err, block) => {
135+
if (err) {
136+
log.error(err)
137+
return reply({
138+
Message: 'Failed to get block stats: ' + err,
139+
Code: 0
140+
}).code(500)
141+
}
142+
143+
return reply({
144+
Key: bs58.encode(block.Key).toString(),
145+
Size: block.Size
146+
})
147+
})
148+
}
149+
}

0 commit comments

Comments
 (0)