Correctly notify on auto blacklist
authorChocobozzz <me@florianbigard.com>
Tue, 23 Jul 2019 10:04:15 +0000 (12:04 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Wed, 24 Jul 2019 08:58:16 +0000 (10:58 +0200)
15 files changed:
scripts/optimize-old-videos.ts
server/controllers/api/videos/blacklist.ts
server/controllers/api/videos/import.ts
server/controllers/api/videos/index.ts
server/helpers/custom-validators/video-channels.ts
server/lib/activitypub/process/process-announce.ts
server/lib/activitypub/process/process-create.ts
server/lib/activitypub/videos.ts
server/lib/job-queue/handlers/video-import.ts
server/lib/job-queue/handlers/video-transcoding.ts
server/lib/notifier.ts
server/lib/schedulers/update-videos-scheduler.ts
server/lib/video-blacklist.ts
server/models/video/video.ts
server/tests/cli/optimize-old-videos.ts

index a1d5345a1164a668ccaded484c407faf9dfdbc25..2c80f16bcf35e40384278b69d9f04d67e8a481b5 100644 (file)
@@ -32,6 +32,7 @@ async function run () {
 
   for (const video of localVideos) {
     currentVideoId = video.id
+
     for (const file of video.VideoFiles) {
       currentFile = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(file))
 
@@ -44,22 +45,29 @@ async function run () {
       const maxBitrate = getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)
       const isMaxBitrateExceeded = videoBitrate > maxBitrate
       if (isMaxBitrateExceeded) {
-        console.log('Optimizing video file %s with bitrate %s kbps (max: %s kbps)',
-          basename(currentFile), videoBitrate / 1000, maxBitrate / 1000)
+        console.log(
+          'Optimizing video file %s with bitrate %s kbps (max: %s kbps)',
+          basename(currentFile), videoBitrate / 1000, maxBitrate / 1000
+        )
+
         const backupFile = `${currentFile}_backup`
         await copy(currentFile, backupFile)
+
         await optimizeVideofile(video, file)
+
         const originalDuration = await getDurationFromVideoFile(backupFile)
         const newDuration = await getDurationFromVideoFile(currentFile)
+
         if (originalDuration === newDuration) {
           console.log('Finished optimizing %s', basename(currentFile))
           await remove(backupFile)
-        } else {
-          console.log('Failed to optimize %s, restoring original', basename(currentFile))
-          move(backupFile, currentFile, { overwrite: true })
-          await video.createTorrentAndSetInfoHash(file)
-          await file.save()
+          return
         }
+
+        console.log('Failed to optimize %s, restoring original', basename(currentFile))
+        await move(backupFile, currentFile, { overwrite: true })
+        await video.createTorrentAndSetInfoHash(file)
+        await file.save()
       }
     }
   }
index 0ec518e0d629505908e06572483ce6ccd299cda1..9ff494defbd74746ad8a551190d7db245f4b87ce 100644 (file)
@@ -115,6 +115,7 @@ async function removeVideoFromBlacklistController (req: express.Request, res: ex
     const videoBlacklistType = videoBlacklist.type
 
     await videoBlacklist.destroy({ transaction: t })
+    video.VideoBlacklist = undefined
 
     // Re federate the video
     if (unfederated === true) {
@@ -131,7 +132,7 @@ async function removeVideoFromBlacklistController (req: express.Request, res: ex
 
     // Delete on object so new video notifications will send
     delete video.VideoBlacklist
-    Notifier.Instance.notifyOnNewVideo(video)
+    Notifier.Instance.notifyOnNewVideoIfNeeded(video)
   }
 
   logger.info('Video %s removed from blacklist.', res.locals.video.uuid)
index 47c6f122cf698cb81ea6b9fa80b1c1b8a29c4298..1f08fe20acbae488bf3c110ebb8828779d466011 100644 (file)
@@ -245,7 +245,14 @@ function insertIntoDB (parameters: {
     if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t)
     if (previewModel) await videoCreated.addAndSaveThumbnail(previewModel, t)
 
-    await autoBlacklistVideoIfNeeded({ video, user, isRemote: false, isNew: true, transaction: t })
+    await autoBlacklistVideoIfNeeded({
+      video,
+      user,
+      notify: false,
+      isRemote: false,
+      isNew: true,
+      transaction: t
+    })
 
     // Set tags to the video
     if (tags) {
index 6a79a16c78de709b6897fb84ee62c2422bb286c2..973bf1123e0a8bb0443a8e7e29865d335e0b25b0 100644 (file)
@@ -235,7 +235,7 @@ async function addVideo (req: express.Request, res: express.Response) {
   // Create the torrent file
   await video.createTorrentAndSetInfoHash(videoFile)
 
-  const { videoCreated, videoWasAutoBlacklisted } = await sequelizeTypescript.transaction(async t => {
+  const { videoCreated } = await sequelizeTypescript.transaction(async t => {
     const sequelizeOptions = { transaction: t }
 
     const videoCreated = await video.save(sequelizeOptions)
@@ -268,23 +268,22 @@ async function addVideo (req: express.Request, res: express.Response) {
       }, { transaction: t })
     }
 
-    const videoWasAutoBlacklisted = await autoBlacklistVideoIfNeeded({
+    await autoBlacklistVideoIfNeeded({
       video,
       user: res.locals.oauth.token.User,
       isRemote: false,
       isNew: true,
       transaction: t
     })
-    if (!videoWasAutoBlacklisted) await federateVideoIfNeeded(video, true, t)
+    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, videoWasAutoBlacklisted }
+    return { videoCreated }
   })
 
-  if (videoWasAutoBlacklisted) Notifier.Instance.notifyOnVideoAutoBlacklist(videoCreated)
-  else Notifier.Instance.notifyOnNewVideo(videoCreated)
+  Notifier.Instance.notifyOnNewVideoIfNeeded(videoCreated)
 
   if (video.state === VideoState.TO_TRANSCODE) {
     // Put uuid because we don't have id auto incremented for now
@@ -413,11 +412,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
       })
 
       const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE
-
-      // Don't send update if the video was unfederated
-      if (!videoInstanceUpdated.VideoBlacklist || videoInstanceUpdated.VideoBlacklist.unfederated === false) {
-        await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
-      }
+      await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
 
       auditLogger.update(
         getAuditIdFromRes(res),
@@ -430,7 +425,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
     })
 
     if (wasUnlistedVideo || wasPrivateVideo) {
-      Notifier.Instance.notifyOnNewVideo(videoInstanceUpdated)
+      Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated)
     }
 
     Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated })
index 0471f6ec4422c48ee374038b63738ff0e6dd13c7..f55f0c8ef12083fb423541734fc5650427e67200 100644 (file)
@@ -1,9 +1,7 @@
-import * as express from 'express'
 import 'express-validator'
 import 'multer'
 import * as validator from 'validator'
 import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
-import { VideoChannelModel } from '../../models/video/video-channel'
 import { exists } from './misc'
 
 const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS
@@ -25,18 +23,5 @@ function isVideoChannelSupportValid (value: string) {
 export {
   isVideoChannelDescriptionValid,
   isVideoChannelNameValid,
-  isVideoChannelSupportValid,
-}
-
-function processVideoChannelExist (videoChannel: VideoChannelModel, res: express.Response) {
-  if (!videoChannel) {
-    res.status(404)
-       .json({ error: 'Video channel not found' })
-       .end()
-
-    return false
-  }
-
-  res.locals.videoChannel = videoChannel
-  return true
+  isVideoChannelSupportValid
 }
index bbf1bd3a8f21ec9ac407ee6430745fcf26863a94..1fe347506c76128110cf84894ddbcce9a6add77f 100644 (file)
@@ -63,5 +63,5 @@ async function processVideoShare (actorAnnouncer: ActorModel, activity: Activity
     return undefined
   })
 
-  if (videoCreated) Notifier.Instance.notifyOnNewVideo(video)
+  if (videoCreated) Notifier.Instance.notifyOnNewVideoIfNeeded(video)
 }
index b9f584aa572572f36b81606aa21789ef5cc7f705..1e893cdebda534ebc7d08c929b1d59ca67a41a29 100644 (file)
@@ -48,9 +48,9 @@ export {
 async function processCreateVideo (activity: ActivityCreate) {
   const videoToCreateData = activity.object as VideoTorrentObject
 
-  const { video, created, autoBlacklisted } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData })
+  const { video, created } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData })
 
