mirror of
https://framagit.org/les/gancio.git
synced 2025-02-01 00:52:01 +01:00
commenting from federation
This commit is contained in:
parent
37b63fc767
commit
5b013829fe
11 changed files with 137 additions and 21 deletions
|
@ -64,12 +64,12 @@ export default {
|
||||||
.map(e => ({
|
.map(e => ({
|
||||||
key: e.id,
|
key: e.id,
|
||||||
dot: getColor(e),
|
dot: getColor(e),
|
||||||
dates: new Date(e.start_datetime)})))
|
dates: new Date(e.start_datetime*1000)})))
|
||||||
|
|
||||||
attributes = attributes.concat(this.filteredEventsWithPast
|
attributes = attributes.concat(this.filteredEventsWithPast
|
||||||
.filter(e => e.multidate)
|
.filter(e => e.multidate)
|
||||||
.map( e => ({ key: e.id, highlight: getColor(e), dates: {
|
.map( e => ({ key: e.id, highlight: getColor(e), dates: {
|
||||||
start: new Date(e.start_datetime), end: new Date(e.end_datetime) }})))
|
start: new Date(e.start_datetime*1000), end: new Date(e.end_datetime*1000) }})))
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,16 +40,13 @@
|
||||||
el-button(plain type='primary' size='mini' @click='$router.replace(`/add/${event.id}`)') {{$t('common.edit')}}
|
el-button(plain type='primary' size='mini' @click='$router.replace(`/add/${event.id}`)') {{$t('common.edit')}}
|
||||||
|
|
||||||
//- comments
|
//- comments
|
||||||
#comments.card-body(v-if='event.activitypub_id && settings')
|
#comments.card-body(v-if='event.comments.length')
|
||||||
strong {{$t('common.related')}} -
|
strong {{$t('common.related')}} -
|
||||||
a(:href='`https://${settings.mastodon_instance}/web/statuses/${event.activitypub_id}`') {{$t('common.add')}}
|
//a(:href='') {{$t('common.add')}}
|
||||||
|
|
||||||
.card-header(v-for='comment in event.comments' :key='comment.id')
|
.card-header(v-for='comment in event.comments' :key='comment.id')
|
||||||
img.avatar(:src='comment.data.account.avatar')
|
a.float-right(:href='comment.data.url')
|
||||||
strong {{comment.data.account.display_name}} @{{comment.data.account.username}}
|
small {{comment.data.published|datetime}}
|
||||||
//- a.float-right(:href='comment.data.url')
|
|
||||||
a.float-right(:href='`https://${settings.mastodon_instance}/web/statuses/${comment.data.id}`')
|
|
||||||
small {{comment.data.created_at|datetime}}
|
|
||||||
div.mt-1(v-html='comment_filter(comment.data.content)')
|
div.mt-1(v-html='comment_filter(comment.data.content)')
|
||||||
img(v-for='img in comment.data.media_attachments' :src='img.url')
|
img(v-for='img in comment.data.media_attachments' :src='img.url')
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,10 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
},
|
},
|
||||||
image_path: DataTypes.STRING,
|
image_path: DataTypes.STRING,
|
||||||
is_visible: DataTypes.BOOLEAN,
|
is_visible: DataTypes.BOOLEAN,
|
||||||
activitypub_id: {
|
|
||||||
type: DataTypes.STRING(18),
|
|
||||||
index: true
|
|
||||||
},
|
|
||||||
recurrent: DataTypes.JSON,
|
recurrent: DataTypes.JSON,
|
||||||
// parent: DataTypes.INTEGER
|
// parent: DataTypes.INTEGER
|
||||||
|
likes: { type: DataTypes.JSON, defaultValue: [] },
|
||||||
|
boost: { type: DataTypes.JSON, defaultValue: [] }
|
||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
event.associate = function (models) {
|
event.associate = function (models) {
|
||||||
|
|
24
server/federation/comments.js
Normal file
24
server/federation/comments.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
const { event: Event, comment: Comment } = require('../api/models')
|
||||||
|
const config = require('config')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async create (body) {
|
||||||
|
|
||||||
|
//search for related event
|
||||||
|
const inReplyTo = body.object.inReplyTo
|
||||||
|
const event_id = inReplyTo.match(`${config.baseurl}/federation/m/(.*)`)[1]
|
||||||
|
|
||||||
|
console.error(event_id)
|
||||||
|
const event = await Event.findByPk(event_id)
|
||||||
|
if (!event) {
|
||||||
|
return console.error('event not found!')
|
||||||
|
}
|
||||||
|
|
||||||
|
await Comment.create({
|
||||||
|
activitypub_id: body.object.id,
|
||||||
|
data: body.object,
|
||||||
|
eventId: event.id
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,12 +23,15 @@ const Helpers = {
|
||||||
const signature_b64 = signature.toString('base64')
|
const signature_b64 = signature.toString('base64')
|
||||||
const header = `keyId="${config.baseurl}/federation/u/${user.username}",headers="(request-target) host date",signature="${signature_b64}"`
|
const header = `keyId="${config.baseurl}/federation/u/${user.username}",headers="(request-target) host date",signature="${signature_b64}"`
|
||||||
console.error('header ', header)
|
console.error('header ', header)
|
||||||
|
console.error('requestTo ', toInbox)
|
||||||
|
console.error('host ', toOrigin.hostname)
|
||||||
request({
|
request({
|
||||||
url: toInbox,
|
url: toInbox,
|
||||||
headers: {
|
headers: {
|
||||||
'Host': toOrigin.hostname,
|
'Host': toOrigin.hostname,
|
||||||
'Date': d.toUTCString(),
|
'Date': d.toUTCString(),
|
||||||
'Signature': header
|
'Signature': header,
|
||||||
|
'Content-Type': 'application/activity+json; charset=utf-8'
|
||||||
},
|
},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
json: true,
|
json: true,
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
const config = require('config')
|
const config = require('config')
|
||||||
const bodyParser = require('body-parser')
|
|
||||||
const cors = require('cors')
|
const cors = require('cors')
|
||||||
const Follows = require('./follows')
|
const Follows = require('./follows')
|
||||||
const Users = require('./users')
|
const Users = require('./users')
|
||||||
|
const { event: Event, user: User } = require('../api/models')
|
||||||
|
const Comments = require('./comments')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Federation is calling!
|
* Federation is calling!
|
||||||
* ref: https://www.w3.org/TR/activitypub/#Overview
|
* ref: https://www.w3.org/TR/activitypub/#Overview
|
||||||
*/
|
*/
|
||||||
router.use(cors())
|
router.use(cors())
|
||||||
router.use(bodyParser.json({type: 'application/activity+json'}))
|
router.use(express.json({type: ['application/json', 'application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"']}))
|
||||||
|
|
||||||
|
|
||||||
|
router.get('/m/:event_id', async (req, res) => {
|
||||||
|
const event_id = req.params.event_id
|
||||||
|
if (req.accepts('html')) return res.redirect(301, `/event/${event_id}`)
|
||||||
|
|
||||||
|
console.error('Not asked for html!')
|
||||||
|
const event = await Event.findByPk(req.params.event_id, { include: [ User ] })
|
||||||
|
if (!event) return res.status(404).send('Not found')
|
||||||
|
return res.json(event.toAP(event.user.username))
|
||||||
|
})
|
||||||
|
|
||||||
// get any message coming from federation
|
// get any message coming from federation
|
||||||
// Federation is calling!
|
// Federation is calling!
|
||||||
|
@ -26,16 +38,40 @@ router.post('/u/:name/inbox', async (req, res) => {
|
||||||
Follows.follow(req, res, b, targetOrigin, domain)
|
Follows.follow(req, res, b, targetOrigin, domain)
|
||||||
break
|
break
|
||||||
case 'Undo':
|
case 'Undo':
|
||||||
|
// unfollow || unlike
|
||||||
|
if (b.object.type === 'Follow') {
|
||||||
Follows.unfollow(req, res, b, targetOrigin, domain)
|
Follows.unfollow(req, res, b, targetOrigin, domain)
|
||||||
|
} else if (b.object.type === 'Like') {
|
||||||
|
console.error('Unlike!')
|
||||||
|
} else if (b.object.type === 'Announce') {
|
||||||
|
console.error('Unboost')
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case 'Announce':
|
case 'Announce':
|
||||||
console.error('This is a boost ?')
|
console.error('This is a boost ?')
|
||||||
break
|
break
|
||||||
case 'Note':
|
case 'Note':
|
||||||
console.error('this is a note ! I should not receive this')
|
console.error('This is a note ! I probably should not receive this')
|
||||||
|
break
|
||||||
|
case 'Like':
|
||||||
|
console.error('This is a like!')
|
||||||
|
|
||||||
|
break
|
||||||
|
case 'Delete':
|
||||||
|
console.error('Delete a comment ?!?!')
|
||||||
|
break
|
||||||
|
case 'Announce':
|
||||||
|
console.error('Boost!')
|
||||||
break
|
break
|
||||||
case 'Create':
|
case 'Create':
|
||||||
console.error('Create what? This is probably a reply', b.object.type)
|
// this is a reply
|
||||||
|
if (b.object.type === 'Note' && b.object.inReplyTo) {
|
||||||
|
console.error('this is a reply to an event')
|
||||||
|
Comments.create(b)
|
||||||
|
} else {
|
||||||
|
console.error('Create what? ', b.object.type)
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,7 +16,6 @@ module.exports = {
|
||||||
id: `${config.baseurl}/federation/u/${name}`,
|
id: `${config.baseurl}/federation/u/${name}`,
|
||||||
type: 'Person',
|
type: 'Person',
|
||||||
preferredUsername: name,
|
preferredUsername: name,
|
||||||
nodeInfo2Url: `${config.baseurl}/.well-known/x-nodeinfo2`,
|
|
||||||
inbox: `${config.baseurl}/federation/u/${name}/inbox`,
|
inbox: `${config.baseurl}/federation/u/${name}/inbox`,
|
||||||
outbox: `${config.baseurl}/federation/u/${name}/outbox`,
|
outbox: `${config.baseurl}/federation/u/${name}/outbox`,
|
||||||
followers: `${config.baseurl}/federation/u/${name}/followers`,
|
followers: `${config.baseurl}/federation/u/${name}/followers`,
|
||||||
|
@ -26,6 +25,7 @@ module.exports = {
|
||||||
publicKeyPem: get(user, 'rsa.publicKey', '')
|
publicKeyPem: get(user, 'rsa.publicKey', '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
res.type('application/activity+json; charset=utf-8')
|
||||||
res.json(ret)
|
res.json(ret)
|
||||||
},
|
},
|
||||||
async followers (req, res) {
|
async followers (req, res) {
|
||||||
|
@ -80,6 +80,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
// last: `${config.baseurl}/federation/u/${name}/outbox?page=true`
|
// last: `${config.baseurl}/federation/u/${name}/outbox?page=true`
|
||||||
}
|
}
|
||||||
|
res.type('application/activity+json; charset=utf-8')
|
||||||
return res.json(ret)
|
return res.json(ret)
|
||||||
}
|
}
|
||||||
const ret = {
|
const ret = {
|
||||||
|
@ -89,6 +90,7 @@ module.exports = {
|
||||||
partOf: `${config.baseurl}/federation/u/${name}/outbox`,
|
partOf: `${config.baseurl}/federation/u/${name}/outbox`,
|
||||||
orderedItems: user.events.map(e => e.toAP(user.username))
|
orderedItems: user.events.map(e => e.toAP(user.username))
|
||||||
}
|
}
|
||||||
|
res.type('application/activity+json; charset=utf-8')
|
||||||
res.json(ret)
|
res.json(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ router.get('/', async (req, res) => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
res.set('Content-Type', 'application/jrd+json; charset=utf-8')
|
||||||
res.json(ret)
|
res.json(ret)
|
||||||
})
|
})
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
27
server/migrations/20190801105908-likes.js
Normal file
27
server/migrations/20190801105908-likes.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
queryInterface.addColumn('event', 'likes', {
|
||||||
|
type: Sequelize.JSON,
|
||||||
|
defaultValue: []
|
||||||
|
})
|
||||||
|
/*
|
||||||
|
Add altering commands here.
|
||||||
|
Return a promise to correctly handle asynchronicity.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface, Sequelize) => {
|
||||||
|
/*
|
||||||
|
Add reverting commands here.
|
||||||
|
Return a promise to correctly handle asynchronicity.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
return queryInterface.dropTable('users');
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
28
server/migrations/20190801110053-boost.js
Normal file
28
server/migrations/20190801110053-boost.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
queryInterface.addColumn('event', 'boost', {
|
||||||
|
type: Sequelize.JSON,
|
||||||
|
defaultValue: []
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add altering commands here.
|
||||||
|
Return a promise to correctly handle asynchronicity.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface, Sequelize) => {
|
||||||
|
/*
|
||||||
|
Add reverting commands here.
|
||||||
|
Return a promise to correctly handle asynchronicity.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
return queryInterface.dropTable('users');
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue