git ssb

2+

mixmix / ticktack



Tree: 2e6dc4c90652f68f6fc799235fb4a887ecef021f

Files: 2e6dc4c90652f68f6fc799235fb4a887ecef021f / ssb-server-blog-stats.js

4073 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 = 2
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 // getLikes
43 // getComments
44 }
45
46 function map (msg, seq) {
47 var root
48
49 switch (getType(msg)) {
50 case 'blog':
51 if (isBlog(msg) && isMyMsg(msg)) return [['B', msg.key, getTimestamp(msg)]]
52 else return []
53
54 case 'vote':
55 // process.stdout.write('L')
56 root = getLikeRoot(msg)
57 // TODO figure out how to only store likes I care about
58 if (root) return [['L', root, getTimestamp(msg)]]
59 else return []
60
61 // Note this catches:
62 // - all likes, on all things D:
63 // - likes AND unlikes
64
65 case 'post':
66 // process.stdout.write('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 // return false // Disable plogs
84 if (get(msg, 'value.content.text', '').length >= 3000) console.log(get(msg, 'value.content.text', '').length)
85 return get(msg, 'value.content.text', '').length >= 3000
86 }
87
88 function readBlogs (options = {}) {
89 const query = Object.assign({}, {
90 gte: ['B', null, null],
91 // null is the 'minimum' structure in bytewise ordering
92 lte: ['B', undefined, undefined],
93 reverse: true,
94 values: true,
95 keys: false,
96 seqs: false
97 }, options)
98
99 return view.read(query)
100 }
101
102 function getBlogs (options, cb) {
103 pull(
104 readBlogs(options),
105 pull.collect(cb)
106 )
107 }
108
109 function readComments (blog, options = {}) {
110 var key = getBlogKey(blog)
111
112 const query = Object.assign({}, {
113 gt: ['C', key, null],
114 lt: ['C', key, undefined],
115 // undefined is the 'maximum' structure in bytewise ordering https://www.npmjs.com/package/bytewise#order-of-supported-structures
116 reverse: true,
117 values: true,
118 keys: false,
119 seqs: false
120 }, options)
121
122 return view.read(query)
123 }
124
125 function readLikes (blog, options = {}) {
126 var key = getBlogKey(blog)
127
128 const query = Object.assign({}, {
129 gt: ['L', key, null],
130 lt: ['L', key, undefined],
131 reverse: true,
132 values: true,
133 keys: false,
134 seqs: false
135 }, options)
136
137 return view.read(query)
138 }
139
140 function getBlogKey (blog) {
141 if (isMsgRef(blog)) return blog
142 // else if (isMsgRef(blog.key) && isBlog(blog)) return blog.key
143 else if (isMsgRef(blog.key) && (isBlog(blog) || isPlog(blog))) return blog.key
144 }
145
146 function isMyMsg (msg) {
147 return getAuthor(msg) === myKey
148 }
149 }
150}
151

Built with git-ssb-web