diff options
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r-- | server/models/video/video.ts | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index b13dee403..5db718061 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -133,6 +133,7 @@ export enum ScopeNames { | |||
133 | 133 | ||
134 | type AvailableForListOptions = { | 134 | type AvailableForListOptions = { |
135 | actorId: number, | 135 | actorId: number, |
136 | includeLocalVideos: boolean, | ||
136 | filter?: VideoFilter, | 137 | filter?: VideoFilter, |
137 | categoryOneOf?: number[], | 138 | categoryOneOf?: number[], |
138 | nsfw?: boolean, | 139 | nsfw?: boolean, |
@@ -201,6 +202,15 @@ type AvailableForListOptions = { | |||
201 | 202 | ||
202 | // Force actorId to be a number to avoid SQL injections | 203 | // Force actorId to be a number to avoid SQL injections |
203 | const actorIdNumber = parseInt(options.actorId.toString(), 10) | 204 | const actorIdNumber = parseInt(options.actorId.toString(), 10) |
205 | let localVideosReq = '' | ||
206 | if (options.includeLocalVideos === true) { | ||
207 | localVideosReq = ' UNION ALL ' + | ||
208 | 'SELECT "video"."id" AS "id" FROM "video" ' + | ||
209 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
210 | 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + | ||
211 | 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' + | ||
212 | 'WHERE "actor"."serverId" IS NULL' | ||
213 | } | ||
204 | 214 | ||
205 | // FIXME: It would be more efficient to use a CTE so we join AFTER the filters, but sequelize does not support it... | 215 | // FIXME: It would be more efficient to use a CTE so we join AFTER the filters, but sequelize does not support it... |
206 | const query: IFindOptions<VideoModel> = { | 216 | const query: IFindOptions<VideoModel> = { |
@@ -214,12 +224,6 @@ type AvailableForListOptions = { | |||
214 | 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' + | 224 | 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' + |
215 | 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' + | 225 | 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' + |
216 | 'WHERE "actorFollow"."actorId" = ' + actorIdNumber + | 226 | 'WHERE "actorFollow"."actorId" = ' + actorIdNumber + |
217 | ' UNION ' + | ||
218 | 'SELECT "video"."id" AS "id" FROM "video" ' + | ||
219 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
220 | 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + | ||
221 | 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' + | ||
222 | 'WHERE "actor"."serverId" IS NULL ' + | ||
223 | ' UNION ALL ' + | 227 | ' UNION ALL ' + |
224 | 'SELECT "video"."id" AS "id" FROM "video" ' + | 228 | 'SELECT "video"."id" AS "id" FROM "video" ' + |
225 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | 229 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + |
@@ -227,6 +231,7 @@ type AvailableForListOptions = { | |||
227 | 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' + | 231 | 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' + |
228 | 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' + | 232 | 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' + |
229 | 'WHERE "actorFollow"."actorId" = ' + actorIdNumber + | 233 | 'WHERE "actorFollow"."actorId" = ' + actorIdNumber + |
234 | localVideosReq + | ||
230 | ')' | 235 | ')' |
231 | ) | 236 | ) |
232 | }, | 237 | }, |
@@ -825,6 +830,7 @@ export class VideoModel extends Model<VideoModel> { | |||
825 | count: number, | 830 | count: number, |
826 | sort: string, | 831 | sort: string, |
827 | nsfw: boolean, | 832 | nsfw: boolean, |
833 | includeLocalVideos: boolean, | ||
828 | withFiles: boolean, | 834 | withFiles: boolean, |
829 | categoryOneOf?: number[], | 835 | categoryOneOf?: number[], |
830 | licenceOneOf?: number[], | 836 | licenceOneOf?: number[], |
@@ -833,7 +839,8 @@ export class VideoModel extends Model<VideoModel> { | |||
833 | tagsAllOf?: string[], | 839 | tagsAllOf?: string[], |
834 | filter?: VideoFilter, | 840 | filter?: VideoFilter, |
835 | accountId?: number, | 841 | accountId?: number, |
836 | videoChannelId?: number | 842 | videoChannelId?: number, |
843 | actorId?: number | ||
837 | }) { | 844 | }) { |
838 | const query = { | 845 | const query = { |
839 | offset: options.start, | 846 | offset: options.start, |
@@ -841,11 +848,12 @@ export class VideoModel extends Model<VideoModel> { | |||
841 | order: getSort(options.sort) | 848 | order: getSort(options.sort) |
842 | } | 849 | } |
843 | 850 | ||
844 | const serverActor = await getServerActor() | 851 | const actorId = options.actorId || (await getServerActor()).id |
852 | |||
845 | const scopes = { | 853 | const scopes = { |
846 | method: [ | 854 | method: [ |
847 | ScopeNames.AVAILABLE_FOR_LIST, { | 855 | ScopeNames.AVAILABLE_FOR_LIST, { |
848 | actorId: serverActor.id, | 856 | actorId, |
849 | nsfw: options.nsfw, | 857 | nsfw: options.nsfw, |
850 | categoryOneOf: options.categoryOneOf, | 858 | categoryOneOf: options.categoryOneOf, |
851 | licenceOneOf: options.licenceOneOf, | 859 | licenceOneOf: options.licenceOneOf, |
@@ -855,7 +863,8 @@ export class VideoModel extends Model<VideoModel> { | |||
855 | filter: options.filter, | 863 | filter: options.filter, |
856 | withFiles: options.withFiles, | 864 | withFiles: options.withFiles, |
857 | accountId: options.accountId, | 865 | accountId: options.accountId, |
858 | videoChannelId: options.videoChannelId | 866 | videoChannelId: options.videoChannelId, |
867 | includeLocalVideos: options.includeLocalVideos | ||
859 | } as AvailableForListOptions | 868 | } as AvailableForListOptions |
860 | ] | 869 | ] |
861 | } | 870 | } |
@@ -871,6 +880,7 @@ export class VideoModel extends Model<VideoModel> { | |||
871 | } | 880 | } |
872 | 881 | ||
873 | static async searchAndPopulateAccountAndServer (options: { | 882 | static async searchAndPopulateAccountAndServer (options: { |
883 | includeLocalVideos: boolean | ||
874 | search?: string | 884 | search?: string |
875 | start?: number | 885 | start?: number |
876 | count?: number | 886 | count?: number |
@@ -955,6 +965,7 @@ export class VideoModel extends Model<VideoModel> { | |||
955 | method: [ | 965 | method: [ |
956 | ScopeNames.AVAILABLE_FOR_LIST, { | 966 | ScopeNames.AVAILABLE_FOR_LIST, { |
957 | actorId: serverActor.id, | 967 | actorId: serverActor.id, |
968 | includeLocalVideos: options.includeLocalVideos, | ||
958 | nsfw: options.nsfw, | 969 | nsfw: options.nsfw, |
959 | categoryOneOf: options.categoryOneOf, | 970 | categoryOneOf: options.categoryOneOf, |
960 | licenceOneOf: options.licenceOneOf, | 971 | licenceOneOf: options.licenceOneOf, |