git ssb

2+

mixmix / ticktack



Tree: 858e6680e313a0e7ea426317a18f59ff5c7098c8

Files: 858e6680e313a0e7ea426317a18f59ff5c7098c8 / ssb-server-blog-stats.js

4992 bytesRaw
1const FlumeView = require('flumeview-level')
2const get = require('lodash/get')
3const pull = require('pull-stream')
4const defer = require('pull-defer')
5const isBlog = require('scuttle-blog/isBlog')
6const { isMsg: isMsgRef } = require('ssb-ref')
7
8const getType = (msg) => get(msg, 'value.content.type')
9const getAuthor = (msg) => get(msg, 'value.author')
10const getCommentRoot = (msg) => get(msg, 'value.content.root')
11const getLikeRoot = (msg) => get(msg, 'value.content.vote.link')
12const getTimestamp = (msg) => get(msg, 'value.timestamp')
13
14const FLUME_VIEW_VERSION = 1
15
16module.exports = {
17 name: 'blogStats',
18 version: 1,
19 manifest: {
20 get: 'async',
21 read: 'source',
22 readBlogs: 'source',
23 getBlogs: 'async',
24 readComments: 'source',
25 readAllComments: 'source', // TEMP
26 readLikes: 'source'
27 },
28 init: (server, config) => {
29 console.log('initialising blog-stats plugin')
30 const myKey = server.keys.id
31
32 const view = server._flumeUse(
33 'internalblogStats',
34 FlumeView(FLUME_VIEW_VERSION, map)
35 )
36
37 return {
38 get: view.get,
39 read: view.read,
40 readBlogs,
41 getBlogs,
42 readComments,
43 readAllComments,
44 readLikes
45 // readShares
46 }
47
48 function map (msg, seq) {
49 var root
50
51 switch (getType(msg)) {
52 case 'blog':
53 if (isBlog(msg) && isMyMsg(msg)) return [['B', msg.key, getTimestamp(msg)]]
54 else return []
55
56 case 'vote':
57 root = getLikeRoot(msg)
58 // TODO figure out how to only store likes I care about
59 if (root) return [['L', root, getTimestamp(msg)]]
60 else return []
61
62 // Note this catches:
63 // - all likes, on all things D:
64 // - likes AND unlikes
65
66 case 'post':
67 root = getCommentRoot(msg)
68 // TODO figure out how to only store comments I care about
69 if (!root && isMyMsg(msg) && isPlog(msg)) return [['B', msg.key, getTimestamp(msg)]]
70 else if (root) return [['C', root, getTimestamp(msg)]]
71 else return []
72
73 // Note this catches:
74 // - all comments, on all things D:
75
76 default:
77 return []
78 }
79 }
80
81 // a Plog is a Blog shaped Post!
82 function isPlog (msg) {
83 // if (get(msg, 'value.content.text', '').length >= 2500) console.log(get(msg, 'value.content.text', '').length)
84 return get(msg, 'value.content.text', '').length >= 2500
85 }
86
87 function readBlogs (options = {}) {
88 const query = Object.assign({}, {
89 gte: ['B', null, null],
90 // null is the 'minimum' structure in bytewise ordering
91 lte: ['B', undefined, undefined],
92 reverse: true,
93 values: true,
94 keys: false,
95 seqs: false
96 }, options)
97
98 return view.read(query)
99 }
100
101 function getBlogs (options, cb) {
102 if (typeof options === 'function') {
103 cb = options
104 options = {}
105 }
106
107 pull(
108 readBlogs(options),
109 pull.collect(cb)
110 )
111 }
112
113 function readComments (blog, options = {}) {
114 var key = getBlogKey(blog)
115
116 const query = Object.assign({}, {
117 gt: ['C', key, null],
118 lt: ['C', key, undefined],
119 // undefined is the 'maximum' structure in bytewise ordering https://www.npmjs.com/package/bytewise#order-of-supported-structures
120 reverse: true,
121 values: true,
122 keys: false,
123 seqs: false
124 }, options)
125
126 return view.read(query)
127 }
128
129 function readAllComments () {
130 var source = defer.source()
131
132 getBlogs({ keys: true, values: false }, (err, data) => {
133 if (err) throw err
134
135 const blogIds = data.map(d => d[1])
136
137 const _source = pull(
138 view.read({
139 // live: true,
140 gt: [ 'B~', undefined, undefined ],
141 lt: [ 'C~', null, null ],
142 reverse: true,
143 values: true,
144 keys: true,
145 seqs: false
146 }),
147 pull.filter(result => {
148 return blogIds.includes(result.key[1])
149 }),
150 pull.map(result => result.value)
151 )
152
153 // pull(
154 // _source,
155 // pull.log()
156 // )
157 source.resolve(_source)
158 // source.resolve(pull.values([1, 2, 3, 4, ':)']))
159 })
160
161 return pull(
162 source
163 )
164 }
165
166 function readLikes (blog, options = {}) {
167 var key = getBlogKey(blog)
168
169 const query = Object.assign({}, {
170 gt: ['L', key, null],
171 lt: ['L', key, undefined],
172 reverse: true,
173 values: true,
174 keys: false,
175 seqs: false
176 }, options)
177
178 return view.read(query)
179 }
180
181 function getBlogKey (blog) {
182 if (isMsgRef(blog)) return blog
183 // else if (isMsgRef(blog.key) && isBlog(blog)) return blog.key
184 else if (isMsgRef(blog.key) && (isBlog(blog) || isPlog(blog))) return blog.key
185 }
186
187 function isMyMsg (msg) {
188 return getAuthor(msg) === myKey
189 }
190 }
191}
192

Built with git-ssb-web