mirror of
https://github.com/Sonarr/Sonarr
synced 2025-12-06 08:28:37 +01:00
Add v5 backup endpoints
This commit is contained in:
parent
3091f40ca8
commit
29170f17d2
2 changed files with 146 additions and 0 deletions
133
src/Sonarr.Api.V5/System/Backup/BackupController.cs
Normal file
133
src/Sonarr.Api.V5/System/Backup/BackupController.cs
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Common.Crypto;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Backup;
|
||||
using Sonarr.Http;
|
||||
using Sonarr.Http.REST;
|
||||
using Sonarr.Http.REST.Attributes;
|
||||
|
||||
namespace Sonarr.Api.V5.System.Backup;
|
||||
|
||||
[V5ApiController("system/backup")]
|
||||
public class BackupController : Controller
|
||||
{
|
||||
private readonly IBackupService _backupService;
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
|
||||
private static readonly List<string> ValidExtensions = new() { ".zip", ".db", ".xml" };
|
||||
|
||||
public BackupController(IBackupService backupService,
|
||||
IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider)
|
||||
{
|
||||
_backupService = backupService;
|
||||
_appFolderInfo = appFolderInfo;
|
||||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public ActionResult<List<BackupResource>> GetAll()
|
||||
{
|
||||
var backups = _backupService.GetBackups();
|
||||
|
||||
var resources = backups.Select(backup => new BackupResource
|
||||
{
|
||||
Id = GetBackupId(backup),
|
||||
Name = backup.Name,
|
||||
Path = $"/backup/{backup.Type.ToString().ToLowerInvariant()}/{backup.Name}",
|
||||
Size = backup.Size,
|
||||
Type = backup.Type,
|
||||
Time = backup.Time
|
||||
})
|
||||
.OrderByDescending(b => b.Time)
|
||||
.ToList();
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
[RestDeleteById]
|
||||
public ActionResult Delete(int id)
|
||||
{
|
||||
var backup = GetBackupById(id);
|
||||
|
||||
if (backup == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var path = GetBackupPath(backup);
|
||||
|
||||
if (!_diskProvider.FileExists(path))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
_diskProvider.DeleteFile(path);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("restore/{id:int}")]
|
||||
[Produces("application/json")]
|
||||
public ActionResult<object> Restore([FromRoute] int id)
|
||||
{
|
||||
var backup = GetBackupById(id);
|
||||
|
||||
if (backup == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var path = GetBackupPath(backup);
|
||||
_backupService.Restore(path);
|
||||
|
||||
return new { RestartRequired = true };
|
||||
}
|
||||
|
||||
[HttpPost("restore/upload")]
|
||||
[Produces("application/json")]
|
||||
[RequestFormLimits(MultipartBodyLengthLimit = 5000000000)]
|
||||
public ActionResult<object> RestoreUpload()
|
||||
{
|
||||
var files = Request.Form.Files;
|
||||
|
||||
if (files.Count == 0)
|
||||
{
|
||||
throw new BadRequestException("file must be provided");
|
||||
}
|
||||
|
||||
var file = files[0];
|
||||
var extension = Path.GetExtension(file.FileName);
|
||||
|
||||
if (!ValidExtensions.Contains(extension))
|
||||
{
|
||||
return BadRequest(new { error = $"Invalid extension, must be one of: {string.Join(", ", ValidExtensions)}" });
|
||||
}
|
||||
|
||||
var path = Path.Combine(_appFolderInfo.TempFolder, $"sonarr_backup_restore{extension}");
|
||||
|
||||
_diskProvider.SaveStream(file.OpenReadStream(), path);
|
||||
_backupService.Restore(path);
|
||||
_diskProvider.DeleteFile(path);
|
||||
|
||||
return new { RestartRequired = true };
|
||||
}
|
||||
|
||||
private string GetBackupPath(NzbDrone.Core.Backup.Backup backup)
|
||||
{
|
||||
return Path.Combine(_backupService.GetBackupFolder(backup.Type), backup.Name);
|
||||
}
|
||||
|
||||
private static int GetBackupId(NzbDrone.Core.Backup.Backup backup)
|
||||
{
|
||||
return HashConverter.GetHashInt31($"backup-{backup.Type}-{backup.Name}");
|
||||
}
|
||||
|
||||
private NzbDrone.Core.Backup.Backup? GetBackupById(int id)
|
||||
{
|
||||
return _backupService.GetBackups().SingleOrDefault(b => GetBackupId(b) == id);
|
||||
}
|
||||
}
|
||||
13
src/Sonarr.Api.V5/System/Backup/BackupResource.cs
Normal file
13
src/Sonarr.Api.V5/System/Backup/BackupResource.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using NzbDrone.Core.Backup;
|
||||
using Sonarr.Http.REST;
|
||||
|
||||
namespace Sonarr.Api.V5.System.Backup;
|
||||
|
||||
public class BackupResource : RestResource
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required string Path { get; set; }
|
||||
public BackupType Type { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
Loading…
Reference in a new issue