aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r--server/models/video/video.ts79
1 files changed, 53 insertions, 26 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index c7f2658ed..05d625fc1 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -91,7 +91,7 @@ import {
91} from '../utils' 91} from '../utils'
92import { TagModel } from './tag' 92import { TagModel } from './tag'
93import { VideoAbuseModel } from './video-abuse' 93import { VideoAbuseModel } from './video-abuse'
94import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel' 94import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
95import { VideoCommentModel } from './video-comment' 95import { VideoCommentModel } from './video-comment'
96import { VideoFileModel } from './video-file' 96import { VideoFileModel } from './video-file'
97import { VideoShareModel } from './video-share' 97import { VideoShareModel } from './video-share'
@@ -190,26 +190,29 @@ export enum ScopeNames {
190 WITH_FILES = 'WITH_FILES', 190 WITH_FILES = 'WITH_FILES',
191 WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE', 191 WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE',
192 WITH_BLACKLISTED = 'WITH_BLACKLISTED', 192 WITH_BLACKLISTED = 'WITH_BLACKLISTED',
193 WITH_BLOCKLIST = 'WITH_BLOCKLIST',
193 WITH_USER_HISTORY = 'WITH_USER_HISTORY', 194 WITH_USER_HISTORY = 'WITH_USER_HISTORY',
194 WITH_STREAMING_PLAYLISTS = 'WITH_STREAMING_PLAYLISTS', 195 WITH_STREAMING_PLAYLISTS = 'WITH_STREAMING_PLAYLISTS',
195 WITH_USER_ID = 'WITH_USER_ID', 196 WITH_USER_ID = 'WITH_USER_ID',
196 WITH_THUMBNAILS = 'WITH_THUMBNAILS' 197 WITH_THUMBNAILS = 'WITH_THUMBNAILS'
197} 198}
198 199
199type ForAPIOptions = { 200export type ForAPIOptions = {
200 ids: number[] 201 ids?: number[]
201 202
202 videoPlaylistId?: number 203 videoPlaylistId?: number
203 204
204 withFiles?: boolean 205 withFiles?: boolean
206
207 withAccountBlockerIds?: number[]
205} 208}
206 209
207type AvailableForListIDsOptions = { 210export type AvailableForListIDsOptions = {
208 serverAccountId: number 211 serverAccountId: number
209 followerActorId: number 212 followerActorId: number
210 includeLocalVideos: boolean 213 includeLocalVideos: boolean
211 214
212 withoutId?: boolean 215 attributesType?: 'none' | 'id' | 'all'
213 216
214 filter?: VideoFilter 217 filter?: VideoFilter
215 categoryOneOf?: number[] 218 categoryOneOf?: number[]
@@ -236,14 +239,16 @@ type AvailableForListIDsOptions = {
236@Scopes(() => ({ 239@Scopes(() => ({
237 [ ScopeNames.FOR_API ]: (options: ForAPIOptions) => { 240 [ ScopeNames.FOR_API ]: (options: ForAPIOptions) => {
238 const query: FindOptions = { 241 const query: FindOptions = {
239 where: {
240 id: {
241 [ Op.in ]: options.ids // FIXME: sequelize ANY seems broken
242 }
243 },
244 include: [ 242 include: [
245 { 243 {
246 model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, true ] }), 244 model: VideoChannelModel.scope({
245 method: [
246 VideoChannelScopeNames.SUMMARY, {
247 withAccount: true,
248 withAccountBlockerIds: options.withAccountBlockerIds
249 } as SummaryOptions
250 ]
251 }),
247 required: true 252 required: true
248 }, 253 },
249 { 254 {
@@ -254,6 +259,14 @@ type AvailableForListIDsOptions = {
254 ] 259 ]
255 } 260 }
256 261
262 if (options.ids) {
263 query.where = {
264 id: {
265 [ Op.in ]: options.ids // FIXME: sequelize ANY seems broken
266 }
267 }
268 }
269
257 if (options.withFiles === true) { 270 if (options.withFiles === true) {
258 query.include.push({ 271 query.include.push({
259 model: VideoFileModel.unscoped(), 272 model: VideoFileModel.unscoped(),
@@ -278,10 +291,14 @@ type AvailableForListIDsOptions = {
278 291
279 const query: FindOptions = { 292 const query: FindOptions = {
280 raw: true, 293 raw: true,
281 attributes: options.withoutId === true ? [] : [ 'id' ],
282 include: [] 294 include: []
283 } 295 }
284 296
297 const attributesType = options.attributesType || 'id'
298
299 if (attributesType === 'id') query.attributes = [ 'id' ]
300 else if (attributesType === 'none') query.attributes = [ ]
301
285 whereAnd.push({ 302 whereAnd.push({
286 id: { 303 id: {
287 [ Op.notIn ]: Sequelize.literal( 304 [ Op.notIn ]: Sequelize.literal(
@@ -290,17 +307,19 @@ type AvailableForListIDsOptions = {
290 } 307 }
291 }) 308 })
292 309
293 whereAnd.push({ 310 if (options.serverAccountId) {
294 channelId: { 311 whereAnd.push({
295 [ Op.notIn ]: Sequelize.literal( 312 channelId: {
296 '(' + 313 [ Op.notIn ]: Sequelize.literal(
297 'SELECT id FROM "videoChannel" WHERE "accountId" IN (' + 314 '(' +
298 buildBlockedAccountSQL(options.serverAccountId, options.user ? options.user.Account.id : undefined) + 315 'SELECT id FROM "videoChannel" WHERE "accountId" IN (' +
299 ')' + 316 buildBlockedAccountSQL(options.serverAccountId, options.user ? options.user.Account.id : undefined) +
300 ')' 317 ')' +
301 ) 318 ')'
302 } 319 )
303 }) 320 }
321 })
322 }
304 323
305 // Only list public/published videos 324 // Only list public/published videos
306 if (!options.filter || options.filter !== 'all-local') { 325 if (!options.filter || options.filter !== 'all-local') {
@@ -528,6 +547,9 @@ type AvailableForListIDsOptions = {
528 547
529 return query 548 return query
530 }, 549 },
550 [ScopeNames.WITH_BLOCKLIST]: {
551
552 },
531 [ ScopeNames.WITH_THUMBNAILS ]: { 553 [ ScopeNames.WITH_THUMBNAILS ]: {
532 include: [ 554 include: [
533 { 555 {
@@ -845,9 +867,9 @@ export class VideoModel extends Model<VideoModel> {
845 @HasMany(() => VideoPlaylistElementModel, { 867 @HasMany(() => VideoPlaylistElementModel, {
846 foreignKey: { 868 foreignKey: {
847 name: 'videoId', 869 name: 'videoId',
848 allowNull: false 870 allowNull: true
849 }, 871 },
850 onDelete: 'cascade' 872 onDelete: 'set null'
851 }) 873 })
852 VideoPlaylistElements: VideoPlaylistElementModel[] 874 VideoPlaylistElements: VideoPlaylistElementModel[]
853 875
@@ -1586,7 +1608,7 @@ export class VideoModel extends Model<VideoModel> {
1586 serverAccountId: serverActor.Account.id, 1608 serverAccountId: serverActor.Account.id,
1587 followerActorId, 1609 followerActorId,
1588 includeLocalVideos: true, 1610 includeLocalVideos: true,
1589 withoutId: true // Don't break aggregation 1611 attributesType: 'none' // Don't break aggregation
1590 } 1612 }
1591 1613
1592 const query: FindOptions = { 1614 const query: FindOptions = {
@@ -1719,6 +1741,11 @@ export class VideoModel extends Model<VideoModel> {
1719 return !!this.VideoBlacklist 1741 return !!this.VideoBlacklist
1720 } 1742 }
1721 1743
1744 isBlocked () {
1745 return (this.VideoChannel.Account.Actor.Server && this.VideoChannel.Account.Actor.Server.isBlocked()) ||
1746 this.VideoChannel.Account.isBlocked()
1747 }
1748
1722 getOriginalFile () { 1749 getOriginalFile () {
1723 if (Array.isArray(this.VideoFiles) === false) return undefined 1750 if (Array.isArray(this.VideoFiles) === false) return undefined
1724 1751