]>
Commit | Line | Data |
---|---|---|
1 | import { Sequelize, Transaction } from 'sequelize' | |
2 | import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder' | |
3 | import { VideoFileQueryBuilder } from './shared/video-file-query-builder' | |
4 | import { VideoModelBuilder } from './shared/video-model-builder' | |
5 | import { VideoTables } from './shared/video-tables' | |
6 | ||
7 | /** | |
8 | * | |
9 | * Build a GET SQL query, fetch rows and create the video model | |
10 | * | |
11 | */ | |
12 | ||
13 | export type GetType = | |
14 | 'api' | | |
15 | 'full-light' | | |
16 | 'account-blacklist-files' | | |
17 | 'all-files' | | |
18 | 'thumbnails' | | |
19 | 'thumbnails-blacklist' | | |
20 | 'id' | | |
21 | 'blacklist-rights' | |
22 | ||
23 | export type BuildVideoGetQueryOptions = { | |
24 | id?: number | string | |
25 | url?: string | |
26 | ||
27 | type: GetType | |
28 | ||
29 | userId?: number | |
30 | transaction?: Transaction | |
31 | ||
32 | logging?: boolean | |
33 | } | |
34 | ||
35 | export class VideoModelGetQueryBuilder { | |
36 | videoQueryBuilder: VideosModelGetQuerySubBuilder | |
37 | webtorrentFilesQueryBuilder: VideoFileQueryBuilder | |
38 | streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder | |
39 | ||
40 | private readonly videoModelBuilder: VideoModelBuilder | |
41 | ||
42 | private static readonly videoFilesInclude = new Set<GetType>([ 'api', 'full-light', 'account-blacklist-files', 'all-files' ]) | |
43 | ||
44 | constructor (protected readonly sequelize: Sequelize) { | |
45 | this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize) | |
46 | this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize) | |
47 | this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize) | |
48 | ||
49 | this.videoModelBuilder = new VideoModelBuilder('get', new VideoTables('get')) | |
50 | } | |
51 | ||
52 | async queryVideo (options: BuildVideoGetQueryOptions) { | |
53 | const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([ | |
54 | this.videoQueryBuilder.queryVideos(options), | |
55 | ||
56 | VideoModelGetQueryBuilder.videoFilesInclude.has(options.type) | |
57 | ? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options) | |
58 | : Promise.resolve(undefined), | |
59 | ||
60 | VideoModelGetQueryBuilder.videoFilesInclude.has(options.type) | |
61 | ? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options) | |
62 | : Promise.resolve(undefined) | |
63 | ]) | |
64 | ||
65 | const videos = this.videoModelBuilder.buildVideosFromRows({ | |
66 | rows: videoRows, | |
67 | rowsWebTorrentFiles: webtorrentFilesRows, | |
68 | rowsStreamingPlaylist: streamingPlaylistFilesRows | |
69 | }) | |
70 | ||
71 | if (videos.length > 1) { | |
72 | throw new Error('Video results is more than ') | |
73 | } | |
74 | ||
75 | if (videos.length === 0) return null | |
76 | return videos[0] | |
77 | } | |
78 | } | |
79 | ||
80 | export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder { | |
81 | protected attributes: { [key: string]: string } | |
82 | ||
83 | protected webtorrentFilesQuery: string | |
84 | protected streamingPlaylistFilesQuery: string | |
85 | ||
86 | private static readonly trackersInclude = new Set<GetType>([ 'api' ]) | |
87 | private static readonly liveInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
88 | private static readonly scheduleUpdateInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
89 | private static readonly tagsInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
90 | private static readonly userHistoryInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
91 | private static readonly accountInclude = new Set<GetType>([ 'api', 'full-light', 'account-blacklist-files' ]) | |
92 | private static readonly ownerUserInclude = new Set<GetType>([ 'blacklist-rights' ]) | |
93 | ||
94 | private static readonly blacklistedInclude = new Set<GetType>([ | |
95 | 'api', | |
96 | 'full-light', | |
97 | 'account-blacklist-files', | |
98 | 'thumbnails-blacklist', | |
99 | 'blacklist-rights' | |
100 | ]) | |
101 | ||
102 | private static readonly thumbnailsInclude = new Set<GetType>([ | |
103 | 'api', | |
104 | 'full-light', | |
105 | 'account-blacklist-files', | |
106 | 'all-files', | |
107 | 'thumbnails', | |
108 | 'thumbnails-blacklist' | |
109 | ]) | |
110 | ||
111 | constructor (protected readonly sequelize: Sequelize) { | |
112 | super('get') | |
113 | } | |
114 | ||
115 | queryVideos (options: BuildVideoGetQueryOptions) { | |
116 | this.buildMainGetQuery(options) | |
117 | ||
118 | return this.runQuery(options) | |
119 | } | |
120 | ||
121 | private buildMainGetQuery (options: BuildVideoGetQueryOptions) { | |
122 | this.attributes = { | |
123 | '"video".*': '' | |
124 | } | |
125 | ||
126 | if (VideosModelGetQuerySubBuilder.thumbnailsInclude.has(options.type)) { | |
127 | this.includeThumbnails() | |
128 | } | |
129 | ||
130 | if (VideosModelGetQuerySubBuilder.blacklistedInclude.has(options.type)) { | |
131 | this.includeBlacklisted() | |
132 | } | |
133 | ||
134 | if (VideosModelGetQuerySubBuilder.accountInclude.has(options.type)) { | |
135 | this.includeChannels() | |
136 | this.includeAccounts() | |
137 | } | |
138 | ||
139 | if (VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)) { | |
140 | this.includeTags() | |
141 | } | |
142 | ||
143 | if (VideosModelGetQuerySubBuilder.scheduleUpdateInclude.has(options.type)) { | |
144 | this.includeScheduleUpdate() | |
145 | } | |
146 | ||
147 | if (VideosModelGetQuerySubBuilder.liveInclude.has(options.type)) { | |
148 | this.includeLive() | |
149 | } | |
150 | ||
151 | if (options.userId && VideosModelGetQuerySubBuilder.userHistoryInclude.has(options.type)) { | |
152 | this.includeUserHistory(options.userId) | |
153 | } | |
154 | ||
155 | if (VideosModelGetQuerySubBuilder.ownerUserInclude.has(options.type)) { | |
156 | this.includeOwnerUser() | |
157 | } | |
158 | ||
159 | if (VideosModelGetQuerySubBuilder.trackersInclude.has(options.type)) { | |
160 | this.includeTrackers() | |
161 | } | |
162 | ||
163 | this.whereId(options) | |
164 | ||
165 | this.query = this.buildQuery(options) | |
166 | } | |
167 | ||
168 | private buildQuery (options: BuildVideoGetQueryOptions) { | |
169 | const order = VideosModelGetQuerySubBuilder.tagsInclude.has(options.type) | |
170 | ? 'ORDER BY "Tags"."name" ASC' | |
171 | : '' | |
172 | ||
173 | const from = `SELECT * FROM "video" ${this.where} LIMIT 1` | |
174 | ||
175 | return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}` | |
176 | } | |
177 | } |