diff options
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r-- | server/models/video/video.ts | 149 |
1 files changed, 90 insertions, 59 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index b59df397d..6856dcd9f 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -36,7 +36,7 @@ import { | |||
36 | Table, | 36 | Table, |
37 | UpdatedAt | 37 | UpdatedAt |
38 | } from 'sequelize-typescript' | 38 | } from 'sequelize-typescript' |
39 | import { UserRight, VideoPrivacy, VideoResolution, VideoState } from '../../../shared' | 39 | import { UserRight, VideoPrivacy, VideoState } from '../../../shared' |
40 | import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' | 40 | import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' |
41 | import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos' | 41 | import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos' |
42 | import { VideoFilter } from '../../../shared/models/videos/video-query.type' | 42 | import { VideoFilter } from '../../../shared/models/videos/video-query.type' |
@@ -111,7 +111,6 @@ import { | |||
111 | videoModelToFormattedJSON | 111 | videoModelToFormattedJSON |
112 | } from './video-format-utils' | 112 | } from './video-format-utils' |
113 | import { UserVideoHistoryModel } from '../account/user-video-history' | 113 | import { UserVideoHistoryModel } from '../account/user-video-history' |
114 | import { UserModel } from '../account/user' | ||
115 | import { VideoImportModel } from './video-import' | 114 | import { VideoImportModel } from './video-import' |
116 | import { VideoStreamingPlaylistModel } from './video-streaming-playlist' | 115 | import { VideoStreamingPlaylistModel } from './video-streaming-playlist' |
117 | import { VideoPlaylistElementModel } from './video-playlist-element' | 116 | import { VideoPlaylistElementModel } from './video-playlist-element' |
@@ -120,6 +119,29 @@ import { ThumbnailModel } from './thumbnail' | |||
120 | import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' | 119 | import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' |
121 | import { createTorrentPromise } from '../../helpers/webtorrent' | 120 | import { createTorrentPromise } from '../../helpers/webtorrent' |
122 | import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' | 121 | import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' |
122 | import { | ||
123 | MChannel, | ||
124 | MChannelAccountDefault, | ||
125 | MChannelId, | ||
126 | MUserAccountId, | ||
127 | MUserId, | ||
128 | MVideoAccountLight, | ||
129 | MVideoAccountLightBlacklistAllFiles, | ||
130 | MVideoAP, | ||
131 | MVideoDetails, | ||
132 | MVideoFormattable, | ||
133 | MVideoFormattableDetails, | ||
134 | MVideoForUser, | ||
135 | MVideoFullLight, | ||
136 | MVideoIdThumbnail, | ||
137 | MVideoThumbnail, | ||
138 | MVideoThumbnailBlacklist, | ||
139 | MVideoWithAllFiles, | ||
140 | MVideoWithFile, | ||
141 | MVideoWithRights | ||
142 | } from '../../typings/models' | ||
143 | import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file' | ||
144 | import { MThumbnail } from '../../typings/models/video/thumbnail' | ||
123 | 145 | ||
124 | // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation | 146 | // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation |
125 | const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [ | 147 | const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [ |
@@ -232,8 +254,8 @@ export type AvailableForListIDsOptions = { | |||
232 | videoPlaylistId?: number | 254 | videoPlaylistId?: number |
233 | 255 | ||
234 | trendingDays?: number | 256 | trendingDays?: number |
235 | user?: UserModel, | 257 | user?: MUserAccountId |
236 | historyOfUser?: UserModel | 258 | historyOfUser?: MUserId |
237 | 259 | ||
238 | baseWhere?: WhereOptions[] | 260 | baseWhere?: WhereOptions[] |
239 | } | 261 | } |
@@ -446,13 +468,15 @@ export type AvailableForListIDsOptions = { | |||
446 | // FIXME: issues with sequelize count when making a join on n:m relation, so we just make a IN() | 468 | // FIXME: issues with sequelize count when making a join on n:m relation, so we just make a IN() |
447 | if (options.tagsAllOf || options.tagsOneOf) { | 469 | if (options.tagsAllOf || options.tagsOneOf) { |
448 | if (options.tagsOneOf) { | 470 | if (options.tagsOneOf) { |
471 | const tagsOneOfLower = options.tagsOneOf.map(t => t.toLowerCase()) | ||
472 | |||
449 | whereAnd.push({ | 473 | whereAnd.push({ |
450 | id: { | 474 | id: { |
451 | [ Op.in ]: Sequelize.literal( | 475 | [ Op.in ]: Sequelize.literal( |
452 | '(' + | 476 | '(' + |
453 | 'SELECT "videoId" FROM "videoTag" ' + | 477 | 'SELECT "videoId" FROM "videoTag" ' + |
454 | 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + | 478 | 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + |
455 | 'WHERE "tag"."name" IN (' + createSafeIn(VideoModel, options.tagsOneOf) + ')' + | 479 | 'WHERE lower("tag"."name") IN (' + createSafeIn(VideoModel, tagsOneOfLower) + ')' + |
456 | ')' | 480 | ')' |
457 | ) | 481 | ) |
458 | } | 482 | } |
@@ -460,14 +484,16 @@ export type AvailableForListIDsOptions = { | |||
460 | } | 484 | } |
461 | 485 | ||
462 | if (options.tagsAllOf) { | 486 | if (options.tagsAllOf) { |
487 | const tagsAllOfLower = options.tagsAllOf.map(t => t.toLowerCase()) | ||
488 | |||
463 | whereAnd.push({ | 489 | whereAnd.push({ |
464 | id: { | 490 | id: { |
465 | [ Op.in ]: Sequelize.literal( | 491 | [ Op.in ]: Sequelize.literal( |
466 | '(' + | 492 | '(' + |
467 | 'SELECT "videoId" FROM "videoTag" ' + | 493 | 'SELECT "videoId" FROM "videoTag" ' + |
468 | 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + | 494 | 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + |
469 | 'WHERE "tag"."name" IN (' + createSafeIn(VideoModel, options.tagsAllOf) + ')' + | 495 | 'WHERE lower("tag"."name") IN (' + createSafeIn(VideoModel, tagsAllOfLower) + ')' + |
470 | 'GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + options.tagsAllOf.length + | 496 | 'GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + tagsAllOfLower.length + |
471 | ')' | 497 | ')' |
472 | ) | 498 | ) |
473 | } | 499 | } |
@@ -634,7 +660,7 @@ export type AvailableForListIDsOptions = { | |||
634 | [ ScopeNames.WITH_BLACKLISTED ]: { | 660 | [ ScopeNames.WITH_BLACKLISTED ]: { |
635 | include: [ | 661 | include: [ |
636 | { | 662 | { |
637 | attributes: [ 'id', 'reason' ], | 663 | attributes: [ 'id', 'reason', 'unfederated' ], |
638 | model: VideoBlacklistModel, | 664 | model: VideoBlacklistModel, |
639 | required: false | 665 | required: false |
640 | } | 666 | } |
@@ -989,18 +1015,16 @@ export class VideoModel extends Model<VideoModel> { | |||
989 | VideoCaptions: VideoCaptionModel[] | 1015 | VideoCaptions: VideoCaptionModel[] |
990 | 1016 | ||
991 | @BeforeDestroy | 1017 | @BeforeDestroy |
992 | static async sendDelete (instance: VideoModel, options) { | 1018 | static async sendDelete (instance: MVideoAccountLight, options) { |
993 | if (instance.isOwned()) { | 1019 | if (instance.isOwned()) { |
994 | if (!instance.VideoChannel) { | 1020 | if (!instance.VideoChannel) { |
995 | instance.VideoChannel = await instance.$get('VideoChannel', { | 1021 | instance.VideoChannel = await instance.$get('VideoChannel', { |
996 | include: [ | 1022 | include: [ |
997 | { | 1023 | ActorModel, |
998 | model: AccountModel, | 1024 | AccountModel |
999 | include: [ ActorModel ] | ||
1000 | } | ||
1001 | ], | 1025 | ], |
1002 | transaction: options.transaction | 1026 | transaction: options.transaction |
1003 | }) as VideoChannelModel | 1027 | }) as MChannelAccountDefault |
1004 | } | 1028 | } |
1005 | 1029 | ||
1006 | return sendDeleteVideo(instance, options.transaction) | 1030 | return sendDeleteVideo(instance, options.transaction) |
@@ -1039,7 +1063,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1039 | return undefined | 1063 | return undefined |
1040 | } | 1064 | } |
1041 | 1065 | ||
1042 | static listLocal () { | 1066 | static listLocal (): Bluebird<MVideoWithAllFiles[]> { |
1043 | const query = { | 1067 | const query = { |
1044 | where: { | 1068 | where: { |
1045 | remote: false | 1069 | remote: false |
@@ -1159,7 +1183,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1159 | }) | 1183 | }) |
1160 | } | 1184 | } |
1161 | 1185 | ||
1162 | static listUserVideosForApi (accountId: number, start: number, count: number, sort: string, withFiles = false) { | 1186 | static listUserVideosForApi (accountId: number, start: number, count: number, sort: string) { |
1163 | function buildBaseQuery (): FindOptions { | 1187 | function buildBaseQuery (): FindOptions { |
1164 | return { | 1188 | return { |
1165 | offset: start, | 1189 | offset: start, |
@@ -1192,16 +1216,9 @@ export class VideoModel extends Model<VideoModel> { | |||
1192 | ScopeNames.WITH_THUMBNAILS | 1216 | ScopeNames.WITH_THUMBNAILS |
1193 | ] | 1217 | ] |
1194 | 1218 | ||
1195 | if (withFiles === true) { | ||
1196 | findQuery.include.push({ | ||
1197 | model: VideoFileModel.unscoped(), | ||
1198 | required: true | ||
1199 | }) | ||
1200 | } | ||
1201 | |||
1202 | return Promise.all([ | 1219 | return Promise.all([ |
1203 | VideoModel.count(countQuery), | 1220 | VideoModel.count(countQuery), |
1204 | VideoModel.scope(findScopes).findAll(findQuery) | 1221 | VideoModel.scope(findScopes).findAll<MVideoForUser>(findQuery) |
1205 | ]).then(([ count, rows ]) => { | 1222 | ]).then(([ count, rows ]) => { |
1206 | return { | 1223 | return { |
1207 | data: rows, | 1224 | data: rows, |
@@ -1228,8 +1245,8 @@ export class VideoModel extends Model<VideoModel> { | |||
1228 | followerActorId?: number | 1245 | followerActorId?: number |
1229 | videoPlaylistId?: number, | 1246 | videoPlaylistId?: number, |
1230 | trendingDays?: number, | 1247 | trendingDays?: number, |
1231 | user?: UserModel, | 1248 | user?: MUserAccountId, |
1232 | historyOfUser?: UserModel | 1249 | historyOfUser?: MUserId |
1233 | }, countVideos = true) { | 1250 | }, countVideos = true) { |
1234 | if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { | 1251 | if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { |
1235 | throw new Error('Try to filter all-local but no user has not the see all videos right') | 1252 | throw new Error('Try to filter all-local but no user has not the see all videos right') |
@@ -1294,7 +1311,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1294 | tagsAllOf?: string[] | 1311 | tagsAllOf?: string[] |
1295 | durationMin?: number // seconds | 1312 | durationMin?: number // seconds |
1296 | durationMax?: number // seconds | 1313 | durationMax?: number // seconds |
1297 | user?: UserModel, | 1314 | user?: MUserAccountId, |
1298 | filter?: VideoFilter | 1315 | filter?: VideoFilter |
1299 | }) { | 1316 | }) { |
1300 | const whereAnd = [] | 1317 | const whereAnd = [] |
@@ -1387,7 +1404,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1387 | return VideoModel.getAvailableForApi(query, queryOptions) | 1404 | return VideoModel.getAvailableForApi(query, queryOptions) |
1388 | } | 1405 | } |
1389 | 1406 | ||
1390 | static load (id: number | string, t?: Transaction) { | 1407 | static load (id: number | string, t?: Transaction): Bluebird<MVideoThumbnail> { |
1391 | const where = buildWhereIdOrUUID(id) | 1408 | const where = buildWhereIdOrUUID(id) |
1392 | const options = { | 1409 | const options = { |
1393 | where, | 1410 | where, |
@@ -1397,7 +1414,20 @@ export class VideoModel extends Model<VideoModel> { | |||
1397 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) | 1414 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) |
1398 | } | 1415 | } |
1399 | 1416 | ||
1400 | static loadWithRights (id: number | string, t?: Transaction) { | 1417 | static loadWithBlacklist (id: number | string, t?: Transaction): Bluebird<MVideoThumbnailBlacklist> { |
1418 | const where = buildWhereIdOrUUID(id) | ||
1419 | const options = { | ||
1420 | where, | ||
1421 | transaction: t | ||
1422 | } | ||
1423 | |||
1424 | return VideoModel.scope([ | ||
1425 | ScopeNames.WITH_THUMBNAILS, | ||
1426 | ScopeNames.WITH_BLACKLISTED | ||
1427 | ]).findOne(options) | ||
1428 | } | ||
1429 | |||
1430 | static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> { | ||
1401 | const where = buildWhereIdOrUUID(id) | 1431 | const where = buildWhereIdOrUUID(id) |
1402 | const options = { | 1432 | const options = { |
1403 | where, | 1433 | where, |
@@ -1411,7 +1441,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1411 | ]).findOne(options) | 1441 | ]).findOne(options) |
1412 | } | 1442 | } |
1413 | 1443 | ||
1414 | static loadOnlyId (id: number | string, t?: Transaction) { | 1444 | static loadOnlyId (id: number | string, t?: Transaction): Bluebird<MVideoIdThumbnail> { |
1415 | const where = buildWhereIdOrUUID(id) | 1445 | const where = buildWhereIdOrUUID(id) |
1416 | 1446 | ||
1417 | const options = { | 1447 | const options = { |
@@ -1423,7 +1453,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1423 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) | 1453 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) |
1424 | } | 1454 | } |
1425 | 1455 | ||
1426 | static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean) { | 1456 | static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Bluebird<MVideoWithAllFiles> { |
1427 | const where = buildWhereIdOrUUID(id) | 1457 | const where = buildWhereIdOrUUID(id) |
1428 | 1458 | ||
1429 | const query = { | 1459 | const query = { |
@@ -1439,7 +1469,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1439 | ]).findOne(query) | 1469 | ]).findOne(query) |
1440 | } | 1470 | } |
1441 | 1471 | ||
1442 | static loadByUUID (uuid: string) { | 1472 | static loadByUUID (uuid: string): Bluebird<MVideoThumbnail> { |
1443 | const options = { | 1473 | const options = { |
1444 | where: { | 1474 | where: { |
1445 | uuid | 1475 | uuid |
@@ -1449,7 +1479,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1449 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) | 1479 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) |
1450 | } | 1480 | } |
1451 | 1481 | ||
1452 | static loadByUrl (url: string, transaction?: Transaction) { | 1482 | static loadByUrl (url: string, transaction?: Transaction): Bluebird<MVideoThumbnail> { |
1453 | const query: FindOptions = { | 1483 | const query: FindOptions = { |
1454 | where: { | 1484 | where: { |
1455 | url | 1485 | url |
@@ -1460,7 +1490,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1460 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query) | 1490 | return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query) |
1461 | } | 1491 | } |
1462 | 1492 | ||
1463 | static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction) { | 1493 | static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountLightBlacklistAllFiles> { |
1464 | const query: FindOptions = { | 1494 | const query: FindOptions = { |
1465 | where: { | 1495 | where: { |
1466 | url | 1496 | url |
@@ -1472,11 +1502,12 @@ export class VideoModel extends Model<VideoModel> { | |||
1472 | ScopeNames.WITH_ACCOUNT_DETAILS, | 1502 | ScopeNames.WITH_ACCOUNT_DETAILS, |
1473 | ScopeNames.WITH_FILES, | 1503 | ScopeNames.WITH_FILES, |
1474 | ScopeNames.WITH_STREAMING_PLAYLISTS, | 1504 | ScopeNames.WITH_STREAMING_PLAYLISTS, |
1475 | ScopeNames.WITH_THUMBNAILS | 1505 | ScopeNames.WITH_THUMBNAILS, |
1506 | ScopeNames.WITH_BLACKLISTED | ||
1476 | ]).findOne(query) | 1507 | ]).findOne(query) |
1477 | } | 1508 | } |
1478 | 1509 | ||
1479 | static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number) { | 1510 | static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Bluebird<MVideoFullLight> { |
1480 | const where = buildWhereIdOrUUID(id) | 1511 | const where = buildWhereIdOrUUID(id) |
1481 | 1512 | ||
1482 | const options = { | 1513 | const options = { |
@@ -1508,7 +1539,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1508 | id: number | string, | 1539 | id: number | string, |
1509 | t?: Transaction, | 1540 | t?: Transaction, |
1510 | userId?: number | 1541 | userId?: number |
1511 | }) { | 1542 | }): Bluebird<MVideoDetails> { |
1512 | const { id, t, userId } = parameters | 1543 | const { id, t, userId } = parameters |
1513 | const where = buildWhereIdOrUUID(id) | 1544 | const where = buildWhereIdOrUUID(id) |
1514 | 1545 | ||
@@ -1586,7 +1617,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1586 | .then(results => results.length === 1) | 1617 | .then(results => results.length === 1) |
1587 | } | 1618 | } |
1588 | 1619 | ||
1589 | static bulkUpdateSupportField (videoChannel: VideoChannelModel, t: Transaction) { | 1620 | static bulkUpdateSupportField (videoChannel: MChannel, t: Transaction) { |
1590 | const options = { | 1621 | const options = { |
1591 | where: { | 1622 | where: { |
1592 | channelId: videoChannel.id | 1623 | channelId: videoChannel.id |
@@ -1597,7 +1628,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1597 | return VideoModel.update({ support: videoChannel.support }, options) | 1628 | return VideoModel.update({ support: videoChannel.support }, options) |
1598 | } | 1629 | } |
1599 | 1630 | ||
1600 | static getAllIdsFromChannel (videoChannel: VideoChannelModel) { | 1631 | static getAllIdsFromChannel (videoChannel: MChannelId): Bluebird<number[]> { |
1601 | const query = { | 1632 | const query = { |
1602 | attributes: [ 'id' ], | 1633 | attributes: [ 'id' ], |
1603 | where: { | 1634 | where: { |
@@ -1756,20 +1787,20 @@ export class VideoModel extends Model<VideoModel> { | |||
1756 | this.VideoChannel.Account.isBlocked() | 1787 | this.VideoChannel.Account.isBlocked() |
1757 | } | 1788 | } |
1758 | 1789 | ||
1759 | getOriginalFile () { | 1790 | getOriginalFile <T extends MVideoWithFile> (this: T) { |
1760 | if (Array.isArray(this.VideoFiles) === false) return undefined | 1791 | if (Array.isArray(this.VideoFiles) === false) return undefined |
1761 | 1792 | ||
1762 | // The original file is the file that have the higher resolution | 1793 | // The original file is the file that have the higher resolution |
1763 | return maxBy(this.VideoFiles, file => file.resolution) | 1794 | return maxBy(this.VideoFiles, file => file.resolution) |
1764 | } | 1795 | } |
1765 | 1796 | ||
1766 | getFile (resolution: number) { | 1797 | getFile <T extends MVideoWithFile> (this: T, resolution: number) { |
1767 | if (Array.isArray(this.VideoFiles) === false) return undefined | 1798 | if (Array.isArray(this.VideoFiles) === false) return undefined |
1768 | 1799 | ||
1769 | return this.VideoFiles.find(f => f.resolution === resolution) | 1800 | return this.VideoFiles.find(f => f.resolution === resolution) |
1770 | } | 1801 | } |
1771 | 1802 | ||
1772 | async addAndSaveThumbnail (thumbnail: ThumbnailModel, transaction: Transaction) { | 1803 | async addAndSaveThumbnail (thumbnail: MThumbnail, transaction: Transaction) { |
1773 | thumbnail.videoId = this.id | 1804 | thumbnail.videoId = this.id |
1774 | 1805 | ||
1775 | const savedThumbnail = await thumbnail.save({ transaction }) | 1806 | const savedThumbnail = await thumbnail.save({ transaction }) |
@@ -1782,7 +1813,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1782 | this.Thumbnails.push(savedThumbnail) | 1813 | this.Thumbnails.push(savedThumbnail) |
1783 | } | 1814 | } |
1784 | 1815 | ||
1785 | getVideoFilename (videoFile: VideoFileModel) { | 1816 | getVideoFilename (videoFile: MVideoFile) { |
1786 | return this.uuid + '-' + videoFile.resolution + videoFile.extname | 1817 | return this.uuid + '-' + videoFile.resolution + videoFile.extname |
1787 | } | 1818 | } |
1788 | 1819 | ||
@@ -1806,7 +1837,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1806 | return this.Thumbnails.find(t => t.type === ThumbnailType.PREVIEW) | 1837 | return this.Thumbnails.find(t => t.type === ThumbnailType.PREVIEW) |
1807 | } | 1838 | } |
1808 | 1839 | ||
1809 | getTorrentFileName (videoFile: VideoFileModel) { | 1840 | getTorrentFileName (videoFile: MVideoFile) { |
1810 | const extension = '.torrent' | 1841 | const extension = '.torrent' |
1811 | return this.uuid + '-' + videoFile.resolution + extension | 1842 | return this.uuid + '-' + videoFile.resolution + extension |
1812 | } | 1843 | } |
@@ -1815,15 +1846,15 @@ export class VideoModel extends Model<VideoModel> { | |||
1815 | return this.remote === false | 1846 | return this.remote === false |
1816 | } | 1847 | } |
1817 | 1848 | ||
1818 | getTorrentFilePath (videoFile: VideoFileModel) { | 1849 | getTorrentFilePath (videoFile: MVideoFile) { |
1819 | return join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) | 1850 | return join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) |
1820 | } | 1851 | } |
1821 | 1852 | ||
1822 | getVideoFilePath (videoFile: VideoFileModel) { | 1853 | getVideoFilePath (videoFile: MVideoFile) { |
1823 | return join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile)) | 1854 | return join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile)) |
1824 | } | 1855 | } |
1825 | 1856 | ||
1826 | async createTorrentAndSetInfoHash (videoFile: VideoFileModel) { | 1857 | async createTorrentAndSetInfoHash (videoFile: MVideoFile) { |
1827 | const options = { | 1858 | const options = { |
1828 | // Keep the extname, it's used by the client to stream the file inside a web browser | 1859 | // Keep the extname, it's used by the client to stream the file inside a web browser |
1829 | name: `${this.name} ${videoFile.resolution}p${videoFile.extname}`, | 1860 | name: `${this.name} ${videoFile.resolution}p${videoFile.extname}`, |
@@ -1869,11 +1900,11 @@ export class VideoModel extends Model<VideoModel> { | |||
1869 | return join(LAZY_STATIC_PATHS.PREVIEWS, preview.filename) | 1900 | return join(LAZY_STATIC_PATHS.PREVIEWS, preview.filename) |
1870 | } | 1901 | } |
1871 | 1902 | ||
1872 | toFormattedJSON (options?: VideoFormattingJSONOptions): Video { | 1903 | toFormattedJSON (this: MVideoFormattable, options?: VideoFormattingJSONOptions): Video { |
1873 | return videoModelToFormattedJSON(this, options) | 1904 | return videoModelToFormattedJSON(this, options) |
1874 | } | 1905 | } |
1875 | 1906 | ||
1876 | toFormattedDetailsJSON (): VideoDetails { | 1907 | toFormattedDetailsJSON (this: MVideoFormattableDetails): VideoDetails { |
1877 | return videoModelToFormattedDetailsJSON(this) | 1908 | return videoModelToFormattedDetailsJSON(this) |
1878 | } | 1909 | } |
1879 | 1910 | ||
@@ -1881,7 +1912,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1881 | return videoFilesModelToFormattedJSON(this, this.VideoFiles) | 1912 | return videoFilesModelToFormattedJSON(this, this.VideoFiles) |
1882 | } | 1913 | } |
1883 | 1914 | ||
1884 | toActivityPubObject (): VideoTorrentObject { | 1915 | toActivityPubObject (this: MVideoAP): VideoTorrentObject { |
1885 | return videoModelToActivityPubObject(this) | 1916 | return videoModelToActivityPubObject(this) |
1886 | } | 1917 | } |
1887 | 1918 | ||
@@ -1908,7 +1939,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1908 | return this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) | 1939 | return this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) |
1909 | } | 1940 | } |
1910 | 1941 | ||
1911 | removeFile (videoFile: VideoFileModel, isRedundancy = false) { | 1942 | removeFile (videoFile: MVideoFile, isRedundancy = false) { |
1912 | const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR | 1943 | const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR |
1913 | 1944 | ||
1914 | const filePath = join(baseDir, this.getVideoFilename(videoFile)) | 1945 | const filePath = join(baseDir, this.getVideoFilename(videoFile)) |
@@ -1916,7 +1947,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1916 | .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) | 1947 | .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) |
1917 | } | 1948 | } |
1918 | 1949 | ||
1919 | removeTorrent (videoFile: VideoFileModel) { | 1950 | removeTorrent (videoFile: MVideoFile) { |
1920 | const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) | 1951 | const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) |
1921 | return remove(torrentPath) | 1952 | return remove(torrentPath) |
1922 | .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err })) | 1953 | .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err })) |
@@ -1957,7 +1988,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1957 | return { baseUrlHttp, baseUrlWs } | 1988 | return { baseUrlHttp, baseUrlWs } |
1958 | } | 1989 | } |
1959 | 1990 | ||
1960 | generateMagnetUri (videoFile: VideoFileModel, baseUrlHttp: string, baseUrlWs: string) { | 1991 | generateMagnetUri (videoFile: MVideoFileRedundanciesOpt, baseUrlHttp: string, baseUrlWs: string) { |
1961 | const xs = this.getTorrentUrl(videoFile, baseUrlHttp) | 1992 | const xs = this.getTorrentUrl(videoFile, baseUrlHttp) |
1962 | const announce = this.getTrackerUrls(baseUrlHttp, baseUrlWs) | 1993 | const announce = this.getTrackerUrls(baseUrlHttp, baseUrlWs) |
1963 | let urlList = [ this.getVideoFileUrl(videoFile, baseUrlHttp) ] | 1994 | let urlList = [ this.getVideoFileUrl(videoFile, baseUrlHttp) ] |
@@ -1980,27 +2011,27 @@ export class VideoModel extends Model<VideoModel> { | |||
1980 | return [ baseUrlWs + '/tracker/socket', baseUrlHttp + '/tracker/announce' ] | 2011 | return [ baseUrlWs + '/tracker/socket', baseUrlHttp + '/tracker/announce' ] |
1981 | } | 2012 | } |
1982 | 2013 | ||
1983 | getTorrentUrl (videoFile: VideoFileModel, baseUrlHttp: string) { | 2014 | getTorrentUrl (videoFile: MVideoFile, baseUrlHttp: string) { |
1984 | return baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentFileName(videoFile) | 2015 | return baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentFileName(videoFile) |
1985 | } | 2016 | } |
1986 | 2017 | ||
1987 | getTorrentDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { | 2018 | getTorrentDownloadUrl (videoFile: MVideoFile, baseUrlHttp: string) { |
1988 | return baseUrlHttp + STATIC_DOWNLOAD_PATHS.TORRENTS + this.getTorrentFileName(videoFile) | 2019 | return baseUrlHttp + STATIC_DOWNLOAD_PATHS.TORRENTS + this.getTorrentFileName(videoFile) |
1989 | } | 2020 | } |
1990 | 2021 | ||
1991 | getVideoFileUrl (videoFile: VideoFileModel, baseUrlHttp: string) { | 2022 | getVideoFileUrl (videoFile: MVideoFile, baseUrlHttp: string) { |
1992 | return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile) | 2023 | return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile) |
1993 | } | 2024 | } |
1994 | 2025 | ||
1995 | getVideoRedundancyUrl (videoFile: VideoFileModel, baseUrlHttp: string) { | 2026 | getVideoRedundancyUrl (videoFile: MVideoFile, baseUrlHttp: string) { |
1996 | return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile) | 2027 | return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile) |
1997 | } | 2028 | } |
1998 | 2029 | ||
1999 | getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { | 2030 | getVideoFileDownloadUrl (videoFile: MVideoFile, baseUrlHttp: string) { |
2000 | return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile) | 2031 | return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile) |
2001 | } | 2032 | } |
2002 | 2033 | ||
2003 | getBandwidthBits (videoFile: VideoFileModel) { | 2034 | getBandwidthBits (videoFile: MVideoFile) { |
2004 | return Math.ceil((videoFile.size * 8) / this.duration) | 2035 | return Math.ceil((videoFile.size * 8) / this.duration) |
2005 | } | 2036 | } |
2006 | } | 2037 | } |