Skip to content

Commit

Permalink
Made the video channels limit (per user) server-wide configurable (#4491
Browse files Browse the repository at this point in the history
)

* Made the video channels limit (per user) server-wide configurable

Implements #3092

Also added a "quota bar" in the account's settings page

* Fixed lint errors

* Another pass at fixing lint errors

* Applied code suggestions

* Removed 'video channels quota'
  • Loading branch information
Poslovitch committed Oct 26, 2021
1 parent 615836d commit 754b6f5
Show file tree
Hide file tree
Showing 19 changed files with 87 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,28 @@
</div>
</div>

<div class="form-row mt-4"> <!-- video channels grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="inner-form-title">VIDEO CHANNELS</div>
</div>

<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<div class="form-group" formGroupName="videoChannels">
<label i18n for="videoChannelsMaxPerUser">Max video channels per user</label>

<div class="number-with-unit">
<input
type="number" min="1" id="videoChannelsMaxPerUser" class="form-control"
formControlName="maxPerUser" [ngClass]="{ 'input-error': formErrors['videoChannels.maxPerUser'] }"
>
<span i18n>{form.value['videoChannels']['maxPerUser'], plural, =1 {channel} other {channels}}</span>
</div>

<div *ngIf="formErrors.videoChannels.maxPerUser" class="form-error">{{ formErrors.videoChannels.maxPerUser }}</div>
</div>
</div>
</div>

<div class="form-row mt-4"> <!-- search grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="inner-form-title">SEARCH</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
SERVICES_TWITTER_USERNAME_VALIDATOR,
SIGNUP_LIMIT_VALIDATOR,
SIGNUP_MINIMUM_AGE_VALIDATOR,
TRANSCODING_THREADS_VALIDATOR
TRANSCODING_THREADS_VALIDATOR,
MAX_VIDEO_CHANNELS_PER_USER_VALIDATOR
} from '@app/shared/form-validators/custom-config-validators'
import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators'
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
Expand Down Expand Up @@ -151,6 +152,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
videoQuota: USER_VIDEO_QUOTA_VALIDATOR,
videoQuotaDaily: USER_VIDEO_QUOTA_DAILY_VALIDATOR
},
videoChannels: {
maxPerUser: MAX_VIDEO_CHANNELS_PER_USER_VALIDATOR
},
transcoding: {
enabled: null,
threads: TRANSCODING_THREADS_VALIDATOR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ export const MAX_USER_LIVES_VALIDATOR: BuildFormValidator = {
}
}

export const MAX_VIDEO_CHANNELS_PER_USER_VALIDATOR: BuildFormValidator = {
VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
MESSAGES: {
required: $localize`Max video channels per user is required.`,
min: $localize`Max video channels per user must be greater or equal to 1.`,
pattern: $localize`Max video channels per user must be a number.`
}
}

