Remove HLS torrents
authorChocobozzz <me@florianbigard.com>
Fri, 24 Jan 2020 15:48:05 +0000 (16:48 +0100)
committerChocobozzz <me@florianbigard.com>
Fri, 24 Jan 2020 15:48:05 +0000 (16:48 +0100)
server/models/redundancy/video-redundancy.ts
server/models/video/video-streaming-playlist.ts
server/models/video/video.ts
server/tests/api/redundancy/redundancy.ts
server/tests/api/videos/multiple-servers.ts
shared/extra-utils/videos/videos.ts

index 77f83d8aa074df538ef557de708ef3c2b295cc2a..8c9a7eabf8fa1ba3148bf4a87a6ff7e85ba7e444 100644 (file)
@@ -160,7 +160,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
       const videoUUID = videoStreamingPlaylist.Video.uuid
       logger.info('Removing duplicated video streaming playlist %s.', videoUUID)
 
-      videoStreamingPlaylist.Video.removeStreamingPlaylist(true)
+      videoStreamingPlaylist.Video.removeStreamingPlaylistFiles(videoStreamingPlaylist, true)
                .catch(err => logger.error('Cannot delete video streaming playlist files of %s.', videoUUID, { err }))
     }
 
index 0099add4ef6b6a779bf1dece083d5ae39268ae7f..24959621803f8b270039d406f390687658834ef6 100644 (file)
@@ -17,10 +17,12 @@ import { join } from 'path'
 import { sha1 } from '../../helpers/core-utils'
 import { isArrayOf } from '../../helpers/custom-validators/misc'
 import { Op, QueryTypes } from 'sequelize'
-import { MStreamingPlaylist, MVideoFile } from '@server/typings/models'
+import { MStreamingPlaylist, MStreamingPlaylistVideo, MVideoFile } from '@server/typings/models'
 import { VideoFileModel } from '@server/models/video/video-file'
-import { getTorrentFileName, getVideoFilename } from '@server/lib/video-paths'
+import { getTorrentFileName, getTorrentFilePath, getVideoFilename } from '@server/lib/video-paths'
 import * as memoizee from 'memoizee'
+import { remove } from 'fs-extra'
+import { logger } from '@server/helpers/logger'
 
 @Table({
   tableName: 'videoStreamingPlaylist',
@@ -209,4 +211,10 @@ export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistMod
     return this.type === other.type &&
       this.videoId === other.videoId
   }
+
+  removeTorrent (this: MStreamingPlaylistVideo, videoFile: MVideoFile) {
+    const torrentPath = getTorrentFilePath(this, videoFile)
+    return remove(torrentPath)
+      .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err }))
+  }
 }
index 243871028a4a9526adc692befbbcb281d9cd0b0e..eacffe1864156d84d84e0cc2ee817c892cd354ae 100644 (file)
@@ -136,7 +136,8 @@ import {
   MVideoThumbnailBlacklist,
   MVideoWithAllFiles,
   MVideoWithFile,
-  MVideoWithRights
+  MVideoWithRights,
+  MStreamingPlaylistFiles
 } from '../../typings/models'
 import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file'
 import { MThumbnail } from '../../typings/models/video/thumbnail'
@@ -1071,7 +1072,13 @@ export class VideoModel extends Model<VideoModel> {
       })
 
       // Remove playlists file
-      tasks.push(instance.removeStreamingPlaylist())
+      if (!Array.isArray(instance.VideoStreamingPlaylists)) {
+        instance.VideoStreamingPlaylists = await instance.$get('VideoStreamingPlaylists')
+      }
+
+      for (const p of instance.VideoStreamingPlaylists) {
+        tasks.push(instance.removeStreamingPlaylistFiles(p))
+      }
     }
 
     // Do not wait video deletion because we could be in a transaction
@@ -2001,11 +2008,24 @@ export class VideoModel extends Model<VideoModel> {
       .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err }))
   }
 
