WIP: store and get relation between rooms and channels

This commit is contained in:
John Livingston 2023-09-07 19:01:56 +02:00
parent 1a1b246d45
commit 32b52adebb
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
3 changed files with 148 additions and 0 deletions

114
server/lib/room/channel.ts Normal file
View File

@ -0,0 +1,114 @@
import { RegisterServerOptions } from '@peertube/peertube-types'
import { getProsodyDomain } from '../prosody/config/domain'
import * as path from 'path'
import * as fs from 'fs'
/**
* Stores that given room is related to given channel.
* Can throw an exception.
* @param options server options
* @param channelId channel ID
* @param roomJIDLocalPart room JID (only the local part)
*/
async function setChannel2Room (
options: RegisterServerOptions,
channelId: number,
roomJIDLocalPart: string
): Promise<void> {
const logger = options.peertubeHelpers.logger
logger.info(`Calling setChannel2Room for channel ${channelId} and room ${roomJIDLocalPart}...`)
_checkParameters(channelId, roomJIDLocalPart)
const prosodyDomain = await getProsodyDomain(options)
{
const [channel2roomDir, channel2room] = await _getFilePath(
options, channelId, roomJIDLocalPart, prosodyDomain, 'channel2room'
)
await fs.promises.mkdir(channel2roomDir, {
recursive: true
})
await fs.promises.writeFile(
channel2room,
''
)
}
{
const [room2channelDir, room2channel, room2channelFile] = await _getFilePath(
options, channelId, roomJIDLocalPart, prosodyDomain, 'room2channel'
)
await fs.promises.mkdir(room2channelDir, {
recursive: true
})
// The video's channel could have changed. We must delete any deprecated file.
const previousFiles = await fs.promises.readdir(room2channelDir)
for (const filename of previousFiles) {
if (filename !== room2channelFile) {
const p = path.resolve(room2channelDir, filename)
logger.info('Cleaning a deprecated room2channelFile: ' + p)
await fs.promises.unlink(p)
}
}
await fs.promises.writeFile(
room2channel,
''
)
}
}
function _checkParameters (channelId: number | string, roomJIDLocalPart: string): void {
channelId = channelId.toString()
if (!/^\d+$/.test(channelId)) {
throw new Error(`Invalid Channel ID: ${channelId}`)
}
if (!/^[\w-.]+$/.test(roomJIDLocalPart)) { // channel.X or video uuid
throw new Error(`Invalid ROOM JID: ${channelId}`)
}
}
async function _getFilePath (
options: RegisterServerOptions,
channelId: number | string,
roomJIDLocalPart: string,
prosodyDomain: string,
way: 'channel2room' | 'room2channel'
): Promise<[string, string, string]> {
channelId = channelId.toString()
const roomJID = roomJIDLocalPart + '@' + prosodyDomain
if (way === 'channel2room') {
const dir = path.resolve(
options.peertubeHelpers.plugin.getDataDirectoryPath(),
'channel2room',
channelId
)
return [
dir,
path.resolve(dir, roomJID),
roomJID
]
} else if (way === 'room2channel') {
const dir = path.resolve(
options.peertubeHelpers.plugin.getDataDirectoryPath(),
'room2channel',
roomJID
)
return [
dir,
path.resolve(dir, channelId),
channelId
]
} else {
throw new Error('Invalid way parameter')
}
}
export {
setChannel2Room
}

View File

@ -6,6 +6,7 @@ import { getCheckAPIKeyMiddleware } from '../../middlewares/apikey'
import { Affiliations, getVideoAffiliations, getChannelAffiliations } from '../../prosody/config/affiliations' import { Affiliations, getVideoAffiliations, getChannelAffiliations } from '../../prosody/config/affiliations'
import { fillVideoCustomFields } from '../../custom-fields' import { fillVideoCustomFields } from '../../custom-fields'
import { getChannelInfosById } from '../../database/channel' import { getChannelInfosById } from '../../database/channel'
import { setChannel2Room } from '../../room/channel'
// See here for description: https://modules.prosody.im/mod_muc_http_defaults.html // See here for description: https://modules.prosody.im/mod_muc_http_defaults.html
interface RoomDefaults { interface RoomDefaults {
@ -78,6 +79,9 @@ async function initRoomApiRouter (options: RegisterServerOptions, router: Router
}, },
affiliations: affiliations affiliations: affiliations
} }
await setChannel2Room(options, channelId, jid)
res.json(roomDefaults) res.json(roomDefaults)
} else { } else {
// FIXME: @peertube/peertype-types@4.2.2: wrongly considere video as MVideoThumbnail. // FIXME: @peertube/peertype-types@4.2.2: wrongly considere video as MVideoThumbnail.
@ -127,6 +131,9 @@ async function initRoomApiRouter (options: RegisterServerOptions, router: Router
}, },
affiliations: affiliations affiliations: affiliations
} }
await setChannel2Room(options, video.channelId, jid)
res.json(roomDefaults) res.json(roomDefaults)
} }
} }

View File

@ -54,3 +54,30 @@ it stores it in `videoInfos/local/video_uuid.json` (where `video_uuid` is the vi
The `channelConfigurationOptions` folder contains JSON files describing channels advanced configuration. The `channelConfigurationOptions` folder contains JSON files describing channels advanced configuration.
Filenames are like `1.json` where `1` is the channel id. Filenames are like `1.json` where `1` is the channel id.
The content of the files are similar to the content sent by the front-end when saving these configuration. The content of the files are similar to the content sent by the front-end when saving these configuration.
## channel2room and room2channel
Some parts of the plugin need a quick way to get the channel id from the room id, or the all room id from a channel id.
We won't use SQL queries, because we only want such information for video that have a chatroom.
So we have 2 folders: `channel2room` and `room2channel`.
When a chatroom is created, we create 2 empty files:
* `channel2room/channel_id/room_id@muc_domain`
* `room2channel/room_id@muc_domain/channel_id`
Where:
* `muc_domain` is the room's domain (should be `room.your_instance.tld`)
* `channel_id` is the channel numerical id
* `room_id` is the local part of the room JID
So we can easily list all rooms for a given channel id, just by listing files in `channel2room`.
Or get the channel id for a room JID (Jabber ID).
Note: we include muc_domain, in case the instance domain changes. In such case, existing rooms
could get lost, and we want a way to ignore them to avoid gettings errors.
Note: there could be some inconsistencies, when video or rooms are deleted.
The code must take this into account, and always double check room or channel existence.
There will be some cleaning batch, to delete deprecated files.