From 850ea3e61fc378d6cc966a5436ccc6769661e391 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Thu, 20 Apr 2023 16:07:00 +0200 Subject: [PATCH] Chat federation: refactoring code + fix case when video has no chat --- server/lib/federation/incoming.ts | 21 ++++++ server/lib/federation/init.ts | 113 ++++-------------------------- server/lib/federation/outgoing.ts | 84 ++++++++++++++++++++++ server/lib/federation/types.ts | 45 ++++++++++++ 4 files changed, 163 insertions(+), 100 deletions(-) create mode 100644 server/lib/federation/incoming.ts create mode 100644 server/lib/federation/outgoing.ts create mode 100644 server/lib/federation/types.ts diff --git a/server/lib/federation/incoming.ts b/server/lib/federation/incoming.ts new file mode 100644 index 00000000..8995d005 --- /dev/null +++ b/server/lib/federation/incoming.ts @@ -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 { + 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 +} diff --git a/server/lib/federation/init.ts b/server/lib/federation/init.ts index f0b133f1..9f78bd58 100644 --- a/server/lib/federation/init.ts +++ b/server/lib/federation/init.ts @@ -1,21 +1,7 @@ -import type { RegisterServerOptions, VideoObject, MVideoAP, MVideoFullLight } from '@peertube/peertube-types' -import { videoHasWebchat } from '../../../shared/lib/video' -import { getBoshUri, getWSUri } from '../uri/webchat' -import { canonicalizePluginUri } from '../uri/canonicalize' -import { getProsodyDomain } from '../prosody/config/domain' - -interface LiveChatVideoObject extends VideoObject { - peertubeLiveChat: boolean -} - -interface VideoBuildResultContext { - video: MVideoAP -} - -interface RemoteHandlerParams { - video: MVideoFullLight - videoAPObject: VideoObject | LiveChatVideoObject -} +import type { RegisterServerOptions, VideoObject } from '@peertube/peertube-types' +import type { VideoBuildResultContext, RemoteVideoHandlerParams } from './types' +import { videoBuildJSONLD } from './outgoing' +import { readIncomingAPVideo } from './incoming' export async function initFederation (options: RegisterServerOptions): Promise { const logger = options.peertubeHelpers.logger @@ -24,73 +10,8 @@ export async function initFederation (options: RegisterServerOptions): Promise => { - 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 - } - }) + handler: async (jsonld: VideoObject, context: VideoBuildResultContext) => { + return videoBuildJSONLD(options, jsonld, context) } }) @@ -98,28 +19,20 @@ export async function initFederation (options: RegisterServerOptions): Promise { - // return jsonld.concat([ - // { peertubeLiveChat: 'sc:Boolean' } - // ]) + // return videoContectBuildJSONLD(options, jsonld) // } // }) - const remoteHandler = async ({ video, videoAPObject }: RemoteHandlerParams): Promise => { - 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({ target: 'action:activity-pub.remote-video.created', - handler: remoteHandler + handler: async (params: RemoteVideoHandlerParams) => { + return readIncomingAPVideo(options, params) + } }) registerHook({ target: 'action:activity-pub.remote-video.updated', - handler: remoteHandler + handler: async (params: RemoteVideoHandlerParams) => { + return readIncomingAPVideo(options, params) + } }) } diff --git a/server/lib/federation/outgoing.ts b/server/lib/federation/outgoing.ts new file mode 100644 index 00000000..e3dd4998 --- /dev/null +++ b/server/lib/federation/outgoing.ts @@ -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 { + 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 +} diff --git a/server/lib/federation/types.ts b/server/lib/federation/types.ts new file mode 100644 index 00000000..8f20507b --- /dev/null +++ b/server/lib/federation/types.ts @@ -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 +}