aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r--server/models/video/video.ts180
1 files changed, 140 insertions, 40 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 0b1af4d21..d9b976404 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -60,6 +60,7 @@ let getPreviewPath: VideoMethods.GetPreviewPath
60let getTorrentFileName: VideoMethods.GetTorrentFileName 60let getTorrentFileName: VideoMethods.GetTorrentFileName
61let isOwned: VideoMethods.IsOwned 61let isOwned: VideoMethods.IsOwned
62let toFormattedJSON: VideoMethods.ToFormattedJSON 62let toFormattedJSON: VideoMethods.ToFormattedJSON
63let toFormattedDetailsJSON: VideoMethods.ToFormattedDetailsJSON
63let toAddRemoteJSON: VideoMethods.ToAddRemoteJSON 64let toAddRemoteJSON: VideoMethods.ToAddRemoteJSON
64let toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON 65let toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON
65let optimizeOriginalVideofile: VideoMethods.OptimizeOriginalVideofile 66let optimizeOriginalVideofile: VideoMethods.OptimizeOriginalVideofile
@@ -206,9 +207,6 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
206 { 207 {
207 indexes: [ 208 indexes: [
208 { 209 {
209 fields: [ 'authorId' ]
210 },
211 {
212 fields: [ 'name' ] 210 fields: [ 'name' ]
213 }, 211 },
214 { 212 {
@@ -225,6 +223,9 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
225 }, 223 },
226 { 224 {
227 fields: [ 'uuid' ] 225 fields: [ 'uuid' ]
226 },
227 {
228 fields: [ 'channelId' ]
228 } 229 }
229 ], 230 ],
230 hooks: { 231 hooks: {
@@ -268,6 +269,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
268 removeTorrent, 269 removeTorrent,
269 toAddRemoteJSON, 270 toAddRemoteJSON,
270 toFormattedJSON, 271 toFormattedJSON,
272 toFormattedDetailsJSON,
271 toUpdateRemoteJSON, 273 toUpdateRemoteJSON,
272 optimizeOriginalVideofile, 274 optimizeOriginalVideofile,
273 transcodeOriginalVideofile, 275 transcodeOriginalVideofile,
@@ -282,9 +284,9 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
282// ------------------------------ METHODS ------------------------------ 284// ------------------------------ METHODS ------------------------------
283 285
284function associate (models) { 286function associate (models) {
285 Video.belongsTo(models.Author, { 287 Video.belongsTo(models.VideoChannel, {
286 foreignKey: { 288 foreignKey: {
287 name: 'authorId', 289 name: 'channelId',
288 allowNull: false 290 allowNull: false
289 }, 291 },
290 onDelete: 'cascade' 292 onDelete: 'cascade'
@@ -439,8 +441,8 @@ getPreviewPath = function (this: VideoInstance) {
439toFormattedJSON = function (this: VideoInstance) { 441toFormattedJSON = function (this: VideoInstance) {
440 let podHost 442 let podHost
441 443
442 if (this.Author.Pod) { 444 if (this.VideoChannel.Author.Pod) {
443 podHost = this.Author.Pod.host 445 podHost = this.VideoChannel.Author.Pod.host
444 } else { 446 } else {
445 // It means it's our video 447 // It means it's our video
446 podHost = CONFIG.WEBSERVER.HOST 448 podHost = CONFIG.WEBSERVER.HOST
@@ -472,7 +474,59 @@ toFormattedJSON = function (this: VideoInstance) {
472 description: this.description, 474 description: this.description,
473 podHost, 475 podHost,
474 isLocal: this.isOwned(), 476 isLocal: this.isOwned(),
475 author: this.Author.name, 477 author: this.VideoChannel.Author.name,
478 duration: this.duration,
479 views: this.views,
480 likes: this.likes,
481 dislikes: this.dislikes,
482 tags: map<TagInstance, string>(this.Tags, 'name'),
483 thumbnailPath: this.getThumbnailPath(),
484 previewPath: this.getPreviewPath(),
485 embedPath: this.getEmbedPath(),
486 createdAt: this.createdAt,
487 updatedAt: this.updatedAt
488 }
489
490 return json
491}
492
493toFormattedDetailsJSON = function (this: VideoInstance) {
494 let podHost
495
496 if (this.VideoChannel.Author.Pod) {
497 podHost = this.VideoChannel.Author.Pod.host
498 } else {
499 // It means it's our video
500 podHost = CONFIG.WEBSERVER.HOST
501 }
502
503 // Maybe our pod is not up to date and there are new categories since our version
504 let categoryLabel = VIDEO_CATEGORIES[this.category]
505 if (!categoryLabel) categoryLabel = 'Misc'
506
507 // Maybe our pod is not up to date and there are new licences since our version
508 let licenceLabel = VIDEO_LICENCES[this.licence]
509 if (!licenceLabel) licenceLabel = 'Unknown'
510
511 // Language is an optional attribute
512 let languageLabel = VIDEO_LANGUAGES[this.language]
513 if (!languageLabel) languageLabel = 'Unknown'
514
515 const json = {
516 id: this.id,
517 uuid: this.uuid,
518 name: this.name,
519 category: this.category,
520 categoryLabel,
521 licence: this.licence,
522 licenceLabel,
523 language: this.language,
524 languageLabel,
525 nsfw: this.nsfw,
526 description: this.description,
527 podHost,
528 isLocal: this.isOwned(),
529 author: this.VideoChannel.Author.name,
476 duration: this.duration, 530 duration: this.duration,
477 views: this.views, 531 views: this.views,
478 likes: this.likes, 532 likes: this.likes,
@@ -483,6 +537,7 @@ toFormattedJSON = function (this: VideoInstance) {
483 embedPath: this.getEmbedPath(), 537 embedPath: this.getEmbedPath(),
484 createdAt: this.createdAt, 538 createdAt: this.createdAt,
485 updatedAt: this.updatedAt, 539 updatedAt: this.updatedAt,
540 channel: this.VideoChannel.toFormattedJSON(),
486 files: [] 541 files: []
487 } 542 }
488 543
@@ -525,7 +580,7 @@ toAddRemoteJSON = function (this: VideoInstance) {
525 language: this.language, 580 language: this.language,
526 nsfw: this.nsfw, 581 nsfw: this.nsfw,
527 description: this.description, 582 description: this.description,
528 author: this.Author.name, 583 channelUUID: this.VideoChannel.uuid,
529 duration: this.duration, 584 duration: this.duration,
530 thumbnailData: thumbnailData.toString('binary'), 585 thumbnailData: thumbnailData.toString('binary'),
531 tags: map<TagInstance, string>(this.Tags, 'name'), 586 tags: map<TagInstance, string>(this.Tags, 'name'),
@@ -559,7 +614,6 @@ toUpdateRemoteJSON = function (this: VideoInstance) {
559 language: this.language, 614 language: this.language,
560 nsfw: this.nsfw, 615 nsfw: this.nsfw,
561 description: this.description, 616 description: this.description,
562 author: this.Author.name,
563 duration: this.duration, 617 duration: this.duration,
564 tags: map<TagInstance, string>(this.Tags, 'name'), 618 tags: map<TagInstance, string>(this.Tags, 'name'),
565 createdAt: this.createdAt, 619 createdAt: this.createdAt,
@@ -723,8 +777,18 @@ listForApi = function (start: number, count: number, sort: string) {
723 order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ], 777 order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ],
724 include: [ 778 include: [
725 { 779 {
726 model: Video['sequelize'].models.Author, 780 model: Video['sequelize'].models.VideoChannel,
727 include: [ { model: Video['sequelize'].models.Pod, required: false } ] 781 include: [
782 {
783 model: Video['sequelize'].models.Author,
784 include: [
785 {
786 model: Video['sequelize'].models.Pod,
787 required: false
788 }
789 ]
790 }
791 ]
728 }, 792 },
729 Video['sequelize'].models.Tag, 793 Video['sequelize'].models.Tag,
730 Video['sequelize'].models.VideoFile 794 Video['sequelize'].models.VideoFile
@@ -740,8 +804,8 @@ listForApi = function (start: number, count: number, sort: string) {
740 }) 804 })
741} 805}
742 806
743loadByHostAndUUID = function (fromHost: string, uuid: string) { 807loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
744 const query = { 808 const query: Sequelize.FindOptions<VideoAttributes> = {
745 where: { 809 where: {
746 uuid 810 uuid
747 }, 811 },
@@ -750,20 +814,27 @@ loadByHostAndUUID = function (fromHost: string, uuid: string) {
750 model: Video['sequelize'].models.VideoFile 814 model: Video['sequelize'].models.VideoFile
751 }, 815 },
752 { 816 {
753 model: Video['sequelize'].models.Author, 817 model: Video['sequelize'].models.VideoChannel,
754 include: [ 818 include: [
755 { 819 {
756 model: Video['sequelize'].models.Pod, 820 model: Video['sequelize'].models.Author,
757 required: true, 821 include: [
758 where: { 822 {
759 host: fromHost 823 model: Video['sequelize'].models.Pod,
760 } 824 required: true,
825 where: {
826 host: fromHost
827 }
828 }
829 ]
761 } 830 }
762 ] 831 ]
763 } 832 }
764 ] 833 ]
765 } 834 }
766 835
836 if (t !== undefined) query.transaction = t
837
767 return Video.findOne(query) 838 return Video.findOne(query)
768} 839}
769 840
@@ -774,7 +845,10 @@ listOwnedAndPopulateAuthorAndTags = function () {
774 }, 845 },
775 include: [ 846 include: [
776 Video['sequelize'].models.VideoFile, 847 Video['sequelize'].models.VideoFile,
777 Video['sequelize'].models.Author, 848 {
849 model: Video['sequelize'].models.VideoChannel,
850 include: [ Video['sequelize'].models.Author ]
851 },
778 Video['sequelize'].models.Tag 852 Video['sequelize'].models.Tag
779 ] 853 ]
780 } 854 }
@@ -792,10 +866,15 @@ listOwnedByAuthor = function (author: string) {
792 model: Video['sequelize'].models.VideoFile 866 model: Video['sequelize'].models.VideoFile
793 }, 867 },
794 { 868 {
795 model: Video['sequelize'].models.Author, 869 model: Video['sequelize'].models.VideoChannel,
796 where: { 870 include: [
797 name: author 871 {
798 } 872 model: Video['sequelize'].models.Author,
873 where: {
874 name: author
875 }
876 }
877 ]
799 } 878 }
800 ] 879 ]
801 } 880 }
@@ -807,19 +886,28 @@ load = function (id: number) {
807 return Video.findById(id) 886 return Video.findById(id)
808} 887}
809 888
810loadByUUID = function (uuid: string) { 889loadByUUID = function (uuid: string, t?: Sequelize.Transaction) {
811 const query = { 890 const query: Sequelize.FindOptions<VideoAttributes> = {
812 where: { 891 where: {
813 uuid 892 uuid
814 }, 893 },
815 include: [ Video['sequelize'].models.VideoFile ] 894 include: [ Video['sequelize'].models.VideoFile ]
816 } 895 }
896
897 if (t !== undefined) query.transaction = t
898
817 return Video.findOne(query) 899 return Video.findOne(query)
818} 900}
819 901
820loadAndPopulateAuthor = function (id: number) { 902loadAndPopulateAuthor = function (id: number) {
821 const options = { 903 const options = {
822 include: [ Video['sequelize'].models.VideoFile, Video['sequelize'].models.Author ] 904 include: [
905 Video['sequelize'].models.VideoFile,
906 {
907 model: Video['sequelize'].models.VideoChannel,
908 include: [ Video['sequelize'].models.Author ]
909 }
910 ]
823 } 911 }
824 912
825 return Video.findById(id, options) 913 return Video.findById(id, options)
@@ -829,8 +917,13 @@ loadAndPopulateAuthorAndPodAndTags = function (id: number) {
829 const options = { 917 const options = {
830 include: [ 918 include: [
831 { 919 {
832 model: Video['sequelize'].models.Author, 920 model: Video['sequelize'].models.VideoChannel,
833 include: [ { model: Video['sequelize'].models.Pod, required: false } ] 921 include: [
922 {
923 model: Video['sequelize'].models.Author,
924 include: [ { model: Video['sequelize'].models.Pod, required: false } ]
925 }
926 ]
834 }, 927 },
835 Video['sequelize'].models.Tag, 928 Video['sequelize'].models.Tag,
836 Video['sequelize'].models.VideoFile 929 Video['sequelize'].models.VideoFile
@@ -847,8 +940,13 @@ loadByUUIDAndPopulateAuthorAndPodAndTags = function (uuid: string) {
847 }, 940 },
848 include: [ 941 include: [
849 { 942 {
850 model: Video['sequelize'].models.Author, 943 model: Video['sequelize'].models.VideoChannel,
851 include: [ { model: Video['sequelize'].models.Pod, required: false } ] 944 include: [
945 {
946 model: Video['sequelize'].models.Author,
947 include: [ { model: Video['sequelize'].models.Pod, required: false } ]
948 }
949 ]
852 }, 950 },
853 Video['sequelize'].models.Tag, 951 Video['sequelize'].models.Tag,
854 Video['sequelize'].models.VideoFile 952 Video['sequelize'].models.VideoFile
@@ -866,9 +964,13 @@ searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, s
866 964
867 const authorInclude: Sequelize.IncludeOptions = { 965 const authorInclude: Sequelize.IncludeOptions = {
868 model: Video['sequelize'].models.Author, 966 model: Video['sequelize'].models.Author,
869 include: [ 967 include: [ podInclude ]
870 podInclude 968 }
871 ] 969
970 const videoChannelInclude: Sequelize.IncludeOptions = {
971 model: Video['sequelize'].models.VideoChannel,
972 include: [ authorInclude ],
973 required: true
872 } 974 }
873 975
874 const tagInclude: Sequelize.IncludeOptions = { 976 const tagInclude: Sequelize.IncludeOptions = {
@@ -915,8 +1017,6 @@ searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, s
915 $iLike: '%' + value + '%' 1017 $iLike: '%' + value + '%'
916 } 1018 }
917 } 1019 }
918
919 // authorInclude.or = true
920 } else { 1020 } else {
921 query.where[field] = { 1021 query.where[field] = {
922 $iLike: '%' + value + '%' 1022 $iLike: '%' + value + '%'
@@ -924,7 +1024,7 @@ searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, s
924 } 1024 }
925 1025
926 query.include = [ 1026 query.include = [
927 authorInclude, tagInclude, videoFileInclude 1027 videoChannelInclude, tagInclude, videoFileInclude
928 ] 1028 ]
929 1029
930 return Video.findAndCountAll(query).then(({ rows, count }) => { 1030 return Video.findAndCountAll(query).then(({ rows, count }) => {
@@ -955,8 +1055,8 @@ function getBaseUrls (video: VideoInstance) {
955 baseUrlHttp = CONFIG.WEBSERVER.URL 1055 baseUrlHttp = CONFIG.WEBSERVER.URL
956 baseUrlWs = CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT 1056 baseUrlWs = CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
957 } else { 1057 } else {
958 baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + video.Author.Pod.host 1058 baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + video.VideoChannel.Author.Pod.host
959 baseUrlWs = REMOTE_SCHEME.WS + '://' + video.Author.Pod.host 1059 baseUrlWs = REMOTE_SCHEME.WS + '://' + video.VideoChannel.Author.Pod.host
960 } 1060 }
961 1061
962 return { baseUrlHttp, baseUrlWs } 1062 return { baseUrlHttp, baseUrlWs }