diff options
Diffstat (limited to 'server/models/video')
-rw-r--r-- | server/models/video/video-interface.ts | 4 | ||||
-rw-r--r-- | server/models/video/video.ts | 86 |
2 files changed, 35 insertions, 55 deletions
diff --git a/server/models/video/video-interface.ts b/server/models/video/video-interface.ts index 2afbaf09e..3a7bc82a4 100644 --- a/server/models/video/video-interface.ts +++ b/server/models/video/video-interface.ts | |||
@@ -38,6 +38,8 @@ export namespace VideoMethods { | |||
38 | export type GetEmbedPath = (this: VideoInstance) => string | 38 | export type GetEmbedPath = (this: VideoInstance) => string |
39 | export type GetThumbnailPath = (this: VideoInstance) => string | 39 | export type GetThumbnailPath = (this: VideoInstance) => string |
40 | export type GetPreviewPath = (this: VideoInstance) => string | 40 | export type GetPreviewPath = (this: VideoInstance) => string |
41 | export type GetDescriptionPath = (this: VideoInstance) => string | ||
42 | export type GetTruncatedDescription = (this: VideoInstance) => string | ||
41 | 43 | ||
42 | // Return thumbnail name | 44 | // Return thumbnail name |
43 | export type GenerateThumbnailFromData = (video: VideoInstance, thumbnailData: string) => Promise<string> | 45 | export type GenerateThumbnailFromData = (video: VideoInstance, thumbnailData: string) => Promise<string> |
@@ -135,6 +137,8 @@ export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.In | |||
135 | transcodeOriginalVideofile: VideoMethods.TranscodeOriginalVideofile | 137 | transcodeOriginalVideofile: VideoMethods.TranscodeOriginalVideofile |
136 | getOriginalFileHeight: VideoMethods.GetOriginalFileHeight | 138 | getOriginalFileHeight: VideoMethods.GetOriginalFileHeight |
137 | getEmbedPath: VideoMethods.GetEmbedPath | 139 | getEmbedPath: VideoMethods.GetEmbedPath |
140 | getDescriptionPath: VideoMethods.GetDescriptionPath | ||
141 | getTruncatedDescription : VideoMethods.GetTruncatedDescription | ||
138 | 142 | ||
139 | setTags: Sequelize.HasManySetAssociationsMixin<TagAttributes, string> | 143 | setTags: Sequelize.HasManySetAssociationsMixin<TagAttributes, string> |
140 | addVideoFile: Sequelize.HasManyAddAssociationMixin<VideoFileAttributes, string> | 144 | addVideoFile: Sequelize.HasManyAddAssociationMixin<VideoFileAttributes, string> |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 27f59f3a9..1877c506a 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -6,7 +6,7 @@ import * as parseTorrent from 'parse-torrent' | |||
6 | import { join } from 'path' | 6 | import { join } from 'path' |
7 | import * as Sequelize from 'sequelize' | 7 | import * as Sequelize from 'sequelize' |
8 | import * as Promise from 'bluebird' | 8 | import * as Promise from 'bluebird' |
9 | import { maxBy } from 'lodash' | 9 | import { maxBy, truncate } from 'lodash' |
10 | 10 | ||
11 | import { TagInstance } from './tag-interface' | 11 | import { TagInstance } from './tag-interface' |
12 | import { | 12 | import { |
@@ -35,7 +35,10 @@ import { | |||
35 | VIDEO_CATEGORIES, | 35 | VIDEO_CATEGORIES, |
36 | VIDEO_LICENCES, | 36 | VIDEO_LICENCES, |
37 | VIDEO_LANGUAGES, | 37 | VIDEO_LANGUAGES, |
38 | THUMBNAILS_SIZE | 38 | THUMBNAILS_SIZE, |
39 | PREVIEWS_SIZE, | ||
40 | CONSTRAINTS_FIELDS, | ||
41 | API_VERSION | ||
39 | } from '../../initializers' | 42 | } from '../../initializers' |
40 | import { removeVideoToFriends } from '../../lib' | 43 | import { removeVideoToFriends } from '../../lib' |
41 | import { VideoResolution } from '../../../shared' | 44 | import { VideoResolution } from '../../../shared' |
@@ -48,7 +51,6 @@ import { | |||
48 | 51 | ||
49 | VideoMethods | 52 | VideoMethods |
50 | } from './video-interface' | 53 | } from './video-interface' |
51 | import { PREVIEWS_SIZE } from '../../initializers/constants' | ||
52 | 54 | ||
53 | let Video: Sequelize.Model<VideoInstance, VideoAttributes> | 55 | let Video: Sequelize.Model<VideoInstance, VideoAttributes> |
54 | let getOriginalFile: VideoMethods.GetOriginalFile | 56 | let getOriginalFile: VideoMethods.GetOriginalFile |
@@ -71,6 +73,8 @@ let getVideoFilePath: VideoMethods.GetVideoFilePath | |||
71 | let createTorrentAndSetInfoHash: VideoMethods.CreateTorrentAndSetInfoHash | 73 | let createTorrentAndSetInfoHash: VideoMethods.CreateTorrentAndSetInfoHash |
72 | let getOriginalFileHeight: VideoMethods.GetOriginalFileHeight | 74 | let getOriginalFileHeight: VideoMethods.GetOriginalFileHeight |
73 | let getEmbedPath: VideoMethods.GetEmbedPath | 75 | let getEmbedPath: VideoMethods.GetEmbedPath |
76 | let getDescriptionPath: VideoMethods.GetDescriptionPath | ||
77 | let getTruncatedDescription: VideoMethods.GetTruncatedDescription | ||
74 | 78 | ||
75 | let generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData | 79 | let generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData |
76 | let list: VideoMethods.List | 80 | let list: VideoMethods.List |
@@ -153,7 +157,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
153 | } | 157 | } |
154 | }, | 158 | }, |
155 | description: { | 159 | description: { |
156 | type: DataTypes.STRING, | 160 | type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max), |
157 | allowNull: false, | 161 | allowNull: false, |
158 | validate: { | 162 | validate: { |
159 | descriptionValid: value => { | 163 | descriptionValid: value => { |
@@ -276,7 +280,9 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
276 | optimizeOriginalVideofile, | 280 | optimizeOriginalVideofile, |
277 | transcodeOriginalVideofile, | 281 | transcodeOriginalVideofile, |
278 | getOriginalFileHeight, | 282 | getOriginalFileHeight, |
279 | getEmbedPath | 283 | getEmbedPath, |
284 | getTruncatedDescription, | ||
285 | getDescriptionPath | ||
280 | ] | 286 | ] |
281 | addMethodsToModel(Video, classMethods, instanceMethods) | 287 | addMethodsToModel(Video, classMethods, instanceMethods) |
282 | 288 | ||
@@ -473,7 +479,7 @@ toFormattedJSON = function (this: VideoInstance) { | |||
473 | language: this.language, | 479 | language: this.language, |
474 | languageLabel, | 480 | languageLabel, |
475 | nsfw: this.nsfw, | 481 | nsfw: this.nsfw, |
476 | description: this.description, | 482 | description: this.getTruncatedDescription(), |
477 | podHost, | 483 | podHost, |
478 | isLocal: this.isOwned(), | 484 | isLocal: this.isOwned(), |
479 | author: this.VideoChannel.Author.name, | 485 | author: this.VideoChannel.Author.name, |
@@ -493,59 +499,17 @@ toFormattedJSON = function (this: VideoInstance) { | |||
493 | } | 499 | } |
494 | 500 | ||
495 | toFormattedDetailsJSON = function (this: VideoInstance) { | 501 | toFormattedDetailsJSON = function (this: VideoInstance) { |
496 | let podHost | 502 | const formattedJson = this.toFormattedJSON() |
497 | |||
498 | if (this.VideoChannel.Author.Pod) { | ||
499 | podHost = this.VideoChannel.Author.Pod.host | ||
500 | } else { | ||
501 | // It means it's our video | ||
502 | podHost = CONFIG.WEBSERVER.HOST | ||
503 | } | ||
504 | 503 | ||
505 | // Maybe our pod is not up to date and there are new categories since our version | 504 | const detailsJson = { |
506 | let categoryLabel = VIDEO_CATEGORIES[this.category] | 505 | descriptionPath: this.getDescriptionPath(), |
507 | if (!categoryLabel) categoryLabel = 'Misc' | ||
508 | |||
509 | // Maybe our pod is not up to date and there are new licences since our version | ||
510 | let licenceLabel = VIDEO_LICENCES[this.licence] | ||
511 | if (!licenceLabel) licenceLabel = 'Unknown' | ||
512 | |||
513 | // Language is an optional attribute | ||
514 | let languageLabel = VIDEO_LANGUAGES[this.language] | ||
515 | if (!languageLabel) languageLabel = 'Unknown' | ||
516 | |||
517 | const json = { | ||
518 | id: this.id, | ||
519 | uuid: this.uuid, | ||
520 | name: this.name, | ||
521 | category: this.category, | ||
522 | categoryLabel, | ||
523 | licence: this.licence, | ||
524 | licenceLabel, | ||
525 | language: this.language, | ||
526 | languageLabel, | ||
527 | nsfw: this.nsfw, | ||
528 | description: this.description, | ||
529 | podHost, | ||
530 | isLocal: this.isOwned(), | ||
531 | author: this.VideoChannel.Author.name, | ||
532 | duration: this.duration, | ||
533 | views: this.views, | ||
534 | likes: this.likes, | ||
535 | dislikes: this.dislikes, | ||
536 | tags: map<TagInstance, string>(this.Tags, 'name'), | ||
537 | thumbnailPath: this.getThumbnailPath(), | ||
538 | previewPath: this.getPreviewPath(), | ||
539 | embedPath: this.getEmbedPath(), | ||
540 | createdAt: this.createdAt, | ||
541 | updatedAt: this.updatedAt, | ||
542 | channel: this.VideoChannel.toFormattedJSON(), | 506 | channel: this.VideoChannel.toFormattedJSON(), |
543 | files: [] | 507 | files: [] |
544 | } | 508 | } |
545 | 509 | ||
546 | // Format and sort video files | 510 | // Format and sort video files |
547 | const { baseUrlHttp, baseUrlWs } = getBaseUrls(this) | 511 | const { baseUrlHttp, baseUrlWs } = getBaseUrls(this) |
548 | json.files = this.VideoFiles | 512 | detailsJson.files = this.VideoFiles |
549 | .map(videoFile => { | 513 | .map(videoFile => { |
550 | let resolutionLabel = videoFile.resolution + 'p' | 514 | let resolutionLabel = videoFile.resolution + 'p' |
551 | 515 | ||
@@ -566,7 +530,7 @@ toFormattedDetailsJSON = function (this: VideoInstance) { | |||
566 | return -1 | 530 | return -1 |
567 | }) | 531 | }) |
568 | 532 | ||
569 | return json | 533 | return Object.assign(formattedJson, detailsJson) |
570 | } | 534 | } |
571 | 535 | ||
572 | toAddRemoteJSON = function (this: VideoInstance) { | 536 | toAddRemoteJSON = function (this: VideoInstance) { |
@@ -581,7 +545,7 @@ toAddRemoteJSON = function (this: VideoInstance) { | |||
581 | licence: this.licence, | 545 | licence: this.licence, |
582 | language: this.language, | 546 | language: this.language, |
583 | nsfw: this.nsfw, | 547 | nsfw: this.nsfw, |
584 | description: this.description, | 548 | truncatedDescription: this.getTruncatedDescription(), |
585 | channelUUID: this.VideoChannel.uuid, | 549 | channelUUID: this.VideoChannel.uuid, |
586 | duration: this.duration, | 550 | duration: this.duration, |
587 | thumbnailData: thumbnailData.toString('binary'), | 551 | thumbnailData: thumbnailData.toString('binary'), |
@@ -615,7 +579,7 @@ toUpdateRemoteJSON = function (this: VideoInstance) { | |||
615 | licence: this.licence, | 579 | licence: this.licence, |
616 | language: this.language, | 580 | language: this.language, |
617 | nsfw: this.nsfw, | 581 | nsfw: this.nsfw, |
618 | description: this.description, | 582 | truncatedDescription: this.getTruncatedDescription(), |
619 | duration: this.duration, | 583 | duration: this.duration, |
620 | tags: map<TagInstance, string>(this.Tags, 'name'), | 584 | tags: map<TagInstance, string>(this.Tags, 'name'), |
621 | createdAt: this.createdAt, | 585 | createdAt: this.createdAt, |
@@ -638,6 +602,14 @@ toUpdateRemoteJSON = function (this: VideoInstance) { | |||
638 | return json | 602 | return json |
639 | } | 603 | } |
640 | 604 | ||
605 | getTruncatedDescription = function (this: VideoInstance) { | ||
606 | const options = { | ||
607 | length: CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max | ||
608 | } | ||
609 | |||
610 | return truncate(this.description, options) | ||
611 | } | ||
612 | |||
641 | optimizeOriginalVideofile = function (this: VideoInstance) { | 613 | optimizeOriginalVideofile = function (this: VideoInstance) { |
642 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | 614 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR |
643 | const newExtname = '.mp4' | 615 | const newExtname = '.mp4' |
@@ -730,6 +702,10 @@ getOriginalFileHeight = function (this: VideoInstance) { | |||
730 | return getVideoFileHeight(originalFilePath) | 702 | return getVideoFileHeight(originalFilePath) |
731 | } | 703 | } |
732 | 704 | ||
705 | getDescriptionPath = function (this: VideoInstance) { | ||
706 | return `/api/${API_VERSION}/videos/${this.uuid}/description` | ||
707 | } | ||
708 | |||
733 | removeThumbnail = function (this: VideoInstance) { | 709 | removeThumbnail = function (this: VideoInstance) { |
734 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName()) | 710 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName()) |
735 | return unlinkPromise(thumbnailPath) | 711 | return unlinkPromise(thumbnailPath) |