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.ts131
1 files changed, 68 insertions, 63 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 1e5648a36..56a5b0e18 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -24,14 +24,14 @@ import {
24 Table, 24 Table,
25 UpdatedAt 25 UpdatedAt
26} from 'sequelize-typescript' 26} from 'sequelize-typescript'
27import { setAsUpdated } from '@server/helpers/database-utils'
28import { buildNSFWFilter } from '@server/helpers/express-utils' 27import { buildNSFWFilter } from '@server/helpers/express-utils'
28import { uuidToShort } from '@server/helpers/uuid'
29import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video' 29import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video'
30import { LiveManager } from '@server/lib/live/live-manager' 30import { LiveManager } from '@server/lib/live/live-manager'
31import { getHLSDirectory, getVideoFilePath } from '@server/lib/video-paths' 31import { getHLSDirectory, getVideoFilePath } from '@server/lib/video-paths'
32import { getServerActor } from '@server/models/application/application' 32import { getServerActor } from '@server/models/application/application'
33import { ModelCache } from '@server/models/model-cache' 33import { ModelCache } from '@server/models/model-cache'
34import { AttributesOnly } from '@shared/core-utils' 34import { AttributesOnly, buildVideoEmbedPath, buildVideoWatchPath, pick } from '@shared/core-utils'
35import { VideoFile } from '@shared/models/videos/video-file.model' 35import { VideoFile } from '@shared/models/videos/video-file.model'
36import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared' 36import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared'
37import { VideoObject } from '../../../shared/models/activitypub/objects' 37import { VideoObject } from '../../../shared/models/activitypub/objects'
@@ -91,6 +91,7 @@ import { VideoRedundancyModel } from '../redundancy/video-redundancy'
91import { ServerModel } from '../server/server' 91import { ServerModel } from '../server/server'
92import { TrackerModel } from '../server/tracker' 92import { TrackerModel } from '../server/tracker'
93import { VideoTrackerModel } from '../server/video-tracker' 93import { VideoTrackerModel } from '../server/video-tracker'
94import { setAsUpdated } from '../shared'
94import { UserModel } from '../user/user' 95import { UserModel } from '../user/user'
95import { UserVideoHistoryModel } from '../user/user-video-history' 96import { UserVideoHistoryModel } from '../user/user-video-history'
96import { buildTrigramSearchIndex, buildWhereIdOrUUID, getVideoSort, isOutdated, throwIfNotValid } from '../utils' 97import { buildTrigramSearchIndex, buildWhereIdOrUUID, getVideoSort, isOutdated, throwIfNotValid } from '../utils'
@@ -762,8 +763,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
762 763
763 // Remove physical files and torrents 764 // Remove physical files and torrents
764 instance.VideoFiles.forEach(file => { 765 instance.VideoFiles.forEach(file => {
765 tasks.push(instance.removeFile(file)) 766 tasks.push(instance.removeFileAndTorrent(file))
766 tasks.push(file.removeTorrent())
767 }) 767 })
768 768
769 // Remove playlists file 769 // Remove playlists file
@@ -1070,7 +1070,8 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1070 const trendingDays = options.sort.endsWith('trending') 1070 const trendingDays = options.sort.endsWith('trending')
1071 ? CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS 1071 ? CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS
1072 : undefined 1072 : undefined
1073 let trendingAlgorithm 1073
1074 let trendingAlgorithm: string
1074 if (options.sort.endsWith('hot')) trendingAlgorithm = 'hot' 1075 if (options.sort.endsWith('hot')) trendingAlgorithm = 'hot'
1075 if (options.sort.endsWith('best')) trendingAlgorithm = 'best' 1076 if (options.sort.endsWith('best')) trendingAlgorithm = 'best'
1076 1077
@@ -1082,40 +1083,44 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1082 : serverActor.id 1083 : serverActor.id
1083 1084
1084 const queryOptions = { 1085 const queryOptions = {
1085 start: options.start, 1086 ...pick(options, [
1086 count: options.count, 1087 'start',
1087 sort: options.sort, 1088 'count',
1089 'sort',
1090 'nsfw',
1091 'isLive',
1092 'categoryOneOf',
1093 'licenceOneOf',
1094 'languageOneOf',
1095 'tagsOneOf',
1096 'tagsAllOf',
1097 'filter',
1098 'withFiles',
1099 'accountId',
1100 'videoChannelId',
1101 'videoPlaylistId',
1102 'includeLocalVideos',
1103 'user',
1104 'historyOfUser',
1105 'search'
1106 ]),
1107
1088 followerActorId, 1108 followerActorId,
1089 serverAccountId: serverActor.Account.id, 1109 serverAccountId: serverActor.Account.id,
1090 nsfw: options.nsfw,
1091 isLive: options.isLive,
1092 categoryOneOf: options.categoryOneOf,
1093 licenceOneOf: options.licenceOneOf,
1094 languageOneOf: options.languageOneOf,
1095 tagsOneOf: options.tagsOneOf,
1096 tagsAllOf: options.tagsAllOf,
1097 filter: options.filter,
1098 withFiles: options.withFiles,
1099 accountId: options.accountId,
1100 videoChannelId: options.videoChannelId,
1101 videoPlaylistId: options.videoPlaylistId,
1102 includeLocalVideos: options.includeLocalVideos,
1103 user: options.user,
1104 historyOfUser: options.historyOfUser,
1105 trendingDays, 1110 trendingDays,
1106 trendingAlgorithm, 1111 trendingAlgorithm
1107 search: options.search
1108 } 1112 }
1109 1113
1110 return VideoModel.getAvailableForApi(queryOptions, options.countVideos) 1114 return VideoModel.getAvailableForApi(queryOptions, options.countVideos)
1111 } 1115 }
1112 1116
1113 static async searchAndPopulateAccountAndServer (options: { 1117 static async searchAndPopulateAccountAndServer (options: {
1118 start: number
1119 count: number
1120 sort: string
1114 includeLocalVideos: boolean 1121 includeLocalVideos: boolean
1115 search?: string 1122 search?: string
1116 start?: number 1123 host?: string
1117 count?: number
1118 sort?: string
1119 startDate?: string // ISO 8601 1124 startDate?: string // ISO 8601
1120 endDate?: string // ISO 8601 1125 endDate?: string // ISO 8601
1121 originallyPublishedStartDate?: string 1126 originallyPublishedStartDate?: string
@@ -1131,41 +1136,38 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1131 durationMax?: number // seconds 1136 durationMax?: number // seconds
1132 user?: MUserAccountId 1137 user?: MUserAccountId
1133 filter?: VideoFilter 1138 filter?: VideoFilter
1139 uuids?: string[]
1134 }) { 1140 }) {
1135 const serverActor = await getServerActor() 1141 const serverActor = await getServerActor()
1136 1142
1137 const queryOptions = { 1143 const queryOptions = {
1138 followerActorId: serverActor.id, 1144 ...pick(options, [
1139 serverAccountId: serverActor.Account.id, 1145 'includeLocalVideos',
1140 1146 'nsfw',
1141 includeLocalVideos: options.includeLocalVideos, 1147 'isLive',
1142 nsfw: options.nsfw, 1148 'categoryOneOf',
1143 isLive: options.isLive, 1149 'licenceOneOf',
1144 1150 'languageOneOf',
1145 categoryOneOf: options.categoryOneOf, 1151 'tagsOneOf',
1146 licenceOneOf: options.licenceOneOf, 1152 'tagsAllOf',
1147 languageOneOf: options.languageOneOf, 1153 'user',
1154 'filter',
1155 'host',
1156 'start',
1157 'count',
1158 'sort',
1159 'startDate',
1160 'endDate',
1161 'originallyPublishedStartDate',
1162 'originallyPublishedEndDate',
1163 'durationMin',
1164 'durationMax',
1165 'uuids',
1166 'search'
1167 ]),
1148 1168
1149 tagsOneOf: options.tagsOneOf, 1169 followerActorId: serverActor.id,
1150 tagsAllOf: options.tagsAllOf, 1170 serverAccountId: serverActor.Account.id
1151
1152 user: options.user,
1153 filter: options.filter,
1154
1155 start: options.start,
1156 count: options.count,
1157 sort: options.sort,
1158
1159 startDate: options.startDate,
1160 endDate: options.endDate,
1161
1162 originallyPublishedStartDate: options.originallyPublishedStartDate,
1163 originallyPublishedEndDate: options.originallyPublishedEndDate,
1164
1165 durationMin: options.durationMin,
1166 durationMax: options.durationMax,
1167
1168 search: options.search
1169 } 1171 }
1170 1172
1171 return VideoModel.getAvailableForApi(queryOptions) 1173 return VideoModel.getAvailableForApi(queryOptions)
@@ -1579,11 +1581,11 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1579 } 1581 }
1580 1582
1581 getWatchStaticPath () { 1583 getWatchStaticPath () {
1582 return '/w/' + this.uuid 1584 return buildVideoWatchPath({ shortUUID: uuidToShort(this.uuid) })
1583 } 1585 }
1584 1586
1585 getEmbedStaticPath () { 1587 getEmbedStaticPath () {
1586 return '/videos/embed/' + this.uuid 1588 return buildVideoEmbedPath(this)
1587 } 1589 }
1588 1590
1589 getMiniatureStaticPath () { 1591 getMiniatureStaticPath () {
@@ -1670,10 +1672,13 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1670 .concat(toAdd) 1672 .concat(toAdd)
1671 } 1673 }
1672 1674
1673 removeFile (videoFile: MVideoFile, isRedundancy = false) { 1675 removeFileAndTorrent (videoFile: MVideoFile, isRedundancy = false) {
1674 const filePath = getVideoFilePath(this, videoFile, isRedundancy) 1676 const filePath = getVideoFilePath(this, videoFile, isRedundancy)
1675 return remove(filePath) 1677
1676 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) 1678 const promises: Promise<any>[] = [ remove(filePath) ]
1679 if (!isRedundancy) promises.push(videoFile.removeTorrent())
1680
1681 return Promise.all(promises)
1677 } 1682 }
1678 1683
1679 async removeStreamingPlaylistFiles (streamingPlaylist: MStreamingPlaylist, isRedundancy = false) { 1684 async removeStreamingPlaylistFiles (streamingPlaylist: MStreamingPlaylist, isRedundancy = false) {