Files: 8440eb927f93ded7f18ab38dbd0d6005785ee076 / lib / about.js
3167 bytesRaw
1 | var pull = require('pull-stream') |
2 | var multicb = require('multicb') |
3 | var cat = require('pull-cat') |
4 | var u = require('./util') |
5 | |
6 | module.exports = About |
7 | |
8 | function About(app, myId) { |
9 | this.app = app |
10 | this.myId = myId |
11 | } |
12 | |
13 | About.prototype.createAboutOpStream = function (id) { |
14 | return pull( |
15 | this.app.sbot.links({dest: id, rel: 'about', values: true, reverse: true}), |
16 | pull.map(function (msg) { |
17 | var c = msg.value.content || {} |
18 | return Object.keys(c).filter(function (key) { |
19 | return key !== 'about' |
20 | && key !== 'type' |
21 | && key !== 'recps' |
22 | }).map(function (key) { |
23 | var value = c[key] |
24 | return { |
25 | id: msg.key, |
26 | author: msg.value.author, |
27 | timestamp: msg.value.timestamp, |
28 | prop: key, |
29 | value: value, |
30 | remove: value && value.remove, |
31 | } |
32 | }) |
33 | }), |
34 | pull.flatten() |
35 | ) |
36 | } |
37 | |
38 | About.prototype.createAboutStreams = function (id) { |
39 | var ops = this.createAboutOpStream(id) |
40 | var scalars = {/* author: {prop: value} */} |
41 | var sets = {/* author: {prop: {link}} */} |
42 | |
43 | var setsDone = multicb({pluck: 1, spread: true}) |
44 | setsDone()(null, pull.values([])) |
45 | return { |
46 | scalars: pull( |
47 | ops, |
48 | pull.unique(function (op) { |
49 | return op.author + '-' + op.prop + '-' |
50 | }), |
51 | pull.filter(function (op) { |
52 | return !op.remove |
53 | }) |
54 | ), |
55 | sets: u.readNext(setsDone) |
56 | } |
57 | } |
58 | |
59 | function computeTopAbout(aboutByFeed) { |
60 | var propValueCounts = {/* prop: {value: count} */} |
61 | var topValues = {/* prop: value */} |
62 | var topValueCounts = {/* prop: count */} |
63 | for (var feed in aboutByFeed) { |
64 | var feedAbout = aboutByFeed[feed] |
65 | for (var prop in feedAbout) { |
66 | var value = feedAbout[prop] |
67 | var valueCounts = propValueCounts[prop] || (propValueCounts[prop] = {}) |
68 | var count = (valueCounts[value] || 0) + 1 |
69 | valueCounts[value] = count |
70 | if (count > (topValueCounts[prop] || 0)) { |
71 | topValueCounts[prop] = count |
72 | topValues[prop] = value |
73 | } |
74 | } |
75 | } |
76 | return topValues |
77 | } |
78 | |
79 | About.prototype.get = function (dest, cb) { |
80 | var self = this |
81 | var aboutByFeed = {} |
82 | pull( |
83 | cat([ |
84 | dest[0] === '%' && self.app.pullGetMsg(dest), |
85 | self.app.sbot.links({ |
86 | rel: 'about', |
87 | dest: dest, |
88 | values: true, |
89 | }) |
90 | ]), |
91 | self.app.unboxMessages(), |
92 | pull.drain(function (msg) { |
93 | var author = msg.value.author |
94 | var c = msg.value.content |
95 | if (!c) return |
96 | var about = aboutByFeed[author] || (aboutByFeed[author] = {}) |
97 | if (c.name) about.name = c.name |
98 | if (c.title) about.title = c.title |
99 | if (c.image) about.image = u.linkDest(c.image) |
100 | if (c.description) about.description = c.description |
101 | }, function (err) { |
102 | if (err) return cb(err) |
103 | // bias the author's choices by giving them an extra vote |
104 | aboutByFeed._author = aboutByFeed[dest] |
105 | var about = {} |
106 | var myAbout = aboutByFeed[self.myId] || {} |
107 | var topAbout = computeTopAbout(aboutByFeed) |
108 | for (var k in topAbout) about[k] = topAbout[k] |
109 | // always prefer own choices |
110 | for (var k in myAbout) about[k] = myAbout[k] |
111 | cb(null, about) |
112 | }) |
113 | ) |
114 | } |
115 |
Built with git-ssb-web