diff options
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r-- | server/models/video/video.ts | 180 |
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 | |||
60 | let getTorrentFileName: VideoMethods.GetTorrentFileName | 60 | let getTorrentFileName: VideoMethods.GetTorrentFileName |
61 | let isOwned: VideoMethods.IsOwned | 61 | let isOwned: VideoMethods.IsOwned |
62 | let toFormattedJSON: VideoMethods.ToFormattedJSON | 62 | let toFormattedJSON: VideoMethods.ToFormattedJSON |
63 | let toFormattedDetailsJSON: VideoMethods.ToFormattedDetailsJSON | ||
63 | let toAddRemoteJSON: VideoMethods.ToAddRemoteJSON | 64 | let toAddRemoteJSON: VideoMethods.ToAddRemoteJSON |
64 | let toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON | 65 | let toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON |
65 | let optimizeOriginalVideofile: VideoMethods.OptimizeOriginalVideofile | 66 | let 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 | ||
284 | function associate (models) { | 286 | function 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) { | |||
439 | toFormattedJSON = function (this: VideoInstance) { | 441 | toFormattedJSON = 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 | |||
493 | toFormattedDetailsJSON = 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 | ||
743 | loadByHostAndUUID = function (fromHost: string, uuid: string) { | 807 | loadByHostAndUUID = 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 | ||
810 | loadByUUID = function (uuid: string) { | 889 | loadByUUID = 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 | ||
820 | loadAndPopulateAuthor = function (id: number) { | 902 | loadAndPopulateAuthor = 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 } |