+ const specialPlaylists = this.Account.VideoPlaylists
+ .map(p => ({ id: p.id, name: p.name, type: p.type }))
+
+ return Object.assign(formatted, { specialPlaylists })
+ }
+
+ async isAbleToUploadVideo (videoFile: { size: number }) {
+ if (this.videoQuota === -1 && this.videoQuotaDaily === -1) return Promise.resolve(true)
+
+ const [ totalBytes, totalBytesDaily ] = await Promise.all([
+ UserModel.getOriginalVideoFileTotalFromUser(this),
+ UserModel.getOriginalVideoFileTotalDailyFromUser(this)
+ ])
+
+ const uploadedTotal = videoFile.size + totalBytes
+ const uploadedDaily = videoFile.size + totalBytesDaily
+
+ if (this.videoQuotaDaily === -1) return uploadedTotal < this.videoQuota
+ if (this.videoQuota === -1) return uploadedDaily < this.videoQuotaDaily
+
+ return uploadedTotal < this.videoQuota && uploadedDaily < this.videoQuotaDaily
+ }
+
+ private static generateUserQuotaBaseSQL (options: {
+ whereUserId: '$userId' | '"UserModel"."id"'
+ withSelect: boolean
+ where?: string
+ }) {
+ const andWhere = options.where
+ ? 'AND ' + options.where
+ : ''
+
+ const videoChannelJoin = 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
+ 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' +
+ `WHERE "account"."userId" = ${options.whereUserId} ${andWhere}`
+
+ const webtorrentFiles = 'SELECT "videoFile"."size" AS "size", "video"."id" AS "videoId" FROM "videoFile" ' +
+ 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' +
+ videoChannelJoin
+
+ const hlsFiles = 'SELECT "videoFile"."size" AS "size", "video"."id" AS "videoId" FROM "videoFile" ' +
+ 'INNER JOIN "videoStreamingPlaylist" ON "videoFile"."videoStreamingPlaylistId" = "videoStreamingPlaylist".id ' +
+ 'INNER JOIN "video" ON "videoStreamingPlaylist"."videoId" = "video"."id" ' +
+ videoChannelJoin
+
+ return 'SELECT COALESCE(SUM("size"), 0) AS "total" ' +
+ 'FROM (' +
+ `SELECT MAX("t1"."size") AS "size" FROM (${webtorrentFiles} UNION ${hlsFiles}) t1 ` +
+ 'GROUP BY "t1"."videoId"' +
+ ') t2'
+ }
+
+ private static getTotalRawQuery (query: string, userId: number) {
+ const options = {
+ bind: { userId },
+ type: QueryTypes.SELECT as QueryTypes.SELECT
+ }
+
+ return UserModel.sequelize.query<{ total: string }>(query, options)
+ .then(([ { total } ]) => {
+ if (total === null) return 0
+
+ return parseInt(total, 10)
+ })