aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models
diff options
context:
space:
mode:
Diffstat (limited to 'server/models')
-rw-r--r--server/models/video/sql/video/videos-id-list-query-builder.ts22
-rw-r--r--server/models/video/video.ts10
2 files changed, 30 insertions, 2 deletions
diff --git a/server/models/video/sql/video/videos-id-list-query-builder.ts b/server/models/video/sql/video/videos-id-list-query-builder.ts
index 62f1855c7..cba77c1d1 100644
--- a/server/models/video/sql/video/videos-id-list-query-builder.ts
+++ b/server/models/video/sql/video/videos-id-list-query-builder.ts
@@ -78,6 +78,8 @@ export type BuildVideosListQueryOptions = {
78 78
79 transaction?: Transaction 79 transaction?: Transaction
80 logging?: boolean 80 logging?: boolean
81
82 excludeAlreadyWatched?: boolean
81} 83}
82 84
83export class VideosIdListQueryBuilder extends AbstractRunQuery { 85export class VideosIdListQueryBuilder extends AbstractRunQuery {
@@ -260,6 +262,14 @@ export class VideosIdListQueryBuilder extends AbstractRunQuery {
260 this.whereDurationMax(options.durationMax) 262 this.whereDurationMax(options.durationMax)
261 } 263 }
262 264
265 if (options.excludeAlreadyWatched) {
266 if (exists(options.user.id)) {
267 this.whereExcludeAlreadyWatched(options.user.id)
268 } else {
269 throw new Error('Cannot use excludeAlreadyWatched parameter when auth token is not provided')
270 }
271 }
272
263 this.whereSearch(options.search) 273 this.whereSearch(options.search)
264 274
265 if (options.isCount === true) { 275 if (options.isCount === true) {
@@ -598,6 +608,18 @@ export class VideosIdListQueryBuilder extends AbstractRunQuery {
598 this.replacements.durationMax = durationMax 608 this.replacements.durationMax = durationMax
599 } 609 }
600 610
611 private whereExcludeAlreadyWatched (userId: number) {
612 this.and.push(
613 'NOT EXISTS (' +
614 ' SELECT 1' +
615 ' FROM "userVideoHistory"' +
616 ' WHERE "video"."id" = "userVideoHistory"."videoId"' +
617 ' AND "userVideoHistory"."userId" = :excludeAlreadyWatchedUserId' +
618 ')'
619 )
620 this.replacements.excludeAlreadyWatchedUserId = userId
621 }
622
601 private groupForTrending (trendingDays: number) { 623 private groupForTrending (trendingDays: number) {
602 const viewsGteDate = new Date(new Date().getTime() - (24 * 3600 * 1000) * trendingDays) 624 const viewsGteDate = new Date(new Date().getTime() - (24 * 3600 * 1000) * trendingDays)
603 625
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 0c5ed64ec..f817c4a33 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -1086,6 +1086,8 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1086 countVideos?: boolean 1086 countVideos?: boolean
1087 1087
1088 search?: string 1088 search?: string
1089
1090 excludeAlreadyWatched?: boolean
1089 }) { 1091 }) {
1090 VideoModel.throwIfPrivateIncludeWithoutUser(options.include, options.user) 1092 VideoModel.throwIfPrivateIncludeWithoutUser(options.include, options.user)
1091 VideoModel.throwIfPrivacyOneOfWithoutUser(options.privacyOneOf, options.user) 1093 VideoModel.throwIfPrivacyOneOfWithoutUser(options.privacyOneOf, options.user)
@@ -1124,7 +1126,8 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1124 'historyOfUser', 1126 'historyOfUser',
1125 'hasHLSFiles', 1127 'hasHLSFiles',
1126 'hasWebtorrentFiles', 1128 'hasWebtorrentFiles',
1127 'search' 1129 'search',
1130 'excludeAlreadyWatched'
1128 ]), 1131 ]),
1129 1132
1130 serverAccountIdForBlock: serverActor.Account.id, 1133 serverAccountIdForBlock: serverActor.Account.id,
@@ -1170,6 +1173,8 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1170 durationMin?: number // seconds 1173 durationMin?: number // seconds
1171 durationMax?: number // seconds 1174 durationMax?: number // seconds
1172 uuids?: string[] 1175 uuids?: string[]
1176
1177 excludeAlreadyWatched?: boolean
1173 }) { 1178 }) {
1174 VideoModel.throwIfPrivateIncludeWithoutUser(options.include, options.user) 1179 VideoModel.throwIfPrivateIncludeWithoutUser(options.include, options.user)
1175 VideoModel.throwIfPrivacyOneOfWithoutUser(options.privacyOneOf, options.user) 1180 VideoModel.throwIfPrivacyOneOfWithoutUser(options.privacyOneOf, options.user)
@@ -1203,7 +1208,8 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1203 'hasWebtorrentFiles', 1208 'hasWebtorrentFiles',
1204 'uuids', 1209 'uuids',
1205 'search', 1210 'search',
1206 'displayOnlyForFollower' 1211 'displayOnlyForFollower',
1212 'excludeAlreadyWatched'
1207 ]), 1213 ]),
1208 serverAccountIdForBlock: serverActor.Account.id 1214 serverAccountIdForBlock: serverActor.Account.id
1209 } 1215 }