@ -1,19 +1,39 @@
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using Nancy ;
using NzbDrone.Common.Crypto ;
using NzbDrone.Common.Disk ;
using NzbDrone.Common.EnvironmentInfo ;
using NzbDrone.Common.Extensions ;
using NzbDrone.Core.Backup ;
using Radarr.Http ;
using Radarr.Http.Extensions ;
using Radarr.Http.REST ;
namespace Radarr.Api.V2.System.Backup
{
public class BackupModule : RadarrRestModule < BackupResource >
{
private readonly IBackupService _backupService ;
private readonly IAppFolderInfo _appFolderInfo ;
private readonly IDiskProvider _diskProvider ;
public BackupModule ( IBackupService backupService ) : base ( "system/backup" )
private static readonly List < string > ValidExtensions = new List < string > { ".zip" , ".db" , ".xml" } ;
public BackupModule ( IBackupService backupService ,
IAppFolderInfo appFolderInfo ,
IDiskProvider diskProvider )
: base ( "system/backup" )
{
_backupService = backupService ;
_appFolderInfo = appFolderInfo ;
_diskProvider = diskProvider ;
GetResourceAll = GetBackupFiles ;
DeleteResource = DeleteBackup ;
Post [ @"/restore/(?<id>[\d]{1,10})" ] = x = > Restore ( ( int ) x . Id ) ;
Post [ "/restore/upload" ] = x = > UploadAndRestore ( ) ;
}
public List < BackupResource > GetBackupFiles ( )
@ -22,12 +42,92 @@ namespace Radarr.Api.V2.System.Backup
return backups . Select ( b = > new BackupResource
{
Id = b. Name . GetHashCode ( ) ,
Id = GetBackupId( b ) ,
Name = b . Name ,
Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}" ,
Type = b . Type ,
Time = b . Time
} ) . ToList ( ) ;
} )
. OrderByDescending ( b = > b . Time )
. ToList ( ) ;
}
private void DeleteBackup ( int id )
{
var backup = GetBackup ( id ) ;
var path = GetBackupPath ( backup ) ;
if ( ! _diskProvider . FileExists ( path ) )
{
throw new NotFoundException ( ) ;
}
_diskProvider . DeleteFile ( path ) ;
}
public Response Restore ( int id )
{
var backup = GetBackup ( id ) ;
if ( backup = = null )
{
throw new NotFoundException ( ) ;
}
var path = GetBackupPath ( backup ) ;
_backupService . Restore ( path ) ;
return new
{
RestartRequired = true
} . AsResponse ( ) ;
}
public Response UploadAndRestore ( )
{
var files = Context . Request . Files . ToList ( ) ;
if ( files . Empty ( ) )
{
throw new BadRequestException ( "file must be provided" ) ;
}
var file = files . First ( ) ;
var extension = Path . GetExtension ( file . Name ) ;
if ( ! ValidExtensions . Contains ( extension ) )
{
throw new UnsupportedMediaTypeException ( $"Invalid extension, must be one of: {ValidExtensions.Join(" , ")}" ) ;
}
var path = Path . Combine ( _appFolderInfo . TempFolder , $"radarr_backup_restore{extension}" ) ;
_diskProvider . SaveStream ( file . Value , path ) ;
_backupService . Restore ( path ) ;
// Cleanup restored file
_diskProvider . DeleteFile ( path ) ;
return new
{
RestartRequired = true
} . AsResponse ( ) ;
}
private string GetBackupPath ( NzbDrone . Core . Backup . Backup backup )
{
return Path . Combine ( _backupService . GetBackupFolder ( backup . Type ) , backup . Name ) ;
}
private int GetBackupId ( NzbDrone . Core . Backup . Backup backup )
{
return HashConverter . GetHashInt31 ( $"backup-{backup.Type}-{backup.Name}" ) ;
}
private NzbDrone . Core . Backup . Backup GetBackup ( int id )
{
return _backupService . GetBackups ( ) . SingleOrDefault ( b = > GetBackupId ( b ) = = id ) ;
}
}
}