git ssb

16+

cel / patchfoo



Tree: ea522127885486018de1547de0db04f3d3144eb6

Files: ea522127885486018de1547de0db04f3d3144eb6 / lib / about.js

4476 bytesRaw
1var pull = require('pull-stream')
2var multicb = require('multicb')
3var cat = require('pull-cat')
4var u = require('./util')
5
6module.exports = About
7
8function About(app, myId, follows) {
9 this.app = app
10 this.myId = myId
11 this.follows = follows
12}
13
14About.prototype.createAboutOpStream = function (id) {
15 return pull(
16 this.app.sbot.links({dest: id, rel: 'about', values: true, reverse: true, private: true, meta: false}),
17 this.app.unboxMessages(),
18 pull.map(function (msg) {
19 var c = msg.value.content
20 if (typeof c !== 'object' || c === null) return []
21 return Object.keys(c).filter(function (key) {
22 return key !== 'about'
23 && key !== 'type'
24 && key !== 'recps'
25 && key !== 'reason'
26 }).map(function (key) {
27 var value = c[key]
28 return {
29 id: msg.key,
30 author: msg.value.author,
31 timestamp: msg.value.timestamp,
32 prop: key,
33 value: value,
34 remove: value && value.remove,
35 }
36 })
37 }),
38 pull.flatten()
39 )
40}
41
42About.prototype.createAboutStreams = function (id) {
43 var ops = this.createAboutOpStream(id)
44 var scalars = {/* author: {prop: value} */}
45 var sets = {/* author: {prop: {link}} */}
46
47 var setsDone = multicb({pluck: 1, spread: true})
48 setsDone()(null, pull.values([]))
49 return {
50 scalars: pull(
51 ops,
52 pull.unique(function (op) {
53 return op.author + '-' + op.prop + '-'
54 }),
55 pull.filter(function (op) {
56 return !op.remove
57 })
58 ),
59 sets: u.readNext(setsDone)
60 }
61}
62
63function computeTopAbout(aboutByFeed) {
64 var propValueCounts = {/* prop: {value: count} */}
65 var topValues = {/* prop: value */}
66 var topValueCounts = {/* prop: count */}
67 for (var feed in aboutByFeed) {
68 var feedAbout = aboutByFeed[feed]
69 for (var prop in feedAbout) {
70 var value = feedAbout[prop]
71 var valueCounts = propValueCounts[prop] || (propValueCounts[prop] = {})
72 var count = (valueCounts[value] || 0) + 1
73 valueCounts[value] = count
74 if (count > (topValueCounts[prop] || 0)) {
75 topValueCounts[prop] = count
76 topValues[prop] = value
77 }
78 }
79 }
80 return topValues
81}
82
83About.prototype.get = function (dest, cb) {
84 var self = this
85 var myAbout = []
86 var aboutByFeed = {}
87 var aboutByFeedFollowed = {}
88 this.follows.getFollows(this.myId, function (err, follows) {
89 if (err) return cb(err)
90 pull(
91 cat([
92 dest[0] === '%' && self.app.pullGetMsg(dest),
93 self.app.sbot.links({
94 rel: 'about',
95 dest: dest,
96 values: true,
97 private: true,
98 meta: false
99 })
100 ]),
101 self.app.unboxMessages(),
102 pull.drain(function (msg) {
103 var author = msg.value.author
104 var c = msg.value.content
105 if (!c) return
106 if (msg.key === dest && c.type === 'about') {
107 // don't describe an about message with itself
108 return
109 }
110 var about = author === self.myId ? myAbout :
111 follows[author] ?
112 aboutByFeedFollowed[author] || (aboutByFeedFollowed[author] = {}) :
113 aboutByFeed[author] || (aboutByFeed[author] = {})
114
115 if (c.name) about.name = c.name
116 if (c.title) about.title = c.title
117 if (c.image) {
118 about.image = u.linkDest(c.image)
119 about.imageLink = u.toLink(c.image)
120 }
121 if (c.description) about.description = c.description
122 if (c.publicWebHosting) about.publicWebHosting = c.publicWebHosting
123 }, function (err) {
124 if (err) return cb(err)
125 var destAbout = aboutByFeedFollowed[dest] || aboutByFeed[dest]
126 // bias the author's choices by giving them an extra vote
127 if (destAbout) {
128 if (follows[dest]) aboutByFeedFollowed._author = destAbout
129 else aboutByFeed._author = destAbout
130 }
131 var about = {}
132 var followedAbout = computeTopAbout(aboutByFeedFollowed)
133 var topAbout = computeTopAbout(aboutByFeed)
134 for (var k in topAbout) about[k] = topAbout[k]
135 // prefer followed feeds' choices
136 for (var k in followedAbout) about[k] = followedAbout[k]
137 // if we follow the destination/author feed, prefer its choices
138 if (follows[dest]) for (var k in destAbout) about[k] = destAbout[k]
139 // always prefer own choices
140 for (var k in myAbout) about[k] = myAbout[k]
141 cb(null, about)
142 })
143 )
144 })
145}
146

Built with git-ssb-web