diff options
author | Chocobozzz <me@florianbigard.com> | 2018-12-17 15:52:38 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-12-18 11:35:50 +0100 |
commit | 8b9a525a180cc9f3a98c334cc052dcfc8f36dcd4 (patch) | |
tree | 5e3392af5592d1401ada86d21f93bb7ad9da8ab1 /server/models | |
parent | 583cd0d2129dc855e599f981d70e537feade1632 (diff) | |
download | PeerTube-8b9a525a180cc9f3a98c334cc052dcfc8f36dcd4.tar.gz PeerTube-8b9a525a180cc9f3a98c334cc052dcfc8f36dcd4.tar.zst PeerTube-8b9a525a180cc9f3a98c334cc052dcfc8f36dcd4.zip |
Add history on server side
Add ability to disable, clear and list user videos history
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/account/user-video-history.ts | 33 | ||||
-rw-r--r-- | server/models/account/user.ts | 9 | ||||
-rw-r--r-- | server/models/utils.ts | 2 | ||||
-rw-r--r-- | server/models/video/video.ts | 19 |
4 files changed, 57 insertions, 6 deletions
diff --git a/server/models/account/user-video-history.ts b/server/models/account/user-video-history.ts index 0476cad9d..15cb399c9 100644 --- a/server/models/account/user-video-history.ts +++ b/server/models/account/user-video-history.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Min, Model, Table, UpdatedAt } from 'sequelize-typescript' | 1 | import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Model, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { VideoModel } from '../video/video' | 2 | import { VideoModel } from '../video/video' |
3 | import { UserModel } from './user' | 3 | import { UserModel } from './user' |
4 | import { Transaction, Op, DestroyOptions } from 'sequelize' | ||
4 | 5 | ||
5 | @Table({ | 6 | @Table({ |
6 | tableName: 'userVideoHistory', | 7 | tableName: 'userVideoHistory', |
@@ -52,4 +53,34 @@ export class UserVideoHistoryModel extends Model<UserVideoHistoryModel> { | |||
52 | onDelete: 'CASCADE' | 53 | onDelete: 'CASCADE' |
53 | }) | 54 | }) |
54 | User: UserModel | 55 | User: UserModel |
56 | |||
57 | static listForApi (user: UserModel, start: number, count: number) { | ||
58 | return VideoModel.listForApi({ | ||
59 | start, | ||
60 | count, | ||
61 | sort: '-UserVideoHistories.updatedAt', | ||
62 | nsfw: null, // All | ||
63 | includeLocalVideos: true, | ||
64 | withFiles: false, | ||
65 | user, | ||
66 | historyOfUser: user | ||
67 | }) | ||
68 | } | ||
69 | |||
70 | static removeHistoryBefore (user: UserModel, beforeDate: string, t: Transaction) { | ||
71 | const query: DestroyOptions = { | ||
72 | where: { | ||
73 | userId: user.id | ||
74 | }, | ||
75 | transaction: t | ||
76 | } | ||
77 | |||
78 | if (beforeDate) { | ||
79 | query.where.updatedAt = { | ||
80 | [Op.lt]: beforeDate | ||
81 | } | ||
82 | } | ||
83 | |||
84 | return UserVideoHistoryModel.destroy(query) | ||
85 | } | ||
55 | } | 86 | } |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 1843603f1..ea017c338 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -32,7 +32,8 @@ import { | |||
32 | isUserUsernameValid, | 32 | isUserUsernameValid, |
33 | isUserVideoQuotaDailyValid, | 33 | isUserVideoQuotaDailyValid, |
34 | isUserVideoQuotaValid, | 34 | isUserVideoQuotaValid, |
35 | isUserWebTorrentEnabledValid | 35 | isUserWebTorrentEnabledValid, |
36 | isUserVideosHistoryEnabledValid | ||
36 | } from '../../helpers/custom-validators/users' | 37 | } from '../../helpers/custom-validators/users' |
37 | import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' | 38 | import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' |
38 | import { OAuthTokenModel } from '../oauth/oauth-token' | 39 | import { OAuthTokenModel } from '../oauth/oauth-token' |
@@ -116,6 +117,12 @@ export class UserModel extends Model<UserModel> { | |||
116 | 117 | ||
117 | @AllowNull(false) | 118 | @AllowNull(false) |
118 | @Default(true) | 119 | @Default(true) |
120 | @Is('UserVideosHistoryEnabled', value => throwIfNotValid(value, isUserVideosHistoryEnabledValid, 'Videos history enabled')) | ||
121 | @Column | ||
122 | videosHistoryEnabled: boolean | ||
123 | |||
124 | @AllowNull(false) | ||
125 | @Default(true) | ||
119 | @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) | 126 | @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) |
120 | @Column | 127 | @Column |
121 | autoPlayVideo: boolean | 128 | autoPlayVideo: boolean |
diff --git a/server/models/utils.ts b/server/models/utils.ts index 60b0906e8..6694eda69 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts | |||
@@ -29,7 +29,7 @@ function getVideoSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) { | |||
29 | ] | 29 | ] |
30 | } | 30 | } |
31 | 31 | ||
32 | return [ [ field, direction ], lastSort ] | 32 | return [ field.split('.').concat([ direction ]), lastSort ] |
33 | } | 33 | } |
34 | 34 | ||
35 | function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) { | 35 | function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) { |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index adef37937..199ea9ea4 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -153,7 +153,8 @@ type AvailableForListIDsOptions = { | |||
153 | accountId?: number | 153 | accountId?: number |
154 | videoChannelId?: number | 154 | videoChannelId?: number |
155 | trendingDays?: number | 155 | trendingDays?: number |
156 | user?: UserModel | 156 | user?: UserModel, |
157 | historyOfUser?: UserModel | ||
157 | } | 158 | } |
158 | 159 | ||
159 | @Scopes({ | 160 | @Scopes({ |
@@ -416,6 +417,16 @@ type AvailableForListIDsOptions = { | |||
416 | query.subQuery = false | 417 | query.subQuery = false |
417 | } | 418 | } |
418 | 419 | ||
420 | if (options.historyOfUser) { | ||
421 | query.include.push({ | ||
422 | model: UserVideoHistoryModel, | ||
423 | required: true, | ||
424 | where: { | ||
425 | userId: options.historyOfUser.id | ||
426 | } | ||
427 | }) | ||
428 | } | ||
429 | |||
419 | return query | 430 | return query |
420 | }, | 431 | }, |
421 | [ ScopeNames.WITH_ACCOUNT_DETAILS ]: { | 432 | [ ScopeNames.WITH_ACCOUNT_DETAILS ]: { |
@@ -987,7 +998,8 @@ export class VideoModel extends Model<VideoModel> { | |||
987 | videoChannelId?: number, | 998 | videoChannelId?: number, |
988 | followerActorId?: number | 999 | followerActorId?: number |
989 | trendingDays?: number, | 1000 | trendingDays?: number, |
990 | user?: UserModel | 1001 | user?: UserModel, |
1002 | historyOfUser?: UserModel | ||
991 | }, countVideos = true) { | 1003 | }, countVideos = true) { |
992 | if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { | 1004 | if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { |
993 | throw new Error('Try to filter all-local but no user has not the see all videos right') | 1005 | throw new Error('Try to filter all-local but no user has not the see all videos right') |
@@ -1026,6 +1038,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1026 | videoChannelId: options.videoChannelId, | 1038 | videoChannelId: options.videoChannelId, |
1027 | includeLocalVideos: options.includeLocalVideos, | 1039 | includeLocalVideos: options.includeLocalVideos, |
1028 | user: options.user, | 1040 | user: options.user, |
1041 | historyOfUser: options.historyOfUser, | ||
1029 | trendingDays | 1042 | trendingDays |
1030 | } | 1043 | } |
1031 | 1044 | ||
@@ -1341,7 +1354,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1341 | } | 1354 | } |
1342 | 1355 | ||
1343 | const [ count, rowsId ] = await Promise.all([ | 1356 | const [ count, rowsId ] = await Promise.all([ |
1344 | countVideos ? VideoModel.scope(countScope).count(countQuery) : Promise.resolve(undefined), | 1357 | countVideos ? VideoModel.scope(countScope).count(countQuery) : Promise.resolve<number>(undefined), |
1345 | VideoModel.scope(idsScope).findAll(query) | 1358 | VideoModel.scope(idsScope).findAll(query) |
1346 | ]) | 1359 | ]) |
1347 | const ids = rowsId.map(r => r.id) | 1360 | const ids = rowsId.map(r => r.id) |