diff options
Diffstat (limited to 'server/models/video')
-rw-r--r-- | server/models/video/video-format-utils.ts | 6 | ||||
-rw-r--r-- | server/models/video/video-query-builder.ts | 32 | ||||
-rw-r--r-- | server/models/video/video.ts | 56 |
3 files changed, 84 insertions, 10 deletions
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts index 7a17c839f..ad512fc7f 100644 --- a/server/models/video/video-format-utils.ts +++ b/server/models/video/video-format-utils.ts | |||
@@ -59,7 +59,11 @@ function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFor | |||
59 | label: VideoModel.getPrivacyLabel(video.privacy) | 59 | label: VideoModel.getPrivacyLabel(video.privacy) |
60 | }, | 60 | }, |
61 | nsfw: video.nsfw, | 61 | nsfw: video.nsfw, |
62 | description: options && options.completeDescription === true ? video.description : video.getTruncatedDescription(), | 62 | |
63 | description: options && options.completeDescription === true | ||
64 | ? video.description | ||
65 | : video.getTruncatedDescription(), | ||
66 | |||
63 | isLocal: video.isOwned(), | 67 | isLocal: video.isOwned(), |
64 | duration: video.duration, | 68 | duration: video.duration, |
65 | views: video.views, | 69 | views: video.views, |
diff --git a/server/models/video/video-query-builder.ts b/server/models/video/video-query-builder.ts index 466890364..b14bb16d6 100644 --- a/server/models/video/video-query-builder.ts +++ b/server/models/video/video-query-builder.ts | |||
@@ -156,7 +156,16 @@ function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions) | |||
156 | } | 156 | } |
157 | 157 | ||
158 | if (options.withFiles === true) { | 158 | if (options.withFiles === true) { |
159 | and.push('EXISTS (SELECT 1 FROM "videoFile" WHERE "videoFile"."videoId" = "video"."id")') | 159 | and.push( |
160 | '(' + | ||
161 | ' EXISTS (SELECT 1 FROM "videoFile" WHERE "videoFile"."videoId" = "video"."id") ' + | ||
162 | ' OR EXISTS (' + | ||
163 | ' SELECT 1 FROM "videoStreamingPlaylist" ' + | ||
164 | ' INNER JOIN "videoFile" ON "videoFile"."videoStreamingPlaylistId" = "videoStreamingPlaylist"."id" ' + | ||
165 | ' WHERE "videoStreamingPlaylist"."videoId" = "video"."id"' + | ||
166 | ' )' + | ||
167 | ')' | ||
168 | ) | ||
160 | } | 169 | } |
161 | 170 | ||
162 | if (options.tagsOneOf) { | 171 | if (options.tagsOneOf) { |
@@ -443,7 +452,13 @@ function wrapForAPIResults (baseQuery: string, replacements: any, options: Build | |||
443 | ] | 452 | ] |
444 | 453 | ||
445 | if (options.withFiles) { | 454 | if (options.withFiles) { |
446 | joins.push('INNER JOIN "videoFile" AS "VideoFiles" ON "VideoFiles"."videoId" = "video"."id"') | 455 | joins.push('LEFT JOIN "videoFile" AS "VideoFiles" ON "VideoFiles"."videoId" = "video"."id"') |
456 | |||
457 | joins.push('LEFT JOIN "videoStreamingPlaylist" AS "VideoStreamingPlaylists" ON "VideoStreamingPlaylists"."videoId" = "video"."id"') | ||
458 | joins.push( | ||
459 | 'LEFT JOIN "videoFile" AS "VideoStreamingPlaylists->VideoFiles" ' + | ||
460 | 'ON "VideoStreamingPlaylists->VideoFiles"."videoStreamingPlaylistId" = "VideoStreamingPlaylists"."id"' | ||
461 | ) | ||
447 | 462 | ||
448 | Object.assign(attributes, { | 463 | Object.assign(attributes, { |
449 | '"VideoFiles"."id"': '"VideoFiles.id"', | 464 | '"VideoFiles"."id"': '"VideoFiles.id"', |
@@ -454,7 +469,18 @@ function wrapForAPIResults (baseQuery: string, replacements: any, options: Build | |||
454 | '"VideoFiles"."extname"': '"VideoFiles.extname"', | 469 | '"VideoFiles"."extname"': '"VideoFiles.extname"', |
455 | '"VideoFiles"."infoHash"': '"VideoFiles.infoHash"', | 470 | '"VideoFiles"."infoHash"': '"VideoFiles.infoHash"', |
456 | '"VideoFiles"."fps"': '"VideoFiles.fps"', | 471 | '"VideoFiles"."fps"': '"VideoFiles.fps"', |
457 | '"VideoFiles"."videoId"': '"VideoFiles.videoId"' | 472 | '"VideoFiles"."videoId"': '"VideoFiles.videoId"', |
473 | |||
474 | '"VideoStreamingPlaylists"."id"': '"VideoStreamingPlaylists.id"', | ||
475 | '"VideoStreamingPlaylists->VideoFiles"."id"': '"VideoStreamingPlaylists.VideoFiles.id"', | ||
476 | '"VideoStreamingPlaylists->VideoFiles"."createdAt"': '"VideoStreamingPlaylists.VideoFiles.createdAt"', | ||
477 | '"VideoStreamingPlaylists->VideoFiles"."updatedAt"': '"VideoStreamingPlaylists.VideoFiles.updatedAt"', | ||
478 | '"VideoStreamingPlaylists->VideoFiles"."resolution"': '"VideoStreamingPlaylists.VideoFiles.resolution"', | ||
479 | '"VideoStreamingPlaylists->VideoFiles"."size"': '"VideoStreamingPlaylists.VideoFiles.size"', | ||
480 | '"VideoStreamingPlaylists->VideoFiles"."extname"': '"VideoStreamingPlaylists.VideoFiles.extname"', | ||
481 | '"VideoStreamingPlaylists->VideoFiles"."infoHash"': '"VideoStreamingPlaylists.VideoFiles.infoHash"', | ||
482 | '"VideoStreamingPlaylists->VideoFiles"."fps"': '"VideoStreamingPlaylists.VideoFiles.fps"', | ||
483 | '"VideoStreamingPlaylists->VideoFiles"."videoId"': '"VideoStreamingPlaylists.VideoFiles.videoId"' | ||
458 | }) | 484 | }) |
459 | } | 485 | } |
460 | 486 | ||
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 43609587c..1eded0d56 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -95,7 +95,7 @@ import { | |||
95 | MVideoWithRights | 95 | MVideoWithRights |
96 | } from '../../types/models' | 96 | } from '../../types/models' |
97 | import { MThumbnail } from '../../types/models/video/thumbnail' | 97 | import { MThumbnail } from '../../types/models/video/thumbnail' |
98 | import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../types/models/video/video-file' | 98 | import { MVideoFile, MVideoFileStreamingPlaylistVideo, MVideoFileRedundanciesOpt } from '../../types/models/video/video-file' |
99 | import { VideoAbuseModel } from '../abuse/video-abuse' | 99 | import { VideoAbuseModel } from '../abuse/video-abuse' |
100 | import { AccountModel } from '../account/account' | 100 | import { AccountModel } from '../account/account' |
101 | import { AccountVideoRateModel } from '../account/account-video-rate' | 101 | import { AccountVideoRateModel } from '../account/account-video-rate' |
@@ -127,6 +127,7 @@ import { VideoShareModel } from './video-share' | |||
127 | import { VideoStreamingPlaylistModel } from './video-streaming-playlist' | 127 | import { VideoStreamingPlaylistModel } from './video-streaming-playlist' |
128 | import { VideoTagModel } from './video-tag' | 128 | import { VideoTagModel } from './video-tag' |
129 | import { VideoViewModel } from './video-view' | 129 | import { VideoViewModel } from './video-view' |
130 | import { stream } from 'winston' | ||
130 | 131 | ||
131 | export enum ScopeNames { | 132 | export enum ScopeNames { |
132 | AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', | 133 | AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', |
@@ -1472,11 +1473,13 @@ export class VideoModel extends Model<VideoModel> { | |||
1472 | } | 1473 | } |
1473 | 1474 | ||
1474 | private static buildAPIResult (rows: any[]) { | 1475 | private static buildAPIResult (rows: any[]) { |
1475 | const memo: { [ id: number ]: VideoModel } = {} | 1476 | const videosMemo: { [ id: number ]: VideoModel } = {} |
1477 | const videoStreamingPlaylistMemo: { [ id: number ]: VideoStreamingPlaylistModel } = {} | ||
1476 | 1478 | ||
1477 | const thumbnailsDone = new Set<number>() | 1479 | const thumbnailsDone = new Set<number>() |
1478 | const historyDone = new Set<number>() | 1480 | const historyDone = new Set<number>() |
1479 | const videoFilesDone = new Set<number>() | 1481 | const videoFilesDone = new Set<number>() |
1482 | const videoStreamingPlaylistsDone = new Set<number>() | ||
1480 | 1483 | ||
1481 | const videos: VideoModel[] = [] | 1484 | const videos: VideoModel[] = [] |
1482 | 1485 | ||
@@ -1484,6 +1487,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1484 | const actorKeys = [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ] | 1487 | const actorKeys = [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ] |
1485 | const serverKeys = [ 'id', 'host' ] | 1488 | const serverKeys = [ 'id', 'host' ] |
1486 | const videoFileKeys = [ 'id', 'createdAt', 'updatedAt', 'resolution', 'size', 'extname', 'infoHash', 'fps', 'videoId' ] | 1489 | const videoFileKeys = [ 'id', 'createdAt', 'updatedAt', 'resolution', 'size', 'extname', 'infoHash', 'fps', 'videoId' ] |
1490 | const videoStreamingPlaylistKeys = [ 'id' ] | ||
1487 | const videoKeys = [ | 1491 | const videoKeys = [ |
1488 | 'id', | 1492 | 'id', |
1489 | 'uuid', | 1493 | 'uuid', |
@@ -1529,7 +1533,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1529 | } | 1533 | } |
1530 | 1534 | ||
1531 | for (const row of rows) { | 1535 | for (const row of rows) { |
1532 | if (!memo[row.id]) { | 1536 | if (!videosMemo[row.id]) { |
1533 | // Build Channel | 1537 | // Build Channel |
1534 | const channel = row.VideoChannel | 1538 | const channel = row.VideoChannel |
1535 | const channelModel = new VideoChannelModel(pick(channel, [ 'id', 'name', 'description', 'actorId' ])) | 1539 | const channelModel = new VideoChannelModel(pick(channel, [ 'id', 'name', 'description', 'actorId' ])) |
@@ -1547,13 +1551,14 @@ export class VideoModel extends Model<VideoModel> { | |||
1547 | videoModel.UserVideoHistories = [] | 1551 | videoModel.UserVideoHistories = [] |
1548 | videoModel.Thumbnails = [] | 1552 | videoModel.Thumbnails = [] |
1549 | videoModel.VideoFiles = [] | 1553 | videoModel.VideoFiles = [] |
1554 | videoModel.VideoStreamingPlaylists = [] | ||
1550 | 1555 | ||
1551 | memo[row.id] = videoModel | 1556 | videosMemo[row.id] = videoModel |
1552 | // Don't take object value to have a sorted array | 1557 | // Don't take object value to have a sorted array |
1553 | videos.push(videoModel) | 1558 | videos.push(videoModel) |
1554 | } | 1559 | } |
1555 | 1560 | ||
1556 | const videoModel = memo[row.id] | 1561 | const videoModel = videosMemo[row.id] |
1557 | 1562 | ||
1558 | if (row.userVideoHistory?.id && !historyDone.has(row.userVideoHistory.id)) { | 1563 | if (row.userVideoHistory?.id && !historyDone.has(row.userVideoHistory.id)) { |
1559 | const historyModel = new UserVideoHistoryModel(pick(row.userVideoHistory, [ 'id', 'currentTime' ])) | 1564 | const historyModel = new UserVideoHistoryModel(pick(row.userVideoHistory, [ 'id', 'currentTime' ])) |
@@ -1575,6 +1580,31 @@ export class VideoModel extends Model<VideoModel> { | |||
1575 | 1580 | ||
1576 | videoFilesDone.add(row.VideoFiles.id) | 1581 | videoFilesDone.add(row.VideoFiles.id) |
1577 | } | 1582 | } |
1583 | |||
1584 | if (row.VideoFiles?.id && !videoFilesDone.has(row.VideoFiles.id)) { | ||
1585 | const videoFileModel = new VideoFileModel(pick(row.VideoFiles, videoFileKeys)) | ||
1586 | videoModel.VideoFiles.push(videoFileModel) | ||
1587 | |||
1588 | videoFilesDone.add(row.VideoFiles.id) | ||
1589 | } | ||
1590 | |||
1591 | if (row.VideoStreamingPlaylists?.id && !videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id]) { | ||
1592 | const streamingPlaylist = new VideoStreamingPlaylistModel(pick(row.VideoStreamingPlaylists, videoStreamingPlaylistKeys)) | ||
1593 | streamingPlaylist.VideoFiles = [] | ||
1594 | |||
1595 | videoModel.VideoStreamingPlaylists.push(streamingPlaylist) | ||
1596 | |||
1597 | videoStreamingPlaylistMemo[streamingPlaylist.id] = streamingPlaylist | ||
1598 | } | ||
1599 | |||
1600 | if (row.VideoStreamingPlaylists?.VideoFiles?.id && !videoFilesDone.has(row.VideoStreamingPlaylists.VideoFiles.id)) { | ||
1601 | const streamingPlaylist = videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id] | ||
1602 | |||
1603 | const videoFileModel = new VideoFileModel(pick(row.VideoStreamingPlaylists.VideoFiles, videoFileKeys)) | ||
1604 | streamingPlaylist.VideoFiles.push(videoFileModel) | ||
1605 | |||
1606 | videoFilesDone.add(row.VideoStreamingPlaylists.VideoFiles.id) | ||
1607 | } | ||
1578 | } | 1608 | } |
1579 | 1609 | ||
1580 | return videos | 1610 | return videos |
@@ -1717,7 +1747,21 @@ export class VideoModel extends Model<VideoModel> { | |||
1717 | 1747 | ||
1718 | getFormattedVideoFilesJSON (): VideoFile[] { | 1748 | getFormattedVideoFilesJSON (): VideoFile[] { |
1719 | const { baseUrlHttp, baseUrlWs } = this.getBaseUrls() | 1749 | const { baseUrlHttp, baseUrlWs } = this.getBaseUrls() |
1720 | return videoFilesModelToFormattedJSON(this, baseUrlHttp, baseUrlWs, this.VideoFiles) | 1750 | let files: MVideoFileRedundanciesOpt[] = [] |
1751 | |||
1752 | logger.info('coucou', { files }) | ||
1753 | |||
1754 | if (Array.isArray(this.VideoFiles)) { | ||
1755 | files = files.concat(this.VideoFiles) | ||
1756 | } | ||
1757 | |||
1758 | for (const p of (this.VideoStreamingPlaylists || [])) { | ||
1759 | files = files.concat(p.VideoFiles || []) | ||
1760 | } | ||
1761 | |||
1762 | logger.info('coucou', { files, video: this.VideoStreamingPlaylists }) | ||
1763 | |||
1764 | return videoFilesModelToFormattedJSON(this, baseUrlHttp, baseUrlWs, files) | ||
1721 | } | 1765 | } |
1722 | 1766 | ||
1723 | toActivityPubObject (this: MVideoAP): VideoTorrentObject { | 1767 | toActivityPubObject (this: MVideoAP): VideoTorrentObject { |