aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/account/user.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/account/user.ts')
-rw-r--r--server/models/account/user.ts149
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'
22import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, VideoPlaylistType, VideoPrivacy } from '../../../shared' 22import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, VideoPlaylistType, VideoPrivacy, VideoAbuseState } from '../../../shared'
23import { User, UserRole } from '../../../shared/models/users' 23import { User, UserRole } from '../../../shared/models/users'
24import { 24import {
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
73const 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
73enum ScopeNames { 89enum 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,