diff options
Diffstat (limited to 'server/models/account')
-rw-r--r-- | server/models/account/user.ts | 149 |
1 files changed, 128 insertions, 21 deletions
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 777f09666..026bf1318 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -19,7 +19,7 @@ import { | |||
19 | Table, | 19 | Table, |
20 | UpdatedAt | 20 | UpdatedAt |
21 | } from 'sequelize-typescript' | 21 | } from 'sequelize-typescript' |
22 | import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, VideoPlaylistType, VideoPrivacy } from '../../../shared' | 22 | import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, VideoPlaylistType, VideoPrivacy, VideoAbuseState } from '../../../shared' |
23 | import { User, UserRole } from '../../../shared/models/users' | 23 | import { User, UserRole } from '../../../shared/models/users' |
24 | import { | 24 | import { |
25 | isNoInstanceConfigWarningModal, | 25 | isNoInstanceConfigWarningModal, |
@@ -70,8 +70,26 @@ import { | |||
70 | MVideoFullLight | 70 | MVideoFullLight |
71 | } from '@server/typings/models' | 71 | } from '@server/typings/models' |
72 | 72 | ||
73 | const literalVideoQuotaUsed: any = [ | ||
74 | literal( | ||
75 | '(' + | ||
76 | 'SELECT COALESCE(SUM("size"), 0) ' + | ||
77 | 'FROM (' + | ||
78 | 'SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + | ||
79 | 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + | ||
80 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
81 | 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' + | ||
82 | 'WHERE "account"."userId" = "UserModel"."id" GROUP BY "video"."id"' + | ||
83 | ') t' + | ||
84 | ')' | ||
85 | ), | ||
86 | 'videoQuotaUsed' | ||
87 | ] | ||
88 | |||
73 | enum ScopeNames { | 89 | enum ScopeNames { |
74 | FOR_ME_API = 'FOR_ME_API' | 90 | FOR_ME_API = 'FOR_ME_API', |
91 | WITH_VIDEOCHANNELS = 'WITH_VIDEOCHANNELS', | ||
92 | WITH_STATS = 'WITH_STATS' | ||
75 | } | 93 | } |
76 | 94 | ||
77 | @DefaultScope(() => ({ | 95 | @DefaultScope(() => ({ |
@@ -112,6 +130,86 @@ enum ScopeNames { | |||
112 | required: true | 130 | required: true |
113 | } | 131 | } |
114 | ] | 132 | ] |
133 | }, | ||
134 | [ScopeNames.WITH_VIDEOCHANNELS]: { | ||
135 | include: [ | ||
136 | { | ||
137 | model: AccountModel, | ||
138 | include: [ | ||
139 | { | ||
140 | model: VideoChannelModel | ||
141 | }, | ||
142 | { | ||
143 | attributes: [ 'id', 'name', 'type' ], | ||
144 | model: VideoPlaylistModel.unscoped(), | ||
145 | required: true, | ||
146 | where: { | ||
147 | type: { | ||
148 | [Op.ne]: VideoPlaylistType.REGULAR | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | ] | ||
153 | } | ||
154 | ] | ||
155 | }, | ||
156 | [ScopeNames.WITH_STATS]: { | ||
157 | attributes: { | ||
158 | include: [ | ||
159 | literalVideoQuotaUsed, | ||
160 | [ | ||
161 | literal( | ||
162 | '(' + | ||
163 | 'SELECT COUNT("video"."id") ' + | ||
164 | 'FROM "video" ' + | ||
165 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
166 | 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + | ||
167 | 'WHERE "account"."userId" = "UserModel"."id"' + | ||
168 | ')' | ||
169 | ), | ||
170 | 'videosCount' | ||
171 | ], | ||
172 | [ | ||
173 | literal( | ||
174 | '(' + | ||
175 | `SELECT concat_ws(':', "abuses", "acceptedAbuses") ` + | ||
176 | 'FROM (' + | ||
177 | 'SELECT COUNT("videoAbuse"."id") AS "abuses", ' + | ||
178 | `COUNT("videoAbuse"."id") FILTER (WHERE "videoAbuse"."state" = ${VideoAbuseState.ACCEPTED}) AS "acceptedAbuses" ` + | ||
179 | 'FROM "videoAbuse" ' + | ||
180 | 'INNER JOIN "video" ON "videoAbuse"."videoId" = "video"."id" ' + | ||
181 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
182 | 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + | ||
183 | 'WHERE "account"."userId" = "UserModel"."id"' + | ||
184 | ') t' + | ||
185 | ')' | ||
186 | ), | ||
187 | 'videoAbusesCount' | ||
188 | ], | ||
189 | [ | ||
190 | literal( | ||
191 | '(' + | ||
192 | 'SELECT COUNT("videoAbuse"."id") ' + | ||
193 | 'FROM "videoAbuse" ' + | ||
194 | 'INNER JOIN "account" ON "account"."id" = "videoAbuse"."reporterAccountId" ' + | ||
195 | 'WHERE "account"."userId" = "UserModel"."id"' + | ||
196 | ')' | ||
197 | ), | ||
198 | 'videoAbusesCreatedCount' | ||
199 | ], | ||
200 | [ | ||
201 | literal( | ||
202 | '(' + | ||
203 | 'SELECT COUNT("videoComment"."id") ' + | ||
204 | 'FROM "videoComment" ' + | ||
205 | 'INNER JOIN "account" ON "account"."id" = "videoComment"."accountId" ' + | ||
206 | 'WHERE "account"."userId" = "UserModel"."id"' + | ||
207 | ')' | ||
208 | ), | ||
209 | 'videoCommentsCount' | ||
210 | ] | ||
211 | ] | ||
212 | } | ||
115 | } | 213 | } |
116 | })) | 214 | })) |
117 | @Table({ | 215 | @Table({ |
@@ -332,23 +430,7 @@ export class UserModel extends Model<UserModel> { | |||
332 | 430 | ||
333 | const query: FindOptions = { | 431 | const query: FindOptions = { |
334 | attributes: { | 432 | attributes: { |
335 | include: [ | 433 | include: [ literalVideoQuotaUsed ] |
336 | [ | ||
337 | literal( | ||
338 | '(' + | ||
339 | 'SELECT COALESCE(SUM("size"), 0) ' + | ||
340 | 'FROM (' + | ||
341 | 'SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + | ||
342 | 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + | ||
343 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
344 | 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' + | ||
345 | 'WHERE "account"."userId" = "UserModel"."id" GROUP BY "video"."id"' + | ||
346 | ') t' + | ||
347 | ')' | ||
348 | ), | ||
349 | 'videoQuotaUsed' | ||
350 | ] | ||
351 | ] | ||
352 | }, | 434 | }, |
353 | offset: start, | 435 | offset: start, |
354 | limit: count, | 436 | limit: count, |
@@ -430,8 +512,14 @@ export class UserModel extends Model<UserModel> { | |||
430 | return UserModel.findAll(query) | 512 | return UserModel.findAll(query) |
431 | } | 513 | } |
432 | 514 | ||
433 | static loadById (id: number): Bluebird<MUserDefault> { | 515 | static loadById (id: number, withStats = false): Bluebird<MUserDefault> { |
434 | return UserModel.findByPk(id) | 516 | const scopes = [ |
517 | ScopeNames.WITH_VIDEOCHANNELS | ||
518 | ] | ||
519 | |||
520 | if (withStats) scopes.push(ScopeNames.WITH_STATS) | ||
521 | |||
522 | return UserModel.scope(scopes).findByPk(id) | ||
435 | } | 523 | } |
436 | 524 | ||
437 | static loadByUsername (username: string): Bluebird<MUserDefault> { | 525 | static loadByUsername (username: string): Bluebird<MUserDefault> { |
@@ -637,6 +725,10 @@ export class UserModel extends Model<UserModel> { | |||
637 | toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User { | 725 | toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User { |
638 | const videoQuotaUsed = this.get('videoQuotaUsed') | 726 | const videoQuotaUsed = this.get('videoQuotaUsed') |
639 | const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') | 727 | const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') |
728 | const videosCount = this.get('videosCount') | ||
729 | const [ videoAbusesCount, videoAbusesAcceptedCount ] = (this.get('videoAbusesCount') as string || ':').split(':') | ||
730 | const videoAbusesCreatedCount = this.get('videoAbusesCreatedCount') | ||
731 | const videoCommentsCount = this.get('videoCommentsCount') | ||
640 | 732 | ||
641 | const json: User = { | 733 | const json: User = { |
642 | id: this.id, | 734 | id: this.id, |
@@ -666,6 +758,21 @@ export class UserModel extends Model<UserModel> { | |||
666 | videoQuotaUsedDaily: videoQuotaUsedDaily !== undefined | 758 | videoQuotaUsedDaily: videoQuotaUsedDaily !== undefined |
667 | ? parseInt(videoQuotaUsedDaily + '', 10) | 759 | ? parseInt(videoQuotaUsedDaily + '', 10) |
668 | : undefined, | 760 | : undefined, |
761 | videosCount: videosCount !== undefined | ||
762 | ? parseInt(videosCount + '', 10) | ||
763 | : undefined, | ||
764 | videoAbusesCount: videoAbusesCount | ||
765 | ? parseInt(videoAbusesCount, 10) | ||
766 | : undefined, | ||
767 | videoAbusesAcceptedCount: videoAbusesAcceptedCount | ||
768 | ? parseInt(videoAbusesAcceptedCount, 10) | ||
769 | : undefined, | ||
770 | videoAbusesCreatedCount: videoAbusesCreatedCount !== undefined | ||
771 | ? parseInt(videoAbusesCreatedCount + '', 10) | ||
772 | : undefined, | ||
773 | videoCommentsCount: videoCommentsCount !== undefined | ||
774 | ? parseInt(videoCommentsCount + '', 10) | ||
775 | : undefined, | ||
669 | 776 | ||
670 | noInstanceConfigWarningModal: this.noInstanceConfigWarningModal, | 777 | noInstanceConfigWarningModal: this.noInstanceConfigWarningModal, |
671 | noWelcomeModal: this.noWelcomeModal, | 778 | noWelcomeModal: this.noWelcomeModal, |