Add import.video.torrent configuration
This commit is contained in:
parent
990b6a0b0c
commit
a84b8fa5cf
|
@ -108,6 +108,11 @@
|
||||||
i18n-labelText labelText="Video import with HTTP enabled"
|
i18n-labelText labelText="Video import with HTTP enabled"
|
||||||
></my-peertube-checkbox>
|
></my-peertube-checkbox>
|
||||||
|
|
||||||
|
<my-peertube-checkbox
|
||||||
|
inputName="importVideosTorrentEnabled" formControlName="importVideosTorrentEnabled"
|
||||||
|
i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
|
||||||
<div i18n class="inner-form-title">Administrator</div>
|
<div i18n class="inner-form-title">Administrator</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -72,6 +72,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
||||||
signupEnabled: null,
|
signupEnabled: null,
|
||||||
signupLimit: this.customConfigValidatorsService.SIGNUP_LIMIT,
|
signupLimit: this.customConfigValidatorsService.SIGNUP_LIMIT,
|
||||||
importVideosHttpEnabled: null,
|
importVideosHttpEnabled: null,
|
||||||
|
importVideosTorrentEnabled: null,
|
||||||
adminEmail: this.customConfigValidatorsService.ADMIN_EMAIL,
|
adminEmail: this.customConfigValidatorsService.ADMIN_EMAIL,
|
||||||
userVideoQuota: this.userValidatorsService.USER_VIDEO_QUOTA,
|
userVideoQuota: this.userValidatorsService.USER_VIDEO_QUOTA,
|
||||||
transcodingThreads: this.customConfigValidatorsService.TRANSCODING_THREADS,
|
transcodingThreads: this.customConfigValidatorsService.TRANSCODING_THREADS,
|
||||||
|
@ -189,6 +190,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: this.form.value['importVideosHttpEnabled']
|
enabled: this.form.value['importVideosHttpEnabled']
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: this.form.value['importVideosTorrentEnabled']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,7 +235,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
||||||
transcodingEnabled: this.customConfig.transcoding.enabled,
|
transcodingEnabled: this.customConfig.transcoding.enabled,
|
||||||
customizationJavascript: this.customConfig.instance.customizations.javascript,
|
customizationJavascript: this.customConfig.instance.customizations.javascript,
|
||||||
customizationCSS: this.customConfig.instance.customizations.css,
|
customizationCSS: this.customConfig.instance.customizations.css,
|
||||||
importVideosHttpEnabled: this.customConfig.import.videos.http.enabled
|
importVideosHttpEnabled: this.customConfig.import.videos.http.enabled,
|
||||||
|
importVideosTorrentEnabled: this.customConfig.import.videos.torrent.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const resolution of this.resolutions) {
|
for (const resolution of this.resolutions) {
|
||||||
|
|
|
@ -73,6 +73,9 @@ export class ServerService {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: false
|
enabled: false
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ $background-color: #F7F7F7;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 440px;
|
min-height: 440px;
|
||||||
|
padding-bottom: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -40,6 +40,6 @@ export class VideoAddComponent implements CanComponentDeactivate {
|
||||||
}
|
}
|
||||||
|
|
||||||
isVideoImportTorrentEnabled () {
|
isVideoImportTorrentEnabled () {
|
||||||
return this.serverService.getConfig().import.videos.http.enabled
|
return this.serverService.getConfig().import.videos.torrent.enabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,8 @@ import:
|
||||||
videos:
|
videos:
|
||||||
http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html
|
http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html
|
||||||
enabled: false
|
enabled: false
|
||||||
|
torrent: # Magnet URI or torrent file (use classic TCP/UDP/WebSeed to download the file)
|
||||||
|
enabled: false
|
||||||
|
|
||||||
instance:
|
instance:
|
||||||
name: 'PeerTube'
|
name: 'PeerTube'
|
||||||
|
|
|
@ -111,6 +111,8 @@ import:
|
||||||
videos:
|
videos:
|
||||||
http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html
|
http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html
|
||||||
enabled: false
|
enabled: false
|
||||||
|
torrent: # Magnet URI or torrent file (use classic TCP/UDP/WebSeed to download the file)
|
||||||
|
enabled: false
|
||||||
|
|
||||||
# Instance settings
|
# Instance settings
|
||||||
instance:
|
instance:
|
||||||
|
|
|
@ -44,6 +44,8 @@ import:
|
||||||
videos:
|
videos:
|
||||||
http:
|
http:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
torrent:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
instance:
|
instance:
|
||||||
default_nsfw_policy: 'display'
|
default_nsfw_policy: 'display'
|
|
@ -9,7 +9,7 @@ import { CONFIG, CONSTRAINTS_FIELDS, reloadConfig } from '../../initializers'
|
||||||
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares'
|
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares'
|
||||||
import { customConfigUpdateValidator } from '../../middlewares/validators/config'
|
import { customConfigUpdateValidator } from '../../middlewares/validators/config'
|
||||||
import { ClientHtml } from '../../lib/client-html'
|
import { ClientHtml } from '../../lib/client-html'
|
||||||
import { CustomConfigAuditView, auditLoggerFactory } from '../../helpers/audit-logger'
|
import { auditLoggerFactory, CustomConfigAuditView } from '../../helpers/audit-logger'
|
||||||
|
|
||||||
const packageJSON = require('../../../../package.json')
|
const packageJSON = require('../../../../package.json')
|
||||||
const configRouter = express.Router()
|
const configRouter = express.Router()
|
||||||
|
@ -69,6 +69,9 @@ async function getConfig (req: express.Request, res: express.Response, next: exp
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED
|
enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -237,6 +240,9 @@ function customConfig (): CustomConfig {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED
|
enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ async function getUserVideos (req: express.Request, res: express.Response, next:
|
||||||
async function getUserVideoImports (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function getUserVideoImports (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const user = res.locals.oauth.token.User as UserModel
|
const user = res.locals.oauth.token.User as UserModel
|
||||||
const resultList = await VideoImportModel.listUserVideoImportsForApi(
|
const resultList = await VideoImportModel.listUserVideoImportsForApi(
|
||||||
user.Account.id,
|
user.id,
|
||||||
req.query.start as number,
|
req.query.start as number,
|
||||||
req.query.count as number,
|
req.query.count as number,
|
||||||
req.query.sort
|
req.query.sort
|
||||||
|
|
|
@ -61,12 +61,13 @@ export {
|
||||||
function addVideoImport (req: express.Request, res: express.Response) {
|
function addVideoImport (req: express.Request, res: express.Response) {
|
||||||
if (req.body.targetUrl) return addYoutubeDLImport(req, res)
|
if (req.body.targetUrl) return addYoutubeDLImport(req, res)
|
||||||
|
|
||||||
const file = req.files['torrentfile'][0]
|
const file = req.files && req.files['torrentfile'] ? req.files['torrentfile'][0] : undefined
|
||||||
if (req.body.magnetUri || file) return addTorrentImport(req, res, file)
|
if (req.body.magnetUri || file) return addTorrentImport(req, res, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addTorrentImport (req: express.Request, res: express.Response, torrentfile: Express.Multer.File) {
|
async function addTorrentImport (req: express.Request, res: express.Response, torrentfile: Express.Multer.File) {
|
||||||
const body: VideoImportCreate = req.body
|
const body: VideoImportCreate = req.body
|
||||||
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
let videoName: string
|
let videoName: string
|
||||||
let torrentName: string
|
let torrentName: string
|
||||||
|
@ -100,7 +101,8 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
|
||||||
const videoImportAttributes = {
|
const videoImportAttributes = {
|
||||||
magnetUri,
|
magnetUri,
|
||||||
torrentName,
|
torrentName,
|
||||||
state: VideoImportState.PENDING
|
state: VideoImportState.PENDING,
|
||||||
|
userId: user.id
|
||||||
}
|
}
|
||||||
const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes)
|
const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes)
|
||||||
|
|
||||||
|
@ -120,6 +122,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
|
||||||
async function addYoutubeDLImport (req: express.Request, res: express.Response) {
|
async function addYoutubeDLImport (req: express.Request, res: express.Response) {
|
||||||
const body: VideoImportCreate = req.body
|
const body: VideoImportCreate = req.body
|
||||||
const targetUrl = body.targetUrl
|
const targetUrl = body.targetUrl
|
||||||
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
let youtubeDLInfo: YoutubeDLInfo
|
let youtubeDLInfo: YoutubeDLInfo
|
||||||
try {
|
try {
|
||||||
|
@ -140,7 +143,8 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
|
||||||
const tags = body.tags || youtubeDLInfo.tags
|
const tags = body.tags || youtubeDLInfo.tags
|
||||||
const videoImportAttributes = {
|
const videoImportAttributes = {
|
||||||
targetUrl,
|
targetUrl,
|
||||||
state: VideoImportState.PENDING
|
state: VideoImportState.PENDING,
|
||||||
|
userId: user.id
|
||||||
}
|
}
|
||||||
const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes)
|
const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes)
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ let config: IConfig = require('config')
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 245
|
const LAST_MIGRATION_VERSION = 240
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -211,6 +211,9 @@ const CONFIG = {
|
||||||
VIDEOS: {
|
VIDEOS: {
|
||||||
HTTP: {
|
HTTP: {
|
||||||
get ENABLED () { return config.get<boolean>('import.videos.http.enabled') }
|
get ENABLED () { return config.get<boolean>('import.videos.http.enabled') }
|
||||||
|
},
|
||||||
|
TORRENT: {
|
||||||
|
get ENABLED () { return config.get<boolean>('import.videos.torrent.enabled') }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import * as Sequelize from 'sequelize'
|
|
||||||
import { Migration } from '../../models/migrations'
|
|
||||||
import { CONSTRAINTS_FIELDS } from '../index'
|
|
||||||
|
|
||||||
async function up (utils: {
|
|
||||||
transaction: Sequelize.Transaction
|
|
||||||
queryInterface: Sequelize.QueryInterface
|
|
||||||
sequelize: Sequelize.Sequelize
|
|
||||||
}): Promise<any> {
|
|
||||||
{
|
|
||||||
const data = {
|
|
||||||
type: Sequelize.STRING,
|
|
||||||
allowNull: true,
|
|
||||||
defaultValue: null
|
|
||||||
} as Migration.String
|
|
||||||
await utils.queryInterface.changeColumn('videoImport', 'targetUrl', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const data = {
|
|
||||||
type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max),
|
|
||||||
allowNull: true,
|
|
||||||
defaultValue: null
|
|
||||||
}
|
|
||||||
await utils.queryInterface.addColumn('videoImport', 'magnetUri', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const data = {
|
|
||||||
type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_NAME.max),
|
|
||||||
allowNull: true,
|
|
||||||
defaultValue: null
|
|
||||||
}
|
|
||||||
await utils.queryInterface.addColumn('videoImport', 'torrentName', data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function down (options) {
|
|
||||||
throw new Error('Not implemented.')
|
|
||||||
}
|
|
||||||
|
|
||||||
export { up, down }
|
|
|
@ -114,16 +114,21 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
|
||||||
tempVideoPath = await downloader()
|
tempVideoPath = await downloader()
|
||||||
|
|
||||||
// Get information about this video
|
// Get information about this video
|
||||||
|
const { size } = await statPromise(tempVideoPath)
|
||||||
|
const isAble = await videoImport.User.isAbleToUploadVideo({ size })
|
||||||
|
if (isAble === false) {
|
||||||
|
throw new Error('The user video quota is exceeded with this video to import.')
|
||||||
|
}
|
||||||
|
|
||||||
const { videoFileResolution } = await getVideoFileResolution(tempVideoPath)
|
const { videoFileResolution } = await getVideoFileResolution(tempVideoPath)
|
||||||
const fps = await getVideoFileFPS(tempVideoPath)
|
const fps = await getVideoFileFPS(tempVideoPath)
|
||||||
const stats = await statPromise(tempVideoPath)
|
|
||||||
const duration = await getDurationFromVideoFile(tempVideoPath)
|
const duration = await getDurationFromVideoFile(tempVideoPath)
|
||||||
|
|
||||||
// Create video file object in database
|
// Create video file object in database
|
||||||
const videoFileData = {
|
const videoFileData = {
|
||||||
extname: extname(tempVideoPath),
|
extname: extname(tempVideoPath),
|
||||||
resolution: videoFileResolution,
|
resolution: videoFileResolution,
|
||||||
size: stats.size,
|
size,
|
||||||
fps,
|
fps,
|
||||||
videoId: videoImport.videoId
|
videoId: videoImport.videoId
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ const customConfigUpdateValidator = [
|
||||||
body('transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'),
|
body('transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'),
|
||||||
body('transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'),
|
body('transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'),
|
||||||
body('import.videos.http.enabled').isBoolean().withMessage('Should have a valid import video http enabled boolean'),
|
body('import.videos.http.enabled').isBoolean().withMessage('Should have a valid import video http enabled boolean'),
|
||||||
|
body('import.videos.torrent.enabled').isBoolean().withMessage('Should have a valid import video torrent enabled boolean'),
|
||||||
|
|
||||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
logger.debug('Checking customConfigUpdateValidator parameters', { parameters: req.body })
|
logger.debug('Checking customConfigUpdateValidator parameters', { parameters: req.body })
|
||||||
|
|
|
@ -33,21 +33,28 @@ const videoImportAddValidator = getCommonVideoAttributes().concat([
|
||||||
logger.debug('Checking videoImportAddValidator parameters', { parameters: req.body })
|
logger.debug('Checking videoImportAddValidator parameters', { parameters: req.body })
|
||||||
|
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
const torrentFile = req.files && req.files['torrentfile'] ? req.files['torrentfile'][0] : undefined
|
||||||
|
|
||||||
if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
|
if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
|
||||||
|
|
||||||
if (CONFIG.IMPORT.VIDEOS.HTTP.ENABLED !== true) {
|
if (req.body.targetUrl && CONFIG.IMPORT.VIDEOS.HTTP.ENABLED !== true) {
|
||||||
cleanUpReqFiles(req)
|
cleanUpReqFiles(req)
|
||||||
return res.status(409)
|
return res.status(409)
|
||||||
.json({ error: 'Import is not enabled on this instance.' })
|
.json({ error: 'HTTP import is not enabled on this instance.' })
|
||||||
.end()
|
.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED !== true && (req.body.magnetUri || torrentFile)) {
|
||||||
|
cleanUpReqFiles(req)
|
||||||
|
return res.status(409)
|
||||||
|
.json({ error: 'Torrent/magnet URI import is not enabled on this instance.' })
|
||||||
|
.end()
|
||||||
|
}
|
||||||
|
|
||||||
if (!await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
|
if (!await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
|
||||||
|
|
||||||
// Check we have at least 1 required param
|
// Check we have at least 1 required param
|
||||||
const file = req.files['torrentfile'][0]
|
if (!req.body.targetUrl && !req.body.magnetUri && !torrentFile) {
|
||||||
if (!req.body.targetUrl && !req.body.magnetUri && !file) {
|
|
||||||
cleanUpReqFiles(req)
|
cleanUpReqFiles(req)
|
||||||
|
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
|
|
|
@ -295,7 +295,7 @@ export class UserModel extends Model<UserModel> {
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
isAbleToUploadVideo (videoFile: Express.Multer.File) {
|
isAbleToUploadVideo (videoFile: { size: number }) {
|
||||||
if (this.videoQuota === -1) return Promise.resolve(true)
|
if (this.videoQuota === -1) return Promise.resolve(true)
|
||||||
|
|
||||||
return UserModel.getOriginalVideoFileTotalFromUser(this)
|
return UserModel.getOriginalVideoFileTotalFromUser(this)
|
||||||
|
|
|
@ -15,34 +15,21 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers'
|
import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers'
|
||||||
import { getSort, throwIfNotValid } from '../utils'
|
import { getSort, throwIfNotValid } from '../utils'
|
||||||
import { VideoModel } from './video'
|
import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
|
||||||
import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
|
import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
|
||||||
import { VideoImport, VideoImportState } from '../../../shared'
|
import { VideoImport, VideoImportState } from '../../../shared'
|
||||||
import { VideoChannelModel } from './video-channel'
|
|
||||||
import { AccountModel } from '../account/account'
|
|
||||||
import { TagModel } from './tag'
|
|
||||||
import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
|
import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
|
||||||
|
import { UserModel } from '../account/user'
|
||||||
|
|
||||||
@DefaultScope({
|
@DefaultScope({
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: () => VideoModel,
|
model: () => UserModel.unscoped(),
|
||||||
required: false,
|
required: true
|
||||||
include: [
|
},
|
||||||
{
|
{
|
||||||
model: () => VideoChannelModel,
|
model: () => VideoModel.scope([ VideoModelScopeNames.WITH_ACCOUNT_DETAILS, VideoModelScopeNames.WITH_TAGS]),
|
||||||
required: true,
|
required: false
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: () => AccountModel,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: () => TagModel
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -53,6 +40,9 @@ import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
|
||||||
{
|
{
|
||||||
fields: [ 'videoId' ],
|
fields: [ 'videoId' ],
|
||||||
unique: true
|
unique: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'userId' ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -91,6 +81,18 @@ export class VideoImportModel extends Model<VideoImportModel> {
|
||||||
@Column(DataType.TEXT)
|
@Column(DataType.TEXT)
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
|
@ForeignKey(() => UserModel)
|
||||||
|
@Column
|
||||||
|
userId: number
|
||||||
|
|
||||||
|
@BelongsTo(() => UserModel, {
|
||||||
|
foreignKey: {
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
onDelete: 'cascade'
|
||||||
|
})
|
||||||
|
User: UserModel
|
||||||
|
|
||||||
@ForeignKey(() => VideoModel)
|
@ForeignKey(() => VideoModel)
|
||||||
@Column
|
@Column
|
||||||
videoId: number
|
videoId: number
|
||||||
|
@ -116,41 +118,24 @@ export class VideoImportModel extends Model<VideoImportModel> {
|
||||||
return VideoImportModel.findById(id)
|
return VideoImportModel.findById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static listUserVideoImportsForApi (accountId: number, start: number, count: number, sort: string) {
|
static listUserVideoImportsForApi (userId: number, start: number, count: number, sort: string) {
|
||||||
const query = {
|
const query = {
|
||||||
distinct: true,
|
distinct: true,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: UserModel.unscoped(), // FIXME: Without this, sequelize try to COUNT(DISTINCT(*)) which is an invalid SQL query
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
],
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: getSort(sort),
|
order: getSort(sort),
|
||||||
include: [
|
where: {
|
||||||
{
|
userId
|
||||||
model: VideoModel,
|
}
|
||||||
required: false,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: VideoChannelModel,
|
|
||||||
required: true,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true,
|
|
||||||
where: {
|
|
||||||
id: accountId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: TagModel,
|
|
||||||
required: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoImportModel.unscoped()
|
return VideoImportModel.findAndCountAll(query)
|
||||||
.findAndCountAll(query)
|
|
||||||
.then(({ rows, count }) => {
|
.then(({ rows, count }) => {
|
||||||
return {
|
return {
|
||||||
data: rows,
|
data: rows,
|
||||||
|
|
|
@ -65,6 +65,9 @@ describe('Test config API validators', function () {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: false
|
enabled: false
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ function checkInitialConfig (data: CustomConfig) {
|
||||||
expect(data.transcoding.resolutions['720p']).to.be.true
|
expect(data.transcoding.resolutions['720p']).to.be.true
|
||||||
expect(data.transcoding.resolutions['1080p']).to.be.true
|
expect(data.transcoding.resolutions['1080p']).to.be.true
|
||||||
expect(data.import.videos.http.enabled).to.be.true
|
expect(data.import.videos.http.enabled).to.be.true
|
||||||
|
expect(data.import.videos.torrent.enabled).to.be.true
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkUpdatedConfig (data: CustomConfig) {
|
function checkUpdatedConfig (data: CustomConfig) {
|
||||||
|
@ -72,6 +73,7 @@ function checkUpdatedConfig (data: CustomConfig) {
|
||||||
expect(data.transcoding.resolutions['720p']).to.be.false
|
expect(data.transcoding.resolutions['720p']).to.be.false
|
||||||
expect(data.transcoding.resolutions['1080p']).to.be.false
|
expect(data.transcoding.resolutions['1080p']).to.be.false
|
||||||
expect(data.import.videos.http.enabled).to.be.false
|
expect(data.import.videos.http.enabled).to.be.false
|
||||||
|
expect(data.import.videos.torrent.enabled).to.be.false
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Test config', function () {
|
describe('Test config', function () {
|
||||||
|
@ -167,6 +169,9 @@ describe('Test config', function () {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: false
|
enabled: false
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,9 @@ function updateCustomSubConfig (url: string, token: string, newConfig: any) {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: false
|
enabled: false
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ export interface CustomConfig {
|
||||||
videos: {
|
videos: {
|
||||||
http: {
|
http: {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
|
},
|
||||||
|
torrent: {
|
||||||
|
enabled: boolean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ export interface ServerConfig {
|
||||||
http: {
|
http: {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
}
|
}
|
||||||
|
torrent: {
|
||||||
|
enabled: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue