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

Commit d329092

Browse files
Merge pull request #204 from ipfs/files-core-fix
Files core fix
2 parents 93445ee + 56f965d commit d329092

File tree

13 files changed

+382
-72
lines changed

13 files changed

+382
-72
lines changed

package.json

+15-12
Original file line numberDiff line numberDiff line change
@@ -38,45 +38,48 @@
3838
"homepage": "https://github.com/ipfs/js-ipfs#readme",
3939
"devDependencies": {
4040
"aegir": "^3.0.1",
41-
"async": "^2.0.0-rc.3",
41+
"async": "^2.0.0-rc.4",
4242
"buffer-loader": "0.0.1",
4343
"chai": "^3.5.0",
4444
"expose-loader": "^0.7.1",
4545
"form-data": "^1.0.0-rc3",
4646
"idb-plus-blob-store": "^1.1.2",
47-
"lodash": "^4.11.1",
48-
"mocha": "^2.3.4",
47+
"lodash": "^4.11.2",
48+
"mocha": "^2.4.5",
4949
"ncp": "^2.0.0",
5050
"nexpect": "^0.5.0",
5151
"pre-commit": "^1.1.2",
52-
"rimraf": "^2.4.4",
52+
"rimraf": "^2.5.2",
5353
"stream-to-promise": "^1.1.0",
5454
"transform-loader": "^0.2.3"
5555
},
5656
"dependencies": {
5757
"babel-runtime": "^6.6.1",
5858
"bl": "^1.1.2",
59-
"boom": "^3.1.1",
59+
"boom": "^3.1.2",
6060
"bs58": "^3.0.0",
6161
"debug": "^2.2.0",
6262
"fs-blob-store": "^5.2.1",
6363
"glob": "^7.0.3",
6464
"hapi": "^13.3.0",
65-
"ipfs-api": "^3.0.1",
65+
"ipfs-api": "^3.0.2",
6666
"ipfs-block": "^0.3.0",
67-
"ipfs-block-service": "^0.3.0",
68-
"ipfs-data-importing": "^0.3.3",
67+
"ipfs-block-service": "^0.4.0",
6968
"ipfs-merkle-dag": "^0.5.0",
7069
"ipfs-multipart": "^0.1.0",
7170
"ipfs-repo": "^0.8.0",
72-
"joi": "^8.0.2",
71+
"ipfs-unixfs-engine": "^0.6.1",
72+
"joi": "^8.0.5",
7373
"libp2p-ipfs": "^0.3.3",
74+
"libp2p-swarm": "^0.12.5",
7475
"lodash.get": "^4.2.1",
75-
"lodash.set": "^4.0.0",
76-
"multiaddr": "^1.3.0",
76+
"lodash.set": "^4.1.0",
77+
"multiaddr": "^1.4.1",
78+
"path-exists": "^3.0.0",
7779
"peer-book": "0.1.0",
7880
"peer-id": "^0.6.6",
7981
"peer-info": "^0.6.2",
82+
"readable-stream": "1.1.13",
8083
"ronin": "^0.3.11",
8184
"temp": "^0.8.3"
8285
},
@@ -112,4 +115,4 @@
112115
"kumavis <kumavis@users.noreply.github.com>",
113116
"nginnever <ginneversource@gmail.com>"
114117
]
115-
}
118+
}

src/cli/commands/files/add.js

+72-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,39 @@
11
'use strict'
22

