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.ts92
1 files changed, 65 insertions, 27 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 2ad9c00dd..7ababbf23 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -95,7 +95,14 @@ enum ScopeNames {
95} 95}
96 96
97@Scopes({ 97@Scopes({
98 [ScopeNames.AVAILABLE_FOR_LIST]: (actorId: number, hideNSFW: boolean, filter?: VideoFilter, withFiles?: boolean, accountId?: number) => { 98 [ScopeNames.AVAILABLE_FOR_LIST]: (options: {
99 actorId: number,
100 hideNSFW: boolean,
101 filter?: VideoFilter,
102 withFiles?: boolean,
103 accountId?: number,
104 videoChannelId?: number
105 }) => {
99 const accountInclude = { 106 const accountInclude = {
100 attributes: [ 'name' ], 107 attributes: [ 'name' ],
101 model: AccountModel.unscoped(), 108 model: AccountModel.unscoped(),
@@ -106,7 +113,7 @@ enum ScopeNames {
106 attributes: [ 'preferredUsername', 'url', 'serverId', 'avatarId' ], 113 attributes: [ 'preferredUsername', 'url', 'serverId', 'avatarId' ],
107 model: ActorModel.unscoped(), 114 model: ActorModel.unscoped(),
108 required: true, 115 required: true,
109 where: VideoModel.buildActorWhereWithFilter(filter), 116 where: VideoModel.buildActorWhereWithFilter(options.filter),
110 include: [ 117 include: [
111 { 118 {
112 attributes: [ 'host' ], 119 attributes: [ 'host' ],
@@ -122,6 +129,18 @@ enum ScopeNames {
122 ] 129 ]
123 } 130 }
124 131
132 const videoChannelInclude = {
133 attributes: [ 'name', 'description' ],
134 model: VideoChannelModel.unscoped(),
135 required: true,
136 where: {},
137 include: [
138 accountInclude
139 ]
140 }
141
142 // Force actorId to be a number to avoid SQL injections
143 const actorIdNumber = parseInt(options.actorId.toString(), 10)
125 const query: IFindOptions<VideoModel> = { 144 const query: IFindOptions<VideoModel> = {
126 where: { 145 where: {
127 id: { 146 id: {
@@ -132,32 +151,23 @@ enum ScopeNames {
132 '(' + 151 '(' +
133 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' + 152 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
134 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' + 153 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
135 'WHERE "actorFollow"."actorId" = ' + parseInt(actorId.toString(), 10) + 154 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
136 ' UNION ' + 155 ' UNION ' +
137 'SELECT "video"."id" AS "id" FROM "video" ' + 156 'SELECT "video"."id" AS "id" FROM "video" ' +
138 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + 157 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
139 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + 158 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
140 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' + 159 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
141 'LEFT JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' + 160 'LEFT JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' +
142 'WHERE "actor"."serverId" IS NULL OR "actorFollow"."actorId" = ' + parseInt(actorId.toString(), 10) + 161 'WHERE "actor"."serverId" IS NULL OR "actorFollow"."actorId" = ' + actorIdNumber +
143 ')' 162 ')'
144 ) 163 )
145 }, 164 },
146 privacy: VideoPrivacy.PUBLIC 165 privacy: VideoPrivacy.PUBLIC
147 }, 166 },
148 include: [ 167 include: [ videoChannelInclude ]
149 {
150 attributes: [ 'name', 'description' ],
151 model: VideoChannelModel.unscoped(),
152 required: true,
153 include: [
154 accountInclude
155 ]
156 }
157 ]
158 } 168 }
159 169
160 if (withFiles === true) { 170 if (options.withFiles === true) {
161 query.include.push({ 171 query.include.push({
162 model: VideoFileModel.unscoped(), 172 model: VideoFileModel.unscoped(),
163 required: true 173 required: true
@@ -165,13 +175,19 @@ enum ScopeNames {
165 } 175 }
166 176
167 // Hide nsfw videos? 177 // Hide nsfw videos?
168 if (hideNSFW === true) { 178 if (options.hideNSFW === true) {
169 query.where['nsfw'] = false 179 query.where['nsfw'] = false
170 } 180 }
171 181
172 if (accountId) { 182 if (options.accountId) {
173 accountInclude.where = { 183 accountInclude.where = {
174 id: accountId 184 id: options.accountId
185 }
186 }
187
188 if (options.videoChannelId) {
189 videoChannelInclude.where = {
190 id: options.videoChannelId
175 } 191 }
176 } 192 }
177 193
@@ -697,23 +713,37 @@ export class VideoModel extends Model<VideoModel> {
697 }) 713 })
698 } 714 }
699 715
700 static async listForApi ( 716 static async listForApi (options: {
701 start: number, 717 start: number,
702 count: number, 718 count: number,
703 sort: string, 719 sort: string,
704 hideNSFW: boolean, 720 hideNSFW: boolean,
721 withFiles: boolean,
705 filter?: VideoFilter, 722 filter?: VideoFilter,
706 withFiles = false, 723 accountId?: number,
707 accountId?: number 724 videoChannelId?: number
708 ) { 725 }) {
709 const query = { 726 const query = {
710 offset: start, 727 offset: options.start,
711 limit: count, 728 limit: options.count,
712 order: getSort(sort) 729 order: getSort(options.sort)
713 } 730 }
714 731
715 const serverActor = await getServerActor() 732 const serverActor = await getServerActor()
716 return VideoModel.scope({ method: [ ScopeNames.AVAILABLE_FOR_LIST, serverActor.id, hideNSFW, filter, withFiles, accountId ] }) 733 const scopes = {
734 method: [
735 ScopeNames.AVAILABLE_FOR_LIST, {
736 actorId: serverActor.id,
737 hideNSFW: options.hideNSFW,
738 filter: options.filter,
739 withFiles: options.withFiles,
740 accountId: options.accountId,
741 videoChannelId: options.videoChannelId
742 }
743 ]
744 }
745
746 return VideoModel.scope(scopes)
717 .findAndCountAll(query) 747 .findAndCountAll(query)
718 .then(({ rows, count }) => { 748 .then(({ rows, count }) => {
719 return { 749 return {
@@ -750,8 +780,16 @@ export class VideoModel extends Model<VideoModel> {
750 } 780 }
751 781
752 const serverActor = await getServerActor() 782 const serverActor = await getServerActor()
783 const scopes = {
784 method: [
785 ScopeNames.AVAILABLE_FOR_LIST, {
786 actorId: serverActor.id,
787 hideNSFW
788 }
789 ]
790 }
753 791
754 return VideoModel.scope({ method: [ ScopeNames.AVAILABLE_FOR_LIST, serverActor.id, hideNSFW ] }) 792 return VideoModel.scope(scopes)
755 .findAndCountAll(query) 793 .findAndCountAll(query)
756 .then(({ rows, count }) => { 794 .then(({ rows, count }) => {
757 return { 795 return {