git ssb

0+

Dominic / ssb-irc



Tree: 93f8be5cd174b9ced30164c1efaf91df91e4ac0f

Files: 93f8be5cd174b9ced30164c1efaf91df91e4ac0f / util.js

4424 bytesRaw
1var pull = require('pull-stream')
2var ref = require('ssb-ref')
3var hash = require('ssb-keys/util').hash
4var markdown = require('ssb-markdown')
5
6function isString (s) {
7 return 'string' == typeof s
8}
9
10function update (state, msg) {
11 if(msg.content.type === 'channel') {
12 if(msg.content.subscribed)
13 state.channels[msg.content.channel] = msg.content.irc || msg.content.channel
14 else
15 delete state.channels[msg.content.channel]
16 }
17 else if(msg.content.type === 'about' && ref.isFeed(msg.content.about) && (msg.content.name || msg.content.irc != null)) {
18 state.users[msg.content.about] = msg.content.irc == null ? msg.content.name : msg.content.irc
19 }
20 return state
21}
22
23function init(sbot, id, cb) {
24 var state = {users: {}, channels: {}}
25
26 pull(
27 sbot.createHistoryStream({id: id || sbot.id, live: true}),
28 pull.drain(function (msg) {
29 if(msg.sync)
30 return cb && cb(null, state)
31 state = update(state, msg.value)
32 })
33 )
34 return state
35}
36
37function toKey(fn) {
38 return function (state, msg) {
39 var key
40 if(msg.key) {
41 key = msg.key
42 msg = msg.value
43 }
44 else
45 key = '%'+hash(JSON.stringify(msg, null, 2))
46 return fn(state, msg, key)
47 }
48}
49
50exports.isChannelPost = toKey(function isChannelPost (state, msg, key) {
51 if(state.channels[msg.content.channel] && !msg.content.root) {
52 var text = msg.content.text
53 if(isString(text) && text) {
54 text = text.split('\n')
55 if(text.length > 1)
56 text = text[0]
57 else
58 text = text[0]
59
60 return [{
61 author: msg.author,
62 target: msg.content.channel,
63 text: text.length > 100 ? text.substring(0, 97)+'...' : text,
64 id: key,
65 type: 'channel'
66 }]
67 }
68 }
69})
70
71function uniq (a) {
72 var b = []
73 for(var i = 0; i < a.length; i++)
74 if(!~b.indexOf(a[i])) b.push(a[i])
75 return b
76}
77
78function getChannel(state, name) {
79 name = name.replace(/^#/,'')
80 return state.channels[name] === true ? name : state.channels[name]
81}
82
83function surrounding(text, match, length) {
84 var i = Math.max(text.indexOf(match)-100, 0)
85 return (i > 0 ? '...' : '') + text.substring(i, i+100) + (i + 100 < text.length ? '...' : '')
86}
87
88exports.isChannelMention = toKey(function (state, msg, key) {
89 var text = msg.content.text
90 if(isString(text) && text) {
91 text = markdown.inline(text)
92 if(!/(#\w+)/.test(text)) return []
93
94 var m = uniq(text.match(/(#\w+)/g))
95 return m.filter(function (name) {
96 return getChannel(state, name)
97 }).map(function (name) {
98 return {
99 author: msg.author,
100 target: getChannel(state, name),
101 text: surrounding(text, name, 100),
102 id: key,
103 type: 'channel'
104 }
105 })
106 }
107 return []
108})
109
110exports.isUserMention = toKey(function (state, msg, key) {
111 var text = msg.content.text
112 if(isString(text) && text && Array.isArray(msg.content.mentions)) {
113 text = markdown.inline(text)
114 return msg.content.mentions.filter(function (mention) {
115 return state.users[mention.link]
116 }).map(function (mention) {
117 return {
118 author: msg.author,
119 target: state.users[mention.link],
120 text: surrounding(markdown.inline(text), '@'+mention.name, 100),
121 id: key,
122 type: 'user'
123 }
124 })
125 }
126})
127
128exports.isUserFollow = toKey(function (state, msg, key) {
129 if(msg.content.type == 'contact' && msg.content.following && state.users[msg.content.contact])
130 return {
131 author: msg.author,
132 target: state.users[msg.content.contact],
133 text: 'followed you', //this will make sense since the notification will be a direct message
134 id: key,
135 type: 'user'
136 }
137})
138
139if(!module.parent) {
140 //this is just for testing...
141 require('ssb-client')(function (err, sbot) {
142 if(err) throw err
143 var state = init(sbot, process.argv[2] || sbot.id)
144 //XXX: properly persist state with a flumeview?
145 setTimeout(function () {
146 var tests = [
147 exports.isChannelPost,
148 exports.isChannelMention,
149 exports.isUserMention,
150 exports.isUserFollow
151 ]
152
153 pull(
154 sbot.createLogStream({}),
155 pull.drain(function (msg) {
156 if(msg.sync) return
157 var a = tests.reduce(function (found, test) {
158 return found.concat(test(state, msg) || [])
159 }, [])
160 if(a.length) console.log('ARY', a)
161 })
162 )
163 }, 5000)
164 })
165}
166
167

Built with git-ssb-web