mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-26 22:46:37 -04:00
New: Lidarr to Readarr
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Crypto;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Backup;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.System.Backup
|
||||
{
|
||||
public class BackupModule : ReadarrRestModule<BackupResource>
|
||||
{
|
||||
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 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()
|
||||
{
|
||||
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,
|
||||
Time = b.Time
|
||||
})
|
||||
.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 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
|
||||
};
|
||||
}
|
||||
|
||||
public object 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, $"readarr_backup_restore{extension}");
|
||||
|
||||
_diskProvider.SaveStream(file.Value, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using NzbDrone.Core.Backup;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.System.Backup
|
||||
{
|
||||
public class BackupResource : RestResource
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Path { get; set; }
|
||||
public BackupType Type { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System.Threading.Tasks;
|
||||
using Nancy.Routing;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
|
||||
namespace Readarr.Api.V1.System
|
||||
{
|
||||
public class SystemModule : ReadarrV1Module
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly IOsInfo _osInfo;
|
||||
private readonly IRouteCacheProvider _routeCacheProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IMainDatabase _database;
|
||||
private readonly ILifecycleService _lifecycleService;
|
||||
|
||||
public SystemModule(IAppFolderInfo appFolderInfo,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IPlatformInfo platformInfo,
|
||||
IOsInfo osInfo,
|
||||
IRouteCacheProvider routeCacheProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IMainDatabase database,
|
||||
ILifecycleService lifecycleService)
|
||||
: base("system")
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_platformInfo = platformInfo;
|
||||
_osInfo = osInfo;
|
||||
_routeCacheProvider = routeCacheProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_database = database;
|
||||
_lifecycleService = lifecycleService;
|
||||
Get("/status", x => GetStatus());
|
||||
Get("/routes", x => GetRoutes());
|
||||
Post("/shutdown", x => Shutdown());
|
||||
Post("/restart", x => Restart());
|
||||
}
|
||||
|
||||
private object GetStatus()
|
||||
{
|
||||
return new
|
||||
{
|
||||
Version = BuildInfo.Version.ToString(),
|
||||
BuildTime = BuildInfo.BuildDateTime,
|
||||
IsDebug = BuildInfo.IsDebug,
|
||||
IsProduction = RuntimeInfo.IsProduction,
|
||||
IsAdmin = _runtimeInfo.IsAdmin,
|
||||
IsUserInteractive = RuntimeInfo.IsUserInteractive,
|
||||
StartupPath = _appFolderInfo.StartUpFolder,
|
||||
AppData = _appFolderInfo.GetAppDataPath(),
|
||||
OsName = _osInfo.Name,
|
||||
OsVersion = _osInfo.Version,
|
||||
IsNetCore = PlatformInfo.IsNetCore,
|
||||
IsMono = PlatformInfo.IsMono,
|
||||
IsLinux = OsInfo.IsLinux,
|
||||
IsOsx = OsInfo.IsOsx,
|
||||
IsWindows = OsInfo.IsWindows,
|
||||
IsDocker = _osInfo.IsDocker,
|
||||
Mode = _runtimeInfo.Mode,
|
||||
Branch = _configFileProvider.Branch,
|
||||
Authentication = _configFileProvider.AuthenticationMethod,
|
||||
SqliteVersion = _database.Version,
|
||||
MigrationVersion = _database.Migration,
|
||||
UrlBase = _configFileProvider.UrlBase,
|
||||
RuntimeVersion = _platformInfo.Version,
|
||||
RuntimeName = PlatformInfo.Platform,
|
||||
StartTime = _runtimeInfo.StartTime
|
||||
};
|
||||
}
|
||||
|
||||
private object GetRoutes()
|
||||
{
|
||||
return _routeCacheProvider.GetCache().Values;
|
||||
}
|
||||
|
||||
private object Shutdown()
|
||||
{
|
||||
Task.Factory.StartNew(() => _lifecycleService.Shutdown());
|
||||
return new { ShuttingDown = true };
|
||||
}
|
||||
|
||||
private object Restart()
|
||||
{
|
||||
Task.Factory.StartNew(() => _lifecycleService.Restart());
|
||||
return new { Restarting = true };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.Jobs;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.SignalR;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.System.Tasks
|
||||
{
|
||||
public class TaskModule : ReadarrRestModuleWithSignalR<TaskResource, ScheduledTask>, IHandle<CommandExecutedEvent>
|
||||
{
|
||||
private readonly ITaskManager _taskManager;
|
||||
|
||||
public TaskModule(ITaskManager taskManager, IBroadcastSignalRMessage broadcastSignalRMessage)
|
||||
: base(broadcastSignalRMessage, "system/task")
|
||||
{
|
||||
_taskManager = taskManager;
|
||||
GetResourceAll = GetAll;
|
||||
GetResourceById = GetTask;
|
||||
}
|
||||
|
||||
private List<TaskResource> GetAll()
|
||||
{
|
||||
return _taskManager.GetAll()
|
||||
.Select(ConvertToResource)
|
||||
.OrderBy(t => t.Name)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private TaskResource GetTask(int id)
|
||||
{
|
||||
var task = _taskManager.GetAll()
|
||||
.SingleOrDefault(t => t.Id == id);
|
||||
|
||||
if (task == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ConvertToResource(task);
|
||||
}
|
||||
|
||||
private static TaskResource ConvertToResource(ScheduledTask scheduledTask)
|
||||
{
|
||||
var taskName = scheduledTask.TypeName.Split('.').Last().Replace("Command", "");
|
||||
|
||||
return new TaskResource
|
||||
{
|
||||
Id = scheduledTask.Id,
|
||||
Name = taskName.SplitCamelCase(),
|
||||
TaskName = taskName,
|
||||
Interval = scheduledTask.Interval,
|
||||
LastExecution = scheduledTask.LastExecution,
|
||||
LastStartTime = scheduledTask.LastStartTime,
|
||||
NextExecution = scheduledTask.LastExecution.AddMinutes(scheduledTask.Interval)
|
||||
};
|
||||
}
|
||||
|
||||
public void Handle(CommandExecutedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Readarr.Http.REST;
|
||||
|
||||
namespace Readarr.Api.V1.System.Tasks
|
||||
{
|
||||
public class TaskResource : RestResource
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string TaskName { get; set; }
|
||||
public int Interval { get; set; }
|
||||
public DateTime LastExecution { get; set; }
|
||||
public DateTime LastStartTime { get; set; }
|
||||
public DateTime NextExecution { get; set; }
|
||||
|
||||
public TimeSpan LastDuration => LastExecution - LastStartTime;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user