import { VideoFile } from '@shared/models/videos/video-file.model'
import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared'
import { VideoObject } from '../../../shared/models/activitypub/objects'
-import { Video, VideoDetails } from '../../../shared/models/videos'
+import { Video, VideoDetails, VideoRateType } from '../../../shared/models/videos'
import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
import { VideoFilter } from '../../../shared/models/videos/video-query.type'
import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
import { VideoAbuseModel } from '../abuse/video-abuse'
import { AccountModel } from '../account/account'
import { AccountVideoRateModel } from '../account/account-video-rate'
+import { ActorImageModel } from '../account/actor-image'
import { UserModel } from '../account/user'
import { UserVideoHistoryModel } from '../account/user-video-history'
import { ActorModel } from '../activitypub/actor'
-import { AvatarModel } from '../avatar/avatar'
import { VideoRedundancyModel } from '../redundancy/video-redundancy'
import { ServerModel } from '../server/server'
import { TrackerModel } from '../server/tracker'
required: false
},
{
- model: AvatarModel.unscoped(),
+ model: ActorImageModel.unscoped(),
+ as: 'Avatar',
required: false
}
]
required: false
},
{
- model: AvatarModel.unscoped(),
+ model: ActorImageModel.unscoped(),
+ as: 'Avatar',
required: false
}
]
include: [
{
model: VideoFileModel,
+ separate: true,
required: false,
include: subInclude
}
{
model: VideoStreamingPlaylistModel.unscoped(),
required: false,
+ separate: true,
include: subInclude
}
]
]
},
{ fields: [ 'duration' ] },
- { fields: [ 'views' ] },
+ {
+ fields: [
+ { name: 'views', order: 'DESC' },
+ { name: 'id', order: 'ASC' }
+ ]
+ },
{ fields: [ 'channelId' ] },
{
fields: [ 'originallyPublishedAt' ],
@BeforeDestroy
static async sendDelete (instance: MVideoAccountLight, options) {
- if (instance.isOwned()) {
- if (!instance.VideoChannel) {
- instance.VideoChannel = await instance.$get('VideoChannel', {
- include: [
- ActorModel,
- AccountModel
- ],
- transaction: options.transaction
- }) as MChannelAccountDefault
- }
+ if (!instance.isOwned()) return undefined
- return sendDeleteVideo(instance, options.transaction)
+ // Lazy load channels
+ if (!instance.VideoChannel) {
+ instance.VideoChannel = await instance.$get('VideoChannel', {
+ include: [
+ ActorModel,
+ AccountModel
+ ],
+ transaction: options.transaction
+ }) as MChannelAccountDefault
}
- return undefined
+ return sendDeleteVideo(instance, options.transaction)
}
@BeforeDestroy
logger.info('Saving video abuses details of video %s.', instance.url)
+ if (!instance.Trackers) instance.Trackers = await instance.$get('Trackers', { transaction: options.transaction })
const details = instance.toFormattedDetailsJSON()
for (const abuse of instance.VideoAbuses) {
return VideoModel.scope([
ScopeNames.WITH_BLACKLISTED,
- ScopeNames.WITH_USER_ID,
- ScopeNames.WITH_THUMBNAILS
+ ScopeNames.WITH_USER_ID
]).findOne(options)
}
})
}
+ static updateRatesOf (videoId: number, type: VideoRateType, t: Transaction) {
+ const field = type === 'like'
+ ? 'likes'
+ : 'dislikes'
+
+ const rawQuery = `UPDATE "video" SET "${field}" = ` +
+ '(' +
+ 'SELECT COUNT(id) FROM "accountVideoRate" WHERE "accountVideoRate"."videoId" = "video"."id" AND type = :rateType' +
+ ') ' +
+ 'WHERE "video"."id" = :videoId'
+
+ return AccountVideoRateModel.sequelize.query(rawQuery, {
+ transaction: t,
+ replacements: { videoId, rateType: type },
+ type: QueryTypes.UPDATE
+ })
+ }
+
static checkVideoHasInstanceFollow (videoId: number, followerActorId: number) {
// Instances only share videos
const query = 'SELECT 1 FROM "videoShare" ' +
function buildActor (rowActor: any) {
const avatarModel = rowActor.Avatar.id !== null
- ? new AvatarModel(pick(rowActor.Avatar, avatarKeys), buildOpts)
+ ? new ActorImageModel(pick(rowActor.Avatar, avatarKeys), buildOpts)
: null
const serverModel = rowActor.Server.id !== null