aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-interface.ts3
-rw-r--r--server/models/video/video.ts78
2 files changed, 64 insertions, 17 deletions
diff --git a/server/models/video/video-interface.ts b/server/models/video/video-interface.ts
index 587652f45..cfe65f9aa 100644
--- a/server/models/video/video-interface.ts
+++ b/server/models/video/video-interface.ts
@@ -49,6 +49,7 @@ export namespace VideoMethods {
49 export type ListOwnedByAuthor = (author: string) => Promise<VideoInstance[]> 49 export type ListOwnedByAuthor = (author: string) => Promise<VideoInstance[]>
50 50
51 export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<VideoInstance> > 51 export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<VideoInstance> >
52 export type ListUserVideosForApi = (userId: number, start: number, count: number, sort: string) => Promise< ResultList<VideoInstance> >
52 export type SearchAndPopulateAuthorAndPodAndTags = ( 53 export type SearchAndPopulateAuthorAndPodAndTags = (
53 value: string, 54 value: string,
54 field: string, 55 field: string,
@@ -75,6 +76,7 @@ export interface VideoClass {
75 generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData 76 generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData
76 list: VideoMethods.List 77 list: VideoMethods.List
77 listForApi: VideoMethods.ListForApi 78 listForApi: VideoMethods.ListForApi
79 listUserVideosForApi: VideoMethods.ListUserVideosForApi
78 listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags 80 listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
79 listOwnedByAuthor: VideoMethods.ListOwnedByAuthor 81 listOwnedByAuthor: VideoMethods.ListOwnedByAuthor
80 load: VideoMethods.Load 82 load: VideoMethods.Load
@@ -97,6 +99,7 @@ export interface VideoAttributes {
97 nsfw: boolean 99 nsfw: boolean
98 description: string 100 description: string
99 duration: number 101 duration: number
102 privacy: number
100 views?: number 103 views?: number
101 likes?: number 104 likes?: number
102 dislikes?: number 105 dislikes?: number
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 1877c506a..2c1bd6b6e 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -18,6 +18,7 @@ import {
18 isVideoNSFWValid, 18 isVideoNSFWValid,
19 isVideoDescriptionValid, 19 isVideoDescriptionValid,
20 isVideoDurationValid, 20 isVideoDurationValid,
21 isVideoPrivacyValid,
21 readFileBufferPromise, 22 readFileBufferPromise,
22 unlinkPromise, 23 unlinkPromise,
23 renamePromise, 24 renamePromise,
@@ -38,10 +39,11 @@ import {
38 THUMBNAILS_SIZE, 39 THUMBNAILS_SIZE,
39 PREVIEWS_SIZE, 40 PREVIEWS_SIZE,
40 CONSTRAINTS_FIELDS, 41 CONSTRAINTS_FIELDS,
41 API_VERSION 42 API_VERSION,
43 VIDEO_PRIVACIES
42} from '../../initializers' 44} from '../../initializers'
43import { removeVideoToFriends } from '../../lib' 45import { removeVideoToFriends } from '../../lib'
44import { VideoResolution } from '../../../shared' 46import { VideoResolution, VideoPrivacy } from '../../../shared'
45import { VideoFileInstance, VideoFileModel } from './video-file-interface' 47import { VideoFileInstance, VideoFileModel } from './video-file-interface'
46 48
47import { addMethodsToModel, getSort } from '../utils' 49import { addMethodsToModel, getSort } from '../utils'
@@ -79,6 +81,7 @@ let getTruncatedDescription: VideoMethods.GetTruncatedDescription
79let generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData 81let generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData
80let list: VideoMethods.List 82let list: VideoMethods.List
81let listForApi: VideoMethods.ListForApi 83let listForApi: VideoMethods.ListForApi
84let listUserVideosForApi: VideoMethods.ListUserVideosForApi
82let loadByHostAndUUID: VideoMethods.LoadByHostAndUUID 85let loadByHostAndUUID: VideoMethods.LoadByHostAndUUID
83let listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags 86let listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
84let listOwnedByAuthor: VideoMethods.ListOwnedByAuthor 87let listOwnedByAuthor: VideoMethods.ListOwnedByAuthor
@@ -146,6 +149,16 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
146 } 149 }
147 } 150 }
148 }, 151 },
152 privacy: {
153 type: DataTypes.INTEGER,
154 allowNull: false,
155 validate: {
156 privacyValid: value => {
157 const res = isVideoPrivacyValid(value)
158 if (res === false) throw new Error('Video privacy is not valid.')
159 }
160 }
161 },
149 nsfw: { 162 nsfw: {
150 type: DataTypes.BOOLEAN, 163 type: DataTypes.BOOLEAN,
151 allowNull: false, 164 allowNull: false,
@@ -245,6 +258,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
245 generateThumbnailFromData, 258 generateThumbnailFromData,
246 list, 259 list,
247 listForApi, 260 listForApi,
261 listUserVideosForApi,
248 listOwnedAndPopulateAuthorAndTags, 262 listOwnedAndPopulateAuthorAndTags,
249 listOwnedByAuthor, 263 listOwnedByAuthor,
250 load, 264 load,
@@ -501,7 +515,13 @@ toFormattedJSON = function (this: VideoInstance) {
501toFormattedDetailsJSON = function (this: VideoInstance) { 515toFormattedDetailsJSON = function (this: VideoInstance) {
502 const formattedJson = this.toFormattedJSON() 516 const formattedJson = this.toFormattedJSON()
503 517
518 // Maybe our pod is not up to date and there are new privacy settings since our version
519 let privacyLabel = VIDEO_PRIVACIES[this.privacy]
520 if (!privacyLabel) privacyLabel = 'Unknown'
521
504 const detailsJson = { 522 const detailsJson = {
523 privacyLabel,
524 privacy: this.privacy,
505 descriptionPath: this.getDescriptionPath(), 525 descriptionPath: this.getDescriptionPath(),
506 channel: this.VideoChannel.toFormattedJSON(), 526 channel: this.VideoChannel.toFormattedJSON(),
507 files: [] 527 files: []
@@ -555,6 +575,7 @@ toAddRemoteJSON = function (this: VideoInstance) {
555 views: this.views, 575 views: this.views,
556 likes: this.likes, 576 likes: this.likes,
557 dislikes: this.dislikes, 577 dislikes: this.dislikes,
578 privacy: this.privacy,
558 files: [] 579 files: []
559 } 580 }
560 581
@@ -587,6 +608,7 @@ toUpdateRemoteJSON = function (this: VideoInstance) {
587 views: this.views, 608 views: this.views,
588 likes: this.likes, 609 likes: this.likes,
589 dislikes: this.dislikes, 610 dislikes: this.dislikes,
611 privacy: this.privacy,
590 files: [] 612 files: []
591 } 613 }
592 614
@@ -746,8 +768,39 @@ list = function () {
746 return Video.findAll(query) 768 return Video.findAll(query)
747} 769}
748 770
771listUserVideosForApi = function (userId: number, start: number, count: number, sort: string) {
772 const query = {
773 distinct: true,
774 offset: start,
775 limit: count,
776 order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ],
777 include: [
778 {
779 model: Video['sequelize'].models.VideoChannel,
780 required: true,
781 include: [
782 {
783 model: Video['sequelize'].models.Author,
784 where: {
785 userId
786 },
787 required: true
788 }
789 ]
790 },
791 Video['sequelize'].models.Tag
792 ]
793 }
794
795 return Video.findAndCountAll(query).then(({ rows, count }) => {
796 return {
797 data: rows,
798 total: count
799 }
800 })
801}
802
749listForApi = function (start: number, count: number, sort: string) { 803listForApi = function (start: number, count: number, sort: string) {
750 // Exclude blacklisted videos from the list
751 const query = { 804 const query = {
752 distinct: true, 805 distinct: true,
753 offset: start, 806 offset: start,
@@ -768,8 +821,7 @@ listForApi = function (start: number, count: number, sort: string) {
768 } 821 }
769 ] 822 ]
770 }, 823 },
771 Video['sequelize'].models.Tag, 824 Video['sequelize'].models.Tag
772 Video['sequelize'].models.VideoFile
773 ], 825 ],
774 where: createBaseVideosWhere() 826 where: createBaseVideosWhere()
775 } 827 }
@@ -969,10 +1021,6 @@ searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, s
969 model: Video['sequelize'].models.Tag 1021 model: Video['sequelize'].models.Tag
970 } 1022 }
971 1023
972 const videoFileInclude: Sequelize.IncludeOptions = {
973 model: Video['sequelize'].models.VideoFile
974 }
975
976 const query: Sequelize.FindOptions<VideoAttributes> = { 1024 const query: Sequelize.FindOptions<VideoAttributes> = {
977 distinct: true, 1025 distinct: true,
978 where: createBaseVideosWhere(), 1026 where: createBaseVideosWhere(),
@@ -981,12 +1029,7 @@ searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, s
981 order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ] 1029 order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ]
982 } 1030 }
983 1031
984 // Make an exact search with the magnet 1032 if (field === 'tags') {
985 if (field === 'magnetUri') {
986 videoFileInclude.where = {
987 infoHash: magnetUtil.decode(value).infoHash
988 }
989 } else if (field === 'tags') {
990 const escapedValue = Video['sequelize'].escape('%' + value + '%') 1033 const escapedValue = Video['sequelize'].escape('%' + value + '%')
991 query.where['id'][Sequelize.Op.in] = Video['sequelize'].literal( 1034 query.where['id'][Sequelize.Op.in] = Video['sequelize'].literal(
992 `(SELECT "VideoTags"."videoId" 1035 `(SELECT "VideoTags"."videoId"
@@ -1016,7 +1059,7 @@ searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, s
1016 } 1059 }
1017 1060
1018 query.include = [ 1061 query.include = [
1019 videoChannelInclude, tagInclude, videoFileInclude 1062 videoChannelInclude, tagInclude
1020 ] 1063 ]
1021 1064
1022 return Video.findAndCountAll(query).then(({ rows, count }) => { 1065 return Video.findAndCountAll(query).then(({ rows, count }) => {
@@ -1035,7 +1078,8 @@ function createBaseVideosWhere () {
1035 [Sequelize.Op.notIn]: Video['sequelize'].literal( 1078 [Sequelize.Op.notIn]: Video['sequelize'].literal(
1036 '(SELECT "BlacklistedVideos"."videoId" FROM "BlacklistedVideos")' 1079 '(SELECT "BlacklistedVideos"."videoId" FROM "BlacklistedVideos")'
1037 ) 1080 )
1038 } 1081 },
1082 privacy: VideoPrivacy.PUBLIC
1039 } 1083 }
1040} 1084}
1041 1085