2024-05-23 09:42:14 +00:00
|
|
|
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2023-09-08 18:00:14 +00:00
|
|
|
import type { RegisterServerOptions, MVideoFullLight, VideoChannel } from '@peertube/peertube-types'
|
|
|
|
import { RoomChannel } from '../../room-channel'
|
2023-09-11 15:38:31 +00:00
|
|
|
import { fillVideoCustomFields } from '../../custom-fields'
|
|
|
|
import { videoHasWebchat } from '../../../../shared/lib/video'
|
2024-03-07 15:22:14 +00:00
|
|
|
import { updateProsodyRoom } from '../../prosody/api/manage-rooms'
|
|
|
|
import { getChannelInfosById } from '../../database/channel'
|
2024-06-06 12:55:40 +00:00
|
|
|
import { Emojis } from '../../emojis'
|
2023-09-08 18:00:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Register stuffs related to channel configuration
|
|
|
|
*/
|
|
|
|
async function initChannelConfiguration (options: RegisterServerOptions): Promise<void> {
|
|
|
|
const logger = options.peertubeHelpers.logger
|
|
|
|
const registerHook = options.registerHook
|
|
|
|
logger.info('Registring room-channel hooks...')
|
|
|
|
|
|
|
|
registerHook({
|
|
|
|
target: 'action:api.video.deleted',
|
|
|
|
handler: async (params: { video: MVideoFullLight }) => {
|
|
|
|
// When a video is deleted, we can delete the channel2room and room2channel files.
|
|
|
|
// Note: don't need to check if there is a chat for this video, just deleting existing files...
|
|
|
|
const video = params.video
|
2023-09-11 15:38:31 +00:00
|
|
|
if (video.remote) { return }
|
2023-09-08 18:00:14 +00:00
|
|
|
logger.info(`Video ${video.uuid} deleted, removing 'channel configuration' related stuff.`)
|
|
|
|
// Here the associated channel can be either channel.X@mucdomain or video_uuid@mucdomain.
|
|
|
|
// In first case, nothing to do... in the second, we must delete.
|
|
|
|
// So we don't need to check which case is effective, just delete video_uuid@mucdomain.
|
|
|
|
try {
|
|
|
|
RoomChannel.singleton().removeRoom(video.uuid)
|
|
|
|
} catch (err) {
|
|
|
|
logger.error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note: we don't delete the room. So that admins can check logs afterward, if any doubts.
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
registerHook({
|
|
|
|
target: 'action:api.video-channel.deleted',
|
2024-06-06 12:55:40 +00:00
|
|
|
handler: async (params: { videoChannel: VideoChannel }) => {
|
2023-09-08 18:00:14 +00:00
|
|
|
// When a video is deleted, we can delete the channel2room and room2channel files.
|
|
|
|
// Note: don't need to check if there is a chat for this video, just deleting existing files...
|
2024-06-06 12:55:40 +00:00
|
|
|
|
|
|
|
// Note: this hook is only called for local channels.
|
|
|
|
const channelId = params.videoChannel.id
|
2023-09-08 18:00:14 +00:00
|
|
|
logger.info(`Channel ${channelId} deleted, removing 'channel configuration' related stuff.`)
|
|
|
|
// Here the associated channel can be either channel.X@mucdomain or video_uuid@mucdomain.
|
|
|
|
// In first case, nothing to do... in the second, we must delete.
|
|
|
|
// So we don't need to check which case is effective, just delete video_uuid@mucdomain.
|
|
|
|
try {
|
|
|
|
RoomChannel.singleton().removeChannel(channelId)
|
|
|
|
} catch (err) {
|
|
|
|
logger.error(err)
|
|
|
|
}
|
|
|
|
|
2024-06-06 12:55:40 +00:00
|
|
|
logger.info(`Channel ${channelId} deleted, removing 'custom emojis' related stuff.`)
|
|
|
|
try {
|
|
|
|
Emojis.singletonSafe()?.deleteChannelDefinition(channelId)
|
|
|
|
} catch (err) {
|
|
|
|
logger.error(err)
|
|
|
|
}
|
|
|
|
|
2023-09-08 18:00:14 +00:00
|
|
|
// Note: we don't delete the room. So that admins can check logs afterward, if any doubts.
|
|
|
|
}
|
|
|
|
})
|
2023-09-11 15:38:31 +00:00
|
|
|
|
|
|
|
registerHook({
|
|
|
|
target: 'action:api.video.updated',
|
|
|
|
handler: async (params: { video: MVideoFullLight }) => {
|
|
|
|
// When a video is updated, the channel could change.
|
|
|
|
// So we ensure the room-channel link is ok.
|
|
|
|
// But we can only do this if the video has a chatroom!
|
|
|
|
const video = params.video
|
|
|
|
logger.info(`Video ${video.uuid} updated, updating room-channel informations.`)
|
|
|
|
try {
|
|
|
|
if (video.remote) { return }
|
|
|
|
const settings = await options.settingsManager.getSettings([
|
|
|
|
'chat-per-live-video',
|
|
|
|
'chat-all-lives',
|
|
|
|
'chat-all-non-lives',
|
|
|
|
'chat-videos-list',
|
|
|
|
'prosody-room-type'
|
|
|
|
])
|
|
|
|
|
|
|
|
await fillVideoCustomFields(options, video)
|
|
|
|
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) {
|
2023-09-15 10:38:35 +00:00
|
|
|
// Either there were never any chat, either it was disabled...
|
|
|
|
logger.debug(`Video ${video.uuid} has no chat, ensuring there is no room link`)
|
|
|
|
// Here the associated channel can be either channel.X@mucdomain or video_uuid@mucdomain.
|
|
|
|
// In first case, nothing to do... in the second, we must delete.
|
|
|
|
// So we don't need to check which case is effective, just delete video_uuid@mucdomain.
|
|
|
|
RoomChannel.singleton().removeRoom(video.uuid)
|
2023-09-11 15:38:31 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let roomLocalPart: string
|
|
|
|
if (settings['prosody-room-type'] === 'channel') {
|
|
|
|
roomLocalPart = 'channel.' + video.channelId.toString()
|
|
|
|
} else {
|
|
|
|
roomLocalPart = video.uuid
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.debug(`Ensuring a room-channel link between room ${roomLocalPart} and channel ${video.channelId}`)
|
|
|
|
RoomChannel.singleton().link(video.channelId, roomLocalPart)
|
2024-03-07 15:22:14 +00:00
|
|
|
|
|
|
|
if (settings['prosody-room-type'] === 'video') {
|
|
|
|
// Also updating chatroom meta data.
|
|
|
|
// FIXME: this piece of code should not be in this file (nothing to do with initChannelConfiguration,
|
|
|
|
// but will be more efficient to add here, as we already tested hasChat).
|
|
|
|
// Note: no need to await here, would only degrade performances.
|
2024-06-25 09:28:46 +00:00
|
|
|
// FIXME: should also update livechat_muc_terms if channel has changed.
|
2024-03-07 16:33:18 +00:00
|
|
|
updateProsodyRoom(options, video.uuid, {
|
2024-05-17 13:32:31 +00:00
|
|
|
name: video.name
|
2024-03-07 15:22:14 +00:00
|
|
|
}).then(
|
|
|
|
() => {},
|
|
|
|
(err) => logger.error(err)
|
|
|
|
)
|
|
|
|
}
|
2023-09-11 15:38:31 +00:00
|
|
|
} catch (err) {
|
|
|
|
logger.error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2024-03-07 15:22:14 +00:00
|
|
|
|
|
|
|
registerHook({
|
|
|
|
target: 'action:api.video-channel.updated',
|
|
|
|
handler: async (params: { videoChannel: VideoChannel }) => {
|
|
|
|
const channel = await getChannelInfosById(options, params.videoChannel.id, true)
|
|
|
|
if (!channel) { return }
|
|
|
|
|
|
|
|
// FIXME: this piece of code should not be in this file (nothing to do with initChannelConfiguration,
|
|
|
|
// but for now i keep it close to the similar code on video.updated hook).
|
|
|
|
const settings = await options.settingsManager.getSettings([
|
|
|
|
'prosody-room-type'
|
|
|
|
])
|
|
|
|
if (settings['prosody-room-type'] === 'channel') {
|
|
|
|
const jid = 'channel.' + channel.id.toString()
|
|
|
|
// Note: no need to await here, would only degrade performances.
|
2024-03-07 16:33:18 +00:00
|
|
|
updateProsodyRoom(options, jid, {
|
2024-05-17 13:32:31 +00:00
|
|
|
name: channel.displayName
|
2024-03-07 15:22:14 +00:00
|
|
|
}).then(
|
|
|
|
() => {},
|
|
|
|
(err) => logger.error(err)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2023-09-08 18:00:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export {
|
|
|
|
initChannelConfiguration
|
|
|
|
}
|