diff options
Diffstat (limited to 'server/models/video')
-rw-r--r-- | server/models/video/video-interface.ts | 1 | ||||
-rw-r--r-- | server/models/video/video.ts | 92 |
2 files changed, 47 insertions, 46 deletions
diff --git a/server/models/video/video-interface.ts b/server/models/video/video-interface.ts index be140de86..2a63350af 100644 --- a/server/models/video/video-interface.ts +++ b/server/models/video/video-interface.ts | |||
@@ -50,7 +50,6 @@ export namespace VideoMethods { | |||
50 | export type ListUserVideosForApi = (userId: number, start: number, count: number, sort: string) => Bluebird< ResultList<VideoInstance> > | 50 | export type ListUserVideosForApi = (userId: number, start: number, count: number, sort: string) => Bluebird< ResultList<VideoInstance> > |
51 | export type SearchAndPopulateAccountAndServerAndTags = ( | 51 | export type SearchAndPopulateAccountAndServerAndTags = ( |
52 | value: string, | 52 | value: string, |
53 | field: string, | ||
54 | start: number, | 53 | start: number, |
55 | count: number, | 54 | count: number, |
56 | sort: string | 55 | sort: string |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index f3469c1de..d46fdeebe 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -104,7 +104,8 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
104 | }, | 104 | }, |
105 | category: { | 105 | category: { |
106 | type: DataTypes.INTEGER, | 106 | type: DataTypes.INTEGER, |
107 | allowNull: false, | 107 | allowNull: true, |
108 | defaultValue: null, | ||
108 | validate: { | 109 | validate: { |
109 | categoryValid: value => { | 110 | categoryValid: value => { |
110 | const res = isVideoCategoryValid(value) | 111 | const res = isVideoCategoryValid(value) |
@@ -114,7 +115,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
114 | }, | 115 | }, |
115 | licence: { | 116 | licence: { |
116 | type: DataTypes.INTEGER, | 117 | type: DataTypes.INTEGER, |
117 | allowNull: false, | 118 | allowNull: true, |
118 | defaultValue: null, | 119 | defaultValue: null, |
119 | validate: { | 120 | validate: { |
120 | licenceValid: value => { | 121 | licenceValid: value => { |
@@ -126,6 +127,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
126 | language: { | 127 | language: { |
127 | type: DataTypes.INTEGER, | 128 | type: DataTypes.INTEGER, |
128 | allowNull: true, | 129 | allowNull: true, |
130 | defaultValue: null, | ||
129 | validate: { | 131 | validate: { |
130 | languageValid: value => { | 132 | languageValid: value => { |
131 | const res = isVideoLanguageValid(value) | 133 | const res = isVideoLanguageValid(value) |
@@ -155,7 +157,8 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
155 | }, | 157 | }, |
156 | description: { | 158 | description: { |
157 | type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max), | 159 | type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max), |
158 | allowNull: false, | 160 | allowNull: true, |
161 | defaultValue: null, | ||
159 | validate: { | 162 | validate: { |
160 | descriptionValid: value => { | 163 | descriptionValid: value => { |
161 | const res = isVideoDescriptionValid(value) | 164 | const res = isVideoDescriptionValid(value) |
@@ -486,7 +489,7 @@ toFormattedJSON = function (this: VideoInstance) { | |||
486 | description: this.getTruncatedDescription(), | 489 | description: this.getTruncatedDescription(), |
487 | serverHost, | 490 | serverHost, |
488 | isLocal: this.isOwned(), | 491 | isLocal: this.isOwned(), |
489 | account: this.VideoChannel.Account.name, | 492 | accountName: this.VideoChannel.Account.name, |
490 | duration: this.duration, | 493 | duration: this.duration, |
491 | views: this.views, | 494 | views: this.views, |
492 | likes: this.likes, | 495 | likes: this.likes, |
@@ -514,6 +517,7 @@ toFormattedDetailsJSON = function (this: VideoInstance) { | |||
514 | privacy: this.privacy, | 517 | privacy: this.privacy, |
515 | descriptionPath: this.getDescriptionPath(), | 518 | descriptionPath: this.getDescriptionPath(), |
516 | channel: this.VideoChannel.toFormattedJSON(), | 519 | channel: this.VideoChannel.toFormattedJSON(), |
520 | account: this.VideoChannel.Account.toFormattedJSON(), | ||
517 | files: [] | 521 | files: [] |
518 | } | 522 | } |
519 | 523 | ||
@@ -560,6 +564,22 @@ toActivityPubObject = function (this: VideoInstance) { | |||
560 | } | 564 | } |
561 | } | 565 | } |
562 | 566 | ||
567 | let category | ||
568 | if (this.category) { | ||
569 | category = { | ||
570 | identifier: this.category + '', | ||
571 | name: this.getCategoryLabel() | ||
572 | } | ||
573 | } | ||
574 | |||
575 | let licence | ||
576 | if (this.licence) { | ||
577 | licence = { | ||
578 | identifier: this.licence + '', | ||
579 | name: this.getLicenceLabel() | ||
580 | } | ||
581 | } | ||
582 | |||
563 | let likesObject | 583 | let likesObject |
564 | let dislikesObject | 584 | let dislikesObject |
565 | 585 | ||
@@ -631,14 +651,8 @@ toActivityPubObject = function (this: VideoInstance) { | |||
631 | duration: 'PT' + this.duration + 'S', | 651 | duration: 'PT' + this.duration + 'S', |
632 | uuid: this.uuid, | 652 | uuid: this.uuid, |
633 | tag, | 653 | tag, |
634 | category: { | 654 | category, |
635 | identifier: this.category + '', | 655 | licence, |
636 | name: this.getCategoryLabel() | ||
637 | }, | ||
638 | licence: { | ||
639 | identifier: this.licence + '', | ||
640 | name: this.getLicenceLabel() | ||
641 | }, | ||
642 | language, | 656 | language, |
643 | views: this.views, | 657 | views: this.views, |
644 | nsfw: this.nsfw, | 658 | nsfw: this.nsfw, |
@@ -663,6 +677,8 @@ toActivityPubObject = function (this: VideoInstance) { | |||
663 | } | 677 | } |
664 | 678 | ||
665 | getTruncatedDescription = function (this: VideoInstance) { | 679 | getTruncatedDescription = function (this: VideoInstance) { |
680 | if (!this.description) return null | ||
681 | |||
666 | const options = { | 682 | const options = { |
667 | length: CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max | 683 | length: CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max |
668 | } | 684 | } |
@@ -753,8 +769,6 @@ getDescriptionPath = function (this: VideoInstance) { | |||
753 | 769 | ||
754 | getCategoryLabel = function (this: VideoInstance) { | 770 | getCategoryLabel = function (this: VideoInstance) { |
755 | let categoryLabel = VIDEO_CATEGORIES[this.category] | 771 | let categoryLabel = VIDEO_CATEGORIES[this.category] |
756 | |||
757 | // Maybe our server is not up to date and there are new categories since our version | ||
758 | if (!categoryLabel) categoryLabel = 'Misc' | 772 | if (!categoryLabel) categoryLabel = 'Misc' |
759 | 773 | ||
760 | return categoryLabel | 774 | return categoryLabel |
@@ -762,15 +776,12 @@ getCategoryLabel = function (this: VideoInstance) { | |||
762 | 776 | ||
763 | getLicenceLabel = function (this: VideoInstance) { | 777 | getLicenceLabel = function (this: VideoInstance) { |
764 | let licenceLabel = VIDEO_LICENCES[this.licence] | 778 | let licenceLabel = VIDEO_LICENCES[this.licence] |
765 | |||
766 | // Maybe our server is not up to date and there are new licences since our version | ||
767 | if (!licenceLabel) licenceLabel = 'Unknown' | 779 | if (!licenceLabel) licenceLabel = 'Unknown' |
768 | 780 | ||
769 | return licenceLabel | 781 | return licenceLabel |
770 | } | 782 | } |
771 | 783 | ||
772 | getLanguageLabel = function (this: VideoInstance) { | 784 | getLanguageLabel = function (this: VideoInstance) { |
773 | // Language is an optional attribute | ||
774 | let languageLabel = VIDEO_LANGUAGES[this.language] | 785 | let languageLabel = VIDEO_LANGUAGES[this.language] |
775 | if (!languageLabel) languageLabel = 'Unknown' | 786 | if (!languageLabel) languageLabel = 'Unknown' |
776 | 787 | ||
@@ -1070,7 +1081,7 @@ loadByUUIDAndPopulateAccountAndServerAndTags = function (uuid: string) { | |||
1070 | return Video.findOne(options) | 1081 | return Video.findOne(options) |
1071 | } | 1082 | } |
1072 | 1083 | ||
1073 | searchAndPopulateAccountAndServerAndTags = function (value: string, field: string, start: number, count: number, sort: string) { | 1084 | searchAndPopulateAccountAndServerAndTags = function (value: string, start: number, count: number, sort: string) { |
1074 | const serverInclude: Sequelize.IncludeOptions = { | 1085 | const serverInclude: Sequelize.IncludeOptions = { |
1075 | model: Video['sequelize'].models.Server, | 1086 | model: Video['sequelize'].models.Server, |
1076 | required: false | 1087 | required: false |
@@ -1099,33 +1110,24 @@ searchAndPopulateAccountAndServerAndTags = function (value: string, field: strin | |||
1099 | order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ] | 1110 | order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ] |
1100 | } | 1111 | } |
1101 | 1112 | ||
1102 | if (field === 'tags') { | 1113 | // TODO: search on tags too |
1103 | const escapedValue = Video['sequelize'].escape('%' + value + '%') | 1114 | // const escapedValue = Video['sequelize'].escape('%' + value + '%') |
1104 | query.where['id'][Sequelize.Op.in] = Video['sequelize'].literal( | 1115 | // query.where['id'][Sequelize.Op.in] = Video['sequelize'].literal( |
1105 | `(SELECT "VideoTags"."videoId" | 1116 | // `(SELECT "VideoTags"."videoId" |
1106 | FROM "Tags" | 1117 | // FROM "Tags" |
1107 | INNER JOIN "VideoTags" ON "Tags"."id" = "VideoTags"."tagId" | 1118 | // INNER JOIN "VideoTags" ON "Tags"."id" = "VideoTags"."tagId" |
1108 | WHERE name ILIKE ${escapedValue} | 1119 | // WHERE name ILIKE ${escapedValue} |
1109 | )` | 1120 | // )` |
1110 | ) | 1121 | // ) |
1111 | } else if (field === 'host') { | 1122 | |
1112 | // FIXME: Include our server? (not stored in the database) | 1123 | // TODO: search on account too |
1113 | serverInclude.where = { | 1124 | // accountInclude.where = { |
1114 | host: { | 1125 | // name: { |
1115 | [Sequelize.Op.iLike]: '%' + value + '%' | 1126 | // [Sequelize.Op.iLike]: '%' + value + '%' |
1116 | } | 1127 | // } |
1117 | } | 1128 | // } |
1118 | serverInclude.required = true | 1129 | query.where['name'] = { |
1119 | } else if (field === 'account') { | 1130 | [Sequelize.Op.iLike]: '%' + value + '%' |
1120 | accountInclude.where = { | ||
1121 | name: { | ||
1122 | [Sequelize.Op.iLike]: '%' + value + '%' | ||
1123 | } | ||
1124 | } | ||
1125 | } else { | ||
1126 | query.where[field] = { | ||
1127 | [Sequelize.Op.iLike]: '%' + value + '%' | ||
1128 | } | ||
1129 | } | 1131 | } |
1130 | 1132 | ||
1131 | query.include = [ | 1133 | query.include = [ |