Chat federation: refactoring code + fix case when video has no chat
This commit is contained in:
parent
f1375c1ea8
commit
850ea3e61f
21
server/lib/federation/incoming.ts
Normal file
21
server/lib/federation/incoming.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
||||||
|
import type { RemoteVideoHandlerParams } from './types'
|
||||||
|
|
||||||
|
async function readIncomingAPVideo (
|
||||||
|
options: RegisterServerOptions,
|
||||||
|
{ video, videoAPObject }: RemoteVideoHandlerParams
|
||||||
|
): Promise<void> {
|
||||||
|
if (!('peertubeLiveChat' in videoAPObject)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const logger = options.peertubeHelpers.logger
|
||||||
|
// TODO: save the information.
|
||||||
|
logger.debug(
|
||||||
|
`Remote video uuid=${video.uuid} has a peertubeLiveChat attribute: ` +
|
||||||
|
JSON.stringify(videoAPObject.peertubeLiveChat)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
readIncomingAPVideo
|
||||||
|
}
|
@ -1,21 +1,7 @@
|
|||||||
import type { RegisterServerOptions, VideoObject, MVideoAP, MVideoFullLight } from '@peertube/peertube-types'
|
import type { RegisterServerOptions, VideoObject } from '@peertube/peertube-types'
|
||||||
import { videoHasWebchat } from '../../../shared/lib/video'
|
import type { VideoBuildResultContext, RemoteVideoHandlerParams } from './types'
|
||||||
import { getBoshUri, getWSUri } from '../uri/webchat'
|
import { videoBuildJSONLD } from './outgoing'
|
||||||
import { canonicalizePluginUri } from '../uri/canonicalize'
|
import { readIncomingAPVideo } from './incoming'
|
||||||
import { getProsodyDomain } from '../prosody/config/domain'
|
|
||||||
|
|
||||||
interface LiveChatVideoObject extends VideoObject {
|
|
||||||
peertubeLiveChat: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
interface VideoBuildResultContext {
|
|
||||||
video: MVideoAP
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RemoteHandlerParams {
|
|
||||||
video: MVideoFullLight
|
|
||||||
videoAPObject: VideoObject | LiveChatVideoObject
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function initFederation (options: RegisterServerOptions): Promise<void> {
|
export async function initFederation (options: RegisterServerOptions): Promise<void> {
|
||||||
const logger = options.peertubeHelpers.logger
|
const logger = options.peertubeHelpers.logger
|
||||||
@ -24,73 +10,8 @@ export async function initFederation (options: RegisterServerOptions): Promise<v
|
|||||||
|
|
||||||
registerHook({
|
registerHook({
|
||||||
target: 'filter:activity-pub.video.json-ld.build.result',
|
target: 'filter:activity-pub.video.json-ld.build.result',
|
||||||
handler: async (
|
handler: async (jsonld: VideoObject, context: VideoBuildResultContext) => {
|
||||||
jsonld: VideoObject,
|
return videoBuildJSONLD(options, jsonld, context)
|
||||||
context: VideoBuildResultContext
|
|
||||||
): Promise<VideoObject | LiveChatVideoObject> => {
|
|
||||||
const video = context.video
|
|
||||||
if (video.remote) { return jsonld } // should not happen, but... just in case...
|
|
||||||
|
|
||||||
const settings = await options.settingsManager.getSettings([
|
|
||||||
'chat-per-live-video',
|
|
||||||
'chat-all-lives',
|
|
||||||
'chat-all-non-lives',
|
|
||||||
'chat-videos-list',
|
|
||||||
'disable-websocket',
|
|
||||||
'prosody-room-type',
|
|
||||||
'federation-dont-publish-remotely'
|
|
||||||
])
|
|
||||||
|
|
||||||
if (settings['federation-dont-publish-remotely']) {
|
|
||||||
return jsonld
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasChat = await videoHasWebchat({
|
|
||||||
'chat-per-live-video': !!settings['chat-per-live-video'],
|
|
||||||
'chat-all-lives': !!settings['chat-all-lives'],
|
|
||||||
'chat-all-non-lives': !!settings['chat-all-non-lives'],
|
|
||||||
'chat-videos-list': settings['chat-videos-list'] as string
|
|
||||||
}, video)
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
`Adding LiveChat data on video uuid=${video.uuid}: peertubeLiveChat=${hasChat ? 'true' : 'false'}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const prosodyDomain = await getProsodyDomain(options)
|
|
||||||
const userJID = 'anon.' + prosodyDomain
|
|
||||||
let roomJID: string
|
|
||||||
if (settings['prosody-room-type'] === 'channel') {
|
|
||||||
roomJID = `channel.${video.channelId}@room.${prosodyDomain}`
|
|
||||||
} else {
|
|
||||||
roomJID = `${video.uuid}@room.${prosodyDomain}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const links = [{
|
|
||||||
type: 'xmpp-bosh-anonymous',
|
|
||||||
url: canonicalizePluginUri(options, getBoshUri(options), { removePluginVersion: true }),
|
|
||||||
jid: userJID
|
|
||||||
}]
|
|
||||||
if (!settings['disable-websocket']) {
|
|
||||||
const wsUri = getWSUri(options)
|
|
||||||
if (wsUri) {
|
|
||||||
links.push({
|
|
||||||
type: 'xmpp-websocket-anonymous',
|
|
||||||
url: canonicalizePluginUri(options, wsUri, {
|
|
||||||
removePluginVersion: true,
|
|
||||||
protocol: 'ws'
|
|
||||||
}),
|
|
||||||
jid: userJID
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.assign(jsonld, {
|
|
||||||
peertubeLiveChat: {
|
|
||||||
type: 'xmpp',
|
|
||||||
jid: roomJID,
|
|
||||||
links
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -98,28 +19,20 @@ export async function initFederation (options: RegisterServerOptions): Promise<v
|
|||||||
// registerHook({
|
// registerHook({
|
||||||
// target: 'filter:activity-pub.activity.context.build.result',
|
// target: 'filter:activity-pub.activity.context.build.result',
|
||||||
// handler: (jsonld: any) => {
|
// handler: (jsonld: any) => {
|
||||||
// return jsonld.concat([
|
// return videoContectBuildJSONLD(options, jsonld)
|
||||||
// { peertubeLiveChat: 'sc:Boolean' }
|
|
||||||
// ])
|
|
||||||
// }
|
// }
|
||||||
// })
|
// })
|
||||||
|
|
||||||
const remoteHandler = async ({ video, videoAPObject }: RemoteHandlerParams): Promise<void> => {
|
|
||||||
if (!('peertubeLiveChat' in videoAPObject)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO: save the information.
|
|
||||||
logger.debug(
|
|
||||||
`Remote video uuid=${video.uuid} has a peertubeLiveChat attribute: ` +
|
|
||||||
JSON.stringify(videoAPObject.peertubeLiveChat)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
registerHook({
|
registerHook({
|
||||||
target: 'action:activity-pub.remote-video.created',
|
target: 'action:activity-pub.remote-video.created',
|
||||||
handler: remoteHandler
|
handler: async (params: RemoteVideoHandlerParams) => {
|
||||||
|
return readIncomingAPVideo(options, params)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
registerHook({
|
registerHook({
|
||||||
target: 'action:activity-pub.remote-video.updated',
|
target: 'action:activity-pub.remote-video.updated',
|
||||||
handler: remoteHandler
|
handler: async (params: RemoteVideoHandlerParams) => {
|
||||||
|
return readIncomingAPVideo(options, params)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
84
server/lib/federation/outgoing.ts
Normal file
84
server/lib/federation/outgoing.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import type { RegisterServerOptions, VideoObject } from '@peertube/peertube-types'
|
||||||
|
import type { LiveChatVideoObject, VideoBuildResultContext, LiveChatJSONLDLink } from './types'
|
||||||
|
import { videoHasWebchat } from '../../../shared/lib/video'
|
||||||
|
import { getBoshUri, getWSUri } from '../uri/webchat'
|
||||||
|
import { canonicalizePluginUri } from '../uri/canonicalize'
|
||||||
|
import { getProsodyDomain } from '../prosody/config/domain'
|
||||||
|
|
||||||
|
async function videoBuildJSONLD (
|
||||||
|
options: RegisterServerOptions,
|
||||||
|
jsonld: VideoObject,
|
||||||
|
context: VideoBuildResultContext
|
||||||
|
): Promise<VideoObject | LiveChatVideoObject> {
|
||||||
|
const logger = options.peertubeHelpers.logger
|
||||||
|
const video = context.video
|
||||||
|
if (video.remote) { return jsonld } // should not happen, but... just in case...
|
||||||
|
|
||||||
|
const settings = await options.settingsManager.getSettings([
|
||||||
|
'chat-per-live-video',
|
||||||
|
'chat-all-lives',
|
||||||
|
'chat-all-non-lives',
|
||||||
|
'chat-videos-list',
|
||||||
|
'disable-websocket',
|
||||||
|
'prosody-room-type',
|
||||||
|
'federation-dont-publish-remotely'
|
||||||
|
])
|
||||||
|
|
||||||
|
if (settings['federation-dont-publish-remotely']) {
|
||||||
|
return jsonld
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasChat = await videoHasWebchat({
|
||||||
|
'chat-per-live-video': !!settings['chat-per-live-video'],
|
||||||
|
'chat-all-lives': !!settings['chat-all-lives'],
|
||||||
|
'chat-all-non-lives': !!settings['chat-all-non-lives'],
|
||||||
|
'chat-videos-list': settings['chat-videos-list'] as string
|
||||||
|
}, video)
|
||||||
|
|
||||||
|
if (!hasChat) {
|
||||||
|
// logger.debug(`Video uuid=${video.uuid} has not livechat, adding peertubeLiveChat=false.`)
|
||||||
|
(jsonld as LiveChatVideoObject).peertubeLiveChat = false
|
||||||
|
return jsonld
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Adding LiveChat data on video uuid=${video.uuid}...`)
|
||||||
|
|
||||||
|
const prosodyDomain = await getProsodyDomain(options)
|
||||||
|
const userJID = 'anon.' + prosodyDomain
|
||||||
|
let roomJID: string
|
||||||
|
if (settings['prosody-room-type'] === 'channel') {
|
||||||
|
roomJID = `channel.${video.channelId}@room.${prosodyDomain}`
|
||||||
|
} else {
|
||||||
|
roomJID = `${video.uuid}@room.${prosodyDomain}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const links: LiveChatJSONLDLink[] = [{
|
||||||
|
type: 'xmpp-bosh-anonymous',
|
||||||
|
url: canonicalizePluginUri(options, getBoshUri(options), { removePluginVersion: true }),
|
||||||
|
jid: userJID
|
||||||
|
}]
|
||||||
|
if (!settings['disable-websocket']) {
|
||||||
|
const wsUri = getWSUri(options)
|
||||||
|
if (wsUri) {
|
||||||
|
links.push({
|
||||||
|
type: 'xmpp-websocket-anonymous',
|
||||||
|
url: canonicalizePluginUri(options, wsUri, {
|
||||||
|
removePluginVersion: true,
|
||||||
|
protocol: 'ws'
|
||||||
|
}),
|
||||||
|
jid: userJID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(jsonld as LiveChatVideoObject).peertubeLiveChat = {
|
||||||
|
type: 'xmpp',
|
||||||
|
jid: roomJID,
|
||||||
|
links
|
||||||
|
}
|
||||||
|
return jsonld
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
videoBuildJSONLD
|
||||||
|
}
|
45
server/lib/federation/types.ts
Normal file
45
server/lib/federation/types.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import type { VideoObject, MVideoAP, MVideoFullLight } from '@peertube/peertube-types'
|
||||||
|
|
||||||
|
interface VideoBuildResultContext {
|
||||||
|
video: MVideoAP
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LiveChatJSONLDAnonymousWebsocketLink {
|
||||||
|
type: 'xmpp-websocket-anonymous'
|
||||||
|
url: string
|
||||||
|
jid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LiveChatJSONLDAnonymousBOSHLink {
|
||||||
|
type: 'xmpp-bosh-anonymous'
|
||||||
|
url: string
|
||||||
|
jid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type LiveChatJSONLDLink = LiveChatJSONLDAnonymousBOSHLink | LiveChatJSONLDAnonymousWebsocketLink
|
||||||
|
|
||||||
|
interface LiveChatJSONLDInfos {
|
||||||
|
type: 'xmpp'
|
||||||
|
jid: string
|
||||||
|
links: LiveChatJSONLDLink[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type LiveChatJSONLDAttribute = LiveChatJSONLDInfos | false
|
||||||
|
|
||||||
|
interface LiveChatVideoObject extends VideoObject {
|
||||||
|
peertubeLiveChat: LiveChatJSONLDAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RemoteVideoHandlerParams {
|
||||||
|
video: MVideoFullLight
|
||||||
|
videoAPObject: VideoObject | LiveChatVideoObject
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
VideoBuildResultContext,
|
||||||
|
LiveChatJSONLDLink,
|
||||||
|
LiveChatJSONLDInfos,
|
||||||
|
LiveChatJSONLDAttribute,
|
||||||
|
LiveChatVideoObject,
|
||||||
|
RemoteVideoHandlerParams
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user