aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-08-14 17:56:51 +0200
committerChocobozzz <me@florianbigard.com>2018-08-14 18:01:23 +0200
commita76138ff56ad3ad2df926f59578a06b22fb1f93c (patch)
tree2b97808cbb492af2356beb26d02749223abc6154
parent614d1ae928ec307b708c4a3eb423797353b1df2a (diff)
downloadPeerTube-a76138ff56ad3ad2df926f59578a06b22fb1f93c.tar.gz
PeerTube-a76138ff56ad3ad2df926f59578a06b22fb1f93c.tar.zst
PeerTube-a76138ff56ad3ad2df926f59578a06b22fb1f93c.zip
Add quota used in users list
-rw-r--r--client/src/app/+admin/users/shared/user.service.ts9
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.html2
-rw-r--r--client/src/app/shared/video-import/video-import.service.ts3
-rw-r--r--server/models/account/user.ts30
-rw-r--r--server/tests/api/users/users.ts8
-rw-r--r--shared/models/users/user.model.ts2
6 files changed, 44 insertions, 10 deletions
diff --git a/client/src/app/+admin/users/shared/user.service.ts b/client/src/app/+admin/users/shared/user.service.ts
index ad7fb1eee..a0e2f666d 100644
--- a/client/src/app/+admin/users/shared/user.service.ts
+++ b/client/src/app/+admin/users/shared/user.service.ts
@@ -4,9 +4,9 @@ import { Injectable } from '@angular/core'
4import { BytesPipe } from 'ngx-pipes' 4import { BytesPipe } from 'ngx-pipes'
5import { SortMeta } from 'primeng/components/common/sortmeta' 5import { SortMeta } from 'primeng/components/common/sortmeta'
6import { Observable } from 'rxjs' 6import { Observable } from 'rxjs'
7import { ResultList, UserCreate, UserUpdate } from '../../../../../../shared' 7import { ResultList, UserCreate, UserUpdate, User } from '../../../../../../shared'
8import { environment } from '../../../../environments/environment' 8import { environment } from '../../../../environments/environment'
9import { RestExtractor, RestPagination, RestService, User } from '../../../shared' 9import { RestExtractor, RestPagination, RestService } from '../../../shared'
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11 11
12@Injectable() 12@Injectable()
@@ -79,8 +79,11 @@ export class UserService {
79 videoQuota = this.bytesPipe.transform(user.videoQuota, 0) 79 videoQuota = this.bytesPipe.transform(user.videoQuota, 0)
80 } 80 }
81 81
82 const videoQuotaUsed = this.bytesPipe.transform(user.videoQuotaUsed, 0)
83
82 return Object.assign(user, { 84 return Object.assign(user, {
83 videoQuota 85 videoQuota,
86 videoQuotaUsed
84 }) 87 })
85 } 88 }
86} 89}
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html
index a92fe95ef..bb1b26442 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.html
+++ b/client/src/app/+admin/users/user-list/user-list.component.html
@@ -36,7 +36,7 @@
36 <span *ngIf="user.blocked" class="banned-info">(banned)</span> 36 <span *ngIf="user.blocked" class="banned-info">(banned)</span>
37 </td> 37 </td>
38 <td>{{ user.email }}</td> 38 <td>{{ user.email }}</td>
39 <td>{{ user.videoQuota }}</td> 39 <td>{{ user.videoQuotaUsed }} / {{ user.videoQuota }}</td>
40 <td>{{ user.roleLabel }}</td> 40 <td>{{ user.roleLabel }}</td>
41 <td>{{ user.createdAt }}</td> 41 <td>{{ user.createdAt }}</td>
42 <td class="action-cell"> 42 <td class="action-cell">
diff --git a/client/src/app/shared/video-import/video-import.service.ts b/client/src/app/shared/video-import/video-import.service.ts
index f63bfb2b1..fc34dbf2d 100644
--- a/client/src/app/shared/video-import/video-import.service.ts
+++ b/client/src/app/shared/video-import/video-import.service.ts
@@ -5,9 +5,8 @@ import { Observable } from 'rxjs'
5import { VideoImport } from '../../../../../shared' 5import { VideoImport } from '../../../../../shared'
6import { environment } from '../../../environments/environment' 6import { environment } from '../../../environments/environment'
7import { RestExtractor, RestService } from '../rest' 7import { RestExtractor, RestService } from '../rest'
8import { VideoImportCreate } from '../../../../../shared/models/videos' 8import { VideoImportCreate, VideoUpdate } from '../../../../../shared/models/videos'
9import { objectToFormData } from '@app/shared/misc/utils' 9import { objectToFormData } from '@app/shared/misc/utils'
10import { VideoUpdate } from '../../../../../shared/models/videos'
11import { ResultList } from '../../../../../shared/models/result-list.model' 10import { ResultList } from '../../../../../shared/models/result-list.model'
12import { UserService } from '@app/shared/users/user.service' 11import { UserService } from '@app/shared/users/user.service'
13import { SortMeta } from 'primeng/components/common/sortmeta' 12import { SortMeta } from 'primeng/components/common/sortmeta'
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 81b0651fd..0150df4ce 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -161,6 +161,25 @@ export class UserModel extends Model<UserModel> {
161 161
162 static listForApi (start: number, count: number, sort: string) { 162 static listForApi (start: number, count: number, sort: string) {
163 const query = { 163 const query = {
164 attributes: {
165 include: [
166 [
167 Sequelize.literal(
168 '(' +
169 'SELECT COALESCE(SUM("size"), 0) FROM ' +
170 '(' +
171 'SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' +
172 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' +
173 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
174 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' +
175 'WHERE "account"."userId" = "UserModel"."id" GROUP BY "video"."id"' +
176 ') t' +
177 ')'
178 ),
179 'videoQuotaUsed'
180 ] as any // FIXME: typings
181 ]
182 },
164 offset: start, 183 offset: start,
165 limit: count, 184 limit: count,
166 order: getSort(sort) 185 order: getSort(sort)
@@ -168,6 +187,9 @@ export class UserModel extends Model<UserModel> {
168 187
169 return UserModel.findAndCountAll(query) 188 return UserModel.findAndCountAll(query)
170 .then(({ rows, count }) => { 189 .then(({ rows, count }) => {
190 console.log(rows[0])
191 console.log(rows[0]['videoQuotaUsed'])
192 console.log(rows[0].get('videoQuotaUsed'))
171 return { 193 return {
172 data: rows, 194 data: rows,
173 total: count 195 total: count
@@ -249,8 +271,7 @@ export class UserModel extends Model<UserModel> {
249 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + 271 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' +
250 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + 272 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
251 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' + 273 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' +
252 'INNER JOIN "user" ON "account"."userId" = "user"."id" ' + 274 'WHERE "account"."userId" = $userId GROUP BY "video"."id") t'
253 'WHERE "user"."id" = $userId GROUP BY "video"."id") t'
254 275
255 const options = { 276 const options = {
256 bind: { userId: user.id }, 277 bind: { userId: user.id },
@@ -281,6 +302,8 @@ export class UserModel extends Model<UserModel> {
281 } 302 }
282 303
283 toFormattedJSON (): User { 304 toFormattedJSON (): User {
305 const videoQuotaUsed = this.get('videoQuotaUsed')
306
284 const json = { 307 const json = {
285 id: this.id, 308 id: this.id,
286 username: this.username, 309 username: this.username,
@@ -294,7 +317,8 @@ export class UserModel extends Model<UserModel> {
294 blocked: this.blocked, 317 blocked: this.blocked,
295 blockedReason: this.blockedReason, 318 blockedReason: this.blockedReason,
296 account: this.Account.toFormattedJSON(), 319 account: this.Account.toFormattedJSON(),
297 videoChannels: [] 320 videoChannels: [],
321 videoQuotaUsed: videoQuotaUsed !== undefined ? parseInt(videoQuotaUsed, 10) : undefined
298 } 322 }
299 323
300 if (Array.isArray(this.Account.VideoChannels) === true) { 324 if (Array.isArray(this.Account.VideoChannels) === true) {
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index 77aa00f60..04dcc8fd1 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -2,7 +2,7 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { UserRole } from '../../../../shared/index' 5import { User, UserRole } from '../../../../shared/index'
6import { 6import {
7 createUser, flushTests, getBlacklistedVideosList, getMyUserInformation, getMyUserVideoQuotaUsed, getMyUserVideoRating, 7 createUser, flushTests, getBlacklistedVideosList, getMyUserInformation, getMyUserVideoQuotaUsed, getMyUserVideoRating,
8 getUserInformation, getUsersList, getUsersListPaginationAndSort, getVideosList, killallServers, login, makePutBodyRequest, rateVideo, 8 getUserInformation, getUsersList, getUsersListPaginationAndSort, getVideosList, killallServers, login, makePutBodyRequest, rateVideo,
@@ -192,6 +192,12 @@ describe('Test users', function () {
192 const data = res.body 192 const data = res.body
193 193
194 expect(data.videoQuotaUsed).to.equal(218910) 194 expect(data.videoQuotaUsed).to.equal(218910)
195
196 const resUsers = await getUsersList(server.url, server.accessToken)
197
198 const users: User[] = resUsers.body.data
199 const tmpUser = users.find(u => u.username === user.username)
200 expect(tmpUser.videoQuotaUsed).to.equal(218910)
195 }) 201 })
196 202
197 it('Should be able to list my videos', async function () { 203 it('Should be able to list my videos', async function () {
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts
index 8eddaa496..455211aa3 100644
--- a/shared/models/users/user.model.ts
+++ b/shared/models/users/user.model.ts
@@ -17,4 +17,6 @@ export interface User {
17 17
18 blocked: boolean 18 blocked: boolean
19 blockedReason?: string 19 blockedReason?: string
20
21 videoQuotaUsed?: number
20} 22}