git ssb

2+

mixmix / ticktack



Tree: 1b46fe809a87f906b19ab7dad059971d13730b4f

Files: 1b46fe809a87f906b19ab7dad059971d13730b4f / ssb-server-blog-stats.js

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

Built with git-ssb-web