mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-06 03:50:26 +02:00
add quarantine videos feature (#1637)
* add quarantine videos feature * increase Notification settings test timeout to 20000ms. was completing 7000 locally but timing out after 10000 on travis * fix quarantine video test issues -propagate misspelling -remove skip from server/tests/client.ts * WIP use blacklist for moderator video approval instead of video.quarantine boolean * finish auto-blacklist feature
This commit is contained in:
parent
12fed49eba
commit
7ccddd7b52
58 changed files with 1047 additions and 99 deletions
|
@ -94,6 +94,13 @@ async function getConfig (req: express.Request, res: express.Response) {
|
|||
}
|
||||
}
|
||||
},
|
||||
autoBlacklist: {
|
||||
videos: {
|
||||
ofUsers: {
|
||||
enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED
|
||||
}
|
||||
}
|
||||
},
|
||||
avatar: {
|
||||
file: {
|
||||
size: {
|
||||
|
@ -265,6 +272,13 @@ function customConfig (): CustomConfig {
|
|||
enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED
|
||||
}
|
||||
}
|
||||
},
|
||||
autoBlacklist: {
|
||||
videos: {
|
||||
ofUsers: {
|
||||
enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ async function updateNotificationSettings (req: express.Request, res: express.Re
|
|||
newVideoFromSubscription: body.newVideoFromSubscription,
|
||||
newCommentOnMyVideo: body.newCommentOnMyVideo,
|
||||
videoAbuseAsModerator: body.videoAbuseAsModerator,
|
||||
videoAutoBlacklistAsModerator: body.videoAutoBlacklistAsModerator,
|
||||
blacklistOnMyVideo: body.blacklistOnMyVideo,
|
||||
myVideoPublished: body.myVideoPublished,
|
||||
myVideoImportFinished: body.myVideoImportFinished,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as express from 'express'
|
||||
import { UserRight, VideoBlacklist, VideoBlacklistCreate } from '../../../../shared'
|
||||
import { VideoBlacklist, UserRight, VideoBlacklistCreate, VideoBlacklistType } from '../../../../shared'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { getFormattedObjects } from '../../../helpers/utils'
|
||||
import {
|
||||
|
@ -12,7 +12,8 @@ import {
|
|||
setDefaultPagination,
|
||||
videosBlacklistAddValidator,
|
||||
videosBlacklistRemoveValidator,
|
||||
videosBlacklistUpdateValidator
|
||||
videosBlacklistUpdateValidator,
|
||||
videosBlacklistFiltersValidator
|
||||
} from '../../../middlewares'
|
||||
import { VideoBlacklistModel } from '../../../models/video/video-blacklist'
|
||||
import { sequelizeTypescript } from '../../../initializers'
|
||||
|
@ -36,6 +37,7 @@ blacklistRouter.get('/blacklist',
|
|||
blacklistSortValidator,
|
||||
setBlacklistSort,
|
||||
setDefaultPagination,
|
||||
videosBlacklistFiltersValidator,
|
||||
asyncMiddleware(listBlacklist)
|
||||
)
|
||||
|
||||
|
@ -68,7 +70,8 @@ async function addVideoToBlacklist (req: express.Request, res: express.Response)
|
|||
const toCreate = {
|
||||
videoId: videoInstance.id,
|
||||
unfederated: body.unfederate === true,
|
||||
reason: body.reason
|
||||
reason: body.reason,
|
||||
type: VideoBlacklistType.MANUAL
|
||||
}
|
||||
|
||||
const blacklist = await VideoBlacklistModel.create(toCreate)
|
||||
|
@ -98,7 +101,7 @@ async function updateVideoBlacklistController (req: express.Request, res: expres
|
|||
}
|
||||
|
||||
async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort)
|
||||
const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort, req.query.type)
|
||||
|
||||
return res.json(getFormattedObjects<VideoBlacklist, VideoBlacklistModel>(resultList.data, resultList.total))
|
||||
}
|
||||
|
@ -107,18 +110,30 @@ async function removeVideoFromBlacklistController (req: express.Request, res: ex
|
|||
const videoBlacklist = res.locals.videoBlacklist
|
||||
const video = res.locals.video
|
||||
|
||||
await sequelizeTypescript.transaction(async t => {
|
||||
const videoBlacklistType = await sequelizeTypescript.transaction(async t => {
|
||||
const unfederated = videoBlacklist.unfederated
|
||||
const videoBlacklistType = videoBlacklist.type
|
||||
|
||||
await videoBlacklist.destroy({ transaction: t })
|
||||
|
||||
// Re federate the video
|
||||
if (unfederated === true) {
|
||||
await federateVideoIfNeeded(video, true, t)
|
||||
}
|
||||
|
||||
return videoBlacklistType
|
||||
})
|
||||
|
||||
Notifier.Instance.notifyOnVideoUnblacklist(video)
|
||||
|
||||
if (videoBlacklistType === VideoBlacklistType.AUTO_BEFORE_PUBLISHED) {
|
||||
Notifier.Instance.notifyOnVideoPublishedAfterRemovedFromAutoBlacklist(video)
|
||||
|
||||
// Delete on object so new video notifications will send
|
||||
delete video.VideoBlacklist
|
||||
Notifier.Instance.notifyOnNewVideo(video)
|
||||
}
|
||||
|
||||
logger.info('Video %s removed from blacklist.', res.locals.video.uuid)
|
||||
|
||||
return res.type('json').status(204).end()
|
||||
|
|
|
@ -18,10 +18,12 @@ import { join } from 'path'
|
|||
import { isArray } from '../../../helpers/custom-validators/misc'
|
||||
import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
|
||||
import { VideoChannelModel } from '../../../models/video/video-channel'
|
||||
import { UserModel } from '../../../models/account/user'
|
||||
import * as Bluebird from 'bluebird'
|
||||
import * as parseTorrent from 'parse-torrent'
|
||||
import { getSecureTorrentName } from '../../../helpers/utils'
|
||||
import { readFile, move } from 'fs-extra'
|
||||
import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist'
|
||||
|
||||
const auditLogger = auditLoggerFactory('video-imports')
|
||||
const videoImportsRouter = express.Router()
|
||||
|
@ -85,7 +87,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
|
|||
videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string
|
||||
}
|
||||
|
||||
const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName })
|
||||
const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }, user)
|
||||
|
||||
await processThumbnail(req, video)
|
||||
await processPreview(req, video)
|
||||
|
@ -128,7 +130,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
|
|||
}).end()
|
||||
}
|
||||
|
||||
const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo)
|
||||
const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo, user)
|
||||
|
||||
const downloadThumbnail = !await processThumbnail(req, video)
|
||||
const downloadPreview = !await processPreview(req, video)
|
||||
|
@ -156,7 +158,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
|
|||
return res.json(videoImport.toFormattedJSON()).end()
|
||||
}
|
||||
|
||||
function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo) {
|
||||
function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo, user: UserModel) {
|
||||
const videoData = {
|
||||
name: body.name || importData.name || 'Unknown name',
|
||||
remote: false,
|
||||
|
@ -218,6 +220,8 @@ function insertIntoDB (
|
|||
const videoCreated = await video.save(sequelizeOptions)
|
||||
videoCreated.VideoChannel = videoChannel
|
||||
|
||||
await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t)
|
||||
|
||||
// Set tags to the video
|
||||
if (tags) {
|
||||
const tagInstances = await TagModel.findOrCreateTags(tags, t)
|
||||
|
|
|
@ -6,6 +6,7 @@ import { processImage } from '../../../helpers/image-utils'
|
|||
import { logger } from '../../../helpers/logger'
|
||||
import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger'
|
||||
import { getFormattedObjects, getServerActor } from '../../../helpers/utils'
|
||||
import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist'
|
||||
import {
|
||||
CONFIG,
|
||||
MIMETYPES,
|
||||
|
@ -193,6 +194,7 @@ async function addVideo (req: express.Request, res: express.Response) {
|
|||
channelId: res.locals.videoChannel.id,
|
||||
originallyPublishedAt: videoInfo.originallyPublishedAt
|
||||
}
|
||||
|
||||
const video = new VideoModel(videoData)
|
||||
video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object
|
||||
|
||||
|
@ -237,7 +239,7 @@ async function addVideo (req: express.Request, res: express.Response) {
|
|||
// Create the torrent file
|
||||
await video.createTorrentAndSetInfoHash(videoFile)
|
||||
|
||||
const videoCreated = await sequelizeTypescript.transaction(async t => {
|
||||
const { videoCreated, videoWasAutoBlacklisted } = await sequelizeTypescript.transaction(async t => {
|
||||
const sequelizeOptions = { transaction: t }
|
||||
|
||||
const videoCreated = await video.save(sequelizeOptions)
|
||||
|
@ -266,15 +268,23 @@ async function addVideo (req: express.Request, res: express.Response) {
|
|||
}, { transaction: t })
|
||||
}
|
||||
|
||||
await federateVideoIfNeeded(video, true, t)
|
||||
const videoWasAutoBlacklisted = await autoBlacklistVideoIfNeeded(video, res.locals.oauth.token.User, t)
|
||||
|
||||
if (!videoWasAutoBlacklisted) {
|
||||
await federateVideoIfNeeded(video, true, t)
|
||||
}
|
||||
|
||||
auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON()))
|
||||
logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
|
||||
|
||||
return videoCreated
|
||||
return { videoCreated, videoWasAutoBlacklisted }
|
||||
})
|
||||
|
||||
Notifier.Instance.notifyOnNewVideo(videoCreated)
|
||||
if (videoWasAutoBlacklisted) {
|
||||
Notifier.Instance.notifyOnVideoAutoBlacklist(videoCreated)
|
||||
} else {
|
||||
Notifier.Instance.notifyOnNewVideo(videoCreated)
|
||||
}
|
||||
|
||||
if (video.state === VideoState.TO_TRANSCODE) {
|
||||
// Put uuid because we don't have id auto incremented for now
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue