aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-01-02 16:37:43 +0100
committerChocobozzz <chocobozzz@cpy.re>2019-01-09 11:15:15 +0100
commitdc13348070d808d0ba3feb56a435b835c2e7e791 (patch)
tree887202a33f1aa680fd8ece6ee465381f3931c64e /server/models
parent6e7e63b83f08ba68edc2bb9f72ff03d1802e45df (diff)
downloadPeerTube-dc13348070d808d0ba3feb56a435b835c2e7e791.tar.gz
PeerTube-dc13348070d808d0ba3feb56a435b835c2e7e791.tar.zst
PeerTube-dc13348070d808d0ba3feb56a435b835c2e7e791.zip
Add import finished and video published notifs
Diffstat (limited to 'server/models')
-rw-r--r--server/models/account/account-blocklist.ts15
-rw-r--r--server/models/account/user-notification-setting.ts22
-rw-r--r--server/models/account/user-notification.ts150
-rw-r--r--server/models/account/user.ts24
-rw-r--r--server/models/video/video-file.ts2
-rw-r--r--server/models/video/video-import.ts4
-rw-r--r--server/models/video/video.ts10
7 files changed, 165 insertions, 62 deletions
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts
index fa2819235..54ac290c4 100644
--- a/server/models/account/account-blocklist.ts
+++ b/server/models/account/account-blocklist.ts
@@ -72,6 +72,21 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
72 }) 72 })
73 BlockedAccount: AccountModel 73 BlockedAccount: AccountModel
74 74
75 static isAccountMutedBy (accountId: number, targetAccountId: number) {
76 const query = {
77 attributes: [ 'id' ],
78 where: {
79 accountId,
80 targetAccountId
81 },
82 raw: true
83 }
84
85 return AccountBlocklistModel.unscoped()
86 .findOne(query)
87 .then(a => !!a)
88 }
89
75 static loadByAccountAndTarget (accountId: number, targetAccountId: number) { 90 static loadByAccountAndTarget (accountId: number, targetAccountId: number) {
76 const query = { 91 const query = {
77 where: { 92 where: {
diff --git a/server/models/account/user-notification-setting.ts b/server/models/account/user-notification-setting.ts
index bc24b1e33..6470defa7 100644
--- a/server/models/account/user-notification-setting.ts
+++ b/server/models/account/user-notification-setting.ts
@@ -65,6 +65,24 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM
65 @Column 65 @Column
66 blacklistOnMyVideo: UserNotificationSettingValue 66 blacklistOnMyVideo: UserNotificationSettingValue
67 67
68 @AllowNull(false)
69 @Default(null)
70 @Is(
71 'UserNotificationSettingMyVideoPublished',
72 value => throwIfNotValid(value, isUserNotificationSettingValid, 'myVideoPublished')
73 )
74 @Column
75 myVideoPublished: UserNotificationSettingValue
76
77 @AllowNull(false)
78 @Default(null)
79 @Is(
80 'UserNotificationSettingMyVideoImportFinished',
81 value => throwIfNotValid(value, isUserNotificationSettingValid, 'myVideoImportFinished')
82 )
83 @Column
84 myVideoImportFinished: UserNotificationSettingValue
85
68 @ForeignKey(() => UserModel) 86 @ForeignKey(() => UserModel)
69 @Column 87 @Column
70 userId: number 88 userId: number
@@ -94,7 +112,9 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM
94 newCommentOnMyVideo: this.newCommentOnMyVideo, 112 newCommentOnMyVideo: this.newCommentOnMyVideo,
95 newVideoFromSubscription: this.newVideoFromSubscription, 113 newVideoFromSubscription: this.newVideoFromSubscription,
96 videoAbuseAsModerator: this.videoAbuseAsModerator, 114 videoAbuseAsModerator: this.videoAbuseAsModerator,
97 blacklistOnMyVideo: this.blacklistOnMyVideo 115 blacklistOnMyVideo: this.blacklistOnMyVideo,
116 myVideoPublished: this.myVideoPublished,
117 myVideoImportFinished: this.myVideoImportFinished
98 } 118 }
99 } 119 }
100} 120}
diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts
index e22f0d57f..251244374 100644
--- a/server/models/account/user-notification.ts
+++ b/server/models/account/user-notification.ts
@@ -1,4 +1,17 @@
1import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' 1import {
2 AllowNull,
3 BelongsTo,
4 Column,
5 CreatedAt,
6 Default,
7 ForeignKey,
8 IFindOptions,
9 Is,
10 Model,
11 Scopes,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
2import { UserNotification, UserNotificationType } from '../../../shared' 15import { UserNotification, UserNotificationType } from '../../../shared'
3import { getSort, throwIfNotValid } from '../utils' 16import { getSort, throwIfNotValid } from '../utils'
4import { isBooleanValid } from '../../helpers/custom-validators/misc' 17import { isBooleanValid } from '../../helpers/custom-validators/misc'
@@ -11,66 +24,68 @@ import { VideoChannelModel } from '../video/video-channel'
11import { AccountModel } from './account' 24import { AccountModel } from './account'
12import { VideoAbuseModel } from '../video/video-abuse' 25import { VideoAbuseModel } from '../video/video-abuse'
13import { VideoBlacklistModel } from '../video/video-blacklist' 26import { VideoBlacklistModel } from '../video/video-blacklist'
27import { VideoImportModel } from '../video/video-import'
14 28
15enum ScopeNames { 29enum ScopeNames {
16 WITH_ALL = 'WITH_ALL' 30 WITH_ALL = 'WITH_ALL'
17} 31}
18 32
33function buildVideoInclude (required: boolean) {
34 return {
35 attributes: [ 'id', 'uuid', 'name' ],
36 model: () => VideoModel.unscoped(),
37 required
38 }
39}
40
41function buildChannelInclude () {
42 return {
43 required: true,
44 attributes: [ 'id', 'name' ],
45 model: () => VideoChannelModel.unscoped()
46 }
47}
48
49function buildAccountInclude () {
50 return {
51 required: true,
52 attributes: [ 'id', 'name' ],
53 model: () => AccountModel.unscoped()
54 }
55}
56
19@Scopes({ 57@Scopes({
20 [ScopeNames.WITH_ALL]: { 58 [ScopeNames.WITH_ALL]: {
21 include: [ 59 include: [
60 Object.assign(buildVideoInclude(false), {
61 include: [ buildChannelInclude() ]
62 }),
22 { 63 {
23 attributes: [ 'id', 'uuid', 'name' ], 64 attributes: [ 'id', 'originCommentId' ],
24 model: () => VideoModel.unscoped(),
25 required: false,
26 include: [
27 {
28 required: true,
29 attributes: [ 'id', 'name' ],
30 model: () => VideoChannelModel.unscoped()
31 }
32 ]
33 },
34 {
35 attributes: [ 'id' ],
36 model: () => VideoCommentModel.unscoped(), 65 model: () => VideoCommentModel.unscoped(),
37 required: false, 66 required: false,
38 include: [ 67 include: [
39 { 68 buildAccountInclude(),
40 required: true, 69 buildVideoInclude(true)
41 attributes: [ 'id', 'name' ],
42 model: () => AccountModel.unscoped()
43 },
44 {
45 required: true,
46 attributes: [ 'id', 'uuid', 'name' ],
47 model: () => VideoModel.unscoped()
48 }
49 ] 70 ]
50 }, 71 },
51 { 72 {
52 attributes: [ 'id' ], 73 attributes: [ 'id' ],
53 model: () => VideoAbuseModel.unscoped(), 74 model: () => VideoAbuseModel.unscoped(),
54 required: false, 75 required: false,
55 include: [ 76 include: [ buildVideoInclude(true) ]
56 {
57 required: true,
58 attributes: [ 'id', 'uuid', 'name' ],
59 model: () => VideoModel.unscoped()
60 }
61 ]
62 }, 77 },
63 { 78 {
64 attributes: [ 'id' ], 79 attributes: [ 'id' ],
65 model: () => VideoBlacklistModel.unscoped(), 80 model: () => VideoBlacklistModel.unscoped(),
66 required: false, 81 required: false,
67 include: [ 82 include: [ buildVideoInclude(true) ]
68 { 83 },
69 required: true, 84 {
70 attributes: [ 'id', 'uuid', 'name' ], 85 attributes: [ 'id', 'magnetUri', 'targetUrl', 'torrentName' ],
71 model: () => VideoModel.unscoped() 86 model: () => VideoImportModel.unscoped(),
72 } 87 required: false,
73 ] 88 include: [ buildVideoInclude(false) ]
74 } 89 }
75 ] 90 ]
76 } 91 }
@@ -166,8 +181,20 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
166 }) 181 })
167 VideoBlacklist: VideoBlacklistModel 182 VideoBlacklist: VideoBlacklistModel
168 183
169 static listForApi (userId: number, start: number, count: number, sort: string) { 184 @ForeignKey(() => VideoImportModel)
170 const query = { 185 @Column
186 videoImportId: number
187
188 @BelongsTo(() => VideoImportModel, {
189 foreignKey: {
190 allowNull: true
191 },
192 onDelete: 'cascade'
193 })
194 VideoImport: VideoImportModel
195
196 static listForApi (userId: number, start: number, count: number, sort: string, unread?: boolean) {
197 const query: IFindOptions<UserNotificationModel> = {
171 offset: start, 198 offset: start,
172 limit: count, 199 limit: count,
173 order: getSort(sort), 200 order: getSort(sort),
@@ -176,6 +203,8 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
176 } 203 }
177 } 204 }
178 205
206 if (unread !== undefined) query.where['read'] = !unread
207
179 return UserNotificationModel.scope(ScopeNames.WITH_ALL) 208 return UserNotificationModel.scope(ScopeNames.WITH_ALL)
180 .findAndCountAll(query) 209 .findAndCountAll(query)
181 .then(({ rows, count }) => { 210 .then(({ rows, count }) => {
@@ -200,45 +229,39 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
200 } 229 }
201 230
202 toFormattedJSON (): UserNotification { 231 toFormattedJSON (): UserNotification {
203 const video = this.Video ? { 232 const video = this.Video ? Object.assign(this.formatVideo(this.Video), {
204 id: this.Video.id,
205 uuid: this.Video.uuid,
206 name: this.Video.name,
207 channel: { 233 channel: {
208 id: this.Video.VideoChannel.id, 234 id: this.Video.VideoChannel.id,
209 displayName: this.Video.VideoChannel.getDisplayName() 235 displayName: this.Video.VideoChannel.getDisplayName()
210 } 236 }
237 }) : undefined
238
239 const videoImport = this.VideoImport ? {
240 id: this.VideoImport.id,
241 video: this.VideoImport.Video ? this.formatVideo(this.VideoImport.Video) : undefined,
242 torrentName: this.VideoImport.torrentName,
243 magnetUri: this.VideoImport.magnetUri,
244 targetUrl: this.VideoImport.targetUrl
211 } : undefined 245 } : undefined
212 246
213 const comment = this.Comment ? { 247 const comment = this.Comment ? {
214 id: this.Comment.id, 248 id: this.Comment.id,
249 threadId: this.Comment.getThreadId(),
215 account: { 250 account: {
216 id: this.Comment.Account.id, 251 id: this.Comment.Account.id,
217 displayName: this.Comment.Account.getDisplayName() 252 displayName: this.Comment.Account.getDisplayName()
218 }, 253 },
219 video: { 254 video: this.formatVideo(this.Comment.Video)
220 id: this.Comment.Video.id,
221 uuid: this.Comment.Video.uuid,
222 name: this.Comment.Video.name
223 }
224 } : undefined 255 } : undefined
225 256
226 const videoAbuse = this.VideoAbuse ? { 257 const videoAbuse = this.VideoAbuse ? {
227 id: this.VideoAbuse.id, 258 id: this.VideoAbuse.id,
228 video: { 259 video: this.formatVideo(this.VideoAbuse.Video)
229 id: this.VideoAbuse.Video.id,
230 uuid: this.VideoAbuse.Video.uuid,
231 name: this.VideoAbuse.Video.name
232 }
233 } : undefined 260 } : undefined
234 261
235 const videoBlacklist = this.VideoBlacklist ? { 262 const videoBlacklist = this.VideoBlacklist ? {
236 id: this.VideoBlacklist.id, 263 id: this.VideoBlacklist.id,
237 video: { 264 video: this.formatVideo(this.VideoBlacklist.Video)
238 id: this.VideoBlacklist.Video.id,
239 uuid: this.VideoBlacklist.Video.uuid,
240 name: this.VideoBlacklist.Video.name
241 }
242 } : undefined 265 } : undefined
243 266
244 return { 267 return {
@@ -246,6 +269,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
246 type: this.type, 269 type: this.type,
247 read: this.read, 270 read: this.read,
248 video, 271 video,
272 videoImport,
249 comment, 273 comment,
250 videoAbuse, 274 videoAbuse,
251 videoBlacklist, 275 videoBlacklist,
@@ -253,4 +277,12 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
253 updatedAt: this.updatedAt.toISOString() 277 updatedAt: this.updatedAt.toISOString()
254 } 278 }
255 } 279 }
280
281 private formatVideo (video: VideoModel) {
282 return {
283 id: video.id,
284 uuid: video.uuid,
285 name: video.name
286 }
287 }
256} 288}
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 55ec14d05..33f56f641 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -48,6 +48,7 @@ import { UserNotificationSettingModel } from './user-notification-setting'
48import { VideoModel } from '../video/video' 48import { VideoModel } from '../video/video'
49import { ActorModel } from '../activitypub/actor' 49import { ActorModel } from '../activitypub/actor'
50import { ActorFollowModel } from '../activitypub/actor-follow' 50import { ActorFollowModel } from '../activitypub/actor-follow'
51import { VideoImportModel } from '../video/video-import'
51 52
52enum ScopeNames { 53enum ScopeNames {
53 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' 54 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
@@ -186,6 +187,12 @@ export class UserModel extends Model<UserModel> {
186 }) 187 })
187 NotificationSetting: UserNotificationSettingModel 188 NotificationSetting: UserNotificationSettingModel
188 189
190 @HasMany(() => VideoImportModel, {
191 foreignKey: 'userId',
192 onDelete: 'cascade'
193 })
194 VideoImports: VideoImportModel[]
195
189 @HasMany(() => OAuthTokenModel, { 196 @HasMany(() => OAuthTokenModel, {
190 foreignKey: 'userId', 197 foreignKey: 'userId',
191 onDelete: 'cascade' 198 onDelete: 'cascade'
@@ -400,6 +407,23 @@ export class UserModel extends Model<UserModel> {
400 return UserModel.findOne(query) 407 return UserModel.findOne(query)
401 } 408 }
402 409
410 static loadByVideoImportId (videoImportId: number) {
411 const query = {
412 include: [
413 {
414 required: true,
415 attributes: [ 'id' ],
416 model: VideoImportModel.unscoped(),
417 where: {
418 id: videoImportId
419 }
420 }
421 ]
422 }
423
424 return UserModel.findOne(query)
425 }
426
403 static getOriginalVideoFileTotalFromUser (user: UserModel) { 427 static getOriginalVideoFileTotalFromUser (user: UserModel) {
404 // Don't use sequelize because we need to use a sub query 428 // Don't use sequelize because we need to use a sub query
405 const query = UserModel.generateUserQuotaBaseSQL() 429 const query = UserModel.generateUserQuotaBaseSQL()
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts
index 3fd2d5a99..0fd868cd6 100644
--- a/server/models/video/video-file.ts
+++ b/server/models/video/video-file.ts
@@ -1,4 +1,3 @@
1import { values } from 'lodash'
2import { 1import {
3 AllowNull, 2 AllowNull,
4 BelongsTo, 3 BelongsTo,
@@ -20,7 +19,6 @@ import {
20 isVideoFileSizeValid, 19 isVideoFileSizeValid,
21 isVideoFPSResolutionValid 20 isVideoFPSResolutionValid
22} from '../../helpers/custom-validators/videos' 21} from '../../helpers/custom-validators/videos'
23import { CONSTRAINTS_FIELDS } from '../../initializers'
24import { throwIfNotValid } from '../utils' 22import { throwIfNotValid } from '../utils'
25import { VideoModel } from './video' 23import { VideoModel } from './video'
26import * as Sequelize from 'sequelize' 24import * as Sequelize from 'sequelize'
diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts
index 8d442b3f8..c723e57c0 100644
--- a/server/models/video/video-import.ts
+++ b/server/models/video/video-import.ts
@@ -144,6 +144,10 @@ export class VideoImportModel extends Model<VideoImportModel> {
144 }) 144 })
145 } 145 }
146 146
147 getTargetIdentifier () {
148 return this.targetUrl || this.magnetUri || this.torrentName
149 }
150
147 toFormattedJSON (): VideoImport { 151 toFormattedJSON (): VideoImport {
148 const videoFormatOptions = { 152 const videoFormatOptions = {
149 completeDescription: true, 153 completeDescription: true,
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index fc200e5d1..80a6c7832 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -94,6 +94,7 @@ import {
94import * as validator from 'validator' 94import * as validator from 'validator'
95import { UserVideoHistoryModel } from '../account/user-video-history' 95import { UserVideoHistoryModel } from '../account/user-video-history'
96import { UserModel } from '../account/user' 96import { UserModel } from '../account/user'
97import { VideoImportModel } from './video-import'
97 98
98// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 99// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
99const indexes: Sequelize.DefineIndexesOptions[] = [ 100const indexes: Sequelize.DefineIndexesOptions[] = [
@@ -785,6 +786,15 @@ export class VideoModel extends Model<VideoModel> {
785 }) 786 })
786 VideoBlacklist: VideoBlacklistModel 787 VideoBlacklist: VideoBlacklistModel
787 788
789 @HasOne(() => VideoImportModel, {
790 foreignKey: {
791 name: 'videoId',
792 allowNull: true
793 },
794 onDelete: 'set null'
795 })
796 VideoImport: VideoImportModel
797
788 @HasMany(() => VideoCaptionModel, { 798 @HasMany(() => VideoCaptionModel, {
789 foreignKey: { 799 foreignKey: {
790 name: 'videoId', 800 name: 'videoId',