-  if (created && !autoBlacklisted) Notifier.Instance.notifyOnNewVideo(video)
+  if (created) Notifier.Instance.notifyOnNewVideoIfNeeded(video)
 
   return video
 }
index 67b433165b4c445735d26f45ff971aa078660c5a..d7bc3d65002003145d11045146fc094bb2c0242a 100644 (file)
@@ -58,8 +58,12 @@ import { Hooks } from '../plugins/hooks'
 import { autoBlacklistVideoIfNeeded } from '../video-blacklist'
 
 async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) {
-  // If the video is not private and is published, we federate it
-  if (video.privacy !== VideoPrivacy.PRIVATE && video.state === VideoState.PUBLISHED) {
+  if (
+    // Check this is not a blacklisted video, or unfederated blacklisted video
+    (video.isBlacklisted() === false || (isNewVideo === false && video.VideoBlacklist.unfederated === false)) &&
+    // Check the video is public/unlisted and published
+    video.privacy !== VideoPrivacy.PRIVATE && video.state === VideoState.PUBLISHED
+  ) {
     // Fetch more attributes that we will need to serialize in AP object
     if (isArray(video.VideoCaptions) === false) {
       video.VideoCaptions = await video.$get('VideoCaptions', {
@@ -354,7 +358,7 @@ async function updateVideoFromAP (options: {
       }
     })
 
-    const autoBlacklisted = await autoBlacklistVideoIfNeeded({
+    await autoBlacklistVideoIfNeeded({
       video,
       user: undefined,
       isRemote: true,
@@ -362,8 +366,7 @@ async function updateVideoFromAP (options: {
       transaction: undefined
     })
 
-    if (autoBlacklisted) Notifier.Instance.notifyOnVideoAutoBlacklist(video)
-    else if (!wasPrivateVideo || wasUnlistedVideo) Notifier.Instance.notifyOnNewVideo(video) // Notify our users?
+    if (wasPrivateVideo || wasUnlistedVideo) Notifier.Instance.notifyOnNewVideoIfNeeded(video) // Notify our users?
 
     logger.info('Remote video with uuid %s updated', videoObject.uuid)
   } catch (err) {
index 50e159245f0362f055eb045b0c4a0e5abbf5b1b8..13b741180daefdc15a8d400a0a4f3b2bf3d8d0b6 100644 (file)
@@ -199,10 +199,10 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
 
     Notifier.Instance.notifyOnFinishedVideoImport(videoImportUpdated, true)
 
-    if (videoImportUpdated.Video.VideoBlacklist) {
+    if (videoImportUpdated.Video.isBlacklisted()) {
       Notifier.Instance.notifyOnVideoAutoBlacklist(videoImportUpdated.Video)
     } else {
-      Notifier.Instance.notifyOnNewVideo(videoImportUpdated.Video)
+      Notifier.Instance.notifyOnNewVideoIfNeeded(videoImportUpdated.Video)
     }
 
     // Create transcoding jobs?
index e9b84ecd66722aec9bcdedb0655ba874ae4bd022..981daf9a1a5003e46ad920264fc0957b211dee99 100644 (file)
@@ -112,7 +112,7 @@ async function publishNewResolutionIfNeeded (video: VideoModel, payload?: NewRes
   })
 
   if (videoPublished) {
-    Notifier.Instance.notifyOnNewVideo(videoDatabase)
+    Notifier.Instance.notifyOnNewVideoIfNeeded(videoDatabase)
     Notifier.Instance.notifyOnVideoPublishedAfterTranscoding(videoDatabase)
   }
 
@@ -172,7 +172,7 @@ async function onVideoFileOptimizerSuccess (videoArg: VideoModel, payload: Optim
     return { videoDatabase, videoPublished }
   })
 
-  if (payload.isNewVideo) Notifier.Instance.notifyOnNewVideo(videoDatabase)
+  if (payload.isNewVideo) Notifier.Instance.notifyOnNewVideoIfNeeded(videoDatabase)
   if (videoPublished) Notifier.Instance.notifyOnVideoPublishedAfterTranscoding(videoDatabase)
 
   const hlsPayload = Object.assign({}, payload, { resolution: videoDatabase.getOriginalFile().resolution })
index c1e63fa8faad41de2f5cc3c67a27e257e46d255f..a7dfb09794017c1a14d64253a13c2f78d61672f6 100644 (file)
@@ -22,9 +22,9 @@ class Notifier {
 
   private constructor () {}
 
-  notifyOnNewVideo (video: VideoModel): void {
+  notifyOnNewVideoIfNeeded (video: VideoModel): void {
     // Only notify on public and published videos which are not blacklisted
-    if (video.privacy !== VideoPrivacy.PUBLIC || video.state !== VideoState.PUBLISHED || video.VideoBlacklist) return
+    if (video.privacy !== VideoPrivacy.PUBLIC || video.state !== VideoState.PUBLISHED || video.isBlacklisted()) return
 
     this.notifySubscribersOfNewVideo(video)
       .catch(err => logger.error('Cannot notify subscribers of new video %s.', video.url, { err }))
index 80080a132e8b3da3cd391b6b3518882ed134c9da..5b673b91321c0abb0edd22e5b53fedad6542f4c5 100644 (file)
@@ -57,7 +57,7 @@ export class UpdateVideosScheduler extends AbstractScheduler {
     })
 
     for (const v of publishedVideos) {
-      Notifier.Instance.notifyOnNewVideo(v)
+      Notifier.Instance.notifyOnNewVideoIfNeeded(v)
       Notifier.Instance.notifyOnVideoPublishedAfterScheduledUpdate(v)
     }
   }
index 1dd7139f76cc59f5440501bc2a67a522f435178a..bdaecd8e24bef5351c9a582e22b77691479c24e0 100644 (file)
@@ -7,15 +7,17 @@ import { VideoModel } from '../models/video/video'
 import { logger } from '../helpers/logger'
 import { UserAdminFlag } from '../../shared/models/users/user-flag.model'
 import { Hooks } from './plugins/hooks'
+import { Notifier } from './notifier'
 
 async function autoBlacklistVideoIfNeeded (parameters: {
   video: VideoModel,
   user?: UserModel,
   isRemote: boolean,
   isNew: boolean,
+  notify?: boolean,
   transaction?: Transaction
 }) {
-  const { video, user, isRemote, isNew, transaction } = parameters
+  const { video, user, isRemote, isNew, notify = true, transaction } = parameters
   const doAutoBlacklist = await Hooks.wrapPromiseFun(
     autoBlacklistNeeded,
     { video, user, isRemote, isNew },
@@ -37,9 +39,10 @@ async function autoBlacklistVideoIfNeeded (parameters: {
     defaults: videoBlacklistToCreate,
     transaction
   })
-
   video.VideoBlacklist = videoBlacklist
 
+  if (notify) Notifier.Instance.notifyOnVideoAutoBlacklist(video)
+
   logger.info('Video %s auto-blacklisted.', video.uuid)
 
   return true
index 443aec9c29655508da22c99252e300b3bee5f3d4..c7f2658edd27e4fedb1cdaa92bed4ec0d86b3cca 100644 (file)
@@ -1715,6 +1715,10 @@ export class VideoModel extends Model<VideoModel> {
     return VIDEO_STATES[ id ] || 'Unknown'
   }
 
+  isBlacklisted () {
+    return !!this.VideoBlacklist
+  }
+
   getOriginalFile () {
     if (Array.isArray(this.VideoFiles) === false) return undefined
 
index 3822fca42f05f5d80daf2377f2fdf58160df0f99..fa82f962cbda794104de050da77c00f7a2d8dc4e 100644 (file)
@@ -75,7 +75,7 @@ describe('Test optimize old videos', function () {
   })
 
   it('Should run optimize script', async function () {
-    this.timeout(120000)
+    this.timeout(200000)
 
     const env = getEnvCli(servers[0])
     await execCLI(`${env} npm run optimize-old-videos`)