33
const Command = require('ronin').Command
4-
const IPFS = require('../../../core')
4+
const utils = require('../../utils')
55
const debug = require('debug')
66
const log = debug('cli:version')
77
log.error = debug('cli:version:error')
88
const bs58 = require('bs58')
9+
const fs = require('fs')
10+
const async = require('async')
11+
const path = require('path')
12+
const glob = require('glob')
13+
14+
function checkPath (inPath, recursive) {
15+
// This function is to check for the following possible inputs
16+
// 1) "." add the cwd but throw error for no recursion flag
17+
// 2) "." -r return the cwd
18+
// 3) "/some/path" but throw error for no recursion
19+
// 4) "/some/path" -r
20+
// 5) No path, throw err
21+
// 6) filename.type return the cwd + filename
22+
23+
if (!inPath) {
24+
throw new Error('Error: Argument \'path\' is required')
25+
}
26+
27+
if (inPath === '.') {
28+
inPath = process.cwd()
29+
}
30+
31+
if (fs.statSync(inPath).isDirectory() && recursive === false) {
32+
throw new Error(`Error: ${inPath} is a directory, use the '-r' flag to specify directories`)
33+
}
34+
35+
return inPath
36+
}
937

1038
module.exports = Command.extend({
1139
desc: 'Add a file to IPFS using the UnixFS data format',
@@ -18,16 +46,51 @@ module.exports = Command.extend({
1846
}
1947
},
2048

21-
run: (recursive, path) => {
22-
var node = new IPFS()
23-
path = process.cwd() + '/' + path
24-
node.files.add(path, {
25-
recursive: recursive
26-
}, (err, stats) => {
49+
run: (recursive, inPath) => {
50+
let rs
51+
52+
inPath = checkPath(inPath, recursive)
53+
54+
glob(path.join(inPath, '/**/*'), (err, res) => {
2755
if (err) {
28-
return console.log(err)
56+
throw err
2957
}
30-
console.log('added', bs58.encode(stats.Hash).toString(), stats.Name)
58+
utils.getIPFS((err, ipfs) => {
59+
if (err) {
60+
throw err
61+
}
62+
const i = ipfs.files.add()
63+
var filePair
64+
i.on('data', (file) => {
65+
console.log('added', bs58.encode(file.multihash).toString(), file.path)
66+
})
67+
i.once('end', () => {
68+
return
69+
})
70+
if (res.length !== 0) {
71+
const index = inPath.lastIndexOf('/')
72+
async.eachLimit(res, 10, (element, callback) => {
73+
if (!fs.statSync(element).isDirectory()) {
74+
i.write({
75+
path: element.substring(index + 1, element.length),
76+
stream: fs.createReadStream(element)
77+
})
78+
}
79+
callback()
80+
}, (err) => {
81+
if (err) {
82+
throw err
83+
}
84+
i.end()
85+
})
86+
} else {
87+
rs = fs.createReadStream(inPath)
88+
inPath = inPath.substring(inPath.lastIndexOf('/') + 1, inPath.length)
89+
filePair = {path: inPath, stream: rs}
90+
i.write(filePair)
91+
i.end()
92+
}
93+
})
3194
})
3295
}
3396
})

src/cli/commands/files/cat.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const debug = require('debug')
5+
const utils = require('../../utils')
6+
const log = debug('cli:files')
7+
log.error = debug('cli:files:error')
8+
9+
module.exports = Command.extend({
10+
desc: 'Download IPFS objects',
11+
12+
options: {},
13+
14+
run: (path, options) => {
15+
if (!path) {
16+
throw new Error("Argument 'path' is required")
17+
}
18+
if (!options) {
19+
options = {}
20+
}
21+
utils.getIPFS((err, ipfs) => {
22+
if (err) {
23+
throw err
24+
}
25+
ipfs.files.cat(path, (err, res) => {
26+
if (err) {
27+
throw (err)
28+
}
29+
if (res) {
30+
res.on('file', (data) => {
31+
data.stream.pipe(process.stdout)
32+
})
33+
}
34+
})
35+
})
36+
}
37+
})

src/cli/commands/files/get.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const debug = require('debug')
5+
const utils = require('../../utils')
6+
const log = debug('cli:files')
7+
log.error = debug('cli:files:error')
8+
var fs = require('fs')
9+
const path = require('path')
10+
const pathExists = require('path-exists')
11+
12+
function checkArgs (hash, outPath) {
13+
if (!hash) {
14+
throw new Error("Argument 'path' is required")
15+
}
16+
// format the output directory
17+
if (!outPath) {
18+
return process.cwd()
19+
}
20+
21+
if (!outPath.endsWith('/')) {
22+
outPath += '/'
23+
}
24+
25+
if (!outPath.startsWith('/')) {
26+
outPath = path.join('/', outPath)
27+
}
28+
29+
return outPath
30+
}
31+
32+
function ensureDir (dir, cb) {
33+
pathExists(dir)
34+
.then((exists) => {
35+
if (!exists) {
36+
fs.mkdir(dir, cb)
37+
} else {
38+
cb()
39+
}
40+
})
41+
.catch(cb)
42+
}
43+
44+
function fileHandler (result, dir) {
45+
return function onFile (file) {
46+
// Check to see if the result is in a directory
47+
if (file.path.lastIndexOf('/') === -1) {
48+
const dirPath = path.join(dir, file.path)
49+
// Check to see if the result is a directory
50+
if (file.dir === false) {
51+
file.stream.pipe(fs.createWriteStream(dirPath))
52+
} else {
53+
ensureDir(dirPath, (err) => {
54+
if (err) {
55+
throw err
56+
}
57+
})
58+
}
59+
} else {
60+
const filePath = file.path.substring(0, file.path.lastIndexOf('/') + 1)
61+
const dirPath = path.join(dir, filePath)
62+
ensureDir(dirPath, (err) => {
63+
if (err) {
64+
throw err
65+
}
66+
67+
file.stream.pipe(fs.createWriteStream(dirPath))
68+
})
69+
}
70+
}
71+
}
72+
73+
module.exports = Command.extend({
74+
desc: 'Download IPFS objects',
75+
76+
run: (hash, outPath) => {
77+
const dir = checkArgs(hash, outPath)
78+
79+
utils.getIPFS((err, ipfs) => {
80+
if (err) {
81+
throw err
82+
}
83+
ipfs.files.get(hash, (err, result) => {
84+
if (err) {
85+
throw err
86+
}
87+
result.on('file', fileHandler(result, dir))
88+
})
89+
})
90+
}
91+
})

src/core/ipfs/files.js

+50-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,57 @@
11
'use strict'
22

3-
const importer = require('ipfs-data-importing').import
3+
const Importer = require('ipfs-unixfs-engine').importer
4+
const Exporter = require('ipfs-unixfs-engine').exporter
5+
const UnixFS = require('ipfs-unixfs')
46

5-
module.exports = function libp2p (self) {
7+
module.exports = function files (self) {
68
return {
7-
add: (path, options, callback) => {
8-
options.path = path
9-
options.dagService = self._dagS
10-
importer(options, callback)
9+
add: (arr, callback) => {
10+
if (typeof arr === 'function') {
11+
callback = arr
12+
arr = undefined
13+
}
14+
if (callback === undefined) {
15+
callback = function noop () {}
16+
}
17+
if (arr === undefined) {
18+
return new Importer(self._dagS)
19+
}
20+
21+
const i = new Importer(self._dagS)
22+
const res = []
23+
24+
i.on('data', (info) => {
25+
res.push(info)
26+
})
27+
28+
i.once('end', () => {
29+
callback(null, res)
30+
})
31+
32+
arr.forEach((tuple) => {
33+
i.write(tuple)
34+
})
35+
36+
i.end()
37+
},
38+
cat: (hash, callback) => {
39+
self._dagS.get(hash, (err, fetchedNode) => {
40+
if (err) {
41+
return callback(err, null)
42+
}
43+
const data = UnixFS.unmarshal(fetchedNode.data)
44+
if (data.type === 'directory') {
45+
callback('This dag node is a directory', null)
46+
} else {
47+
const exportEvent = Exporter(hash, self._dagS)
48+
callback(null, exportEvent)
49+
}
50+
})
51+
},
52+
get: (hash, callback) => {
53+
var exportFile = Exporter(hash, self._dagS)
54+
callback(null, exportFile)
1155
}
1256
}
1357
}

0 commit comments

Comments
 (0)