-  removeStreamingPlaylist (isRedundancy = false) {
+  async removeStreamingPlaylistFiles (streamingPlaylist: MStreamingPlaylist, isRedundancy = false) {
     const directoryPath = getHLSDirectory(this, isRedundancy)
 
-    return remove(directoryPath)
-      .catch(err => logger.warn('Cannot delete playlist directory %s.', directoryPath, { err }))
+    await remove(directoryPath)
+
+    if (isRedundancy !== true) {
+      let streamingPlaylistWithFiles = streamingPlaylist as MStreamingPlaylistFilesVideo
+      streamingPlaylistWithFiles.Video = this
+
+      if (!Array.isArray(streamingPlaylistWithFiles.VideoFiles)) {
+        streamingPlaylistWithFiles.VideoFiles = await streamingPlaylistWithFiles.$get('VideoFiles')
+      }
+
+      // Remove physical files and torrents
+      await Promise.all(
+        streamingPlaylistWithFiles.VideoFiles.map(file => streamingPlaylistWithFiles.removeTorrent(file))
+      )
+    }
   }
 
   isOutdated () {
index be24eb32f710d518c9b5a836a87cd666435f91c2..1cdf93aa1996accb35dfdf7e39bdd18c59750547 100644 (file)
@@ -318,7 +318,7 @@ describe('Test videos redundancy', function () {
       await check1WebSeed()
       await check0PlaylistRedundancies()
 
-      await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos', join('playlists', 'hls') ])
+      await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ 'videos', join('playlists', 'hls') ])
     })
 
     after(async function () {
@@ -368,7 +368,7 @@ describe('Test videos redundancy', function () {
       await check1WebSeed()
       await check0PlaylistRedundancies()
 
-      await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ])
+      await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ 'videos' ])
     })
 
     after(async function () {
@@ -437,7 +437,7 @@ describe('Test videos redundancy', function () {
       await waitJobs(servers)
 
       for (const server of servers) {
-        await checkVideoFilesWereRemoved(video1Server2UUID, server.serverNumber)
+        await checkVideoFilesWereRemoved(video1Server2UUID, server.internalServerNumber)
       }
     })
 
@@ -572,7 +572,7 @@ describe('Test videos redundancy', function () {
 
       await waitJobs(servers)
 
-      await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ join('redundancy', 'hls') ])
+      await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ join('redundancy', 'hls') ])
     })
 
     after(async function () {
index 22d87b88cab763430fcf5ece141814374fc562e9..fa3e250ecbbb7227b3761c99dafd48864eb6d7ac 100644 (file)
@@ -15,7 +15,6 @@ import {
   createUser,
   dateIsValid,
   doubleFollow,
-  flushAndRunServer,
   flushAndRunMultipleServers,
   getLocalVideos,
   getVideo,
@@ -697,8 +696,8 @@ describe('Test multiple servers', function () {
 
     it('Should not have files of videos 3 and 3-2 on each server', async function () {
       for (const server of servers) {
-        await checkVideoFilesWereRemoved(toRemove[0].uuid, server.serverNumber)
-        await checkVideoFilesWereRemoved(toRemove[1].uuid, server.serverNumber)
+        await checkVideoFilesWereRemoved(toRemove[0].uuid, server.internalServerNumber)
+        await checkVideoFilesWereRemoved(toRemove[1].uuid, server.internalServerNumber)
       }
     })
 
index d1ac48292887fdb9b0edde0bac66572fe89a8ba9..7a77a03addcddf3f81de80b3c6914f2161493c13 100644 (file)
@@ -465,7 +465,7 @@ function rateVideo (url: string, accessToken: string, id: number, rating: string
 function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
   return new Promise<any>((res, rej) => {
     const torrentName = videoUUID + '-' + resolution + '.torrent'
-    const torrentPath = join(root(), 'test' + server.serverNumber, 'torrents', torrentName)
+    const torrentPath = join(root(), 'test' + server.internalServerNumber, 'torrents', torrentName)
     readFile(torrentPath, (err, data) => {
       if (err) return rej(err)