Commit f180a1dc8e2f0250559dc2f9e7391cb613ce75b3
move temp sbot plugins, add private message index
Matt McKegg committed on 6/9/2017, 8:01:46 AMParent: 61da396c13a5c46a54a687885b89f5108fce69eb
Files changed
package.json | changed |
backlinks-plugin.js | deleted |
flumeview-links-raw.js | deleted |
sbot-plugins/backlinks.js | added |
sbot-plugins/lib/flumeview-links-raw.js | added |
sbot-plugins/private.js | added |
package.json | ||
---|---|---|
@@ -37,8 +37,9 @@ | ||
37 | 37 … | "deep-equal": "^1.0.1", |
38 | 38 … | "depnest": "^1.0.2", |
39 | 39 … | "emoji-named-characters": "^1.0.2", |
40 | 40 … | "es2040": "^1.2.4", |
41 … | + "flumeview-level": "^2.0.2", | |
41 | 42 … | "flumeview-query": "^3.0.3", |
42 | 43 … | "html-escape": "^2.0.0", |
43 | 44 … | "human-time": "0.0.1", |
44 | 45 … | "mutant": "^3.17.0", |
backlinks-plugin.js | ||
---|---|---|
@@ -1,74 +1,0 @@ | ||
1 | -// this shouldn't really be in patchcore, should be its own module | |
2 | - | |
3 | -var FlumeQueryLinks = require('./flumeview-links-raw') | |
4 | -var ref = require('ssb-ref') | |
5 | -var deepEqual = require('deep-equal') | |
6 | -var extend = require('xtend') | |
7 | -var matchChannel = /^#[^\s#]+$/ | |
8 | - | |
9 | -function isString (s) { | |
10 | - return typeof s === 'string' | |
11 | -} | |
12 | - | |
13 | -var indexes = [ | |
14 | - { key: 'DTS', value: [['dest'], ['timestamp']] }, | |
15 | - { key: 'DTY', value: [['dest'], ['value', 'content', 'type'], ['timestamp']] } | |
16 | -] | |
17 | - | |
18 | -var indexVersion = 0 | |
19 | - | |
20 | -exports.name = 'backlinks' | |
21 | -exports.version = require('./package.json').version | |
22 | -exports.manifest = { | |
23 | - read: 'source' | |
24 | -} | |
25 | - | |
26 | -exports.init = function (ssb, config) { | |
27 | - var s = ssb._flumeUse('backlinks', FlumeQueryLinks(indexes, extractLinks, indexVersion)) | |
28 | - var read = s.read | |
29 | - s.read = function (opts) { | |
30 | - if (!opts) opts = {} | |
31 | - // accept json, makes it easier to query from cli. | |
32 | - if (isString(opts)) { | |
33 | - opts = {query: JSON.parse(opts)} | |
34 | - } else if (isString(opts.query)) { | |
35 | - opts.query = JSON.parse(opts.query) | |
36 | - } | |
37 | - return read(opts) | |
38 | - } | |
39 | - return s | |
40 | -} | |
41 | - | |
42 | -function extractLinks (msg, emit) { | |
43 | - var links = new Set() | |
44 | - walk(msg.value.content, function (path, value) { | |
45 | - // HACK: handle legacy channel mentions | |
46 | - if (deepEqual(path, ['channel']) && typeof value === 'string' && value.length < 30) { | |
47 | - value = `#${value.replace(/\s/g, '')}` | |
48 | - } | |
49 | - | |
50 | - // TODO: should add channel matching to ref.type | |
51 | - if (ref.type(value) || isChannel(value)) { | |
52 | - links.add(value) | |
53 | - } | |
54 | - }) | |
55 | - links.forEach(link => { | |
56 | - emit(extend(msg, { | |
57 | - dest: link | |
58 | - })) | |
59 | - }) | |
60 | -} | |
61 | - | |
62 | -function isChannel (value) { | |
63 | - return typeof value === 'string' && value.length < 30 && matchChannel.test(value) | |
64 | -} | |
65 | - | |
66 | -function walk (obj, fn, prefix) { | |
67 | - if (obj && typeof obj === 'object') { | |
68 | - for (var k in obj) { | |
69 | - walk(obj[k], fn, (prefix || []).concat(k)) | |
70 | - } | |
71 | - } else { | |
72 | - fn(prefix, obj) | |
73 | - } | |
74 | -} |
flumeview-links-raw.js | ||
---|---|---|
@@ -1,105 +1,0 @@ | ||
1 | -// FORKED TO REMOVE FILTERING APPLIED TO INDEXED DATA RESULT | |
2 | - | |
3 | -'use strict' | |
4 | -var pull = require('pull-stream') | |
5 | -var query = require('flumeview-query/query') | |
6 | -var select = require('flumeview-query/select') | |
7 | -var mfr = require('map-filter-reduce') | |
8 | -var u = require('flumeview-query/util') | |
9 | -var Flatmap = require('pull-flatmap') | |
10 | -var FlumeViewLevel = require('flumeview-level') | |
11 | - | |
12 | -var isArray = Array.isArray | |
13 | - | |
14 | -//sorted index. | |
15 | - | |
16 | -//split this into TWO modules. flumeview-links and flumeview-query | |
17 | -module.exports = function (indexes, links, version) { | |
18 | - | |
19 | - if(!links) | |
20 | - links = function (data, emit) { emit(data) } | |
21 | - | |
22 | - function getIndexes (data, seq) { | |
23 | - var A = [] | |
24 | - indexes.forEach(function (index) { | |
25 | - var a = [index.key] | |
26 | - for(var i = 0; i < index.value.length; i++) { | |
27 | - var key = index.value[i] | |
28 | - if(!u.has(key, data)) return | |
29 | - a.push(u.get(key, data)) | |
30 | - } | |
31 | - a.push(seq) | |
32 | - A.push(a) | |
33 | - }) | |
34 | - return A | |
35 | - } | |
36 | - | |
37 | - var create = FlumeViewLevel(version || 1, function (value, seq) { | |
38 | - var A = [] | |
39 | - links(value, function (value) { | |
40 | - A = A.concat(getIndexes(value, seq)) | |
41 | - }) | |
42 | - return A | |
43 | - }) | |
44 | - | |
45 | - return function (log, name) { | |
46 | - | |
47 | - var index = create(log, name) | |
48 | - var read = index.read | |
49 | - | |
50 | - index.read = function (opts) { | |
51 | - | |
52 | - opts = opts || {} | |
53 | - var _opts = {} | |
54 | - var q, k | |
55 | - | |
56 | - if(isArray(opts.query)) { | |
57 | - q = opts.query[0].$filter || {} | |
58 | - } | |
59 | - else if(opts.query) { | |
60 | - q = opts.query | |
61 | - } | |
62 | - else | |
63 | - q = {} | |
64 | - | |
65 | - var index = select(indexes, q) | |
66 | - | |
67 | - if(!index) | |
68 | - return pull( | |
69 | - log.stream({ | |
70 | - values: true, seqs: false, live: opts.live, limit: opts.limit, reverse: opts.reverse | |
71 | - }), | |
72 | - Flatmap(function (data) { | |
73 | - var emit = [] | |
74 | - links(data, function (a) { | |
75 | - emit.push(a) | |
76 | - }) | |
77 | - return emit | |
78 | - }) | |
79 | - ) | |
80 | - var _opts = query(index, q) | |
81 | - | |
82 | - | |
83 | - _opts.values = false | |
84 | - _opts.keys = true | |
85 | - | |
86 | - _opts.reverse = !!opts.reverse | |
87 | - _opts.live = opts.live | |
88 | - _opts.old = opts.old | |
89 | - _opts.sync = opts.sync | |
90 | - | |
91 | - return pull( | |
92 | - read(_opts), | |
93 | - pull.map(function (data) { | |
94 | - if(data.sync) return data | |
95 | - var o = data.value | |
96 | - for(var i = 0; i < index.value.length; i++) | |
97 | - u.set(index.value[i], data.key[i+1], o) | |
98 | - return o | |
99 | - }), | |
100 | - isArray(opts.query) ? mfr(opts.query) : pull.through() | |
101 | - ) | |
102 | - } | |
103 | - return index | |
104 | - } | |
105 | -} |
sbot-plugins/backlinks.js | ||
---|---|---|
@@ -1,0 +1,62 @@ | ||
1 … | +// this shouldn't really be in patchcore, should be its own module (ssb-backlinks) | |
2 … | + | |
3 … | +var FlumeQueryLinks = require('./lib/flumeview-links-raw') | |
4 … | +var ref = require('ssb-ref') | |
5 … | +var deepEqual = require('deep-equal') | |
6 … | +var extend = require('xtend') | |
7 … | +var matchChannel = /^#[^\s#]+$/ | |
8 … | + | |
9 … | +var indexes = [ | |
10 … | + { key: 'DTS', value: [['dest'], ['timestamp']] }, | |
11 … | + { key: 'DTY', value: [['dest'], ['value', 'content', 'type'], ['timestamp']] } | |
12 … | +] | |
13 … | + | |
14 … | +var indexVersion = 0 | |
15 … | + | |
16 … | +exports.name = 'backlinks' | |
17 … | +exports.version = require('../package.json').version | |
18 … | +exports.manifest = { | |
19 … | + read: 'source' | |
20 … | +} | |
21 … | + | |
22 … | +exports.init = function (ssb, config) { | |
23 … | + return ssb._flumeUse( | |
24 … | + 'backlinks', | |
25 … | + FlumeQueryLinks(indexes, extractLinks, indexVersion) | |
26 … | + ) | |
27 … | +} | |
28 … | + | |
29 … | +function extractLinks (msg, emit) { | |
30 … | + var links = new Set() | |
31 … | + walk(msg.value.content, function (path, value) { | |
32 … | + // HACK: handle legacy channel mentions | |
33 … | + if (deepEqual(path, ['channel']) && typeof value === 'string' && value.length < 30) { | |
34 … | + value = `#${value.replace(/\s/g, '')}` | |
35 … | + } | |
36 … | + | |
37 … | + // TODO: should add channel matching to ref.type | |
38 … | + if (ref.type(value) || isChannel(value)) { | |
39 … | + links.add(value) | |
40 … | + } | |
41 … | + }) | |
42 … | + links.forEach(link => { | |
43 … | + console.log('index backlink', link) | |
44 … | + emit(extend(msg, { | |
45 … | + dest: link | |
46 … | + })) | |
47 … | + }) | |
48 … | +} | |
49 … | + | |
50 … | +function isChannel (value) { | |
51 … | + return typeof value === 'string' && value.length < 30 && matchChannel.test(value) | |
52 … | +} | |
53 … | + | |
54 … | +function walk (obj, fn, prefix) { | |
55 … | + if (obj && typeof obj === 'object') { | |
56 … | + for (var k in obj) { | |
57 … | + walk(obj[k], fn, (prefix || []).concat(k)) | |
58 … | + } | |
59 … | + } else { | |
60 … | + fn(prefix, obj) | |
61 … | + } | |
62 … | +} |
sbot-plugins/lib/flumeview-links-raw.js | |||
---|---|---|---|
@@ -1,0 +1,105 @@ | |||
1 … | +// FORKED TO REMOVE FILTERING APPLIED TO INDEXED DATA RESULT | ||
2 … | + | ||
3 … | +'use strict' | ||
4 … | +var pull = require('pull-stream') | ||
5 … | +var query = require('flumeview-query/query') | ||
6 … | +var select = require('flumeview-query/select') | ||
7 … | +var mfr = require('map-filter-reduce') | ||
8 … | +var u = require('flumeview-query/util') | ||
9 … | +var Flatmap = require('pull-flatmap') | ||
10 … | +var FlumeViewLevel = require('flumeview-level') | ||
11 … | + | ||
12 … | +var isArray = Array.isArray | ||
13 … | + | ||
14 … | +//sorted index. | ||
15 … | + | ||
16 … | +//split this into TWO modules. flumeview-links and flumeview-query | ||
17 … | +module.exports = function (indexes, links, version) { | ||
18 … | + | ||
19 … | + if(!links) | ||
20 … | + links = function (data, emit) { emit(data) } | ||
21 … | + | ||
22 … | + function getIndexes (data, seq) { | ||
23 … | + var A = [] | ||
24 … | + indexes.forEach(function (index) { | ||
25 … | + var a = [index.key] | ||
26 … | + for(var i = 0; i < index.value.length; i++) { | ||
27 … | + var key = index.value[i] | ||
28 … | + if(!u.has(key, data)) return | ||
29 … | + a.push(u.get(key, data)) | ||
30 … | + } | ||
31 … | + a.push(seq) | ||
32 … | + A.push(a) | ||
33 … | + }) | ||
34 … | + return A | ||
35 … | + } | ||
36 … | + | ||
37 … | + var create = FlumeViewLevel(version || 1, function (value, seq) { | ||
38 … | + var A = [] | ||
39 … | + links(value, function (value) { | ||
40 … | + A = A.concat(getIndexes(value, seq)) | ||
41 … | + }) | ||
42 … | + return A | ||
43 … | + }) | ||
44 … | + | ||
45 … | + return function (log, name) { | ||
46 … | + | ||
47 … | + var index = create(log, name) | ||
48 … | + var read = index.read | ||
49 … | + | ||
50 … | + index.read = function (opts) { | ||
51 … | + | ||
52 … | + opts = opts || {} | ||
53 … | + var _opts = {} | ||
54 … | + var q, k | ||
55 … | + | ||
56 … | + if(isArray(opts.query)) { | ||
57 … | + q = opts.query[0].$filter || {} | ||
58 … | + } | ||
59 … | + else if(opts.query) { | ||
60 … | + q = opts.query | ||
61 … | + } | ||
62 … | + else | ||
63 … | + q = {} | ||
64 … | + | ||
65 … | + var index = select(indexes, q) | ||
66 … | + | ||
67 … | + if(!index) | ||
68 … | + return pull( | ||
69 … | + log.stream({ | ||
70 … | + values: true, seqs: false, live: opts.live, limit: opts.limit, reverse: opts.reverse | ||
71 … | + }), | ||
72 … | + Flatmap(function (data) { | ||
73 … | + var emit = [] | ||
74 … | + links(data, function (a) { | ||
75 … | + emit.push(a) | ||
76 … | + }) | ||
77 … | + return emit | ||
78 … | + }) | ||
79 … | + ) | ||
80 … | + var _opts = query(index, q) | ||
81 … | + | ||
82 … | + | ||
83 … | + _opts.values = false | ||
84 … | + _opts.keys = true | ||
85 … | + | ||
86 … | + _opts.reverse = !!opts.reverse | ||
87 … | + _opts.live = opts.live | ||
88 … | + _opts.old = opts.old | ||
89 … | + _opts.sync = opts.sync | ||
90 … | + | ||
91 … | + return pull( | ||
92 … | + read(_opts), | ||
93 … | + pull.map(function (data) { | ||
94 … | + if(data.sync) return data | ||
95 … | + var o = data.value | ||
96 … | + for(var i = 0; i < index.value.length; i++) | ||
97 … | + u.set(index.value[i], data.key[i+1], o) | ||
98 … | + return o | ||
99 … | + }), | ||
100 … | + isArray(opts.query) ? mfr(opts.query) : pull.through() | ||
101 … | + ) | ||
102 … | + } | ||
103 … | + return index | ||
104 … | + } | ||
105 … | +} |
sbot-plugins/private.js | ||
---|---|---|
@@ -1,0 +1,92 @@ | ||
1 … | +// this shouldn't really be in patchcore, should be its own module (ssb-private) | |
2 … | + | |
3 … | +var ssbKeys = require('ssb-keys') | |
4 … | +var FlumeQueryLinks = require('./lib/flumeview-links-raw') | |
5 … | +var explain = require('explain-error') | |
6 … | +var pull = require('pull-stream') | |
7 … | + | |
8 … | +var indexes = [ | |
9 … | + { key: 'TSP', value: ['timestamp'] }, | |
10 … | + { key: 'ATY', value: [['value', 'author'], ['value', 'content', 'type'], 'timestamp'] } | |
11 … | +] | |
12 … | + | |
13 … | +var indexVersion = 0 | |
14 … | + | |
15 … | +exports.name = 'private' | |
16 … | +exports.version = require('../package.json').version | |
17 … | +exports.manifest = { | |
18 … | + publish: 'async', | |
19 … | + unbox: 'sync', | |
20 … | + read: 'source' | |
21 … | +} | |
22 … | + | |
23 … | +exports.init = function (ssb, config) { | |
24 … | + var index = ssb._flumeUse( | |
25 … | + `private-${ssb.id.slice(1, 10)}`, | |
26 … | + FlumeQueryLinks(indexes, (msg, emit) => { | |
27 … | + var value = unbox(msg) | |
28 … | + if (value) { | |
29 … | + emit(value) | |
30 … | + } | |
31 … | + }, indexVersion) | |
32 … | + ) | |
33 … | + | |
34 … | + return { | |
35 … | + read: function (opts) { | |
36 … | + return pull( | |
37 … | + index.read(opts), | |
38 … | + pull.map(unbox) | |
39 … | + ) | |
40 … | + }, | |
41 … | + | |
42 … | + unbox: function (msgOrData) { | |
43 … | + if (typeof msgOrData === 'string') { | |
44 … | + try { | |
45 … | + var data = ssbKeys.unbox(msgOrData, ssb.keys.private) | |
46 … | + } catch (e) { | |
47 … | + throw explain(e, 'failed to decrypt') | |
48 … | + } | |
49 … | + return data | |
50 … | + } else if (msgOrData && msgOrData.value && msgOrData.value.content === 'string') { | |
51 … | + return unbox(msgOrData) | |
52 … | + } | |
53 … | + }, | |
54 … | + | |
55 … | + publish: function (content, recps, cb) { | |
56 … | + try { | |
57 … | + var ciphertext = ssbKeys.box(content, recps) | |
58 … | + } catch (e) { | |
59 … | + return cb(explain(e, 'failed to encrypt')) | |
60 … | + } | |
61 … | + ssb.publish(ciphertext, cb) | |
62 … | + } | |
63 … | + } | |
64 … | + | |
65 … | + function unbox (msg) { | |
66 … | + if (typeof msg.value.content === 'string') { | |
67 … | + var value = unboxValue(msg.value) | |
68 … | + if (value) { | |
69 … | + return { | |
70 … | + key: msg.key, value: value, timestamp: msg.timestamp | |
71 … | + } | |
72 … | + } | |
73 … | + } | |
74 … | + } | |
75 … | + | |
76 … | + function unboxValue (value) { | |
77 … | + var plaintext = null | |
78 … | + try { | |
79 … | + plaintext = ssbKeys.unbox(value.content, ssb.keys.private) | |
80 … | + } catch (ex) {} | |
81 … | + if (!plaintext) return null | |
82 … | + return { | |
83 … | + previous: value.previous, | |
84 … | + author: value.author, | |
85 … | + sequence: value.sequence, | |
86 … | + timestamp: value.timestamp, | |
87 … | + hash: value.hash, | |
88 … | + content: plaintext, | |
89 … | + private: true | |
90 … | + } | |
91 … | + } | |
92 … | +} |
Built with git-ssb-web