aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-12-17 15:52:38 +0100
committerChocobozzz <me@florianbigard.com>2018-12-18 11:35:50 +0100
commit8b9a525a180cc9f3a98c334cc052dcfc8f36dcd4 (patch)
tree5e3392af5592d1401ada86d21f93bb7ad9da8ab1 /server/models
parent583cd0d2129dc855e599f981d70e537feade1632 (diff)
downloadPeerTube-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.ts33
-rw-r--r--server/models/account/user.ts9
-rw-r--r--server/models/utils.ts2
-rw-r--r--server/models/video/video.ts19
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 @@
1import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Min, Model, Table, UpdatedAt } from 'sequelize-typescript' 1import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Model, Table, UpdatedAt } from 'sequelize-typescript'
2import { VideoModel } from '../video/video' 2import { VideoModel } from '../video/video'
3import { UserModel } from './user' 3import { UserModel } from './user'
4import { 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'
37import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' 38import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
38import { OAuthTokenModel } from '../oauth/oauth-token' 39import { 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
35function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) { 35function 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)