import { pick } from 'lodash' import { AccountModel } from '@server/models/account/account' import { ActorModel } from '@server/models/actor/actor' import { ActorImageModel } from '@server/models/actor/actor-image' import { ServerModel } from '@server/models/server/server' import { UserVideoHistoryModel } from '@server/models/user/user-video-history' import { ThumbnailModel } from '../thumbnail' import { VideoModel } from '../video' import { VideoChannelModel } from '../video-channel' import { VideoFileModel } from '../video-file' import { VideoStreamingPlaylistModel } from '../video-streaming-playlist' function buildVideosFromRows (rows: any[]) { const videosMemo: { [ id: number ]: VideoModel } = {} const videoStreamingPlaylistMemo: { [ id: number ]: VideoStreamingPlaylistModel } = {} const thumbnailsDone = new Set() const historyDone = new Set() const videoFilesDone = new Set() const videos: VideoModel[] = [] const avatarKeys = [ 'id', 'filename', 'fileUrl', 'onDisk', 'createdAt', 'updatedAt' ] const actorKeys = [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ] const serverKeys = [ 'id', 'host' ] const videoFileKeys = [ 'id', 'createdAt', 'updatedAt', 'resolution', 'size', 'extname', 'filename', 'fileUrl', 'torrentFilename', 'torrentUrl', 'infoHash', 'fps', 'videoId', 'videoStreamingPlaylistId' ] const videoStreamingPlaylistKeys = [ 'id', 'type', 'playlistUrl' ] const videoKeys = [ 'id', 'uuid', 'name', 'category', 'licence', 'language', 'privacy', 'nsfw', 'description', 'support', 'duration', 'views', 'likes', 'dislikes', 'remote', 'isLive', 'url', 'commentsEnabled', 'downloadEnabled', 'waitTranscoding', 'state', 'publishedAt', 'originallyPublishedAt', 'channelId', 'createdAt', 'updatedAt' ] const buildOpts = { raw: true } function buildActor (rowActor: any) { const avatarModel = rowActor.Avatar.id !== null ? new ActorImageModel(pick(rowActor.Avatar, avatarKeys), buildOpts) : null const serverModel = rowActor.Server.id !== null ? new ServerModel(pick(rowActor.Server, serverKeys), buildOpts) : null const actorModel = new ActorModel(pick(rowActor, actorKeys), buildOpts) actorModel.Avatar = avatarModel actorModel.Server = serverModel return actorModel } for (const row of rows) { if (!videosMemo[row.id]) { // Build Channel const channel = row.VideoChannel const channelModel = new VideoChannelModel(pick(channel, [ 'id', 'name', 'description', 'actorId' ]), buildOpts) channelModel.Actor = buildActor(channel.Actor) const account = row.VideoChannel.Account const accountModel = new AccountModel(pick(account, [ 'id', 'name' ]), buildOpts) accountModel.Actor = buildActor(account.Actor) channelModel.Account = accountModel const videoModel = new VideoModel(pick(row, videoKeys), buildOpts) videoModel.VideoChannel = channelModel videoModel.UserVideoHistories = [] videoModel.Thumbnails = [] videoModel.VideoFiles = [] videoModel.VideoStreamingPlaylists = [] videosMemo[row.id] = videoModel // Don't take object value to have a sorted array videos.push(videoModel) } const videoModel = videosMemo[row.id] if (row.userVideoHistory?.id && !historyDone.has(row.userVideoHistory.id)) { const historyModel = new UserVideoHistoryModel(pick(row.userVideoHistory, [ 'id', 'currentTime' ]), buildOpts) videoModel.UserVideoHistories.push(historyModel) historyDone.add(row.userVideoHistory.id) } if (row.Thumbnails?.id && !thumbnailsDone.has(row.Thumbnails.id)) { const thumbnailModel = new ThumbnailModel(pick(row.Thumbnails, [ 'id', 'type', 'filename' ]), buildOpts) videoModel.Thumbnails.push(thumbnailModel) thumbnailsDone.add(row.Thumbnails.id) } if (row.VideoFiles?.id && !videoFilesDone.has(row.VideoFiles.id)) { const videoFileModel = new VideoFileModel(pick(row.VideoFiles, videoFileKeys), buildOpts) videoModel.VideoFiles.push(videoFileModel) videoFilesDone.add(row.VideoFiles.id) } if (row.VideoStreamingPlaylists?.id && !videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id]) { const streamingPlaylist = new VideoStreamingPlaylistModel(pick(row.VideoStreamingPlaylists, videoStreamingPlaylistKeys), buildOpts) streamingPlaylist.VideoFiles = [] videoModel.VideoStreamingPlaylists.push(streamingPlaylist) videoStreamingPlaylistMemo[streamingPlaylist.id] = streamingPlaylist } if (row.VideoStreamingPlaylists?.VideoFiles?.id && !videoFilesDone.has(row.VideoStreamingPlaylists.VideoFiles.id)) { const streamingPlaylist = videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id] const videoFileModel = new VideoFileModel(pick(row.VideoStreamingPlaylists.VideoFiles, videoFileKeys), buildOpts) streamingPlaylist.VideoFiles.push(videoFileModel) videoFilesDone.add(row.VideoStreamingPlaylists.VideoFiles.id) } } return videos } export { buildVideosFromRows }