+import { sendDeleteVideo } from '../../lib/activitypub/send'
+import { AccountModel } from '../account/account'
+import { AccountVideoRateModel } from '../account/account-video-rate'
+import { ActorModel } from '../activitypub/actor'
+import { AvatarModel } from '../avatar/avatar'
+import { ServerModel } from '../server/server'
+import {
+ buildBlockedAccountSQL,
+ buildTrigramSearchIndex,
+ buildWhereIdOrUUID,
+ createSafeIn,
+ createSimilarityAttribute,
+ getVideoSort,
+ isOutdated,
+ throwIfNotValid
+} from '../utils'
+import { TagModel } from './tag'
+import { VideoAbuseModel } from './video-abuse'
+import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel'
+import { VideoCommentModel } from './video-comment'
+import { VideoFileModel } from './video-file'
+import { VideoShareModel } from './video-share'
+import { VideoTagModel } from './video-tag'
+import { ScheduleVideoUpdateModel } from './schedule-video-update'
+import { VideoCaptionModel } from './video-caption'
+import { VideoBlacklistModel } from './video-blacklist'
+import { remove, writeFile } from 'fs-extra'
+import { VideoViewModel } from './video-views'
+import { VideoRedundancyModel } from '../redundancy/video-redundancy'
+import {
+ videoFilesModelToFormattedJSON,
+ VideoFormattingJSONOptions,
+ videoModelToActivityPubObject,
+ videoModelToFormattedDetailsJSON,
+ videoModelToFormattedJSON
+} from './video-format-utils'
+import { UserVideoHistoryModel } from '../account/user-video-history'
+import { UserModel } from '../account/user'
+import { VideoImportModel } from './video-import'
+import { VideoStreamingPlaylistModel } from './video-streaming-playlist'
+import { VideoPlaylistElementModel } from './video-playlist-element'
+import { CONFIG } from '../../initializers/config'
+import { ThumbnailModel } from './thumbnail'
+import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
+import { createTorrentPromise } from '../../helpers/webtorrent'
+
+// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
+const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
+ buildTrigramSearchIndex('video_name_trigram', 'name'),
+
+ { fields: [ 'createdAt' ] },
+ { fields: [ 'publishedAt' ] },
+ { fields: [ 'duration' ] },
+ { fields: [ 'views' ] },
+ { fields: [ 'channelId' ] },
+ {
+ fields: [ 'originallyPublishedAt' ],
+ where: {
+ originallyPublishedAt: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'category' ], // We don't care videos with an unknown category
+ where: {
+ category: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'licence' ], // We don't care videos with an unknown licence
+ where: {
+ licence: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'language' ], // We don't care videos with an unknown language
+ where: {
+ language: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'nsfw' ], // Most of the videos are not NSFW
+ where: {
+ nsfw: true
+ }
+ },
+ {
+ fields: [ 'remote' ], // Only index local videos
+ where: {
+ remote: false
+ }
+ },
+ {
+ fields: [ 'uuid' ],
+ unique: true
+ },
+ {
+ fields: [ 'url' ],
+ unique: true
+ }
+]
+
+export enum ScopeNames {
+ AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS',
+ FOR_API = 'FOR_API',
+ WITH_ACCOUNT_DETAILS = 'WITH_ACCOUNT_DETAILS',
+ WITH_TAGS = 'WITH_TAGS',
+ WITH_FILES = 'WITH_FILES',
+ WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE',
+ WITH_BLACKLISTED = 'WITH_BLACKLISTED',
+ WITH_USER_HISTORY = 'WITH_USER_HISTORY',
+ WITH_STREAMING_PLAYLISTS = 'WITH_STREAMING_PLAYLISTS',
+ WITH_USER_ID = 'WITH_USER_ID',
+ WITH_THUMBNAILS = 'WITH_THUMBNAILS'
+}