export const CONCURRENCY_VALIDATOR: BuildFormValidator = {
VALIDATORS: [ Validators.required, Validators.min(1) ],
MESSAGES: {
Expand Down
7 changes: 6 additions & 1 deletion client/src/app/shared/shared-main/shared-main.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ import {
} from './misc'
import { PluginPlaceholderComponent } from './plugins'
import { ActorRedirectGuard } from './router'
import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users'
import {
UserHistoryService,
UserNotificationsComponent,
UserNotificationService,
UserQuotaComponent
} from './users'
import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video'
import { VideoCaptionService } from './video-caption'
import { VideoChannelService } from './video-channel'
Expand Down
3 changes: 3 additions & 0 deletions config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ user:
video_quota: -1
video_quota_daily: -1

video_channels:
max_per_user: 20 # Allows each user to create up to 20 video channels.

# If enabled, the video will be transcoded to mp4 (x264) with `faststart` flag
# In addition, if some resolutions are enabled the mp4 video file will be transcoded to these new resolutions
# Please, do not disable transcoding since many uploaded videos will not work
Expand Down
3 changes: 3 additions & 0 deletions config/production.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ user:
video_quota: -1
video_quota_daily: -1

video_channels:
max_per_user: 20 # Allows each user to create up to 20 video channels.

# If enabled, the video will be transcoded to mp4 (x264) with `faststart` flag
# In addition, if some resolutions are enabled the mp4 video file will be transcoded to these new resolutions
# Please, do not disable transcoding since many uploaded videos will not work
Expand Down
3 changes: 3 additions & 0 deletions server/controllers/api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ function customConfig (): CustomConfig {
videoQuota: CONFIG.USER.VIDEO_QUOTA,
videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY
},
videoChannels: {
maxPerUser: CONFIG.VIDEO_CHANNELS.MAX_PER_USER
},
transcoding: {
enabled: CONFIG.TRANSCODING.ENABLED,
allowAdditionalExtensions: CONFIG.TRANSCODING.ALLOW_ADDITIONAL_EXTENSIONS,
Expand Down
1 change: 1 addition & 0 deletions server/initializers/checker-before-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function checkMissedConfig () {
'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins',
'log.level',
'user.video_quota', 'user.video_quota_daily',
'video_channels.max_per_user',
'csp.enabled', 'csp.report_only', 'csp.report_uri',
'security.frameguard.enabled',
'cache.previews.size', 'cache.captions.size', 'cache.torrents.size', 'admin.email', 'contact_form.enabled',
Expand Down
3 changes: 3 additions & 0 deletions server/initializers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ const CONFIG = {
get VIDEO_QUOTA () { return parseBytes(config.get<number>('user.video_quota')) },
get VIDEO_QUOTA_DAILY () { return parseBytes(config.get<number>('user.video_quota_daily')) }
},
VIDEO_CHANNELS: {
get MAX_PER_USER () { return config.get<number>('video_channels.max_per_user') }
},
TRANSCODING: {
get ENABLED () { return config.get<boolean>('transcoding.enabled') },
get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get<boolean>('transcoding.allow_additional_extensions') },
Expand Down
5 changes: 0 additions & 5 deletions server/initializers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,10 +512,6 @@ const OVERVIEWS = {
}
}

const VIDEO_CHANNELS = {
MAX_PER_USER: 20
}

// ---------------------------------------------------------------------------

const SERVER_ACTOR_NAME = 'peertube'
Expand Down Expand Up @@ -897,7 +893,6 @@ export {
VIDEO_TRANSCODING_FPS,
FFMPEG_NICE,
ABUSE_STATES,
VIDEO_CHANNELS,
LRU_CACHE,
REQUEST_TIMEOUT,
USER_PASSWORD_RESET_LIFETIME,
Expand Down
3 changes: 3 additions & 0 deletions server/lib/server-config-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class ServerConfigManager {
videoQuota: CONFIG.USER.VIDEO_QUOTA,
videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY
},
videoChannels: {
maxPerUser: CONFIG.VIDEO_CHANNELS.MAX_PER_USER
},
trending: {
videos: {
intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS,
Expand Down
2 changes: 2 additions & 0 deletions server/middlewares/validators/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const customConfigUpdateValidator = [
body('user.videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid video quota'),
body('user.videoQuotaDaily').custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily video quota'),

body('videoChannels.maxPerUser').isInt().withMessage("Should have a valid maximum amount of video channels per user"),

body('transcoding.enabled').isBoolean().withMessage('Should have a valid transcoding enabled boolean'),
body('transcoding.allowAdditionalExtensions').isBoolean().withMessage('Should have a valid additional extensions boolean'),
body('transcoding.threads').isInt().withMessage('Should have a valid transcoding threads number'),
Expand Down
6 changes: 3 additions & 3 deletions server/middlewares/validators/videos/video-channels.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import express from 'express'
import { body, param, query } from 'express-validator'
import { VIDEO_CHANNELS } from '@server/initializers/constants'
import { MChannelAccountDefault, MUser } from '@server/types/models'
import { UserRight } from '../../../../shared'
import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
Expand All @@ -15,6 +14,7 @@ import { logger } from '../../../helpers/logger'
import { ActorModel } from '../../../models/actor/actor'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { areValidationErrors, doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../shared'
import { CONFIG } from '@server/initializers/config'

const videoChannelsAddValidator = [
body('name').custom(isVideoChannelUsernameValid).withMessage('Should have a valid channel name'),
Expand All @@ -37,8 +37,8 @@ const videoChannelsAddValidator = [
}

const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id)
if (count >= VIDEO_CHANNELS.MAX_PER_USER) {
res.fail({ message: `You cannot create more than ${VIDEO_CHANNELS.MAX_PER_USER} channels` })
if (count >= CONFIG.VIDEO_CHANNELS.MAX_PER_USER) {
res.fail({ message: `You cannot create more than ${CONFIG.VIDEO_CHANNELS.MAX_PER_USER} channels` })
return false
}

Expand Down
5 changes: 3 additions & 2 deletions server/models/video/video-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
isVideoChannelDisplayNameValid,
isVideoChannelSupportValid
} from '../../helpers/custom-validators/video-channels'
import { CONSTRAINTS_FIELDS, VIDEO_CHANNELS, WEBSERVER } from '../../initializers/constants'
import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants'
import { sendDeleteActor } from '../../lib/activitypub/send'
import {
MChannelActor,
Expand All @@ -44,6 +44,7 @@ import { setAsUpdated } from '../shared'
import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
import { VideoPlaylistModel } from './video-playlist'
import { CONFIG } from '@server/initializers/config'

export enum ScopeNames {
FOR_API = 'FOR_API',
Expand Down Expand Up @@ -584,7 +585,7 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`

static listAllByAccount (accountId: number) {
const query = {
limit: VIDEO_CHANNELS.MAX_PER_USER,
limit: CONFIG.VIDEO_CHANNELS.MAX_PER_USER,
include: [
{
attributes: [],
Expand Down
3 changes: 3 additions & 0 deletions server/tests/api/check-params/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ describe('Test config API validators', function () {
videoQuota: 5242881,
videoQuotaDaily: 318742
},
videoChannels: {
maxPerUser: 20
},
transcoding: {
enabled: true,
allowAdditionalExtensions: true,
Expand Down
7 changes: 7 additions & 0 deletions server/tests/api/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
expect(data.user.videoQuota).to.equal(5242880)
expect(data.user.videoQuotaDaily).to.equal(-1)

expect(data.videoChannels.maxPerUser).to.equal(20)

expect(data.transcoding.enabled).to.be.false
expect(data.transcoding.allowAdditionalExtensions).to.be.false
expect(data.transcoding.allowAudioFiles).to.be.false
Expand Down Expand Up @@ -153,6 +155,8 @@ function checkUpdatedConfig (data: CustomConfig) {
expect(data.user.videoQuota).to.equal(5242881)
expect(data.user.videoQuotaDaily).to.equal(318742)

expect(data.videoChannels.maxPerUser).to.equal(24)

expect(data.transcoding.enabled).to.be.true
expect(data.transcoding.threads).to.equal(1)
expect(data.transcoding.concurrency).to.equal(3)
Expand Down Expand Up @@ -265,6 +269,9 @@ const newCustomConfig: CustomConfig = {
videoQuota: 5242881,
videoQuotaDaily: 318742
},
videoChannels: {
maxPerUser: 24
},
transcoding: {
enabled: true,
allowAdditionalExtensions: true,
Expand Down
3 changes: 3 additions & 0 deletions shared/extra-utils/server/config-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ export class ConfigCommand extends AbstractCommand {
videoQuota: 5242881,
videoQuotaDaily: 318742
},
videoChannels: {
maxPerUser: 20
},
transcoding: {
enabled: true,
allowAdditionalExtensions: true,
Expand Down
4 changes: 4 additions & 0 deletions shared/models/server/custom-config.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export interface CustomConfig {
videoQuotaDaily: number
}

videoChannels: {
maxPerUser: number
}

transcoding: {
enabled: boolean

Expand Down
4 changes: 4 additions & 0 deletions shared/models/server/server-config.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ export interface ServerConfig {
videoQuotaDaily: number
}

videoChannels: {
maxPerUser: number
}

trending: {
videos: {
intervalDays: number
Expand Down

0 comments on commit 754b6f5

Please sign in to comment.