git ssb

4+

Dominic / scuttlebot



Tree: 765a31b854726f3c3f4e39689b4e4d4b8f86bcf8

Files: 765a31b854726f3c3f4e39689b4e4d4b8f86bcf8 / plugins / friends.js

3421 bytesRaw
1var G = require('graphreduce')
2var Reduce = require('flumeview-reduce')
3var pull = require('pull-stream')
4var FlatMap = require('pull-flatmap')
5//var mlib = require('ssb-msgs')
6//var pushable = require('pull-pushable')
7var mdm = require('mdmanifest')
8var valid = require('../lib/validators')
9var apidoc = require('../lib/apidocs').friends
10var ref = require('ssb-ref')
11var Obv = require('obv')
12
13var F = require('ssb-friends')
14var block = require('ssb-friends/block')
15
16// friends plugin
17// methods to analyze the social graph
18// maintains a 'follow' and 'flag' graph
19
20function isFunction (f) {
21 return 'function' === typeof f
22}
23
24function isString (s) {
25 return 'string' === typeof s
26}
27
28function isFriend (friends, a, b) {
29 return friends[a] && friends[b] && friends[a][b] && friends[b][a]
30}
31
32exports.name = 'friends'
33exports.version = '1.0.0'
34exports.manifest = mdm.manifest(apidoc)
35
36exports.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