diff options
Diffstat (limited to 'server/models/video/sql/video-model-builder.ts')
-rw-r--r-- | server/models/video/sql/video-model-builder.ts | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/server/models/video/sql/video-model-builder.ts b/server/models/video/sql/video-model-builder.ts new file mode 100644 index 000000000..c428312fe --- /dev/null +++ b/server/models/video/sql/video-model-builder.ts | |||
@@ -0,0 +1,162 @@ | |||
1 | import { pick } from 'lodash' | ||
2 | import { AccountModel } from '@server/models/account/account' | ||
3 | import { ActorModel } from '@server/models/actor/actor' | ||
4 | import { ActorImageModel } from '@server/models/actor/actor-image' | ||
5 | import { ServerModel } from '@server/models/server/server' | ||
6 | import { UserVideoHistoryModel } from '@server/models/user/user-video-history' | ||
7 | import { ThumbnailModel } from '../thumbnail' | ||
8 | import { VideoModel } from '../video' | ||
9 | import { VideoChannelModel } from '../video-channel' | ||
10 | import { VideoFileModel } from '../video-file' | ||
11 | import { VideoStreamingPlaylistModel } from '../video-streaming-playlist' | ||
12 | |||
13 | function buildVideosFromRows (rows: any[]) { | ||
14 | const videosMemo: { [ id: number ]: VideoModel } = {} | ||
15 | const videoStreamingPlaylistMemo: { [ id: number ]: VideoStreamingPlaylistModel } = {} | ||
16 | |||
17 | const thumbnailsDone = new Set<number>() | ||
18 | const historyDone = new Set<number>() | ||
19 | const videoFilesDone = new Set<number>() | ||
20 | |||
21 | const videos: VideoModel[] = [] | ||
22 | |||
23 | const avatarKeys = [ 'id', 'filename', 'fileUrl', 'onDisk', 'createdAt', 'updatedAt' ] | ||
24 | const actorKeys = [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ] | ||
25 | const serverKeys = [ 'id', 'host' ] | ||
26 | const videoFileKeys = [ | ||
27 | 'id', | ||
28 | 'createdAt', | ||
29 | 'updatedAt', | ||
30 | 'resolution', | ||
31 | 'size', | ||
32 | 'extname', | ||
33 | 'filename', | ||
34 | 'fileUrl', | ||
35 | 'torrentFilename', | ||
36 | 'torrentUrl', | ||
37 | 'infoHash', | ||
38 | 'fps', | ||
39 | 'videoId', | ||
40 | 'videoStreamingPlaylistId' | ||
41 | ] | ||
42 | const videoStreamingPlaylistKeys = [ 'id', 'type', 'playlistUrl' ] | ||
43 | const videoKeys = [ | ||
44 | 'id', | ||
45 | 'uuid', | ||
46 | 'name', | ||
47 | 'category', | ||
48 | 'licence', | ||
49 | 'language', | ||
50 | 'privacy', | ||
51 | 'nsfw', | ||
52 | 'description', | ||
53 | 'support', | ||
54 | 'duration', | ||
55 | 'views', | ||
56 | 'likes', | ||
57 | 'dislikes', | ||
58 | 'remote', | ||
59 | 'isLive', | ||
60 | 'url', | ||
61 | 'commentsEnabled', | ||
62 | 'downloadEnabled', | ||
63 | 'waitTranscoding', | ||
64 | 'state', | ||
65 | 'publishedAt', | ||
66 | 'originallyPublishedAt', | ||
67 | 'channelId', | ||
68 | 'createdAt', | ||
69 | 'updatedAt' | ||
70 | ] | ||
71 | const buildOpts = { raw: true } | ||
72 | |||
73 | function buildActor (rowActor: any) { | ||
74 | const avatarModel = rowActor.Avatar.id !== null | ||
75 | ? new ActorImageModel(pick(rowActor.Avatar, avatarKeys), buildOpts) | ||
76 | : null | ||
77 | |||
78 | const serverModel = rowActor.Server.id !== null | ||
79 | ? new ServerModel(pick(rowActor.Server, serverKeys), buildOpts) | ||
80 | : null | ||
81 | |||
82 | const actorModel = new ActorModel(pick(rowActor, actorKeys), buildOpts) | ||
83 | actorModel.Avatar = avatarModel | ||
84 | actorModel.Server = serverModel | ||
85 | |||
86 | return actorModel | ||
87 | } | ||
88 | |||
89 | for (const row of rows) { | ||
90 | if (!videosMemo[row.id]) { | ||
91 | // Build Channel | ||
92 | const channel = row.VideoChannel | ||
93 | const channelModel = new VideoChannelModel(pick(channel, [ 'id', 'name', 'description', 'actorId' ]), buildOpts) | ||
94 | channelModel.Actor = buildActor(channel.Actor) | ||
95 | |||
96 | const account = row.VideoChannel.Account | ||
97 | const accountModel = new AccountModel(pick(account, [ 'id', 'name' ]), buildOpts) | ||
98 | accountModel.Actor = buildActor(account.Actor) | ||
99 | |||
100 | channelModel.Account = accountModel | ||
101 | |||
102 | const videoModel = new VideoModel(pick(row, videoKeys), buildOpts) | ||
103 | videoModel.VideoChannel = channelModel | ||
104 | |||
105 | videoModel.UserVideoHistories = [] | ||
106 | videoModel.Thumbnails = [] | ||
107 | videoModel.VideoFiles = [] | ||
108 | videoModel.VideoStreamingPlaylists = [] | ||
109 | |||
110 | videosMemo[row.id] = videoModel | ||
111 | // Don't take object value to have a sorted array | ||
112 | videos.push(videoModel) | ||
113 | } | ||
114 | |||
115 | const videoModel = videosMemo[row.id] | ||
116 | |||
117 | if (row.userVideoHistory?.id && !historyDone.has(row.userVideoHistory.id)) { | ||
118 | const historyModel = new UserVideoHistoryModel(pick(row.userVideoHistory, [ 'id', 'currentTime' ]), buildOpts) | ||
119 | videoModel.UserVideoHistories.push(historyModel) | ||
120 | |||
121 | historyDone.add(row.userVideoHistory.id) | ||
122 | } | ||
123 | |||
124 | if (row.Thumbnails?.id && !thumbnailsDone.has(row.Thumbnails.id)) { | ||
125 | const thumbnailModel = new ThumbnailModel(pick(row.Thumbnails, [ 'id', 'type', 'filename' ]), buildOpts) | ||
126 | videoModel.Thumbnails.push(thumbnailModel) | ||
127 | |||
128 | thumbnailsDone.add(row.Thumbnails.id) | ||
129 | } | ||
130 | |||
131 | if (row.VideoFiles?.id && !videoFilesDone.has(row.VideoFiles.id)) { | ||
132 | const videoFileModel = new VideoFileModel(pick(row.VideoFiles, videoFileKeys), buildOpts) | ||
133 | videoModel.VideoFiles.push(videoFileModel) | ||
134 | |||
135 | videoFilesDone.add(row.VideoFiles.id) | ||
136 | } | ||
137 | |||
138 | if (row.VideoStreamingPlaylists?.id && !videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id]) { | ||
139 | const streamingPlaylist = new VideoStreamingPlaylistModel(pick(row.VideoStreamingPlaylists, videoStreamingPlaylistKeys), buildOpts) | ||
140 | streamingPlaylist.VideoFiles = [] | ||
141 | |||
142 | videoModel.VideoStreamingPlaylists.push(streamingPlaylist) | ||
143 | |||
144 | videoStreamingPlaylistMemo[streamingPlaylist.id] = streamingPlaylist | ||
145 | } | ||
146 | |||
147 | if (row.VideoStreamingPlaylists?.VideoFiles?.id && !videoFilesDone.has(row.VideoStreamingPlaylists.VideoFiles.id)) { | ||
148 | const streamingPlaylist = videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id] | ||
149 | |||
150 | const videoFileModel = new VideoFileModel(pick(row.VideoStreamingPlaylists.VideoFiles, videoFileKeys), buildOpts) | ||
151 | streamingPlaylist.VideoFiles.push(videoFileModel) | ||
152 | |||
153 | videoFilesDone.add(row.VideoStreamingPlaylists.VideoFiles.id) | ||
154 | } | ||
155 | } | ||
156 | |||
157 | return videos | ||
158 | } | ||
159 | |||
160 | export { | ||
161 | buildVideosFromRows | ||
162 | } | ||