You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/Lidarr.Api.V1/System/Backup/BackupController.cs

134 lines
3.8 KiB

using System.Collections.Generic;
using System.IO;
using System.Linq;
using Lidarr.Http;
using Lidarr.Http.REST;
using Lidarr.Http.REST.Attributes;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Crypto;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Backup;
namespace Lidarr.Api.V1.System.Backup
{
[V1ApiController("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 List<string> { ".zip", ".db", ".xml" };
public BackupController(IBackupService backupService,
IAppFolderInfo appFolderInfo,
IDiskProvider diskProvider)
{
_backupService = backupService;
_appFolderInfo = appFolderInfo;
_diskProvider = diskProvider;
}
[HttpGet]
public List<BackupResource> GetBackupFiles()
{
var backups = _backupService.GetBackups();
return backups.Select(b => new BackupResource
{
Id = GetBackupId(b),
Name = b.Name,
Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}",
Type = b.Type,
Size = b.Size,
Time = b.Time
})
.OrderByDescending(b => b.Time)
.ToList();
}
[RestDeleteById]
public void DeleteBackup(int id)
{
var backup = GetBackup(id);
var path = GetBackupPath(backup);
if (!_diskProvider.FileExists(path))
{
throw new NotFoundException();
}
_diskProvider.DeleteFile(path);
}
[HttpPost("restore/{id:int}")]
public object Restore(int id)
{
var backup = GetBackup(id);
if (backup == null)
{
throw new NotFoundException();
}
var path = GetBackupPath(backup);
_backupService.Restore(path);
return new
{
RestartRequired = true
};
}
[HttpPost("restore/upload")]
public object UploadAndRestore()
{
var files = Request.Form.Files;
if (files.Empty())
{
throw new BadRequestException("file must be provided");
}
var file = files[0];
var extension = Path.GetExtension(file.FileName);
if (!ValidExtensions.Contains(extension))
{
throw new UnsupportedMediaTypeException($"Invalid extension, must be one of: {ValidExtensions.Join(", ")}");
}
var path = Path.Combine(_appFolderInfo.TempFolder, $"lidarr_backup_restore{extension}");
_diskProvider.SaveStream(file.OpenReadStream(), path);
_backupService.Restore(path);
// Cleanup restored file
_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 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);
}
}
}