mirror of https://github.com/Sonarr/Sonarr
New: Disable backup downloads
This commit is contained in:
parent
8a7b67c593
commit
da59d63bd1
|
@ -2,7 +2,6 @@ import PropTypes from 'prop-types';
|
|||
import React, { Component } from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Link from 'Components/Link/Link';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
|
@ -65,7 +64,6 @@ class BackupRow extends Component {
|
|||
id,
|
||||
type,
|
||||
name,
|
||||
path,
|
||||
size,
|
||||
time
|
||||
} = this.props;
|
||||
|
@ -98,12 +96,7 @@ class BackupRow extends Component {
|
|||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
<Link
|
||||
to={`${window.Sonarr.urlBase}${path}`}
|
||||
noRouter={true}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
{name}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
|
@ -155,7 +148,6 @@ BackupRow.propTypes = {
|
|||
id: PropTypes.number.isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
size: PropTypes.number.isRequired,
|
||||
time: PropTypes.string.isRequired,
|
||||
onDeleteBackupPress: PropTypes.func.isRequired
|
||||
|
|
|
@ -73,6 +73,7 @@ class Backups extends Component {
|
|||
isPopulated,
|
||||
error,
|
||||
items,
|
||||
location,
|
||||
backupExecuting,
|
||||
onBackupPress,
|
||||
onDeleteBackupPress
|
||||
|
@ -101,6 +102,12 @@ class Backups extends Component {
|
|||
</PageToolbar>
|
||||
|
||||
<PageContentBody>
|
||||
<Alert>
|
||||
{translate('BackupFilesLocation', {
|
||||
location
|
||||
})}
|
||||
</Alert>
|
||||
|
||||
{
|
||||
isFetching && !isPopulated &&
|
||||
<LoadingIndicator />
|
||||
|
@ -115,7 +122,7 @@ class Backups extends Component {
|
|||
|
||||
{
|
||||
noBackups &&
|
||||
<Alert kind={kinds.INFO}>
|
||||
<Alert kind={kinds.WARNING}>
|
||||
{translate('NoBackupsAreAvailable')}
|
||||
</Alert>
|
||||
}
|
||||
|
@ -132,7 +139,6 @@ class Backups extends Component {
|
|||
id,
|
||||
type,
|
||||
name,
|
||||
path,
|
||||
size,
|
||||
time
|
||||
} = item;
|
||||
|
@ -143,7 +149,6 @@ class Backups extends Component {
|
|||
id={id}
|
||||
type={type}
|
||||
name={name}
|
||||
path={path}
|
||||
size={size}
|
||||
time={time}
|
||||
onDeleteBackupPress={onDeleteBackupPress}
|
||||
|
@ -171,6 +176,7 @@ Backups.propTypes = {
|
|||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
items: PropTypes.array.isRequired,
|
||||
location: PropTypes.string.isRequired,
|
||||
backupExecuting: PropTypes.bool.isRequired,
|
||||
onBackupPress: PropTypes.func.isRequired,
|
||||
onDeleteBackupPress: PropTypes.func.isRequired
|
||||
|
|
|
@ -11,21 +11,24 @@ import Backups from './Backups';
|
|||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.system.backups,
|
||||
(state) => state.system.status.item,
|
||||
createCommandExecutingSelector(commandNames.BACKUP),
|
||||
(backups, backupExecuting) => {
|
||||
(backups, status, backupExecuting) => {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items
|
||||
} = backups;
|
||||
const { backupFolder } = status;
|
||||
|
||||
return {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items,
|
||||
backupExecuting
|
||||
backupExecuting,
|
||||
location: backupFolder
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
|
@ -4,18 +4,7 @@ namespace NzbDrone.Core.Backup
|
|||
{
|
||||
public class BackupCommand : Command
|
||||
{
|
||||
public BackupType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Trigger == CommandTrigger.Scheduled)
|
||||
{
|
||||
return BackupType.Scheduled;
|
||||
}
|
||||
|
||||
return BackupType.Manual;
|
||||
}
|
||||
}
|
||||
public BackupType Type => Trigger == CommandTrigger.Scheduled ? BackupType.Scheduled : BackupType.Manual;
|
||||
|
||||
public override bool SendUpdatesToClient => true;
|
||||
|
||||
|
|
|
@ -105,12 +105,12 @@ namespace NzbDrone.Core.Backup
|
|||
if (_diskProvider.FolderExists(folder))
|
||||
{
|
||||
backups.AddRange(GetBackupFiles(folder).Select(b => new Backup
|
||||
{
|
||||
Name = Path.GetFileName(b),
|
||||
Type = backupType,
|
||||
Size = _diskProvider.GetFileSize(b),
|
||||
Time = _diskProvider.FileGetLastWrite(b)
|
||||
}));
|
||||
{
|
||||
Name = Path.GetFileName(b),
|
||||
Type = backupType,
|
||||
Size = _diskProvider.GetFileSize(b),
|
||||
Time = _diskProvider.FileGetLastWrite(b)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@
|
|||
"AutomaticSearch": "Automatic Search",
|
||||
"AutomaticUpdatesDisabledDocker": "Automatic updates are not directly supported when using the Docker update mechanism. You will need to update the container image outside of {appName} or use a script",
|
||||
"Backup": "Backup",
|
||||
"BackupFilesLocation": "Backup files are located in: {location}",
|
||||
"BackupFolderHelpText": "Relative paths will be under {appName}'s AppData directory",
|
||||
"BackupIntervalHelpText": "Interval between automatic backups",
|
||||
"BackupNow": "Backup Now",
|
||||
|
@ -248,8 +249,8 @@
|
|||
"ConnectionLost": "Connection Lost",
|
||||
"ConnectionLostReconnect": "{appName} will try to connect automatically, or you can click reload below.",
|
||||
"ConnectionLostToBackend": "{appName} has lost its connection to the backend and will need to be reloaded to restore functionality.",
|
||||
"Connections": "Connections",
|
||||
"ConnectionSettingsUrlBaseHelpText": "Adds a prefix to the {connectionName} url, such as {url}",
|
||||
"Connections": "Connections",
|
||||
"Continuing": "Continuing",
|
||||
"ContinuingOnly": "Continuing Only",
|
||||
"ContinuingSeriesDescription": "More episodes/another season is expected",
|
||||
|
@ -280,8 +281,8 @@
|
|||
"CustomFormats": "Custom Formats",
|
||||
"CustomFormatsLoadError": "Unable to load Custom Formats",
|
||||
"CustomFormatsSettings": "Custom Formats Settings",
|
||||
"CustomFormatsSettingsTriggerInfo": "A Custom Format will be applied to a release or file when it matches at least one of each of the different condition types chosen.",
|
||||
"CustomFormatsSettingsSummary": "Custom Formats and Settings",
|
||||
"CustomFormatsSettingsTriggerInfo": "A Custom Format will be applied to a release or file when it matches at least one of each of the different condition types chosen.",
|
||||
"CustomFormatsSpecificationFlag": "Flag",
|
||||
"CustomFormatsSpecificationLanguage": "Language",
|
||||
"CustomFormatsSpecificationMaximumSize": "Maximum Size",
|
||||
|
@ -410,16 +411,16 @@
|
|||
"DownloadClientAriaSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Aria2 location",
|
||||
"DownloadClientCheckNoneAvailableHealthCheckMessage": "No download client is available",
|
||||
"DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "Unable to communicate with {downloadClientName}. {errorMessage}",
|
||||
"DownloadClientDelugeSettingsDirectory": "Download Directory",
|
||||
"DownloadClientDelugeSettingsDirectoryCompleted": "Move When Completed Directory",
|
||||
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optional location to move completed downloads to, leave blank to use the default Deluge location",
|
||||
"DownloadClientDelugeSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Deluge location",
|
||||
"DownloadClientDelugeSettingsUrlBaseHelpText": "Adds a prefix to the deluge json url, see {url}",
|
||||
"DownloadClientDelugeTorrentStateError": "Deluge is reporting an error",
|
||||
"DownloadClientDelugeValidationLabelPluginFailure": "Configuration of label failed",
|
||||
"DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} was unable to add the label to {clientName}.",
|
||||
"DownloadClientDelugeValidationLabelPluginInactive": "Label plugin not activated",
|
||||
"DownloadClientDelugeValidationLabelPluginInactiveDetail": "You must have the Label plugin enabled in {clientName} to use categories.",
|
||||
"DownloadClientDelugeSettingsDirectory": "Download Directory",
|
||||
"DownloadClientDelugeSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Deluge location",
|
||||
"DownloadClientDelugeSettingsDirectoryCompleted": "Move When Completed Directory",
|
||||
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optional location to move completed downloads to, leave blank to use the default Deluge location",
|
||||
"DownloadClientDownloadStationProviderMessage": "{appName} is unable to connect to Download Station if 2-Factor Authentication is enabled on your DSM account",
|
||||
"DownloadClientDownloadStationSettingsDirectoryHelpText": "Optional shared folder to put downloads into, leave blank to use the default Download Station location",
|
||||
"DownloadClientDownloadStationValidationApiVersion": "Download Station API version not supported, should be at least {requiredVersion}. It supports from {minVersion} to {maxVersion}",
|
||||
|
@ -866,12 +867,12 @@
|
|||
"ImportListsSimklSettingsUserListTypePlanToWatch": "Plan To Watch",
|
||||
"ImportListsSimklSettingsUserListTypeWatching": "Watching",
|
||||
"ImportListsSonarrSettingsApiKeyHelpText": "API Key of the {appName} instance to import from",
|
||||
"ImportListsSonarrSettingsSyncSeasonMonitoring": "Sync Season Monitoring",
|
||||
"ImportListsSonarrSettingsSyncSeasonMonitoringHelpText": "Sync season monitoring from {appName} instance, if enabled 'Monitor' will be ignored",
|
||||
"ImportListsSonarrSettingsFullUrl": "Full URL",
|
||||
"ImportListsSonarrSettingsFullUrlHelpText": "URL, including port, of the {appName} instance to import from",
|
||||
"ImportListsSonarrSettingsQualityProfilesHelpText": "Quality Profiles from the source instance to import from",
|
||||
"ImportListsSonarrSettingsRootFoldersHelpText": "Root Folders from the source instance to import from",
|
||||
"ImportListsSonarrSettingsSyncSeasonMonitoring": "Sync Season Monitoring",
|
||||
"ImportListsSonarrSettingsSyncSeasonMonitoringHelpText": "Sync season monitoring from {appName} instance, if enabled 'Monitor' will be ignored",
|
||||
"ImportListsSonarrSettingsTagsHelpText": "Tags from the source instance to import from",
|
||||
"ImportListsSonarrValidationInvalidUrl": "{appName} URL is invalid, are you missing a URL base?",
|
||||
"ImportListsTraktSettingsAdditionalParameters": "Additional Parameters",
|
||||
|
@ -1787,7 +1788,6 @@
|
|||
"SelectSeries": "Select Series",
|
||||
"SendAnonymousUsageData": "Send Anonymous Usage Data",
|
||||
"Series": "Series",
|
||||
"SeriesFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Series Title:30}`) or the beginning (e.g. `{Series Title:-30}`) are both supported.",
|
||||
"SeriesAndEpisodeInformationIsProvidedByTheTVDB": "Series and episode information is provided by TheTVDB.com. [Please consider supporting them]({url}) .",
|
||||
"SeriesCannotBeFound": "Sorry, that series cannot be found.",
|
||||
"SeriesDetailsCountEpisodeFiles": "{episodeFileCount} episode files",
|
||||
|
@ -1801,6 +1801,7 @@
|
|||
"SeriesFolderFormat": "Series Folder Format",
|
||||
"SeriesFolderFormatHelpText": "Used when adding a new series or moving series via the series editor",
|
||||
"SeriesFolderImportedTooltip": "Episode imported from series folder",
|
||||
"SeriesFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Series Title:30}`) or the beginning (e.g. `{Series Title:-30}`) are both supported.",
|
||||
"SeriesID": "Series ID",
|
||||
"SeriesIndexFooterContinuing": "Continuing (All episodes downloaded)",
|
||||
"SeriesIndexFooterDownloading": "Downloading (One or more episodes)",
|
||||
|
|
|
@ -40,7 +40,6 @@ namespace Sonarr.Api.V3.System.Backup
|
|||
{
|
||||
Id = GetBackupId(b),
|
||||
Name = b.Name,
|
||||
Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}",
|
||||
Size = b.Size,
|
||||
Type = b.Type,
|
||||
Time = b.Time
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace Sonarr.Api.V3.System.Backup
|
|||
public class BackupResource : RestResource
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Path { get; set; }
|
||||
public BackupType Type { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
|
|
|
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Routing;
|
|||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Backup;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
|
@ -27,6 +28,7 @@ namespace Sonarr.Api.V3.System
|
|||
private readonly EndpointDataSource _endpointData;
|
||||
private readonly DfaGraphWriter _graphWriter;
|
||||
private readonly DuplicateEndpointDetector _detector;
|
||||
private readonly IBackupService _backupService;
|
||||
|
||||
public SystemController(IAppFolderInfo appFolderInfo,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
|
@ -38,7 +40,8 @@ namespace Sonarr.Api.V3.System
|
|||
IDeploymentInfoProvider deploymentInfoProvider,
|
||||
EndpointDataSource endpoints,
|
||||
DfaGraphWriter graphWriter,
|
||||
DuplicateEndpointDetector detector)
|
||||
DuplicateEndpointDetector detector,
|
||||
IBackupService backupService)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
|
@ -51,6 +54,7 @@ namespace Sonarr.Api.V3.System
|
|||
_endpointData = endpoints;
|
||||
_graphWriter = graphWriter;
|
||||
_detector = detector;
|
||||
_backupService = backupService;
|
||||
}
|
||||
|
||||
[HttpGet("status")]
|
||||
|
@ -69,6 +73,7 @@ namespace Sonarr.Api.V3.System
|
|||
IsUserInteractive = RuntimeInfo.IsUserInteractive,
|
||||
StartupPath = _appFolderInfo.StartUpFolder,
|
||||
AppData = _appFolderInfo.GetAppDataPath(),
|
||||
BackupFolder = _backupService.GetBackupFolder(),
|
||||
OsName = _osInfo.Name,
|
||||
OsVersion = _osInfo.Version,
|
||||
IsNetCore = true,
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Sonarr.Api.V3.System
|
|||
public bool IsUserInteractive { get; set; }
|
||||
public string StartupPath { get; set; }
|
||||
public string AppData { get; set; }
|
||||
public string BackupFolder { get; set; }
|
||||
public string OsName { get; set; }
|
||||
public string OsVersion { get; set; }
|
||||
public bool IsNetCore { get; set; }
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Backup;
|
||||
|
||||
namespace Sonarr.Http.Frontend.Mappers
|
||||
{
|
||||
public class BackupFileMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IBackupService _backupService;
|
||||
|
||||
public BackupFileMapper(IBackupService backupService, IDiskProvider diskProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_backupService = backupService;
|
||||
}
|
||||
|
||||
public override string Map(string resourceUrl)
|
||||
{
|
||||
var path = resourceUrl.Replace("/backup/", "").Replace('/', Path.DirectorySeparatorChar);
|
||||
|
||||
return Path.Combine(_backupService.GetBackupFolder(), path);
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
{
|
||||
return resourceUrl.StartsWith("/backup/") && BackupService.BackupFileRegex.IsMatch(resourceUrl);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue