diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-09-04 20:07:54 +0200 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-09-04 20:07:54 +0200 |
commit | b0f9f39ed70299a208d1b388c72de8b7f3510cb7 (patch) | |
tree | 4b7d388125265533ac2f6d4bf457d018617e1db6 /server | |
parent | e7dbeae8d915cdf4470ceb51c2724b04148b30b5 (diff) | |
download | PeerTube-b0f9f39ed70299a208d1b388c72de8b7f3510cb7.tar.gz PeerTube-b0f9f39ed70299a208d1b388c72de8b7f3510cb7.tar.zst PeerTube-b0f9f39ed70299a208d1b388c72de8b7f3510cb7.zip |
Begin user quota
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/users.ts | 11 | ||||
-rw-r--r-- | server/helpers/custom-validators/users.ts | 8 | ||||
-rw-r--r-- | server/initializers/constants.ts | 10 | ||||
-rw-r--r-- | server/initializers/database.ts | 1 | ||||
-rw-r--r-- | server/initializers/installer.ts | 9 | ||||
-rw-r--r-- | server/initializers/migrations/0070-user-video-quota.ts | 32 | ||||
-rw-r--r-- | server/middlewares/validators/users.ts | 2 | ||||
-rw-r--r-- | server/middlewares/validators/videos.ts | 17 | ||||
-rw-r--r-- | server/models/user/user-interface.ts | 4 | ||||
-rw-r--r-- | server/models/user/user.ts | 60 | ||||
-rw-r--r-- | server/models/video/video.ts | 7 |
11 files changed, 144 insertions, 17 deletions
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index 04d885185..1b5b7f903 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | 2 | ||
3 | import { database as db } from '../../initializers/database' | 3 | import { database as db } from '../../initializers/database' |
4 | import { USER_ROLES } from '../../initializers' | 4 | import { USER_ROLES, CONFIG } from '../../initializers' |
5 | import { logger, getFormattedObjects } from '../../helpers' | 5 | import { logger, getFormattedObjects } from '../../helpers' |
6 | import { | 6 | import { |
7 | authenticate, | 7 | authenticate, |
@@ -80,12 +80,18 @@ export { | |||
80 | function createUser (req: express.Request, res: express.Response, next: express.NextFunction) { | 80 | function createUser (req: express.Request, res: express.Response, next: express.NextFunction) { |
81 | const body: UserCreate = req.body | 81 | const body: UserCreate = req.body |
82 | 82 | ||
83 | // On registration, we set the user video quota | ||
84 | if (body.videoQuota === undefined) { | ||
85 | body.videoQuota = CONFIG.USER.VIDEO_QUOTA | ||
86 | } | ||
87 | |||
83 | const user = db.User.build({ | 88 | const user = db.User.build({ |
84 | username: body.username, | 89 | username: body.username, |
85 | password: body.password, | 90 | password: body.password, |
86 | email: body.email, | 91 | email: body.email, |
87 | displayNSFW: false, | 92 | displayNSFW: false, |
88 | role: USER_ROLES.USER | 93 | role: USER_ROLES.USER, |
94 | videoQuota: body.videoQuota | ||
89 | }) | 95 | }) |
90 | 96 | ||
91 | user.save() | 97 | user.save() |
@@ -140,6 +146,7 @@ function updateUser (req: express.Request, res: express.Response, next: express. | |||
140 | .then(user => { | 146 | .then(user => { |
141 | if (body.password) user.password = body.password | 147 | if (body.password) user.password = body.password |
142 | if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW | 148 | if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW |
149 | if (body.videoQuota !== undefined) user.videoQuota = body.videoQuota | ||
143 | 150 | ||
144 | return user.save() | 151 | return user.save() |
145 | }) | 152 | }) |
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index 2b37bdde8..00061f9df 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts | |||
@@ -15,6 +15,10 @@ function isUserRoleValid (value: string) { | |||
15 | return values(USER_ROLES).indexOf(value as UserRole) !== -1 | 15 | return values(USER_ROLES).indexOf(value as UserRole) !== -1 |
16 | } | 16 | } |
17 | 17 | ||
18 | function isUserVideoQuotaValid (value: string) { | ||
19 | return exists(value) && validator.isInt(value + '', USERS_CONSTRAINTS_FIELDS.VIDEO_QUOTA) | ||
20 | } | ||
21 | |||
18 | function isUserUsernameValid (value: string) { | 22 | function isUserUsernameValid (value: string) { |
19 | const max = USERS_CONSTRAINTS_FIELDS.USERNAME.max | 23 | const max = USERS_CONSTRAINTS_FIELDS.USERNAME.max |
20 | const min = USERS_CONSTRAINTS_FIELDS.USERNAME.min | 24 | const min = USERS_CONSTRAINTS_FIELDS.USERNAME.min |
@@ -30,6 +34,7 @@ function isUserDisplayNSFWValid (value: any) { | |||
30 | export { | 34 | export { |
31 | isUserPasswordValid, | 35 | isUserPasswordValid, |
32 | isUserRoleValid, | 36 | isUserRoleValid, |
37 | isUserVideoQuotaValid, | ||
33 | isUserUsernameValid, | 38 | isUserUsernameValid, |
34 | isUserDisplayNSFWValid | 39 | isUserDisplayNSFWValid |
35 | } | 40 | } |
@@ -39,6 +44,7 @@ declare module 'express-validator' { | |||
39 | isUserPasswordValid, | 44 | isUserPasswordValid, |
40 | isUserRoleValid, | 45 | isUserRoleValid, |
41 | isUserUsernameValid, | 46 | isUserUsernameValid, |
42 | isUserDisplayNSFWValid | 47 | isUserDisplayNSFWValid, |
48 | isUserVideoQuotaValid | ||
43 | } | 49 | } |
44 | } | 50 | } |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 50a939083..b93a85859 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -15,7 +15,7 @@ import { | |||
15 | 15 | ||
16 | // --------------------------------------------------------------------------- | 16 | // --------------------------------------------------------------------------- |
17 | 17 | ||
18 | const LAST_MIGRATION_VERSION = 65 | 18 | const LAST_MIGRATION_VERSION = 70 |
19 | 19 | ||
20 | // --------------------------------------------------------------------------- | 20 | // --------------------------------------------------------------------------- |
21 | 21 | ||
@@ -77,7 +77,10 @@ const CONFIG = { | |||
77 | }, | 77 | }, |
78 | SIGNUP: { | 78 | SIGNUP: { |
79 | ENABLED: config.get<boolean>('signup.enabled'), | 79 | ENABLED: config.get<boolean>('signup.enabled'), |
80 | LIMIT: config.get<number>('signup.limit') | 80 | LIMIT: config.get<number>('signup.limit'), |
81 | }, | ||
82 | USER: { | ||
83 | VIDEO_QUOTA: config.get<number>('user.video_quota') | ||
81 | }, | 84 | }, |
82 | TRANSCODING: { | 85 | TRANSCODING: { |
83 | ENABLED: config.get<boolean>('transcoding.enabled'), | 86 | ENABLED: config.get<boolean>('transcoding.enabled'), |
@@ -97,7 +100,8 @@ CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT | |||
97 | const CONSTRAINTS_FIELDS = { | 100 | const CONSTRAINTS_FIELDS = { |
98 | USERS: { | 101 | USERS: { |
99 | USERNAME: { min: 3, max: 20 }, // Length | 102 | USERNAME: { min: 3, max: 20 }, // Length |
100 | PASSWORD: { min: 6, max: 255 } // Length | 103 | PASSWORD: { min: 6, max: 255 }, // Length |
104 | VIDEO_QUOTA: { min: -1 } | ||
101 | }, | 105 | }, |
102 | VIDEO_ABUSES: { | 106 | VIDEO_ABUSES: { |
103 | REASON: { min: 2, max: 300 } // Length | 107 | REASON: { min: 2, max: 300 } // Length |
diff --git a/server/initializers/database.ts b/server/initializers/database.ts index c0df2b63a..d04c8db1b 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { join } from 'path' | 1 | import { join } from 'path' |
2 | import { flattenDepth } from 'lodash' | 2 | import { flattenDepth } from 'lodash' |
3 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string | ||
3 | import * as Sequelize from 'sequelize' | 4 | import * as Sequelize from 'sequelize' |
4 | import * as Promise from 'bluebird' | 5 | import * as Promise from 'bluebird' |
5 | 6 | ||
diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts index 43b5adfed..10b74b85f 100644 --- a/server/initializers/installer.ts +++ b/server/initializers/installer.ts | |||
@@ -38,12 +38,12 @@ function removeCacheDirectories () { | |||
38 | } | 38 | } |
39 | 39 | ||
40 | function createDirectoriesIfNotExist () { | 40 | function createDirectoriesIfNotExist () { |
41 | const storages = CONFIG.STORAGE | 41 | const storage = CONFIG.STORAGE |
42 | const cacheDirectories = CACHE.DIRECTORIES | 42 | const cacheDirectories = CACHE.DIRECTORIES |
43 | 43 | ||
44 | const tasks = [] | 44 | const tasks = [] |
45 | Object.keys(storages).forEach(key => { | 45 | Object.keys(storage).forEach(key => { |
46 | const dir = storages[key] | 46 | const dir = storage[key] |
47 | tasks.push(mkdirpPromise(dir)) | 47 | tasks.push(mkdirpPromise(dir)) |
48 | }) | 48 | }) |
49 | 49 | ||
@@ -112,7 +112,8 @@ function createOAuthAdminIfNotExist () { | |||
112 | username, | 112 | username, |
113 | email, | 113 | email, |
114 | password, | 114 | password, |
115 | role | 115 | role, |
116 | videoQuota: -1 | ||
116 | } | 117 | } |
117 | 118 | ||
118 | return db.User.create(userData, createOptions).then(createdUser => { | 119 | return db.User.create(userData, createOptions).then(createdUser => { |
diff --git a/server/initializers/migrations/0070-user-video-quota.ts b/server/initializers/migrations/0070-user-video-quota.ts new file mode 100644 index 000000000..dec4d46dd --- /dev/null +++ b/server/initializers/migrations/0070-user-video-quota.ts | |||
@@ -0,0 +1,32 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import * as Promise from 'bluebird' | ||
3 | |||
4 | function up (utils: { | ||
5 | transaction: Sequelize.Transaction, | ||
6 | queryInterface: Sequelize.QueryInterface, | ||
7 | sequelize: Sequelize.Sequelize, | ||
8 | db: any | ||
9 | }): Promise<void> { | ||
10 | const q = utils.queryInterface | ||
11 | |||
12 | const data = { | ||
13 | type: Sequelize.BIGINT, | ||
14 | allowNull: false, | ||
15 | defaultValue: -1 | ||
16 | } | ||
17 | |||
18 | return q.addColumn('Users', 'videoQuota', data) | ||
19 | .then(() => { | ||
20 | data.defaultValue = null | ||
21 | return q.changeColumn('Users', 'videoQuota', data) | ||
22 | }) | ||
23 | } | ||
24 | |||
25 | function down (options) { | ||
26 | throw new Error('Not implemented.') | ||
27 | } | ||
28 | |||
29 | export { | ||
30 | up, | ||
31 | down | ||
32 | } | ||
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 71e529872..eeb0e3557 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -12,6 +12,7 @@ function usersAddValidator (req: express.Request, res: express.Response, next: e | |||
12 | req.checkBody('username', 'Should have a valid username').isUserUsernameValid() | 12 | req.checkBody('username', 'Should have a valid username').isUserUsernameValid() |
13 | req.checkBody('password', 'Should have a valid password').isUserPasswordValid() | 13 | req.checkBody('password', 'Should have a valid password').isUserPasswordValid() |
14 | req.checkBody('email', 'Should have a valid email').isEmail() | 14 | req.checkBody('email', 'Should have a valid email').isEmail() |
15 | req.checkBody('videoQuota', 'Should have a valid user quota').isUserVideoQuotaValid() | ||
15 | 16 | ||
16 | logger.debug('Checking usersAdd parameters', { parameters: req.body }) | 17 | logger.debug('Checking usersAdd parameters', { parameters: req.body }) |
17 | 18 | ||
@@ -55,6 +56,7 @@ function usersUpdateValidator (req: express.Request, res: express.Response, next | |||
55 | // Add old password verification | 56 | // Add old password verification |
56 | req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() | 57 | req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() |
57 | req.checkBody('displayNSFW', 'Should have a valid display Not Safe For Work attribute').optional().isUserDisplayNSFWValid() | 58 | req.checkBody('displayNSFW', 'Should have a valid display Not Safe For Work attribute').optional().isUserDisplayNSFWValid() |
59 | req.checkBody('videoQuota', 'Should have a valid user quota').optional().isUserVideoQuotaValid() | ||
58 | 60 | ||
59 | logger.debug('Checking usersUpdate parameters', { parameters: req.body }) | 61 | logger.debug('Checking usersUpdate parameters', { parameters: req.body }) |
60 | 62 | ||
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts index 29c1ee0ef..1d19ebfd9 100644 --- a/server/middlewares/validators/videos.ts +++ b/server/middlewares/validators/videos.ts | |||
@@ -24,10 +24,23 @@ function videosAddValidator (req: express.Request, res: express.Response, next: | |||
24 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) | 24 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) |
25 | 25 | ||
26 | checkErrors(req, res, () => { | 26 | checkErrors(req, res, () => { |
27 | const videoFile = req.files['videofile'][0] | 27 | const videoFile: Express.Multer.File = req.files['videofile'][0] |
28 | const user = res.locals.oauth.token.User | ||
28 | 29 | ||
29 | db.Video.getDurationFromFile(videoFile.path) | 30 | user.isAbleToUploadVideo(videoFile) |
31 | .then(isAble => { | ||
32 | if (isAble === false) { | ||
33 | res.status(403).send('The user video quota is exceeded with this video.') | ||
34 | |||
35 | return undefined | ||
36 | } | ||
37 | |||
38 | return db.Video.getDurationFromFile(videoFile.path) | ||
39 | }) | ||
30 | .then(duration => { | 40 | .then(duration => { |
41 | // Previous test failed, abort | ||
42 | if (duration === undefined) return | ||
43 | |||
31 | if (!isVideoDurationValid('' + duration)) { | 44 | if (!isVideoDurationValid('' + duration)) { |
32 | return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') | 45 | return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') |
33 | } | 46 | } |
diff --git a/server/models/user/user-interface.ts b/server/models/user/user-interface.ts index 0b97a8f6d..8974a9a97 100644 --- a/server/models/user/user-interface.ts +++ b/server/models/user/user-interface.ts | |||
@@ -11,6 +11,7 @@ export namespace UserMethods { | |||
11 | 11 | ||
12 | export type ToFormattedJSON = (this: UserInstance) => FormattedUser | 12 | export type ToFormattedJSON = (this: UserInstance) => FormattedUser |
13 | export type IsAdmin = (this: UserInstance) => boolean | 13 | export type IsAdmin = (this: UserInstance) => boolean |
14 | export type IsAbleToUploadVideo = (this: UserInstance, videoFile: Express.Multer.File) => Promise<boolean> | ||
14 | 15 | ||
15 | export type CountTotal = () => Promise<number> | 16 | export type CountTotal = () => Promise<number> |
16 | 17 | ||
@@ -31,6 +32,7 @@ export interface UserClass { | |||
31 | isPasswordMatch: UserMethods.IsPasswordMatch, | 32 | isPasswordMatch: UserMethods.IsPasswordMatch, |
32 | toFormattedJSON: UserMethods.ToFormattedJSON, | 33 | toFormattedJSON: UserMethods.ToFormattedJSON, |
33 | isAdmin: UserMethods.IsAdmin, | 34 | isAdmin: UserMethods.IsAdmin, |
35 | isAbleToUploadVideo: UserMethods.IsAbleToUploadVideo, | ||
34 | 36 | ||
35 | countTotal: UserMethods.CountTotal, | 37 | countTotal: UserMethods.CountTotal, |
36 | getByUsername: UserMethods.GetByUsername, | 38 | getByUsername: UserMethods.GetByUsername, |
@@ -42,11 +44,13 @@ export interface UserClass { | |||
42 | } | 44 | } |
43 | 45 | ||
44 | export interface UserAttributes { | 46 | export interface UserAttributes { |
47 | id?: number | ||
45 | password: string | 48 | password: string |
46 | username: string | 49 | username: string |
47 | email: string | 50 | email: string |
48 | displayNSFW?: boolean | 51 | displayNSFW?: boolean |
49 | role: UserRole | 52 | role: UserRole |
53 | videoQuota: number | ||
50 | } | 54 | } |
51 | 55 | ||
52 | export interface UserInstance extends UserClass, UserAttributes, Sequelize.Instance<UserAttributes> { | 56 | export interface UserInstance extends UserClass, UserAttributes, Sequelize.Instance<UserAttributes> { |
diff --git a/server/models/user/user.ts b/server/models/user/user.ts index d481fa13c..12a7547f5 100644 --- a/server/models/user/user.ts +++ b/server/models/user/user.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { values } from 'lodash' | 1 | import { values } from 'lodash' |
2 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
3 | import * as Promise from 'bluebird' | ||
3 | 4 | ||
4 | import { getSort } from '../utils' | 5 | import { getSort } from '../utils' |
5 | import { USER_ROLES } from '../../initializers' | 6 | import { USER_ROLES } from '../../initializers' |
@@ -8,7 +9,8 @@ import { | |||
8 | comparePassword, | 9 | comparePassword, |
9 | isUserPasswordValid, | 10 | isUserPasswordValid, |
10 | isUserUsernameValid, | 11 | isUserUsernameValid, |
11 | isUserDisplayNSFWValid | 12 | isUserDisplayNSFWValid, |
13 | isUserVideoQuotaValid | ||
12 | } from '../../helpers' | 14 | } from '../../helpers' |
13 | 15 | ||
14 | import { addMethodsToModel } from '../utils' | 16 | import { addMethodsToModel } from '../utils' |
@@ -30,6 +32,7 @@ let listForApi: UserMethods.ListForApi | |||
30 | let loadById: UserMethods.LoadById | 32 | let loadById: UserMethods.LoadById |
31 | let loadByUsername: UserMethods.LoadByUsername | 33 | let loadByUsername: UserMethods.LoadByUsername |
32 | let loadByUsernameOrEmail: UserMethods.LoadByUsernameOrEmail | 34 | let loadByUsernameOrEmail: UserMethods.LoadByUsernameOrEmail |
35 | let isAbleToUploadVideo: UserMethods.IsAbleToUploadVideo | ||
33 | 36 | ||
34 | export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { | 37 | export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { |
35 | User = sequelize.define<UserInstance, UserAttributes>('User', | 38 | User = sequelize.define<UserInstance, UserAttributes>('User', |
@@ -75,6 +78,16 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
75 | role: { | 78 | role: { |
76 | type: DataTypes.ENUM(values(USER_ROLES)), | 79 | type: DataTypes.ENUM(values(USER_ROLES)), |
77 | allowNull: false | 80 | allowNull: false |
81 | }, | ||
82 | videoQuota: { | ||
83 | type: DataTypes.BIGINT, | ||
84 | allowNull: false, | ||
85 | validate: { | ||
86 | videoQuotaValid: value => { | ||
87 | const res = isUserVideoQuotaValid(value) | ||
88 | if (res === false) throw new Error('Video quota is not valid.') | ||
89 | } | ||
90 | } | ||
78 | } | 91 | } |
79 | }, | 92 | }, |
80 | { | 93 | { |
@@ -109,7 +122,8 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
109 | const instanceMethods = [ | 122 | const instanceMethods = [ |
110 | isPasswordMatch, | 123 | isPasswordMatch, |
111 | toFormattedJSON, | 124 | toFormattedJSON, |
112 | isAdmin | 125 | isAdmin, |
126 | isAbleToUploadVideo | ||
113 | ] | 127 | ] |
114 | addMethodsToModel(User, classMethods, instanceMethods) | 128 | addMethodsToModel(User, classMethods, instanceMethods) |
115 | 129 | ||
@@ -136,6 +150,7 @@ toFormattedJSON = function (this: UserInstance) { | |||
136 | email: this.email, | 150 | email: this.email, |
137 | displayNSFW: this.displayNSFW, | 151 | displayNSFW: this.displayNSFW, |
138 | role: this.role, | 152 | role: this.role, |
153 | videoQuota: this.videoQuota, | ||
139 | createdAt: this.createdAt | 154 | createdAt: this.createdAt |
140 | } | 155 | } |
141 | } | 156 | } |
@@ -144,6 +159,14 @@ isAdmin = function (this: UserInstance) { | |||
144 | return this.role === USER_ROLES.ADMIN | 159 | return this.role === USER_ROLES.ADMIN |
145 | } | 160 | } |
146 | 161 | ||
162 | isAbleToUploadVideo = function (this: UserInstance, videoFile: Express.Multer.File) { | ||
163 | if (this.videoQuota === -1) return Promise.resolve(true) | ||
164 | |||
165 | return getOriginalVideoFileTotalFromUser(this).then(totalBytes => { | ||
166 | return (videoFile.size + totalBytes) < this.videoQuota | ||
167 | }) | ||
168 | } | ||
169 | |||
147 | // ------------------------------ STATICS ------------------------------ | 170 | // ------------------------------ STATICS ------------------------------ |
148 | 171 | ||
149 | function associate (models) { | 172 | function associate (models) { |
@@ -215,3 +238,36 @@ loadByUsernameOrEmail = function (username: string, email: string) { | |||
215 | // FIXME: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18387 | 238 | // FIXME: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18387 |
216 | return (User as any).findOne(query) | 239 | return (User as any).findOne(query) |
217 | } | 240 | } |
241 | |||
242 | // --------------------------------------------------------------------------- | ||
243 | |||
244 | function getOriginalVideoFileTotalFromUser (user: UserInstance) { | ||
245 | const query = { | ||
246 | attributes: [ | ||
247 | Sequelize.fn('COUNT', Sequelize.col('VideoFile.size'), 'totalVideoBytes') | ||
248 | ], | ||
249 | where: { | ||
250 | id: user.id | ||
251 | }, | ||
252 | include: [ | ||
253 | { | ||
254 | model: User['sequelize'].models.Author, | ||
255 | include: [ | ||
256 | { | ||
257 | model: User['sequelize'].models.Video, | ||
258 | include: [ | ||
259 | { | ||
260 | model: User['sequelize'].models.VideoFile | ||
261 | } | ||
262 | ] | ||
263 | } | ||
264 | ] | ||
265 | } | ||
266 | ] | ||
267 | } | ||
268 | |||
269 | // FIXME: cast to any because of bad typing... | ||
270 | return User.findAll(query).then((res: any) => { | ||
271 | return res.totalVideoBytes | ||
272 | }) | ||
273 | } | ||
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 7dfea8ac9..4fb4485d8 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -9,6 +9,7 @@ import * as Sequelize from 'sequelize' | |||
9 | import * as Promise from 'bluebird' | 9 | import * as Promise from 'bluebird' |
10 | 10 | ||
11 | import { TagInstance } from './tag-interface' | 11 | import { TagInstance } from './tag-interface' |
12 | import { UserInstance } from '../user/user-interface' | ||
12 | import { | 13 | import { |
13 | logger, | 14 | logger, |
14 | isVideoNameValid, | 15 | isVideoNameValid, |
@@ -582,7 +583,7 @@ transcodeVideofile = function (this: VideoInstance, inputVideoFile: VideoFileIns | |||
582 | return res() | 583 | return res() |
583 | }) | 584 | }) |
584 | .catch(err => { | 585 | .catch(err => { |
585 | // Autodestruction... | 586 | // Auto destruction... |
586 | this.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', err)) | 587 | this.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', err)) |
587 | 588 | ||
588 | return rej(err) | 589 | return rej(err) |
@@ -608,8 +609,8 @@ removeFile = function (this: VideoInstance, videoFile: VideoFileInstance) { | |||
608 | } | 609 | } |
609 | 610 | ||
610 | removeTorrent = function (this: VideoInstance, videoFile: VideoFileInstance) { | 611 | removeTorrent = function (this: VideoInstance, videoFile: VideoFileInstance) { |
611 | const torrenPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) | 612 | const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) |
612 | return unlinkPromise(torrenPath) | 613 | return unlinkPromise(torrentPath) |
613 | } | 614 | } |
614 | 615 | ||
615 | // ------------------------------ STATICS ------------------------------ | 616 | // ------------------------------ STATICS ------------------------------ |