diff options
Diffstat (limited to 'lib/contacts.js')
-rw-r--r-- | lib/contacts.js | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/contacts.js b/lib/contacts.js new file mode 100644 index 0000000..846cdf9 --- /dev/null +++ b/lib/contacts.js @@ -0,0 +1,159 @@ +var pull = require('pull-stream') +var defer = require('pull-defer') +var many = require('pull-many') + +module.exports = Contacts + +function Contacts(sbot) { + if (!(this instanceof Contacts)) return new Contacts(sbot) + this.sbot = sbot +} + +Contacts.prototype._createContactStream = function (source, dest) { + return pull( + this.sbot.links({ + source: source, + dest: dest, + rel: 'contact', + values: true, + reverse: true + }), + pull.filter(function (msg) { + var c = msg && msg.value && msg.value.content + return c && c.type === 'contact' && (!dest || c.contact === dest) + }), + pull.map(function (msg) { + var c = msg && msg.value && msg.value.content + return { + source: msg.value.author, + dest: c.contact, + msg: msg, + value: c.following ? true : c.flagged || c.blocking ? false : null + } + }), + pull.unique(function (edge) { + return edge.source + '-' + edge.dest + }) + ) +} + +Contacts.prototype.createFollowsStream = function (id) { + return pull( + this._createContactStream(id, null), + pull.filter('value'), + pull.map('dest') + ) +} + +Contacts.prototype.createFollowersStream = function (id) { + return pull( + this._createContactStream(null, id), + pull.filter('value'), + pull.map('source') + ) +} + +Contacts.prototype.createFollowedFollowersStream = function (source, dest) { + var follows = {}, followers = {} + return pull( + many([ + this._createContactStream(source, null), + this._createContactStream(null, dest) + ]), + pull.filter('value'), + pull.map(function (edge) { + if (edge.source === source) { + if (followers[edge.dest]) { + delete followers[edge.dest] + return edge.dest + } else { + follows[edge.dest] = true + } + } else if (edge.dest === dest) { + if (follows[edge.source]) { + delete follows[edge.source] + return edge.source + } else { + followers[edge.source] = true + } + } + }), + pull.filter() + ) +} + +Contacts.prototype.createFriendsStream = function (opts, endCb) { + if (typeof opts === 'string') opts = {id: opts} + var id = opts.id + var msgIds = opts.msgIds + var follows = {}, followers = {} + var blocks = {}, blockers = {} + return pull( + many([ + this._createContactStream(id, null), + this._createContactStream(null, id) + ]), + pull.map(function (edge) { + if (edge.value) { + if (edge.source === id) { + if (followers[edge.dest]) { + var item2 = followers[edge.dest] + delete followers[edge.dest] + return msgIds ? {feed: edge.dest, msg: edge.msg, msg2: item2.msg} : edge.dest + } else { + follows[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg} : edge.dest + } + } else if (edge.dest === id) { + if (follows[edge.source]) { + var item2 = follows[edge.source] + delete follows[edge.source] + return msgIds ? {feed: edge.source, msg: edge.msg, msg2: item2.msg} : edge.source + } else { + followers[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg} : edge.source + } + } + } else if (edge.value === false) { + if (edge.source === id) { + blocks[edge.dest] = msgIds ? {feed: edge.dest, msg: edge.msg} : edge.dest + } else if (edge.dest === id) { + blockers[edge.source] = msgIds ? {feed: edge.source, msg: edge.msg} : edge.source + } + } + }), + pull.filter(), + endCb && function (read) { + return function (abort, cb) { + read(abort, function (end, data) { + cb(end, data) + if (end) endCb(end === true ? null : end, { + followers: Object.values(followers), + follows: Object.values(follows), + blocks: Object.values(blocks), + blockers: Object.values(blockers), + }) + }) + } + } + ) +} + +Contacts.prototype.createContactStreams = function (opts) { + var msgIds = opts.msgIds + var follows = defer.source() + var followers = defer.source() + var blocks = defer.source() + var blockers = defer.source() + var friends = this.createFriendsStream(opts, function (err, more) { + follows.resolve(err ? pull.error(err) : pull.values(more.follows)) + followers.resolve(err ? pull.error(err) : pull.values(more.followers)) + blocks.resolve(err ? pull.error(err) : pull.values(more.blocks)) + blockers.resolve(err ? pull.error(err) : pull.values(more.blockers)) + }) + return { + friends: friends, + follows: follows, + followers: followers, + blocks: blocks, + blockers: blockers, + } +} |