X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fvideo.ts;h=a2fe53fb90bec9f78e407d192f3a468ee7eddfdf;hb=156c50af3085468a47b8ae73fe8cfcae46b42398;hp=6c89c16bff39af544ad3c3da0989921ec61519ab;hpb=0491173a61aed66205c017e0d7e0503ea316c144;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 6c89c16bf..a2fe53fb9 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts @@ -92,6 +92,7 @@ import { videoModelToFormattedJSON } from './video-format-utils' import * as validator from 'validator' +import { UserVideoHistoryModel } from '../account/user-video-history' // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation const indexes: Sequelize.DefineIndexesOptions[] = [ @@ -127,7 +128,8 @@ export enum ScopeNames { WITH_TAGS = 'WITH_TAGS', WITH_FILES = 'WITH_FILES', WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE', - WITH_BLACKLISTED = 'WITH_BLACKLISTED' + WITH_BLACKLISTED = 'WITH_BLACKLISTED', + WITH_USER_HISTORY = 'WITH_USER_HISTORY' } type ForAPIOptions = { @@ -464,6 +466,8 @@ type AvailableForListIDsOptions = { include: [ { model: () => VideoFileModel.unscoped(), + // FIXME: typings + [ 'separate' as any ]: true, // We may have multiple files, having multiple redundancies so let's separate this join required: false, include: [ { @@ -482,6 +486,20 @@ type AvailableForListIDsOptions = { required: false } ] + }, + [ ScopeNames.WITH_USER_HISTORY ]: (userId: number) => { + return { + include: [ + { + attributes: [ 'currentTime' ], + model: UserVideoHistoryModel.unscoped(), + required: false, + where: { + userId + } + } + ] + } } }) @Table({ @@ -580,6 +598,10 @@ export class VideoModel extends Model { @Column commentsEnabled: boolean + @AllowNull(false) + @Column + downloadingEnabled: boolean + @AllowNull(false) @Column waitTranscoding: boolean @@ -672,11 +694,19 @@ export class VideoModel extends Model { name: 'videoId', allowNull: false }, - onDelete: 'cascade', - hooks: true + onDelete: 'cascade' }) VideoViews: VideoViewModel[] + @HasMany(() => UserVideoHistoryModel, { + foreignKey: { + name: 'videoId', + allowNull: false + }, + onDelete: 'cascade' + }) + UserVideoHistories: UserVideoHistoryModel[] + @HasOne(() => ScheduleVideoUpdateModel, { foreignKey: { name: 'videoId', @@ -930,7 +960,8 @@ export class VideoModel extends Model { accountId?: number, videoChannelId?: number, actorId?: number - trendingDays?: number + trendingDays?: number, + userId?: number }, countVideos = true) { const query: IFindOptions = { offset: options.start, @@ -961,6 +992,7 @@ export class VideoModel extends Model { accountId: options.accountId, videoChannelId: options.videoChannelId, includeLocalVideos: options.includeLocalVideos, + userId: options.userId, trendingDays } @@ -983,6 +1015,7 @@ export class VideoModel extends Model { tagsAllOf?: string[] durationMin?: number // seconds durationMax?: number // seconds + userId?: number }) { const whereAnd = [] @@ -1058,7 +1091,8 @@ export class VideoModel extends Model { licenceOneOf: options.licenceOneOf, languageOneOf: options.languageOneOf, tagsOneOf: options.tagsOneOf, - tagsAllOf: options.tagsAllOf + tagsAllOf: options.tagsAllOf, + userId: options.userId } return VideoModel.getAvailableForApi(query, queryOptions) @@ -1125,7 +1159,7 @@ export class VideoModel extends Model { return VideoModel.scope([ ScopeNames.WITH_ACCOUNT_DETAILS, ScopeNames.WITH_FILES ]).findOne(query) } - static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Sequelize.Transaction) { + static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Sequelize.Transaction, userId?: number) { const where = VideoModel.buildWhereIdOrUUID(id) const options = { @@ -1134,14 +1168,20 @@ export class VideoModel extends Model { transaction: t } + const scopes = [ + ScopeNames.WITH_TAGS, + ScopeNames.WITH_BLACKLISTED, + ScopeNames.WITH_FILES, + ScopeNames.WITH_ACCOUNT_DETAILS, + ScopeNames.WITH_SCHEDULED_UPDATE + ] + + if (userId) { + scopes.push({ method: [ ScopeNames.WITH_USER_HISTORY, userId ] } as any) // FIXME: typings + } + return VideoModel - .scope([ - ScopeNames.WITH_TAGS, - ScopeNames.WITH_BLACKLISTED, - ScopeNames.WITH_FILES, - ScopeNames.WITH_ACCOUNT_DETAILS, - ScopeNames.WITH_SCHEDULED_UPDATE - ]) + .scope(scopes) .findOne(options) } @@ -1225,7 +1265,11 @@ export class VideoModel extends Model { return {} } - private static async getAvailableForApi (query: IFindOptions, options: AvailableForListIDsOptions, countVideos = true) { + private static async getAvailableForApi ( + query: IFindOptions, + options: AvailableForListIDsOptions & { userId?: number}, + countVideos = true + ) { const idsScope = { method: [ ScopeNames.AVAILABLE_FOR_LIST_IDS, options @@ -1249,8 +1293,15 @@ export class VideoModel extends Model { if (ids.length === 0) return { data: [], total: count } - const apiScope = { - method: [ ScopeNames.FOR_API, { ids, withFiles: options.withFiles } as ForAPIOptions ] + // FIXME: typings + const apiScope: any[] = [ + { + method: [ ScopeNames.FOR_API, { ids, withFiles: options.withFiles } as ForAPIOptions ] + } + ] + + if (options.userId) { + apiScope.push({ method: [ ScopeNames.WITH_USER_HISTORY, options.userId ] }) } const secondQuery = {