diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-10 14:43:55 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-10 15:26:18 +0200 |
commit | d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3 (patch) | |
tree | aa02ee0cc28c845432e91da43b1e6de2a2f04039 /server/models/video/sql/shared/video-model-builder.ts | |
parent | e5dbd5084e7ae91ce118c0bccd5b84c47b88c55f (diff) | |
download | PeerTube-d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3.tar.gz PeerTube-d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3.tar.zst PeerTube-d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3.zip |
Use raw SQL for video get request
Diffstat (limited to 'server/models/video/sql/shared/video-model-builder.ts')
-rw-r--r-- | server/models/video/sql/shared/video-model-builder.ts | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/server/models/video/sql/shared/video-model-builder.ts b/server/models/video/sql/shared/video-model-builder.ts new file mode 100644 index 000000000..9719f6d2e --- /dev/null +++ b/server/models/video/sql/shared/video-model-builder.ts | |||
@@ -0,0 +1,268 @@ | |||
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 { VideoRedundancyModel } from '@server/models/redundancy/video-redundancy' | ||
6 | import { ServerModel } from '@server/models/server/server' | ||
7 | import { TrackerModel } from '@server/models/server/tracker' | ||
8 | import { UserVideoHistoryModel } from '@server/models/user/user-video-history' | ||
9 | import { ScheduleVideoUpdateModel } from '../../schedule-video-update' | ||
10 | import { TagModel } from '../../tag' | ||
11 | import { ThumbnailModel } from '../../thumbnail' | ||
12 | import { VideoModel } from '../../video' | ||
13 | import { VideoBlacklistModel } from '../../video-blacklist' | ||
14 | import { VideoChannelModel } from '../../video-channel' | ||
15 | import { VideoFileModel } from '../../video-file' | ||
16 | import { VideoLiveModel } from '../../video-live' | ||
17 | import { VideoStreamingPlaylistModel } from '../../video-streaming-playlist' | ||
18 | import { VideoAttributes } from './video-attributes' | ||
19 | |||
20 | export class VideoModelBuilder { | ||
21 | private videosMemo: { [ id: number ]: VideoModel } | ||
22 | private videoStreamingPlaylistMemo: { [ id: number ]: VideoStreamingPlaylistModel } | ||
23 | private videoFileMemo: { [ id: number ]: VideoFileModel } | ||
24 | |||
25 | private thumbnailsDone: Set<number> | ||
26 | private historyDone: Set<number> | ||
27 | private blacklistDone: Set<number> | ||
28 | private liveDone: Set<number> | ||
29 | private redundancyDone: Set<number> | ||
30 | private scheduleVideoUpdateDone: Set<number> | ||
31 | |||
32 | private trackersDone: Set<string> | ||
33 | private tagsDone: Set<string> | ||
34 | |||
35 | private videos: VideoModel[] | ||
36 | |||
37 | private readonly buildOpts = { raw: true, isNewRecord: false } | ||
38 | |||
39 | constructor ( | ||
40 | readonly mode: 'get' | 'list', | ||
41 | readonly videoAttributes: VideoAttributes | ||
42 | ) { | ||
43 | |||
44 | } | ||
45 | |||
46 | buildVideosFromRows (rows: any[]) { | ||
47 | this.reinit() | ||
48 | |||
49 | for (const row of rows) { | ||
50 | this.buildVideo(row) | ||
51 | |||
52 | const videoModel = this.videosMemo[row.id] | ||
53 | |||
54 | this.setUserHistory(row, videoModel) | ||
55 | this.addThumbnail(row, videoModel) | ||
56 | this.addWebTorrentFile(row, videoModel) | ||
57 | |||
58 | this.addStreamingPlaylist(row, videoModel) | ||
59 | this.addStreamingPlaylistFile(row) | ||
60 | |||
61 | if (this.mode === 'get') { | ||
62 | this.addTag(row, videoModel) | ||
63 | this.addTracker(row, videoModel) | ||
64 | this.setBlacklisted(row, videoModel) | ||
65 | this.setScheduleVideoUpdate(row, videoModel) | ||
66 | this.setLive(row, videoModel) | ||
67 | |||
68 | if (row.VideoFiles.id) { | ||
69 | this.addRedundancy(row.VideoFiles.RedundancyVideos, this.videoFileMemo[row.VideoFiles.id]) | ||
70 | } | ||
71 | |||
72 | if (row.VideoStreamingPlaylists.id) { | ||
73 | this.addRedundancy(row.VideoStreamingPlaylists.RedundancyVideos, this.videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id]) | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | return this.videos | ||
79 | } | ||
80 | |||
81 | private reinit () { | ||
82 | this.videosMemo = {} | ||
83 | this.videoStreamingPlaylistMemo = {} | ||
84 | this.videoFileMemo = {} | ||
85 | |||
86 | this.thumbnailsDone = new Set<number>() | ||
87 | this.historyDone = new Set<number>() | ||
88 | this.blacklistDone = new Set<number>() | ||
89 | this.liveDone = new Set<number>() | ||
90 | this.redundancyDone = new Set<number>() | ||
91 | this.scheduleVideoUpdateDone = new Set<number>() | ||
92 | |||
93 | this.trackersDone = new Set<string>() | ||
94 | this.tagsDone = new Set<string>() | ||
95 | |||
96 | this.videos = [] | ||
97 | } | ||
98 | |||
99 | private buildVideo (row: any) { | ||
100 | if (this.videosMemo[row.id]) return | ||
101 | |||
102 | // Build Channel | ||
103 | const channel = row.VideoChannel | ||
104 | const channelModel = new VideoChannelModel(pick(channel, this.videoAttributes.getChannelAttributes()), this.buildOpts) | ||
105 | channelModel.Actor = this.buildActor(channel.Actor) | ||
106 | |||
107 | const account = row.VideoChannel.Account | ||
108 | const accountModel = new AccountModel(pick(account, this.videoAttributes.getAccountAttributes()), this.buildOpts) | ||
109 | accountModel.Actor = this.buildActor(account.Actor) | ||
110 | |||
111 | channelModel.Account = accountModel | ||
112 | |||
113 | const videoModel = new VideoModel(pick(row, this.videoAttributes.getVideoAttributes()), this.buildOpts) | ||
114 | videoModel.VideoChannel = channelModel | ||
115 | |||
116 | this.videosMemo[row.id] = videoModel | ||
117 | |||
118 | videoModel.UserVideoHistories = [] | ||
119 | videoModel.Thumbnails = [] | ||
120 | videoModel.VideoFiles = [] | ||
121 | videoModel.VideoStreamingPlaylists = [] | ||
122 | videoModel.Tags = [] | ||
123 | videoModel.Trackers = [] | ||
124 | |||
125 | // Keep rows order | ||
126 | this.videos.push(videoModel) | ||
127 | } | ||
128 | |||
129 | private buildActor (rowActor: any) { | ||
130 | const avatarModel = rowActor.Avatar.id !== null | ||
131 | ? new ActorImageModel(pick(rowActor.Avatar, this.videoAttributes.getAvatarAttributes()), this.buildOpts) | ||
132 | : null | ||
133 | |||
134 | const serverModel = rowActor.Server.id !== null | ||
135 | ? new ServerModel(pick(rowActor.Server, this.videoAttributes.getServerAttributes()), this.buildOpts) | ||
136 | : null | ||
137 | |||
138 | const actorModel = new ActorModel(pick(rowActor, this.videoAttributes.getActorAttributes()), this.buildOpts) | ||
139 | actorModel.Avatar = avatarModel | ||
140 | actorModel.Server = serverModel | ||
141 | |||
142 | return actorModel | ||
143 | } | ||
144 | |||
145 | private setUserHistory (row: any, videoModel: VideoModel) { | ||
146 | if (!row.userVideoHistory?.id || this.historyDone.has(row.userVideoHistory.id)) return | ||
147 | |||
148 | const attributes = pick(row.userVideoHistory, this.videoAttributes.getUserHistoryAttributes()) | ||
149 | const historyModel = new UserVideoHistoryModel(attributes, this.buildOpts) | ||
150 | videoModel.UserVideoHistories.push(historyModel) | ||
151 | |||
152 | this.historyDone.add(row.userVideoHistory.id) | ||
153 | } | ||
154 | |||
155 | private addThumbnail (row: any, videoModel: VideoModel) { | ||
156 | if (!row.Thumbnails?.id || this.thumbnailsDone.has(row.Thumbnails.id)) return | ||
157 | |||
158 | const attributes = pick(row.Thumbnails, this.videoAttributes.getThumbnailAttributes()) | ||
159 | const thumbnailModel = new ThumbnailModel(attributes, this.buildOpts) | ||
160 | videoModel.Thumbnails.push(thumbnailModel) | ||
161 | |||
162 | this.thumbnailsDone.add(row.Thumbnails.id) | ||
163 | } | ||
164 | |||
165 | private addWebTorrentFile (row: any, videoModel: VideoModel) { | ||
166 | if (!row.VideoFiles?.id || this.videoFileMemo[row.VideoFiles.id]) return | ||
167 | |||
168 | const attributes = pick(row.VideoFiles, this.videoAttributes.getFileAttributes()) | ||
169 | const videoFileModel = new VideoFileModel(attributes, this.buildOpts) | ||
170 | videoModel.VideoFiles.push(videoFileModel) | ||
171 | |||
172 | this.videoFileMemo[row.VideoFiles.id] = videoFileModel | ||
173 | } | ||
174 | |||
175 | private addStreamingPlaylist (row: any, videoModel: VideoModel) { | ||
176 | if (!row.VideoStreamingPlaylists?.id || this.videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id]) return | ||
177 | |||
178 | const attributes = pick(row.VideoStreamingPlaylists, this.videoAttributes.getStreamingPlaylistAttributes()) | ||
179 | const streamingPlaylist = new VideoStreamingPlaylistModel(attributes, this.buildOpts) | ||
180 | streamingPlaylist.VideoFiles = [] | ||
181 | |||
182 | videoModel.VideoStreamingPlaylists.push(streamingPlaylist) | ||
183 | |||
184 | this.videoStreamingPlaylistMemo[streamingPlaylist.id] = streamingPlaylist | ||
185 | } | ||
186 | |||
187 | private addStreamingPlaylistFile (row: any) { | ||
188 | if (!row.VideoStreamingPlaylists?.VideoFiles?.id || this.videoFileMemo[row.VideoStreamingPlaylists.VideoFiles.id]) return | ||
189 | |||
190 | const streamingPlaylist = this.videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id] | ||
191 | |||
192 | const attributes = pick(row.VideoStreamingPlaylists.VideoFiles, this.videoAttributes.getFileAttributes()) | ||
193 | const videoFileModel = new VideoFileModel(attributes, this.buildOpts) | ||
194 | streamingPlaylist.VideoFiles.push(videoFileModel) | ||
195 | |||
196 | this.videoFileMemo[row.VideoStreamingPlaylists.VideoFiles.id] = videoFileModel | ||
197 | } | ||
198 | |||
199 | private addRedundancy (redundancyRow: any, to: VideoFileModel | VideoStreamingPlaylistModel) { | ||
200 | if (!to.RedundancyVideos) to.RedundancyVideos = [] | ||
201 | |||
202 | if (!redundancyRow?.id || this.redundancyDone.has(redundancyRow.id)) return | ||
203 | |||
204 | const attributes = pick(redundancyRow, this.videoAttributes.getRedundancyAttributes()) | ||
205 | const redundancyModel = new VideoRedundancyModel(attributes, this.buildOpts) | ||
206 | to.RedundancyVideos.push(redundancyModel) | ||
207 | |||
208 | this.redundancyDone.add(redundancyRow.id) | ||
209 | } | ||
210 | |||
211 | private addTag (row: any, videoModel: VideoModel) { | ||
212 | if (!row.Tags?.name) return | ||
213 | const association = row.Tags.VideoTagModel | ||
214 | |||
215 | const key = `${association.videoId}-${association.tagId}` | ||
216 | if (this.tagsDone.has(key)) return | ||
217 | |||
218 | const attributes = pick(row.Tags, this.videoAttributes.getTagAttributes()) | ||
219 | const tagModel = new TagModel(attributes, this.buildOpts) | ||
220 | videoModel.Tags.push(tagModel) | ||
221 | |||
222 | this.tagsDone.add(key) | ||
223 | } | ||
224 | |||
225 | private addTracker (row: any, videoModel: VideoModel) { | ||
226 | if (!row.Trackers?.id) return | ||
227 | const association = row.Trackers.VideoTrackerModel | ||
228 | |||
229 | const key = `${association.videoId}-${association.trackerId}` | ||
230 | if (this.trackersDone.has(key)) return | ||
231 | |||
232 | const attributes = pick(row.Trackers, this.videoAttributes.getTrackerAttributes()) | ||
233 | const trackerModel = new TrackerModel(attributes, this.buildOpts) | ||
234 | videoModel.Trackers.push(trackerModel) | ||
235 | |||
236 | this.trackersDone.add(key) | ||
237 | } | ||
238 | |||
239 | private setBlacklisted (row: any, videoModel: VideoModel) { | ||
240 | if (!row.VideoBlacklist?.id) return | ||
241 | if (this.blacklistDone.has(row.VideoBlacklist.id)) return | ||
242 | |||
243 | const attributes = pick(row.VideoBlacklist, this.videoAttributes.getBlacklistedAttributes()) | ||
244 | videoModel.VideoBlacklist = new VideoBlacklistModel(attributes, this.buildOpts) | ||
245 | |||
246 | this.blacklistDone.add(row.VideoBlacklist.id) | ||
247 | } | ||
248 | |||
249 | private setScheduleVideoUpdate (row: any, videoModel: VideoModel) { | ||
250 | if (!row.ScheduleVideoUpdate?.id) return | ||
251 | if (this.scheduleVideoUpdateDone.has(row.ScheduleVideoUpdate.id)) return | ||
252 | |||
253 | const attributes = pick(row.ScheduleVideoUpdate, this.videoAttributes.getScheduleUpdateAttributes()) | ||
254 | videoModel.ScheduleVideoUpdate = new ScheduleVideoUpdateModel(attributes, this.buildOpts) | ||
255 | |||
256 | this.scheduleVideoUpdateDone.add(row.ScheduleVideoUpdate.id) | ||
257 | } | ||
258 | |||
259 | private setLive (row: any, videoModel: VideoModel) { | ||
260 | if (!row.VideoLive?.id) return | ||
261 | if (this.liveDone.has(row.VideoLive.id)) return | ||
262 | |||
263 | const attributes = pick(row.VideoLive, this.videoAttributes.getLiveAttributes()) | ||
264 | videoModel.VideoLive = new VideoLiveModel(attributes, this.buildOpts) | ||
265 | |||
266 | this.liveDone.add(row.ScheduleVideoUpdate.id) | ||
267 | } | ||
268 | } | ||