git ssb

30+

cel / git-ssb-web



Tree: 94fac4ede25741324d83db694a7252b79325a855

Files: 94fac4ede25741324d83db694a7252b79325a855 / lib / util.js

5471 bytesRaw
1var pull = require('pull-stream')
2var h = require('pull-hyperscript')
3var paramap = require('pull-paramap')
4var Highlight = require('highlight.js')
5var u = exports
6
7u.imgMimes = {
8 png: 'image/png',
9 jpeg: 'image/jpeg',
10 jpg: 'image/jpeg',
11 gif: 'image/gif',
12 tif: 'image/tiff',
13 svg: 'image/svg+xml',
14 bmp: 'image/bmp'
15}
16
17u.getExtension = function(filename) {
18 var m = /\.([^.]+)$/.exec(filename)
19 return m && m[1]
20}
21
22u.readNext = function (fn) {
23 var next
24 return function (end, cb) {
25 if (next) return next(end, cb)
26 fn(function (err, _next) {
27 if (err) return cb(err)
28 next = _next
29 next(null, cb)
30 })
31 }
32}
33
34u.readOnce = function (fn) {
35 var ended
36 return function (end, cb) {
37 fn(function (err, data) {
38 if (err || ended) return cb(err || ended)
39 ended = true
40 cb(null, data)
41 })
42 }
43}
44
45u.when = function (bool, elFunction) {
46 return bool
47 ? elFunction()
48 : pull.once('')
49}
50
51u.sourceMap = function (source, fn) {
52 return pull(
53 source,
54 pull.filter(Boolean),
55 pull.map(fn)
56 )
57}
58
59u.paraSourceMap = function paraSourceMap (source, fn) {
60 return pull(
61 pull.values(source),
62 paramap(fn, 8)
63 )
64}
65
66u.escape = function (str) {
67 return String(str)
68 .replace(/&/g, '&')
69 .replace(/</g, '&lt;')
70 .replace(/>/g, '&gt;')
71 .replace(/"/g, '&quot;')
72}
73
74u.encodeLink = function (url) {
75 if (!Array.isArray(url)) url = [url]
76 return '/' + url.map(encodeURIComponent).join('/')
77}
78
79u.link = function (parts, text, raw, props) {
80 if (text == null) text = parts[parts.length-1]
81 if (!raw) text = u.escape(text)
82 return '<a href="' + u.encodeLink(parts) + '"' +
83 (props ? ' ' + props : '') +
84 '>' + text + '</a>'
85}
86
87u.timestamp = function (time, req) {
88 time = Number(time)
89 var d = new Date(time)
90 return '<span title="' + time + '">' +
91 d.toLocaleString(req._locale) + '</span>'
92}
93
94u.nav = function (links, page, after) {
95 return h('nav', [
96 u.sourceMap(pull.values(links), link => {
97 return h('a', {
98 href: (typeof link[0] == 'string') ? link[0] : u.encodeLink(link[0]),
99 class: (link[2] == page) ? 'active' : ''
100 },
101 link[1])
102 }),
103 pull.once(after || '')
104 ])
105}
106
107u.hiddenInputs = function (values) {
108 return Object.keys(values).map(function (key) {
109 return '<input type="hidden"' +
110 ' name="' + u.escape(key) + '"' +
111 ' value="' + u.escape(values[key]) + '"/>'
112 }).join('')
113}
114
115u.highlight = function(code, lang) {
116 if (!lang && /^#!\/bin\/[^\/]*sh$/m.test(code)) lang = 'sh'
117 if (!lang || code.length > 100000) return u.escape(code)
118 // auto highlighting removed because it was causing highlight.js to hang
119 try {
120 return Highlight.highlight(lang, code).value
121 } catch(e) {
122 console.error('highlight:', e)
123 return u.escape(code)
124 }
125}
126
127u.pre = function (text) {
128 return '<pre>' + u.escape(text) + '</pre>'
129}
130
131u.json = function (obj) {
132 return u.linkify(u.pre(JSON.stringify(obj, null, 2)))
133}
134
135u.linkify = function (text) {
136 // regex is from ssb-ref
137 return text.replace(/(@|%|&|&amp;)[A-Za-z0-9\/+]{43}=\.[\w\d]+/g, function (str) {
138 return '<a href="/' + str + '">' + str + '</a>'
139 })
140}
141
142u.readObjectString = function (obj, cb) {
143 pull(obj.read, pull.collect(function (err, bufs) {
144 if (err) return cb(err)
145 cb(null, Buffer.concat(bufs, obj.length).toString('utf8'))
146 }))
147}
148
149u.pullReverse = function () {
150 return function (read) {
151 return u.readNext(function (cb) {
152 pull(read, pull.collect(function (err, items) {
153 cb(err, items && pull.values(items.reverse()))
154 }))
155 })
156 }
157}
158
159function compareMsgs(a, b) {
160 return (a.value.timestamp - b.value.timestamp) || (a.key - b.key)
161}
162
163u.pullSort = function (comparator, descending) {
164 return function (read) {
165 return u.readNext(function (cb) {
166 pull(read, pull.collect(function (err, items) {
167 if (err) return cb(err)
168 items.sort(comparator)
169 if (descending) items.reverse()
170 cb(null, pull.values(items))
171 }))
172 })
173 }
174}
175
176u.sortMsgs = function (descending) {
177 return u.pullSort(compareMsgs, descending)
178}
179
180u.truncate = function (str, len) {
181 str = String(str)
182 return str.length < len ? str : str.substr(0, len) + '…'
183}
184
185u.messageTitle = function (msg) {
186 var c = msg.value.content
187 return u.truncate(c.title || c.text || msg.key, 40)
188}
189
190u.ifModifiedSince = function (req, lastMod) {
191 var ifModSince = req.headers['if-modified-since']
192 if (!ifModSince) return false
193 var d = new Date(ifModSince)
194 return d && Math.floor(d/1000) >= Math.floor(lastMod/1000)
195}
196
197u.decryptMessages = function (sbot) {
198 return paramap(function (msg, cb) {
199 var c = msg && msg.value && msg.value.content
200 if (c && typeof c === 'string' && c.slice(-4) === '.box') {
201 sbot.private.unbox(msg.value.content, function (err, content) {
202 if (err) return cb(null, msg) // leave message encrypted
203 var msg1 = {}
204 for (var k in msg) msg1[k] = msg[k]
205 msg1.value = {}
206 for (var j in msg.value) msg1.value[j] = msg.value[j]
207 msg1.value.private = true
208 msg1.value.content = content
209 if (!content.recps) {
210 sbot.whoami(function (err, feed) {
211 if (err) return cb(err)
212 content.recps = [msg1.value.author]
213 if (feed.id !== msg1.value.author) content.recps.push(feed.id)
214 cb(null, msg1)
215 })
216 } else cb(null, msg1)
217 })
218 } else cb(null, msg)
219 }, 4)
220}
221

Built with git-ssb-web