Commit 37d41ff61b662f01ec14293463dbe5afff14adf0
initial
Dominic Tarr committed on 5/15/2019, 9:45:39 AMFiles changed
LICENSE | added |
README.md | added |
all.js | added |
bin.js | added |
gathering.js/index.js | added |
get.js | added |
index.js | added |
package.json | added |
reduce.js | added |
render.js | added |
LICENSE | ||
---|---|---|
@@ -1,0 +1,22 @@ | ||
1 … | +Copyright (c) 2018 Dominic Tarr | |
2 … | + | |
3 … | +Permission is hereby granted, free of charge, | |
4 … | +to any person obtaining a copy of this software and | |
5 … | +associated documentation files (the "Software"), to | |
6 … | +deal in the Software without restriction, including | |
7 … | +without limitation the rights to use, copy, modify, | |
8 … | +merge, publish, distribute, sublicense, and/or sell | |
9 … | +copies of the Software, and to permit persons to whom | |
10 … | +the Software is furnished to do so, | |
11 … | +subject to the following conditions: | |
12 … | + | |
13 … | +The above copyright notice and this permission notice | |
14 … | +shall be included in all copies or substantial portions of the Software. | |
15 … | + | |
16 … | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 … | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
18 … | +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
19 … | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
20 … | +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
21 … | +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
22 … | +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
all.js | ||
---|---|---|
@@ -1,0 +1,24 @@ | ||
1 … | +var pull = require('pull-stream') | |
2 … | + | |
3 … | +module.exports = function (opts) { | |
4 … | + var sbot = this.sbot, api = this.api | |
5 … | + return ['div.Gatherings', | |
6 … | + ['title', 'Gatherings'], | |
7 … | + pull( | |
8 … | + sbot.query.read({ | |
9 … | + query: [{$filter:{ | |
10 … | + value: {content: {type: 'gathering'}}, | |
11 … | + author: opts.author, | |
12 … | + }}], | |
13 … | + limit: 30, | |
14 … | + reverse: true | |
15 … | + }), | |
16 … | + pull.map(function (data) { | |
17 … | + return api.gathering({ | |
18 … | + id: data.key, private: !!opts.private, | |
19 … | + }) | |
20 … | + }) | |
21 … | + ) | |
22 … | + ] | |
23 … | +} | |
24 … | + |
bin.js | ||
---|---|---|
@@ -1,0 +1,9 @@ | ||
1 … | + | |
2 … | +require('ssb-client')(function (err, sbot) { | |
3 … | + if(err) throw err | |
4 … | + require('./get')(sbot, process.argv[2], function (err, value) { | |
5 … | + if(err) throw err | |
6 … | + sbot.close() | |
7 … | + console.log(JSON.stringify(value, null, 2)) | |
8 … | + }) | |
9 … | +}) |
gathering.js/index.js | ||
---|---|---|
@@ -1,0 +1,16 @@ | ||
1 … | +var get = require('./get') | |
2 … | +var Render = require('./render') | |
3 … | + | |
4 … | +//TODO: markdown. and attending link | |
5 … | + | |
6 … | +module.exports = function (opts) { | |
7 … | + var api = this.api, contex = this.context | |
8 … | + var sbot = this.sbot | |
9 … | + return function (cb) { | |
10 … | + get(sbot, opts.id, function (err, gathering) { | |
11 … | + if(err) return cb(err) | |
12 … | + cb(null, Render(api, gathering)) | |
13 … | + }) | |
14 … | + } | |
15 … | +} | |
16 … | + |
get.js | ||
---|---|---|
@@ -1,0 +1,41 @@ | ||
1 … | +var Reduce = require('./reduce') | |
2 … | +var pull = require('pull-stream') | |
3 … | + | |
4 … | +module.exports = function (sbot, opts, cb) { | |
5 … | + if("string" == typeof opts) | |
6 … | + opts = {id: opts, private: false} | |
7 … | + var id = opts.id | |
8 … | + sbot.get(opts, function (err, msg) { | |
9 … | + if(err) return cb(err) | |
10 … | + var seen = {} | |
11 … | + if(msg.content.type !== 'gathering') | |
12 … | + return cb(new Error('not a gathering, was:'+msg.content.type)) | |
13 … | + var root = {key:id, value: msg} | |
14 … | + seen[id] = true | |
15 … | + pull( | |
16 … | + sbot.links({ | |
17 … | + dest: id, values: true, | |
18 … | + rel: opts.replies ? undefined : 'about' | |
19 … | + }), | |
20 … | + pull.filter(function (data) { | |
21 … | + var type = data.value.content.type | |
22 … | + //exclude backlinking posts, except replies | |
23 … | + if(type == 'post' && data.value.content.root != id) | |
24 … | + return | |
25 … | + //the root message is type gathering | |
26 … | + //I really think the "about" message is heavily overloaded | |
27 … | + if(type !== 'gathering' && type !== 'about') | |
28 … | + return | |
29 … | + if(seen[data.key]) return false | |
30 … | + return seen[data.key] = true | |
31 … | + }), | |
32 … | + pull.collect(function (err, ary) { | |
33 … | + if(err) return cb(err) | |
34 … | + ary.unshift(root) | |
35 … | + var r = Reduce(ary) | |
36 … | + cb(null, r) | |
37 … | + }) | |
38 … | + ) | |
39 … | + }) | |
40 … | +} | |
41 … | + |
index.js | ||
---|---|---|
@@ -1,0 +1,20 @@ | ||
1 … | + | |
2 … | +module.exports = function (sbot) { | |
3 … | + return function (use) { | |
4 … | + console.log("GROUP") | |
5 … | + use('event', function (opts, apply, req) { | |
6 … | + opts.id = opts.id || "%eFzw9Qca1MUppBgyGG0e2AwzlwonvwDk2GDyxM9B37c=.sha256" | |
7 … | + return function (cb) { | |
8 … | + require('./get')(sbot, opts, function (err, thread) { | |
9 … | + cb(null, require('./render')(apply, thread)) | |
10 … | + }) | |
11 … | + } | |
12 … | + }) | |
13 … | + use.map('messages', 'gathering', 'event') | |
14 … | + } | |
15 … | +} | |
16 … | + | |
17 … | + | |
18 … | + | |
19 … | + | |
20 … | + |
package.json | |||
---|---|---|---|
@@ -1,0 +1,22 @@ | |||
1 … | +{ | ||
2 … | + "name": "yap-gatherings", | ||
3 … | + "description": "", | ||
4 … | + "version": "1.0.0", | ||
5 … | + "homepage": "https://github.com/dominictarr/yap-gatherings", | ||
6 … | + "repository": { | ||
7 … | + "type": "git", | ||
8 … | + "url": "git://github.com/dominictarr/yap-gatherings.git" | ||
9 … | + }, | ||
10 … | + "dependencies": { | ||
11 … | + "pull-stream": "^3.6.9", | ||
12 … | + "ssb-sort": "^1.1.0" | ||
13 … | + }, | ||
14 … | + "devDependencies": { | ||
15 … | + "ssb-client": "^4.6.0" | ||
16 … | + }, | ||
17 … | + "scripts": { | ||
18 … | + "test": "set -e; for t in test/*.js; do node $t; done" | ||
19 … | + }, | ||
20 … | + "author": "Dominic Tarr <dominic.tarr@gmail.com> (http://dominictarr.com)", | ||
21 … | + "license": "MIT" | ||
22 … | +} |
reduce.js | ||
---|---|---|
@@ -1,0 +1,44 @@ | ||
1 … | +var sort = require('ssb-sort') | |
2 … | + | |
3 … | +module.exports = function (thread) { | |
4 … | + thread = sort(thread) | |
5 … | + var r = thread.reduce(function (acc, data) { | |
6 … | + if(data.value.content.type == 'post') | |
7 … | + acc.replies.push(acc) | |
8 … | + else { | |
9 … | + console.log('DATA', data) | |
10 … | + var c = data.value.content | |
11 … | + for(var k in c) | |
12 … | + //if(Object.hasOwnProperty(acc.value, k)) { | |
13 … | + if(Array.isArray(acc.value[k])) | |
14 … | + acc.value[k] = acc.value[k].concat(c[k]) | |
15 … | + else if(typeof c[k] == typeof acc.value[k]) | |
16 … | + acc.value[k] = c[k] | |
17 … | + //} | |
18 … | + } | |
19 … | + return acc | |
20 … | + }, { | |
21 … | + type: 'gathering', | |
22 … | + creator: thread[0].value.author, | |
23 … | + created: thread[0].value.timestamp, | |
24 … | + value:{ | |
25 … | + progenitor: '', | |
26 … | + startDateTime: {epoch: thread[0].value.timestamp, ts: ''}, | |
27 … | + title: '', | |
28 … | + location: '', | |
29 … | + description: '', | |
30 … | + image: {}, | |
31 … | + mentions: [], | |
32 … | + attendee: [] | |
33 … | + }, | |
34 … | + replies: [] | |
35 … | + }) | |
36 … | + r.root = thread[0].key | |
37 … | + r.branch = sort.heads(thread) | |
38 … | + return r | |
39 … | +} | |
40 … | + | |
41 … | + | |
42 … | + | |
43 … | + | |
44 … | + |
render.js | ||
---|---|---|
@@ -1,0 +1,30 @@ | ||
1 … | +module.exports = function (apply, gathering) { | |
2 … | + var attending = {} | |
3 … | + gathering.value.attendee.forEach(function (attendee) { | |
4 … | + if(attendee.link) attending[attendee.link] = true | |
5 … | + if(attendee.remove) delete attending[attendee.link] | |
6 … | + }) | |
7 … | + return ['div.Gathering', | |
8 … | + apply('avatar', {id: gathering.creator, name: true, image: true}),' ', | |
9 … | + ['label', 'created at: ', new Date(gathering.created)], | |
10 … | + ['h1', | |
11 … | + ['a', | |
12 … | + {href: '/gathering?id='+encodeURIComponent(gathering.root)}, | |
13 … | + gathering.value.title | |
14 … | + ] | |
15 … | + ], | |
16 … | + ['label', new Date(gathering.value.startDateTime.epoch).toString()], | |
17 … | + ['p', gathering.value.description], | |
18 … | + gathering.value.image | |
19 … | + ? ['img', {href: 'http://localhost:8989/blobs/get/'+encodeURIComponent(gathering.value.image.link)}] | |
20 … | + : '', | |
21 … | + ['div.Attending', | |
22 … | + 'attending:', | |
23 … | + Object.keys(attending).map(function (id) { | |
24 … | + return apply('avatar', id) | |
25 … | + }) | |
26 … | + ] | |
27 … | + ] | |
28 … | +} | |
29 … | + | |
30 … | + |
Built with git-ssb-web