2015-11-11 15:51:07 +01:00
|
|
|
/*
|
|
|
|
This file contains the IPFS Boards API. It's a simple abstraction over the
|
|
|
|
js-ipfs-api that also provides an additional level of caching for this
|
|
|
|
particular application. Let's hope it turns out decent
|
2015-11-14 15:03:38 +01:00
|
|
|
|
|
|
|
Needs to be browserified to work in the browser
|
2015-11-11 15:51:07 +01:00
|
|
|
*/
|
|
|
|
|
2015-11-14 18:26:56 +01:00
|
|
|
// EventEmitter used to communicate with clients
|
2015-11-14 15:03:38 +01:00
|
|
|
var EventEmitter = require('wolfy87-eventemitter')
|
2015-11-19 12:59:19 +01:00
|
|
|
var asyncjs = require('async')
|
2015-12-12 17:51:03 +01:00
|
|
|
var semver = require('semver')
|
2015-12-19 13:52:38 +01:00
|
|
|
var wreck = require('wreck')
|
2015-11-14 15:03:38 +01:00
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
function asObj (str, done) {
|
|
|
|
if (str.toString) str = str.toString()
|
|
|
|
if (typeof str === 'string') {
|
2015-11-19 12:59:19 +01:00
|
|
|
var obj
|
|
|
|
try {
|
|
|
|
obj = JSON.parse(str)
|
|
|
|
} catch (e) {
|
2015-12-14 00:29:25 +01:00
|
|
|
console.log('error parsing:', str, 'Error:', e)
|
|
|
|
return done(e, undefined)
|
2015-11-19 12:59:19 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
done(null, obj)
|
2015-11-19 12:59:19 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
console.log('not string:', str)
|
|
|
|
done('not string: ' + str, undefined)
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
function replyAsObj (res, isJson, done) {
|
|
|
|
if (res.readable) {
|
2015-11-11 09:18:36 +01:00
|
|
|
// Is a stream
|
2015-11-14 12:06:37 +01:00
|
|
|
console.log('got stream')
|
2015-11-11 09:18:36 +01:00
|
|
|
res.setEncoding('utf8')
|
|
|
|
var data = ''
|
2015-12-14 00:29:25 +01:00
|
|
|
res.on('data', d => {
|
|
|
|
console.log('got stream data:', d)
|
2015-11-11 09:18:36 +01:00
|
|
|
data += d
|
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
res.on('end', () => {
|
|
|
|
if (isJson) {
|
|
|
|
asObj(data, done)
|
2015-11-11 09:18:36 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
done(null, data)
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
} else if (res.split || res.toString) {
|
|
|
|
// console.log('got string or buffer:',res)
|
|
|
|
if (res.toString) res = res.toString()
|
2015-11-11 09:18:36 +01:00
|
|
|
// Is a string
|
2015-12-14 00:29:25 +01:00
|
|
|
if (isJson) {
|
|
|
|
asObj(res, done)
|
2015-11-11 09:18:36 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
done(null, res)
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
function BoardsAPI (ipfs) {
|
2015-11-11 09:18:36 +01:00
|
|
|
this.ipfs = ipfs
|
2015-11-18 16:56:07 +01:00
|
|
|
this.version = 'ipfs:boards:version:dev'
|
2015-11-16 11:56:25 +01:00
|
|
|
this.baseurl = '/ipfs-boards-profile/'
|
2015-12-12 11:57:51 +01:00
|
|
|
this.users = [] // list of IPNS names
|
|
|
|
this.resolvingIPNS = {}
|
2015-11-14 18:26:56 +01:00
|
|
|
this.ee = new EventEmitter()
|
2015-12-14 00:29:25 +01:00
|
|
|
if (window && window.localStorage !== undefined) {
|
2015-12-12 17:51:03 +01:00
|
|
|
this.ee.on('init', e => {
|
|
|
|
if (e) {
|
|
|
|
console.log('init failed')
|
|
|
|
this.init_error = e
|
|
|
|
}
|
|
|
|
})
|
2015-11-14 23:55:55 +01:00
|
|
|
// Use localStorage to store the IPNS cache
|
2015-12-14 00:29:25 +01:00
|
|
|
var stored = window.localStorage.getItem('ipfs-boards-user-cache')
|
2015-11-14 23:55:55 +01:00
|
|
|
try {
|
|
|
|
this.users = JSON.parse(stored)
|
2015-12-14 00:29:25 +01:00
|
|
|
if (this.users === null || this.users === undefined || !this.users.indexOf || !this.users.push) {
|
2015-12-12 11:57:51 +01:00
|
|
|
this.users = []
|
2015-11-14 23:55:55 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
} catch (e) {
|
2015-12-12 11:57:51 +01:00
|
|
|
this.users = []
|
2015-11-14 23:55:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 17:27:25 +01:00
|
|
|
BoardsAPI.prototype.restoreProfileFromMFS = function (done) {
|
|
|
|
this.ipfs.files.stat('/ipfs-boards-profile', (err, res) => {
|
|
|
|
if (err) return done(err)
|
|
|
|
this.ipfs.name.publish(res.Hash, done)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
BoardsAPI.prototype.restoreProfileFromIPFS = function (hash, done) {
|
|
|
|
this.ipfs.name.publish(hash, done)
|
|
|
|
}
|
|
|
|
|
2015-12-15 21:47:26 +01:00
|
|
|
BoardsAPI.prototype.createProfile = function (profile, done) {
|
|
|
|
console.log('Generating profile:', profile)
|
|
|
|
try {
|
|
|
|
var profile_str = JSON.stringify(profile)
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Error, invalid profile:', e)
|
|
|
|
return done(e)
|
|
|
|
}
|
|
|
|
asyncjs.waterfall([
|
|
|
|
// Create required directories
|
|
|
|
cb => this.ipfs.files.mkdir('/ipfs-boards-profile/boards', { p: true }, cb),
|
|
|
|
(e, cb) => this.ipfs.files.mkdir('/ipfs-boards-profile/comments', { p: true }, cb),
|
|
|
|
(e, cb) => this.ipfs.files.mkdir('/ipfs-boards-profile/posts', { p: true }, cb),
|
|
|
|
(e, cb) => {
|
|
|
|
// Remove old profile files if present
|
|
|
|
var path = '/ipfs-boards-profile/ipfs-boards-version.txt'
|
|
|
|
this.ipfs.files.rm(path, { r: true }, res => {
|
|
|
|
var path = '/ipfs-boards-profile/profile.json'
|
|
|
|
this.ipfs.files.rm(path, { r: true }, res => cb())
|
|
|
|
})
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// Add profile version file
|
|
|
|
var path = '/ipfs-boards-profile/ipfs-boards-version.txt'
|
|
|
|
var version_hash = '/ipfs/' + this.version_hash
|
|
|
|
this.ipfs.files.cp([version_hash, path], cb)
|
|
|
|
},
|
|
|
|
(e, cb) => {
|
|
|
|
// Serialize profile and add to IPFS
|
|
|
|
this.ipfs.add(new Buffer(profile_str), cb)
|
|
|
|
},
|
|
|
|
(res, cb) => {
|
|
|
|
// Move profile into mfs
|
|
|
|
console.log('added profile to IPFS:', res.Hash)
|
|
|
|
var profilepath = '/ipfs/' + res.Hash
|
|
|
|
this.ipfs.files.cp([profilepath, '/ipfs-boards-profile/profile.json'], cb)
|
|
|
|
},
|
|
|
|
(e, cb) => this.ipfs.files.stat('/', cb),
|
|
|
|
(res, cb) => {
|
|
|
|
var profile_hash = res.Hash
|
|
|
|
console.log('Publishing profile...')
|
|
|
|
this.ipfs.name.publish(profile_hash, cb)
|
|
|
|
}
|
|
|
|
], done)
|
2015-12-12 17:51:03 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 18:12:25 +01:00
|
|
|
BoardsAPI.prototype.createBoard = function (board, done) {
|
2015-12-16 23:05:48 +01:00
|
|
|
console.log('Generating board:', board)
|
|
|
|
try {
|
|
|
|
var settings_str = JSON.stringify(board)
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Error, invalid Board Settings:', e)
|
|
|
|
return done(e)
|
|
|
|
}
|
|
|
|
var dest = '/ipfs-boards-profile/boards/' + board.id + '/settings.json'
|
|
|
|
asyncjs.waterfall([
|
|
|
|
// Create required directories
|
|
|
|
cb => this.ipfs.files.mkdir('/ipfs-boards-profile/boards/' + board.id + '/', { p: true }, cb),
|
|
|
|
(e, cb) => {
|
|
|
|
// Remove old board files if present
|
|
|
|
this.ipfs.files.rm(dest, { r: true }, res => cb())
|
|
|
|
},
|
|
|
|
(cb) => {
|
|
|
|
// Serialize Board Settings and add to IPFS
|
|
|
|
this.ipfs.add(new Buffer(settings_str), cb)
|
|
|
|
},
|
|
|
|
(res, cb) => {
|
|
|
|
// Move Board into mfs
|
|
|
|
console.log('added Board Settings to IPFS:', res.Hash)
|
|
|
|
var spath = '/ipfs/' + res.Hash
|
|
|
|
this.ipfs.files.cp([spath, dest], cb)
|
|
|
|
},
|
|
|
|
(e, cb) => this.ipfs.files.stat('/', cb),
|
|
|
|
(res, cb) => {
|
|
|
|
var profile_hash = res.Hash
|
|
|
|
console.log('Publishing profile...')
|
|
|
|
this.ipfs.name.publish(profile_hash, cb)
|
|
|
|
}
|
|
|
|
], done)
|
2015-12-16 18:12:25 +01:00
|
|
|
}
|
|
|
|
|
2015-12-17 19:24:51 +01:00
|
|
|
BoardsAPI.prototype.createPost = function (post, board, done) {
|
|
|
|
try {
|
2015-12-21 16:27:08 +01:00
|
|
|
post.date = parseInt((new Date()).getTime() / 1000, 10)
|
2015-12-17 19:24:51 +01:00
|
|
|
post.op = this.id
|
|
|
|
var post_str = JSON.stringify(post)
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Error, invalid Post:', e)
|
|
|
|
return done(e)
|
|
|
|
}
|
|
|
|
if (!post.text) return done('empty post')
|
|
|
|
console.log('Posting:', post)
|
|
|
|
var dest = '/ipfs-boards-profile/posts/' + board + '/' + post.date + '.json'
|
|
|
|
var posthash
|
|
|
|
asyncjs.waterfall([
|
|
|
|
// Create required directories
|
|
|
|
cb => this.ipfs.files.mkdir('/ipfs-boards-profile/posts/' + board + '/', { p: true }, cb),
|
|
|
|
(e, cb) => {
|
|
|
|
// Remove old post file if present
|
|
|
|
this.ipfs.files.rm(dest, { r: true }, res => cb())
|
|
|
|
},
|
|
|
|
(cb) => {
|
|
|
|
// Serialize post and add to IPFS
|
|
|
|
this.ipfs.add(new Buffer(post_str), cb)
|
|
|
|
},
|
|
|
|
(res, cb) => {
|
|
|
|
// Move post into mfs
|
|
|
|
console.log('added Post to IPFS:', res.Hash)
|
|
|
|
posthash = res.Hash
|
|
|
|
var spath = '/ipfs/' + res.Hash
|
|
|
|
this.ipfs.files.cp([spath, dest], cb)
|
|
|
|
},
|
|
|
|
(e, cb) => this.ipfs.files.stat('/', cb),
|
|
|
|
(res, cb) => {
|
|
|
|
var profile_hash = res.Hash
|
|
|
|
console.log('Publishing profile...')
|
|
|
|
this.ipfs.name.publish(profile_hash, err => {
|
|
|
|
done(err, posthash)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
], done)
|
|
|
|
}
|
2015-12-23 11:47:31 +01:00
|
|
|
BoardsAPI.prototype.createComment = function (comment, parent, done) {
|
|
|
|
try {
|
|
|
|
comment.date = parseInt((new Date()).getTime() / 1000, 10)
|
|
|
|
comment.op = this.id
|
|
|
|
comment.parent = parent
|
|
|
|
var comment_str = JSON.stringify(comment)
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Error, invalid Post:', e)
|
|
|
|
return done(e)
|
|
|
|
}
|
|
|
|
if (!comment.text) return done('empty comment')
|
|
|
|
console.log('Commenting:', comment)
|
|
|
|
var dest = '/ipfs-boards-profile/comments/' + parent + '/' + comment.date + '.json'
|
|
|
|
var commenthash
|
|
|
|
asyncjs.waterfall([
|
|
|
|
// Create required directories
|
|
|
|
cb => this.ipfs.files.mkdir('/ipfs-boards-profile/comments/' + parent + '/', { p: true }, cb),
|
|
|
|
(e, cb) => {
|
|
|
|
// Remove old comment file if present
|
|
|
|
this.ipfs.files.rm(dest, { r: true }, res => cb())
|
|
|
|
},
|
|
|
|
(cb) => {
|
|
|
|
// Serialize comment and add to IPFS
|
|
|
|
this.ipfs.add(new Buffer(comment_str), cb)
|
|
|
|
},
|
|
|
|
(res, cb) => {
|
|
|
|
// Move post into mfs
|
|
|
|
console.log('added Comment to IPFS:', res.Hash)
|
|
|
|
commenthash = res.Hash
|
|
|
|
var spath = '/ipfs/' + res.Hash
|
|
|
|
this.ipfs.files.cp([spath, dest], cb)
|
|
|
|
},
|
|
|
|
(e, cb) => this.ipfs.files.stat('/', cb),
|
|
|
|
(res, cb) => {
|
|
|
|
var profile_hash = res.Hash
|
|
|
|
console.log('Publishing profile...')
|
|
|
|
this.ipfs.name.publish(profile_hash, err => {
|
|
|
|
done(err, commenthash)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
], done)
|
|
|
|
}
|
2015-12-17 19:24:51 +01:00
|
|
|
|
2015-12-18 19:48:49 +01:00
|
|
|
BoardsAPI.prototype.delete = function (opts, done) {
|
|
|
|
var url = '/ipfs-boards-profile/'
|
|
|
|
console.log('Deleting', opts)
|
|
|
|
if (opts.what === 'post') url += 'posts/' + opts.board + '/'
|
|
|
|
if (opts.what === 'comment') url += 'comments/' + opts.parent + '/'
|
|
|
|
if (opts.what === 'comment' || opts.what === 'post') {
|
|
|
|
this.ipfs.files.ls(url, (err, res) => {
|
|
|
|
if (err) return done(err)
|
|
|
|
if (!res || !res.Entries) return done('invalid response')
|
|
|
|
var list = res.Entries
|
|
|
|
for (var item in list) {
|
|
|
|
if (list[item].Hash === opts.hash) {
|
|
|
|
url = url + list[item].Name
|
|
|
|
return this.ipfs.files.rm(url, {}, err => {
|
|
|
|
if (err) return done(err)
|
|
|
|
this.ipfs.files.stat('/', (err, res) => {
|
|
|
|
if (err) return done(err)
|
|
|
|
console.log('Publishing profile...')
|
|
|
|
this.ipfs.name.publish(res.Hash, done)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return done('post does not exist or was already deleted')
|
|
|
|
})
|
|
|
|
} else if (opts.what === 'board' || opts.what === 'profile') {
|
|
|
|
if (opts.what === 'board') {
|
|
|
|
url += 'boards/' + opts.board
|
|
|
|
}
|
|
|
|
this.ipfs.files.rm(url, { r: true }, err => {
|
|
|
|
if (err) return done(err)
|
|
|
|
this.ipfs.files.stat('/', (err, res) => {
|
|
|
|
if (err) return done(err)
|
|
|
|
console.log('Publishing profile...')
|
|
|
|
this.ipfs.name.publish(res.Hash, done)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
done('what?')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BoardsAPI.prototype.deletePost = function (hash, board, done) {
|
|
|
|
this.delete({ what: 'post', hash, board }, done)
|
|
|
|
}
|
|
|
|
|
|
|
|
BoardsAPI.prototype.deleteComment = function (hash, parent, done) {
|
|
|
|
this.delete({ what: 'comment', hash, parent }, done)
|
|
|
|
}
|
|
|
|
|
2015-12-19 13:52:38 +01:00
|
|
|
BoardsAPI.prototype.cat = function (path, done) {
|
|
|
|
if (this.limited) {
|
|
|
|
// Download via gateway
|
2015-12-19 17:43:55 +01:00
|
|
|
if (path.indexOf('Qm') === 0) {
|
|
|
|
path = '/ipfs/' + path
|
|
|
|
}
|
|
|
|
console.log('Downloading via Gateway: ', path)
|
2015-12-19 13:52:38 +01:00
|
|
|
wreck.get(path, (err, res, payload) => {
|
|
|
|
console.log('GET:', err, res, payload)
|
|
|
|
if (payload.toString) payload = payload.toString()
|
|
|
|
done(err, payload)
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
// Download via http api
|
2015-12-23 13:19:23 +01:00
|
|
|
try {
|
|
|
|
this.ipfs.cat(path, done)
|
|
|
|
} catch (e) {
|
|
|
|
done(e)
|
|
|
|
}
|
2015-12-19 13:52:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BoardsAPI.prototype.ls = function (path, done) {
|
|
|
|
if (this.limited) {
|
|
|
|
// Download via gateway not yet implemented :(
|
|
|
|
done('this operation is not supported in limited mode')
|
|
|
|
} else {
|
|
|
|
// Download via http api
|
2015-12-23 13:19:23 +01:00
|
|
|
try {
|
|
|
|
this.ipfs.ls(path, done)
|
|
|
|
} catch (e) {
|
|
|
|
done(e)
|
|
|
|
}
|
2015-12-19 13:52:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.backupCache = function () {
|
|
|
|
if (window && window.localStorage !== undefined) {
|
2015-11-14 23:55:55 +01:00
|
|
|
// Use localStorage to store the IPNS cache
|
2015-12-14 00:29:25 +01:00
|
|
|
window.localStorage.setItem('ipfs-boards-user-cache', JSON.stringify(this.users))
|
2015-11-14 23:55:55 +01:00
|
|
|
}
|
2015-11-11 15:22:58 +01:00
|
|
|
}
|
|
|
|
|
2015-11-14 18:26:56 +01:00
|
|
|
// Rewrote this to use event emitters. Should also add periodic rechecking
|
2015-12-19 17:43:55 +01:00
|
|
|
// TODO: maybe drop this entirely? We can cat and ls IPNS names now.
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.resolveIPNS = function (n, handler) {
|
|
|
|
if (handler && handler.apply) this.ee.on(n, handler)
|
2015-12-19 17:43:55 +01:00
|
|
|
if (this.limited) {
|
|
|
|
// In limited mode, don't solve addresses
|
|
|
|
return this.ee.emit(n, '/ipns/' + n)
|
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
if (!this.resolvingIPNS[n]) {
|
2015-12-12 11:57:51 +01:00
|
|
|
this.resolvingIPNS[n] = true
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ipfs.name.resolve(n, (err, r) => {
|
2015-12-12 11:57:51 +01:00
|
|
|
delete this.resolvingIPNS[n]
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
2015-11-14 18:38:46 +01:00
|
|
|
// Communicate error
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('error', err)
|
2015-12-15 21:47:26 +01:00
|
|
|
if (handler && handler.apply) handler(undefined, err)
|
2015-11-18 15:40:29 +01:00
|
|
|
} else {
|
2015-11-18 16:56:07 +01:00
|
|
|
var url = r.Path
|
2015-12-14 00:29:25 +01:00
|
|
|
if (url === undefined) {
|
|
|
|
console.log('Could not resolve', n)
|
|
|
|
this.ee.emit('error', r.Message)
|
|
|
|
} else if (this.users.indexOf(n) < 0) { // new find
|
|
|
|
this.isUserProfile(url, (isit, err) => {
|
|
|
|
if (isit) {
|
|
|
|
console.log(n, 'is a user')
|
|
|
|
this.ee.emit(n, url)
|
|
|
|
if (this.users.indexOf(n) < 0) {
|
|
|
|
this.ee.emit('user', n, url)
|
2015-12-12 11:57:51 +01:00
|
|
|
this.users.push(n)
|
|
|
|
this.backupCache()
|
|
|
|
}
|
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
console.log(n, 'not a valid profile:', err)
|
|
|
|
this.ee.emit(n, undefined, 'not a valid profile: ' + err)
|
2015-12-12 11:57:51 +01:00
|
|
|
}
|
|
|
|
return true // Remove from listeners
|
|
|
|
})
|
|
|
|
} else { // Already known
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit(n, url)
|
2015-12-12 11:57:51 +01:00
|
|
|
}
|
2015-11-14 18:38:46 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2015-11-14 18:26:56 +01:00
|
|
|
return this.ee
|
2015-11-11 12:38:10 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.isUserProfile = function (addr, done) {
|
|
|
|
if (addr === undefined) return console.log('Asked to check if undefined is a profile')
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(addr + this.baseurl + 'ipfs-boards-version.txt', (err, r) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) return done(false, err)
|
|
|
|
replyAsObj(r, false, (_, res) => {
|
|
|
|
if (!res || !res.trim) {
|
|
|
|
console.log('Could not read version from', addr)
|
2015-11-20 20:32:12 +01:00
|
|
|
} else {
|
|
|
|
var v = res.trim()
|
2015-12-14 00:29:25 +01:00
|
|
|
console.log('Version in profile snapshot', addr, 'is', v)
|
|
|
|
if (v === this.version) {
|
2015-11-20 20:32:12 +01:00
|
|
|
done(true)
|
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
done(false, 'version mismatch: is "' + v + '" but should be "' + this.version + '"')
|
2015-11-20 20:32:12 +01:00
|
|
|
}
|
|
|
|
}
|
2015-11-11 12:38:10 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.searchUsers = function () {
|
2015-11-11 09:18:36 +01:00
|
|
|
// Look at our peers
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ipfs.swarm.peers((err, r) => {
|
|
|
|
if (err) return console.log(err)
|
|
|
|
replyAsObj(r, true, (e, reply) => {
|
|
|
|
if (e) {
|
|
|
|
this.ee.emit('error', e)
|
|
|
|
return console.log('There was an error while getting swarm peers:', e)
|
2015-11-19 12:59:19 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
console.log('Checking', reply.Strings.length, 'peers')
|
|
|
|
// reply.Strings.forEach(item => {
|
2015-11-19 12:59:19 +01:00
|
|
|
var f = (item, done) => {
|
2015-11-18 16:56:07 +01:00
|
|
|
var ss = item.split('/')
|
2015-12-14 00:29:25 +01:00
|
|
|
var n = ss[ss.length - 1]
|
|
|
|
this.ee.once(n, (res, err) => done(err))
|
2015-11-18 16:56:07 +01:00
|
|
|
this.resolveIPNS(n)
|
2015-11-19 12:59:19 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
asyncjs.eachSeries(reply.Strings, f.bind(this))
|
2015-11-11 09:18:36 +01:00
|
|
|
})
|
|
|
|
})
|
2015-11-18 16:56:07 +01:00
|
|
|
// Look for who has the correct version file, they probably have a profile
|
2015-11-22 00:10:46 +01:00
|
|
|
/*
|
2015-11-18 16:56:07 +01:00
|
|
|
this.ipfs.dht.findprovs(this.version_hash, (err,res) => {
|
|
|
|
if(err){
|
|
|
|
console.log('DHT FINDPROVS err',err)
|
|
|
|
} else if(res.readable){
|
|
|
|
console.log('DHT FINDPROVS stream',res)
|
|
|
|
} else {
|
|
|
|
console.log('DHT FINDPROVS string',res)
|
|
|
|
}
|
2015-11-22 00:10:46 +01:00
|
|
|
})*/
|
2015-11-14 18:26:56 +01:00
|
|
|
return this.ee
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getProfile = function (userID, done) {
|
|
|
|
this.resolveIPNS(userID, (url, err) => {
|
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
|
|
|
done(err, null)
|
2015-11-14 15:03:38 +01:00
|
|
|
} else {
|
|
|
|
// Download actual profile
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(url + this.baseurl + 'profile.json', (err2, res) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err2) {
|
|
|
|
this.ee.emit('error', err2)
|
|
|
|
done(err2, null)
|
2015-11-14 15:03:38 +01:00
|
|
|
} else {
|
2015-12-16 23:05:48 +01:00
|
|
|
var p
|
|
|
|
try {
|
|
|
|
p = JSON.parse(res.toString())
|
|
|
|
} catch (e) {
|
|
|
|
this.ee.emit('error', e)
|
|
|
|
if (done && done.apply) done(e)
|
|
|
|
return
|
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('profile for ' + userID, p)
|
|
|
|
done(null, p)
|
2015-11-14 15:03:38 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
// Get other info
|
2015-12-19 17:43:55 +01:00
|
|
|
this.ls(url + this.baseurl + 'boards/', (err2, res) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (!err2) {
|
2015-11-14 15:03:38 +01:00
|
|
|
var l = res.Objects[0].Links.map(i => {
|
|
|
|
return { name: i.Name, hash: i.Hash }
|
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('boards for ' + userID, l)
|
2015-11-16 11:56:25 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('error', err2)
|
2015-11-16 11:56:25 +01:00
|
|
|
}
|
2015-11-14 15:03:38 +01:00
|
|
|
})
|
|
|
|
}
|
2015-11-14 18:26:56 +01:00
|
|
|
return true // remove myself from listeners
|
2015-11-11 09:18:36 +01:00
|
|
|
})
|
2015-11-14 18:26:56 +01:00
|
|
|
return this.ee
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:15:06 +01:00
|
|
|
BoardsAPI.prototype.getBoardSettings = function (userID, board, done) {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (!userID) {
|
|
|
|
return console.log('Invalid USERID', userID)
|
2015-11-24 21:41:27 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
if (!board) {
|
|
|
|
return console.log('Invalid BOARD', board)
|
2015-11-24 21:41:27 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
this.resolveIPNS(userID, (r, e) => {
|
|
|
|
if (e) {
|
|
|
|
this.ee.emit('error', e)
|
2015-11-11 09:18:36 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
var url = r + this.baseurl + 'boards/' + board + '/settings.json'
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(url, (err, resp) => {
|
2015-12-16 23:05:48 +01:00
|
|
|
var settings
|
|
|
|
try {
|
|
|
|
settings = JSON.parse(resp.toString())
|
|
|
|
} catch (e) {
|
|
|
|
this.ee.emit('error', e)
|
|
|
|
if (done && done.apply) done(e)
|
|
|
|
return
|
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-12-16 19:15:06 +01:00
|
|
|
if (done && done.apply) done(err)
|
2015-11-14 16:26:03 +01:00
|
|
|
} else {
|
2015-11-16 14:35:27 +01:00
|
|
|
// SETTINGS file is here, need to parse it a little bit
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('settings for ' + board + '@' + userID, settings, r)
|
2015-12-16 19:15:06 +01:00
|
|
|
if (done && done.apply) done(null, settings)
|
2015-12-14 00:29:25 +01:00
|
|
|
if (settings.whitelist === true) {
|
2015-11-16 14:35:27 +01:00
|
|
|
// Get the whitelist
|
2015-12-14 00:29:25 +01:00
|
|
|
var url = r + this.baseurl + 'boards/' + board + '/whitelist'
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(url, (err, res) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-11-16 14:35:27 +01:00
|
|
|
// Emit an empty whitelist.
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('whitelist for ' + board + '@' + userID, [])
|
|
|
|
} else {
|
|
|
|
replyAsObj(res, false, (err, whitelist) => {
|
|
|
|
if (err) {
|
|
|
|
// Emit an empty whitelist.
|
|
|
|
this.ee.emit('whitelist for ' + board + '@' + userID, [])
|
|
|
|
} else {
|
|
|
|
// Send whitelist
|
|
|
|
var w = whitelist.split(' ').map(x => x.trim())
|
|
|
|
this.ee.emit('whitelist for ' + board + '@' + userID, w)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2015-11-16 14:35:27 +01:00
|
|
|
})
|
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
if (!settings.whitelist_only && !settings.approval_required && settings.blacklist === true) {
|
2015-11-16 14:35:27 +01:00
|
|
|
// Get the blacklist
|
2015-12-14 00:29:25 +01:00
|
|
|
var u = r + this.baseurl + 'boards/' + board + '/blacklist'
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(u, (err, blacklist) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-11-16 14:35:27 +01:00
|
|
|
} else {
|
|
|
|
// Send blacklist
|
|
|
|
var w = blacklist.split(' ')
|
2015-12-14 00:29:25 +01:00
|
|
|
this.emit('blacklist for ' + board + '@' + userID, w)
|
2015-11-16 14:35:27 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2015-11-14 16:26:03 +01:00
|
|
|
}
|
|
|
|
})
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
2015-11-14 18:26:56 +01:00
|
|
|
return true // remove myself from listeners
|
2015-11-11 09:18:36 +01:00
|
|
|
})
|
2015-11-16 14:35:27 +01:00
|
|
|
return this.ee
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
|
2015-12-17 22:19:21 +01:00
|
|
|
if (typeof adminID === 'function') {
|
|
|
|
done = adminID
|
|
|
|
adminID = undefined
|
|
|
|
}
|
|
|
|
if (typeof board === 'function') {
|
|
|
|
done = board
|
|
|
|
board = undefined
|
|
|
|
}
|
|
|
|
if (typeof op === 'function') {
|
|
|
|
done = op
|
|
|
|
op = undefined
|
|
|
|
}
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(hash, (err2, r) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err2) {
|
|
|
|
this.ee.emit('error', err2)
|
|
|
|
console.log('Could not download post', hash, 'of', board + '@' + adminID)
|
|
|
|
if (done && done.apply) done(err2)
|
2015-11-20 21:07:37 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
replyAsObj(r, true, (err, post) => {
|
2015-12-18 19:48:49 +01:00
|
|
|
if (err) {
|
|
|
|
if (done && done.apply) return done(err)
|
|
|
|
return
|
|
|
|
}
|
2015-12-04 11:41:37 +01:00
|
|
|
post.hash = hash
|
2015-12-14 00:29:25 +01:00
|
|
|
if (op) post.op = op // Inject op
|
|
|
|
if (board) {
|
2015-12-17 22:19:21 +01:00
|
|
|
if (adminID) this.ee.emit('post in ' + board + '@' + adminID, hash, post.date, post)
|
|
|
|
else this.ee.emit('post in ' + board, hash, post.date, post)
|
2015-12-04 11:41:37 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit(hash, post, adminID, board)
|
2015-12-17 22:19:21 +01:00
|
|
|
if (done && done.apply) done(null, hash, post.date, post)
|
2015-12-04 11:41:37 +01:00
|
|
|
})
|
2015-11-20 21:07:37 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return this.ee
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.retrieveListOfApproved = function (what, addr, adminID, board) {
|
|
|
|
var a = addr + this.baseurl + 'boards/' + board + '/approved/' + what + '/'
|
2015-12-19 17:43:55 +01:00
|
|
|
this.ls(a, (err, res) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-11-23 18:26:34 +01:00
|
|
|
} else {
|
|
|
|
// Send approved posts list
|
|
|
|
var ret = res.Objects[0].Links.map(item => {
|
|
|
|
return { date: item.Name, hash: item.Hash }
|
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
this.emit('approved ' + what + ' for ' + board + '@' + adminID, ret)
|
2015-11-23 18:26:34 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getAllowedContentProducers = function (adminID, board, options) {
|
|
|
|
if (!options) return
|
|
|
|
this.ee.on('settings for ' + board + '@' + adminID, function (settings, addr) {
|
2015-11-23 18:26:34 +01:00
|
|
|
// Get stuff based on settings
|
2015-12-14 00:29:25 +01:00
|
|
|
if (settings.approval_required === true) {
|
2015-11-16 14:35:27 +01:00
|
|
|
// Get approved posts list
|
2015-12-14 00:29:25 +01:00
|
|
|
if (options.posts) this.retrieveListOfApproved('posts', addr, adminID, board)
|
2015-11-23 18:26:34 +01:00
|
|
|
// Get approved comments list
|
2015-12-14 00:29:25 +01:00
|
|
|
if (options.comments) this.retrieveListOfApproved('comments', addr, adminID, board)
|
|
|
|
} else if (settings.whitelist_only === true) {
|
2015-11-23 18:26:34 +01:00
|
|
|
// TODO: emit all whitelisted users
|
2015-12-14 00:29:25 +01:00
|
|
|
} else if (settings.blacklist === true) {
|
2015-11-23 18:26:34 +01:00
|
|
|
// TODO: emit all users not in the blacklist
|
2015-11-16 14:35:27 +01:00
|
|
|
}
|
2015-11-11 15:22:58 +01:00
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getBoardSettings(adminID, board)
|
2015-11-23 18:26:34 +01:00
|
|
|
return this.ee
|
|
|
|
}
|
|
|
|
|
2015-12-17 22:19:21 +01:00
|
|
|
BoardsAPI.prototype.getPostsInBoard = function (adminID, board, opt) {
|
|
|
|
opt = opt || {}
|
|
|
|
var emitPost = i => this.ee.emit('post in ' + board + '@' + adminID, i.hash, i.date)
|
2015-12-14 00:29:25 +01:00
|
|
|
if (adminID) {
|
|
|
|
this.ee.on('approved posts for ' + board + '@' + adminID, ret => {
|
2015-11-26 18:21:28 +01:00
|
|
|
// Automatically download approved posts
|
2015-12-17 22:19:21 +01:00
|
|
|
ret.forEach(emitPost)
|
2015-11-26 18:21:28 +01:00
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.on('whitelist for ' + board + '@' + adminID, whitelist => {
|
2015-12-02 19:02:09 +01:00
|
|
|
// download posts for each user in whitelist
|
|
|
|
whitelist.forEach(item => {
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getUserPostListInBoard(item, board, (err, postList) => {
|
2015-12-17 22:19:21 +01:00
|
|
|
if (!err) postList.forEach(emitPost)
|
2015-12-02 19:02:09 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
// Get allowed content and content producers
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getAllowedContentProducers(adminID, board, { posts: true })
|
2015-11-26 18:21:28 +01:00
|
|
|
// Get the admin's posts
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getUserPostListInBoard(adminID, board, (err, res) => {
|
2015-12-17 22:19:21 +01:00
|
|
|
if (!err) res.forEach(emitPost)
|
2015-11-26 18:21:28 +01:00
|
|
|
})
|
|
|
|
} else {
|
|
|
|
// TODO: Download all posts in board from everyone
|
|
|
|
// Download my posts
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getUserPostListInBoard(this.id, board, (err, res) => {
|
|
|
|
if (err) {
|
2015-11-26 18:21:28 +01:00
|
|
|
console.log(err)
|
2015-12-17 22:19:21 +01:00
|
|
|
} else res.forEach(emitPost)
|
2015-11-26 18:21:28 +01:00
|
|
|
})
|
|
|
|
}
|
2015-11-14 18:26:56 +01:00
|
|
|
return this.ee
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getUserPostListInBoard = function (user, board, done) {
|
|
|
|
this.resolveIPNS(user, (url, err) => {
|
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-11-11 15:22:58 +01:00
|
|
|
done(err)
|
2015-12-14 00:29:25 +01:00
|
|
|
} else {
|
2015-12-19 17:43:55 +01:00
|
|
|
this.ls(url + this.baseurl + 'posts/' + board, (e, r) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (e) {
|
|
|
|
this.ee.emit('error', e)
|
|
|
|
done(e)
|
|
|
|
} else if (r && !r.split) {
|
|
|
|
console.log('Found', r.Objects[0].Links.length, 'posts in', board, 'at', user)
|
|
|
|
this.ee.emit('post count', board, user, r.Objects[0].Links.length)
|
|
|
|
var l = r.Objects[0].Links.map(i => {
|
|
|
|
return { date: i.Name, hash: i.Hash }
|
|
|
|
})
|
|
|
|
done(null, l)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2015-11-14 18:26:56 +01:00
|
|
|
return true // remove myself from listeners
|
2015-11-11 15:22:58 +01:00
|
|
|
})
|
2015-11-16 11:56:25 +01:00
|
|
|
return this.ee
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.downloadComment = function (hash, adminID, board, target, done) {
|
|
|
|
if (!done && typeof target === 'function') {
|
2015-12-12 13:21:14 +01:00
|
|
|
done = target
|
|
|
|
target = undefined
|
|
|
|
}
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(hash, (err2, r) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err2) {
|
|
|
|
this.ee.emit('error', err2)
|
|
|
|
console.log('Could not download comment', hash, 'of', board + '@' + adminID)
|
|
|
|
if (done) done(err2)
|
2015-11-23 18:26:34 +01:00
|
|
|
} else {
|
|
|
|
// TODO: add JSON parsing error handling
|
|
|
|
var cmnt = JSON.parse(r.toString())
|
|
|
|
cmnt.hash = hash
|
2015-12-14 00:29:25 +01:00
|
|
|
if (target) {
|
2015-12-12 13:21:14 +01:00
|
|
|
cmnt.original_parent = cmnt.parent
|
|
|
|
cmnt.parent = target
|
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit(hash, cmnt, adminID, board)
|
|
|
|
this.ee.emit('comment for ' + (target || cmnt.parent), cmnt)
|
|
|
|
if (done) done(null, cmnt)
|
2015-11-23 18:26:34 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return this.ee
|
|
|
|
}
|
|
|
|
|
2015-12-23 17:07:53 +01:00
|
|
|
BoardsAPI.prototype.getCommentsFor = function (parent, board, adminID, target, list = [parent]) {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (!parent || !board || !adminID) {
|
2015-12-23 17:07:53 +01:00
|
|
|
return console.log('malformed arguments:', parent, board, adminID, target, list)
|
2015-11-24 21:41:27 +01:00
|
|
|
}
|
2015-12-12 12:51:09 +01:00
|
|
|
// figure out if there's a previous version of the item
|
2015-12-19 17:43:55 +01:00
|
|
|
this.cat(parent, (err, res) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-12-12 12:51:09 +01:00
|
|
|
} else {
|
2015-12-14 00:29:25 +01:00
|
|
|
replyAsObj(res, true, (err2, obj) => {
|
|
|
|
if (err2) {
|
|
|
|
this.ee.emit('error', err2)
|
2015-12-23 17:07:53 +01:00
|
|
|
} else if (typeof obj.previous === 'string' && list.indexOf(obj.previous) < 0) {
|
2015-12-12 13:25:55 +01:00
|
|
|
// Also get comments for the previous version of the parent!
|
2015-12-23 17:07:53 +01:00
|
|
|
this.getCommentsFor(obj.previous, board, adminID, (target || parent), list.concat(obj.previous))
|
2015-12-12 12:51:09 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2015-11-23 18:26:34 +01:00
|
|
|
})
|
|
|
|
// get the admin's comments
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getUserCommentList(parent, adminID, (err, res) => {
|
|
|
|
if (!err) {
|
|
|
|
res.forEach(item => this.downloadComment(item.hash, adminID, board, target))
|
2015-11-24 21:41:27 +01:00
|
|
|
}
|
2015-11-23 18:26:34 +01:00
|
|
|
})
|
2015-12-12 13:25:55 +01:00
|
|
|
// Download comments from whitelisted
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.on('whitelist for ' + board + '@' + adminID, whitelist => {
|
2015-12-12 13:25:55 +01:00
|
|
|
// download posts for each user in whitelist
|
|
|
|
whitelist.forEach(item => {
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getUserCommentList(parent, item, (err, res) => {
|
|
|
|
if (err) return
|
|
|
|
res.forEach(i => this.downloadComment(i.hash, adminID, board, target))
|
2015-12-12 13:25:55 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2015-12-12 12:51:09 +01:00
|
|
|
// Handle approved comments
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.on('approved comments for ' + board + '@' + adminID, ret => {
|
|
|
|
ret.forEach(item => this.downloadComment(item.hash, adminID, board, target))
|
2015-12-12 12:51:09 +01:00
|
|
|
})
|
2015-12-14 00:29:25 +01:00
|
|
|
this.getAllowedContentProducers(adminID, board, { comments: true })
|
2015-11-23 18:26:34 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getUserCommentList = function (parent, user, done) {
|
|
|
|
if (!parent || !user) {
|
|
|
|
return console.log('Malformed arguments:', parent, user)
|
2015-11-24 21:41:27 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
this.resolveIPNS(user, (url, err) => {
|
|
|
|
if (err) {
|
|
|
|
this.ee.emit('error', err)
|
2015-11-23 18:26:34 +01:00
|
|
|
done(err)
|
2015-12-14 00:29:25 +01:00
|
|
|
} else {
|
2015-12-19 17:43:55 +01:00
|
|
|
this.ls(url + this.baseurl + 'comments/' + parent, (e, r) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (e) {
|
|
|
|
this.ee.emit('error', e)
|
|
|
|
done(e)
|
|
|
|
} else if (r && !r.split) {
|
|
|
|
if (r.Objects && r.Objects[0]) { // If this is not true, then there are no comments
|
|
|
|
console.log('Found', r.Objects[0].Links.length, 'comments for', parent, 'at', user)
|
|
|
|
var l = r.Objects[0].Links.map(i => {
|
|
|
|
return { date: i.Name, hash: i.Hash }
|
|
|
|
})
|
|
|
|
done(null, l)
|
|
|
|
}
|
2015-11-24 21:41:27 +01:00
|
|
|
}
|
2015-12-14 00:29:25 +01:00
|
|
|
})
|
|
|
|
}
|
2015-11-23 18:26:34 +01:00
|
|
|
return true // remove myself from listeners
|
|
|
|
})
|
|
|
|
return this.ee
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
|
2015-12-19 13:52:38 +01:00
|
|
|
BoardsAPI.prototype.isRunningFromGateway = function () {
|
|
|
|
if (!window) return false
|
2015-12-19 17:43:55 +01:00
|
|
|
return window.location.pathname.indexOf('/ipfs/') === 0 || window.location.pathname.indexOf('/ipns/') === 0
|
2015-12-19 13:52:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
BoardsAPI.prototype.isNode = function () {
|
|
|
|
return process && process.env
|
|
|
|
}
|
|
|
|
|
2015-11-14 23:55:55 +01:00
|
|
|
// API for publishing content and managing to be done later...
|
2015-11-11 09:18:36 +01:00
|
|
|
|
|
|
|
// Initialize API
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.init = function (done) {
|
|
|
|
if (this.isInit) return
|
2015-12-20 21:10:48 +01:00
|
|
|
this.ipfs.version((err, res) => {
|
2015-12-14 00:29:25 +01:00
|
|
|
if (err) {
|
2015-12-20 21:10:48 +01:00
|
|
|
this.limited = this.isRunningFromGateway() ? 2 : false
|
2015-12-14 00:29:25 +01:00
|
|
|
this.ee.emit('error', err)
|
2015-12-19 13:52:38 +01:00
|
|
|
this.ee.emit('init', err, this.limited)
|
2015-12-20 21:10:48 +01:00
|
|
|
console.log('Error while getting ipfs version:', err)
|
|
|
|
if (done && done.apply) done(err, this.limited)
|
|
|
|
} else {
|
|
|
|
this.ipfs_version = res.Version.split('-')[0]
|
|
|
|
console.log('IPFS Version is', res.Version)
|
|
|
|
if (semver.satisfies(this.ipfs_version, '~0.4.0')) {
|
|
|
|
console.log('IPFS version is supported')
|
|
|
|
this.ipfs.id((err, res) => {
|
|
|
|
if (err) {
|
|
|
|
console.log('Error while getting OWN ID:', err)
|
|
|
|
this.limited = this.isRunningFromGateway() ? 1 : false
|
|
|
|
this.ee.emit('error', err)
|
|
|
|
this.ee.emit('init', err, this.limited)
|
|
|
|
if (done && done.apply) {
|
|
|
|
done(err, this.limited)
|
|
|
|
}
|
|
|
|
} else if (res.ID) {
|
|
|
|
console.log('I am', res.ID)
|
|
|
|
this.id = res.ID
|
|
|
|
this.resolveIPNS(res.ID)
|
|
|
|
console.log('Version is', this.version)
|
|
|
|
this.ipfs.add(new Buffer(this.version), (err2, r) => {
|
|
|
|
if (err2) {
|
|
|
|
this.ee.emit('error', err2)
|
|
|
|
console.log('Error while calculating version hash:', err2)
|
|
|
|
this.ee.emit('init', err2, this.limited)
|
|
|
|
if (done && done.apply) done(err2)
|
|
|
|
} else {
|
|
|
|
if (r && r.Hash) this.version_hash = r.Hash
|
|
|
|
if (r && r[0] && r[0].Hash) this.version_hash = r[0].Hash
|
|
|
|
console.log('Version hash is', this.version_hash)
|
|
|
|
// DONE!
|
2015-12-12 17:51:03 +01:00
|
|
|
this.ee.emit('init', undefined)
|
|
|
|
this.isInit = true
|
|
|
|
delete this.init_error
|
|
|
|
if (done && done.apply) done(null)
|
|
|
|
}
|
2015-12-20 21:10:48 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
var e = { Message: 'IPFS Version not supported. This app supports go-ipfs 0.4.x' }
|
|
|
|
if (done && done.apply) done(e)
|
|
|
|
console.log('Error:', e.Message)
|
|
|
|
this.ee.emit('error', e)
|
|
|
|
this.ee.emit('init', e)
|
|
|
|
}
|
2015-11-11 09:18:36 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getEventEmitter = function () {
|
2015-11-16 14:35:27 +01:00
|
|
|
return this.ee
|
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getUsers = function () {
|
2015-12-12 11:57:51 +01:00
|
|
|
return this.users
|
2015-11-19 12:59:19 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 00:29:25 +01:00
|
|
|
BoardsAPI.prototype.getMyID = function () {
|
2015-11-22 00:10:46 +01:00
|
|
|
return this.id
|
|
|
|
}
|
|
|
|
|
2015-12-15 17:15:12 +01:00
|
|
|
BoardsAPI.prototype.getIPFS = function () {
|
|
|
|
return this.ipfs
|
|
|
|
}
|
|
|
|
|
2015-11-11 09:18:36 +01:00
|
|
|
module.exports = BoardsAPI
|