]>
Commit | Line | Data |
---|---|---|
d9bf974f C |
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 | } |