Files: 765a31b854726f3c3f4e39689b4e4d4b8f86bcf8 / plugins / friends.js
3421 bytesRaw
1 | var G = require('graphreduce') |
2 | var Reduce = require('flumeview-reduce') |
3 | var pull = require('pull-stream') |
4 | var FlatMap = require('pull-flatmap') |
5 | //var mlib = require('ssb-msgs') |
6 | //var pushable = require('pull-pushable') |
7 | var mdm = require('mdmanifest') |
8 | var valid = require('../lib/validators') |
9 | var apidoc = require('../lib/apidocs').friends |
10 | var ref = require('ssb-ref') |
11 | var Obv = require('obv') |
12 | |
13 | var F = require('ssb-friends') |
14 | var block = require('ssb-friends/block') |
15 | |
16 | // friends plugin |
17 | // methods to analyze the social graph |
18 | // maintains a 'follow' and 'flag' graph |
19 | |
20 | function isFunction (f) { |
21 | return 'function' === typeof f |
22 | } |
23 | |
24 | function isString (s) { |
25 | return 'string' === typeof s |
26 | } |
27 | |
28 | function isFriend (friends, a, b) { |
29 | return friends[a] && friends[b] && friends[a][b] && friends[b][a] |
30 | } |
31 | |
32 | exports.name = 'friends' |
33 | exports.version = '1.0.0' |
34 | exports.manifest = mdm.manifest(apidoc) |
35 | |
36 | exports.init = function (sbot, config) { |
37 | var post = Obv() |
38 | post.set({}) |
39 | var index = sbot._flumeUse('friends', Reduce(2, function (g, rel) { |
40 | if(!g) g = {} |
41 | G.addEdge(g, rel.from, rel.to, rel.value) |
42 | return g |
43 | }, function (data) { |
44 | if(data.value.content.type === 'contact' && ref.isFeed(data.value.content.contact)) { |
45 | var tristate = ( |
46 | data.value.content.following ? true |
47 | : data.value.content.flagged || data.value.content.blocking ? false |
48 | : null |
49 | ) |
50 | return { |
51 | from: data.value.author, |
52 | to: data.value.content.contact, |
53 | value: tristate |
54 | } |
55 | } |
56 | })) |
57 | |
58 | index.since(function () { |
59 | //it looks async but this will always be sync after loading |
60 | index.get(null, function (_, v) { |
61 | post.set(v) |
62 | }) |
63 | }) |
64 | |
65 | return { |
66 | post: post, |
67 | get: function (opts, cb) { |
68 | index.get(opts, cb) |
69 | }, |
70 | |
71 | createFriendStream: valid.source(function (opts) { |
72 | opts = opts || {} |
73 | var live = opts.live === true |
74 | var meta = opts.meta === true |
75 | var start = opts.start || sbot.id |
76 | var reachable |
77 | return pull( |
78 | index.stream(opts), |
79 | FlatMap(function (v) { |
80 | if(!v) return [] |
81 | |
82 | //this code handles real time streaming of the hops map. |
83 | function push (to, hops) { |
84 | out.push(meta ? {id: to, hops: hops} : to) |
85 | } |
86 | |
87 | var out = [], g = post.value |
88 | |
89 | //the edge has already been added to g |
90 | if(!reachable) { |
91 | reachable = F.reachable(g, start, block) |
92 | for(var k in reachable) |
93 | if(block.isWanted(reachable[k])) |
94 | push(k, reachable[k][0]) |
95 | } else { |
96 | var _reachable = F.reachable(g, start, block) |
97 | var patch = F.diff(reachable, _reachable) |
98 | for(var k in patch) { |
99 | if(patch[k] == null) |
100 | push(k, -1) |
101 | else if(block.isWanted(patch[k])) |
102 | push(k, patch[k][0]) |
103 | } |
104 | reachable = _reachable |
105 | } |
106 | return out |
107 | }) |
108 | |
109 | ) |
110 | }, 'createFriendStreamOpts?'), |
111 | |
112 | hops: function (opts, cb) { |
113 | if(isFunction(opts)) |
114 | cb = opts, opts = {} |
115 | opts = opts || {} |
116 | if(isString(opts)) |
117 | opts = {start: opts} |
118 | index.get(null, function (err, g) { |
119 | if(err) cb(err) |
120 | else cb(null, G.hops(g, opts.start || sbot.id, 0, opts.hops || 3)) |
121 | }) |
122 | } |
123 | } |
124 | } |
125 | |
126 | |
127 | |
128 | |
129 | |
130 |
Built with git-ssb-web