1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
var http = require('http')
var memo = require('asyncmemo')
var lru = require('lrucache')
var pkg = require('../package')
var u = require('./util')
var pull = require('pull-stream')
var ssbAvatar = require('ssb-avatar')
var Serve = require('./serve')
var Render = require('./render')
module.exports = App
function App(sbot, config) {
this.sbot = sbot
this.config = config
var conf = config.patchfoo || {}
this.port = conf.port || 8027
this.host = conf.host || '::1'
var base = conf.base || '/'
this.opts = {
base: base,
blob_base: conf.blob_base || conf.img_base || base,
img_base: conf.img_base || base,
emoji_base: conf.emoji_base || (base + 'emoji/'),
}
sbot.get = memo({cache: lru(100)}, sbot.get)
this.getMsg = memo({cache: lru(100)}, getMsgWithValue, sbot)
this.getAbout = memo({cache: lru(100)}, getAbout, sbot, sbot.id)
this.unboxContent = memo({cache: lru(100)}, sbot.private.unbox)
this.unboxMsg = this.unboxMsg.bind(this)
this.render = new Render(this, this.opts)
}
App.prototype.go = function () {
var self = this
http.createServer(function (req, res) {
new Serve(self, req, res).go()
}).listen(self.port, self.host, function () {
self.log('Listening on http://' + self.host + ':' + self.port)
})
}
var logPrefix = '[' + pkg.name + ']'
App.prototype.log = console.log.bind(console, logPrefix)
App.prototype.error = console.error.bind(console, logPrefix)
App.prototype.unboxMsg = function (msg, cb) {
var self = this
var c = msg.value.content
if (typeof c !== 'string') cb(null, msg)
else self.unboxContent(c, function (err, content) {
if (err) {
self.error('unbox:', err)
return cb(null, msg)
} else if (content === false) {
return cb(null, msg)
}
var m = {}
for (var k in msg) m[k] = msg[k]
m.value = {}
for (var k in msg.value) m.value[k] = msg.value[k]
m.value.content = content
m.value.private = true
cb(null, m)
})
}
App.prototype.search = function (opts) {
var search = this.sbot.fulltext && this.sbot.fulltext.search
if (!search) return pull.error(new Error('Missing fulltext search plugin'))
return search(opts)
}
App.prototype.getMsgDecrypted = function (key, cb) {
var self = this
this.getMsg(key, function (err, msg) {
if (err) return cb(err)
self.unboxMsg(msg, cb)
})
}
App.prototype.publish = function (content, cb) {
if (Array.isArray(content.recps)) {
recps = content.recps.map(u.linkDest)
this.sbot.private.publish(content, recps, cb)
} else {
this.sbot.publish(content, cb)
}
}
function getMsgWithValue(sbot, id, cb) {
sbot.get(id, function (err, value) {
if (err) return cb(err)
cb(null, {key: id, value: value})
})
}
function getAbout(sbot, src, id, cb) {
ssbAvatar(sbot, src, id, function (err, about) {
if (err) return cb(err)
var sigil = id && id[0] || '@'
if (about.name && about.name[0] !== sigil) {
about.name = sigil + about.name
}
cb(null, about)
})
}
App.prototype.createLogStream = function (opts) {
opts = opts || {}
return opts.sortByTimestamp
? this.sbot.createFeedStream(opts)
: this.sbot.createLogStream(opts)
}
|