New: Command line arguments for Custom Scripts are no longer supported

pull/6/head
Mark McDowall 6 years ago committed by ta264
parent b8b8f064c7
commit b9d240924f

@ -2,13 +2,13 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { fetchDevices, clearDevices } from 'Store/Actions/deviceActions'; import { fetchOptions, clearOptions } from 'Store/Actions/providerOptionActions';
import DeviceInput from './DeviceInput'; import DeviceInput from './DeviceInput';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state, { value }) => value, (state, { value }) => value,
(state) => state.devices, (state) => state.providerOptions,
(value, devices) => { (value, devices) => {
return { return {
@ -37,8 +37,8 @@ function createMapStateToProps() {
} }
const mapDispatchToProps = { const mapDispatchToProps = {
dispatchFetchDevices: fetchDevices, dispatchFetchOptions: fetchOptions,
dispatchClearDevices: clearDevices dispatchClearOptions: clearOptions
}; };
class DeviceInputConnector extends Component { class DeviceInputConnector extends Component {
@ -51,7 +51,7 @@ class DeviceInputConnector extends Component {
} }
componentWillUnmount = () => { componentWillUnmount = () => {
// this.props.dispatchClearDevices(); this.props.dispatchClearOptions();
} }
// //
@ -61,10 +61,14 @@ class DeviceInputConnector extends Component {
const { const {
provider, provider,
providerData, providerData,
dispatchFetchDevices dispatchFetchOptions
} = this.props; } = this.props;
dispatchFetchDevices({ provider, providerData }); dispatchFetchOptions({
action: 'getDevices',
provider,
providerData
});
} }
// //
@ -92,8 +96,8 @@ DeviceInputConnector.propTypes = {
providerData: PropTypes.object.isRequired, providerData: PropTypes.object.isRequired,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
dispatchFetchDevices: PropTypes.func.isRequired, dispatchFetchOptions: PropTypes.func.isRequired,
dispatchClearDevices: PropTypes.func.isRequired dispatchClearOptions: PropTypes.func.isRequired
}; };
export default connect(createMapStateToProps, mapDispatchToProps)(DeviceInputConnector); export default connect(createMapStateToProps, mapDispatchToProps)(DeviceInputConnector);

@ -20,7 +20,7 @@ function getType(type) {
return inputTypes.NUMBER; return inputTypes.NUMBER;
case 'path': case 'path':
return inputTypes.PATH; return inputTypes.PATH;
case 'filepath': case 'filePath':
return inputTypes.PATH; return inputTypes.PATH;
case 'select': case 'select':
return inputTypes.SELECT; return inputTypes.SELECT;
@ -60,6 +60,7 @@ function ProviderFieldFormGroup(props) {
value, value,
type, type,
advanced, advanced,
hidden,
pending, pending,
errors, errors,
warnings, warnings,
@ -68,6 +69,13 @@ function ProviderFieldFormGroup(props) {
...otherProps ...otherProps
} = props; } = props;
if (
hidden === 'hidden' ||
(hidden === 'hiddenIfNotSet' && !value)
) {
return null;
}
return ( return (
<FormGroup <FormGroup
advancedSettings={advancedSettings} advancedSettings={advancedSettings}
@ -86,7 +94,7 @@ function ProviderFieldFormGroup(props) {
errors={errors} errors={errors}
warnings={warnings} warnings={warnings}
pending={pending} pending={pending}
includeFiles={type === 'filepath' ? true : undefined} includeFiles={type === 'filePath' ? true : undefined}
onChange={onChange} onChange={onChange}
{...otherProps} {...otherProps}
/> />
@ -108,6 +116,7 @@ ProviderFieldFormGroup.propTypes = {
value: PropTypes.any, value: PropTypes.any,
type: PropTypes.string.isRequired, type: PropTypes.string.isRequired,
advanced: PropTypes.bool.isRequired, advanced: PropTypes.bool.isRequired,
hidden: PropTypes.string,
pending: PropTypes.bool.isRequired, pending: PropTypes.bool.isRequired,
errors: PropTypes.arrayOf(PropTypes.object).isRequired, errors: PropTypes.arrayOf(PropTypes.object).isRequired,
warnings: PropTypes.arrayOf(PropTypes.object).isRequired, warnings: PropTypes.arrayOf(PropTypes.object).isRequired,

@ -1,10 +1,9 @@
import * as addArtist from './addArtistActions'; import * as addArtist from './addArtistActions';
import * as app from './appActions'; import * as app from './appActions';
import * as blacklist from './blacklistActions'; import * as blacklist from './blacklistActions';
import * as calendar from './calendarActions';
import * as captcha from './captchaActions'; import * as captcha from './captchaActions';
import * as customFilters from './customFilterActions'; import * as customFilters from './customFilterActions';
import * as devices from './deviceActions';
import * as calendar from './calendarActions';
import * as commands from './commandActions'; import * as commands from './commandActions';
import * as albums from './albumActions'; import * as albums from './albumActions';
import * as trackFiles from './trackFileActions'; import * as trackFiles from './trackFileActions';
@ -16,6 +15,7 @@ import * as oAuth from './oAuthActions';
import * as organizePreview from './organizePreviewActions'; import * as organizePreview from './organizePreviewActions';
import * as retagPreview from './retagPreviewActions'; import * as retagPreview from './retagPreviewActions';
import * as paths from './pathActions'; import * as paths from './pathActions';
import * as providerOptions from './providerOptionActions';
import * as queue from './queueActions'; import * as queue from './queueActions';
import * as releases from './releaseActions'; import * as releases from './releaseActions';
import * as rootFolders from './rootFolderActions'; import * as rootFolders from './rootFolderActions';
@ -38,7 +38,6 @@ export default [
calendar, calendar,
commands, commands,
customFilters, customFilters,
devices,
albums, albums,
trackFiles, trackFiles,
albumHistory, albumHistory,
@ -49,6 +48,7 @@ export default [
organizePreview, organizePreview,
retagPreview, retagPreview,
paths, paths,
providerOptions,
queue, queue,
releases, releases,
rootFolders, rootFolders,

@ -8,7 +8,7 @@ import { set } from './baseActions';
// //
// Variables // Variables
export const section = 'devices'; export const section = 'providerOptions';
// //
// State // State
@ -23,32 +23,27 @@ export const defaultState = {
// //
// Actions Types // Actions Types
export const FETCH_DEVICES = 'devices/fetchDevices'; export const FETCH_OPTIONS = 'devices/fetchOptions';
export const CLEAR_DEVICES = 'devices/clearDevices'; export const CLEAR_OPTIONS = 'devices/clearOptions';
// //
// Action Creators // Action Creators
export const fetchDevices = createThunk(FETCH_DEVICES); export const fetchOptions = createThunk(FETCH_OPTIONS);
export const clearDevices = createAction(CLEAR_DEVICES); export const clearOptions = createAction(CLEAR_OPTIONS);
// //
// Action Handlers // Action Handlers
export const actionHandlers = handleThunks({ export const actionHandlers = handleThunks({
[FETCH_DEVICES]: function(getState, payload, dispatch) { [FETCH_OPTIONS]: function(getState, payload, dispatch) {
const actionPayload = {
action: 'getDevices',
...payload
};
dispatch(set({ dispatch(set({
section, section,
isFetching: true isFetching: true
})); }));
const promise = requestAction(actionPayload); const promise = requestAction(payload);
promise.done((data) => { promise.done((data) => {
dispatch(set({ dispatch(set({
@ -56,7 +51,7 @@ export const actionHandlers = handleThunks({
isFetching: false, isFetching: false,
isPopulated: true, isPopulated: true,
error: null, error: null,
items: data.devices || [] items: data.options || []
})); }));
}); });
@ -76,7 +71,7 @@ export const actionHandlers = handleThunks({
export const reducers = createHandleActions({ export const reducers = createHandleActions({
[CLEAR_DEVICES]: function(state) { [CLEAR_OPTIONS]: function(state) {
return updateSectionState(state, section, defaultState); return updateSectionState(state, section, defaultState);
} }

@ -15,6 +15,7 @@ namespace Lidarr.Http.ClientSchema
public bool Advanced { get; set; } public bool Advanced { get; set; }
public List<SelectOption> SelectOptions { get; set; } public List<SelectOption> SelectOptions { get; set; }
public string Section { get; set; } public string Section { get; set; }
public string Hidden { get; set; }
public Field Clone() public Field Clone()
{ {

@ -57,6 +57,7 @@ namespace Lidarr.Http.ClientSchema
return (T)ReadFromSchema(fields, typeof(T)); return (T)ReadFromSchema(fields, typeof(T));
} }
// Ideally this function should begin a System.Linq.Expression expression tree since it's faster. // Ideally this function should begin a System.Linq.Expression expression tree since it's faster.
// But it's probably not needed till performance issues pop up. // But it's probably not needed till performance issues pop up.
public static FieldMapping[] GetFieldMappings(Type type) public static FieldMapping[] GetFieldMappings(Type type)
@ -79,6 +80,7 @@ namespace Lidarr.Http.ClientSchema
return result; return result;
} }
} }
private static FieldMapping[] GetFieldMapping(Type type, string prefix, Func<object, object> targetSelector) private static FieldMapping[] GetFieldMapping(Type type, string prefix, Func<object, object> targetSelector)
{ {
var result = new List<FieldMapping>(); var result = new List<FieldMapping>();
@ -97,7 +99,7 @@ namespace Lidarr.Http.ClientSchema
HelpLink = fieldAttribute.HelpLink, HelpLink = fieldAttribute.HelpLink,
Order = fieldAttribute.Order, Order = fieldAttribute.Order,
Advanced = fieldAttribute.Advanced, Advanced = fieldAttribute.Advanced,
Type = fieldAttribute.Type.ToString().ToLowerInvariant(), Type = fieldAttribute.Type.ToString().FirstCharToLower(),
Section = fieldAttribute.Section Section = fieldAttribute.Section
}; };
@ -106,6 +108,11 @@ namespace Lidarr.Http.ClientSchema
field.SelectOptions = GetSelectOptions(fieldAttribute.SelectOptions); field.SelectOptions = GetSelectOptions(fieldAttribute.SelectOptions);
} }
if (fieldAttribute.Hidden != HiddenType.Visible)
{
field.Hidden = fieldAttribute.Hidden.ToString().FirstCharToLower();
}
var valueConverter = GetValueConverter(propertyInfo.PropertyType); var valueConverter = GetValueConverter(propertyInfo.PropertyType);
result.Add(new FieldMapping result.Add(new FieldMapping
@ -138,8 +145,10 @@ namespace Lidarr.Http.ClientSchema
{ {
var options = from Enum e in Enum.GetValues(selectOptions) var options = from Enum e in Enum.GetValues(selectOptions)
select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() }; select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() };
return options.OrderBy(o => o.Value).ToList(); return options.OrderBy(o => o.Value).ToList();
} }
private static Func<object, object> GetValueConverter(Type propertyType) private static Func<object, object> GetValueConverter(Type propertyType)
{ {
if (propertyType == typeof(int)) if (propertyType == typeof(int))
@ -180,11 +189,9 @@ namespace Lidarr.Http.ClientSchema
{ {
return ((JArray)fieldValue).Select(s => s.Value<int>()); return ((JArray)fieldValue).Select(s => s.Value<int>());
} }
else else
{ {
return fieldValue.ToString().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) return fieldValue.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s));
.Select(s => Convert.ToInt32(s));
} }
}; };
} }

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Common.Disk
{
public static class SystemFolders
{
public static List<string> GetSystemFolders()
{
if (OsInfo.IsWindows)
{
return new List<string> { Environment.GetFolderPath(Environment.SpecialFolder.Windows) };
}
if (OsInfo.IsOsx)
{
return new List<string> { "/System" };
}
return new List<string>
{
"/bin",
"/boot",
"/lib",
"/sbin",
"/proc"
};
}
}
}

@ -79,6 +79,7 @@
<Compile Include="Disk\RelativeFileSystemModel.cs" /> <Compile Include="Disk\RelativeFileSystemModel.cs" />
<Compile Include="Disk\FileSystemModel.cs" /> <Compile Include="Disk\FileSystemModel.cs" />
<Compile Include="Disk\FileSystemResult.cs" /> <Compile Include="Disk\FileSystemResult.cs" />
<Compile Include="Disk\SystemFolders.cs" />
<Compile Include="EnvironmentInfo\IOsVersionAdapter.cs" /> <Compile Include="EnvironmentInfo\IOsVersionAdapter.cs" />
<Compile Include="EnvironmentInfo\IPlatformInfo.cs" /> <Compile Include="EnvironmentInfo\IPlatformInfo.cs" />
<Compile Include="EnvironmentInfo\OsVersionModel.cs" /> <Compile Include="EnvironmentInfo\OsVersionModel.cs" />
@ -259,6 +260,7 @@
<PackageReference Include="System.IO.Abstractions"> <PackageReference Include="System.IO.Abstractions">
<Version>4.0.11</Version> <Version>4.0.11</Version>
</PackageReference> </PackageReference>
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

@ -108,11 +108,7 @@ namespace NzbDrone.Common.Processes
public Process Start(string path, string args = null, StringDictionary environmentVariables = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null) public Process Start(string path, string args = null, StringDictionary environmentVariables = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null)
{ {
if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) (path, args) = GetPathAndArgs(path, args);
{
args = GetMonoArgs(path, args);
path = "mono";
}
var logger = LogManager.GetLogger(new FileInfo(path).Name); var logger = LogManager.GetLogger(new FileInfo(path).Name);
@ -192,11 +188,7 @@ namespace NzbDrone.Common.Processes
public Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null, bool noWindow = false) public Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null, bool noWindow = false)
{ {
if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) (path, args) = GetPathAndArgs(path, args);
{
args = GetMonoArgs(path, args);
path = "mono";
}
_logger.Debug("Starting {0} {1}", path, args); _logger.Debug("Starting {0} {1}", path, args);
@ -361,9 +353,19 @@ namespace NzbDrone.Common.Processes
return processes; return processes;
} }
private string GetMonoArgs(string path, string args) private (string Path, string Args) GetPathAndArgs(string path, string args)
{ {
return string.Format("--debug {0} {1}", path, args); if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
{
return ("mono", $"--debug {path} {args}");
}
if (OsInfo.IsWindows && path.EndsWith(".bat", StringComparison.InvariantCultureIgnoreCase))
{
return ("cmd.exe", $"/c {path} {args}");
}
return (path, args);
} }
} }
} }

@ -19,6 +19,7 @@ namespace NzbDrone.Core.Annotations
public bool Advanced { get; set; } public bool Advanced { get; set; }
public Type SelectOptions { get; set; } public Type SelectOptions { get; set; }
public string Section { get; set; } public string Section { get; set; }
public HiddenType Hidden { get; set; }
} }
public enum FieldType public enum FieldType
@ -30,7 +31,6 @@ namespace NzbDrone.Core.Annotations
Select, Select,
Path, Path,
FilePath, FilePath,
Hidden,
Tag, Tag,
Action, Action,
Url, Url,
@ -38,4 +38,11 @@ namespace NzbDrone.Core.Annotations
OAuth, OAuth,
Device Device
} }
public enum HiddenType
{
Visible,
Hidden,
HiddenIfNotSet
}
} }

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.IO; using System.IO;
@ -5,6 +6,7 @@ using System.Linq;
using FluentValidation.Results; using FluentValidation.Results;
using NLog; using NLog;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Processes; using NzbDrone.Common.Processes;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.Music; using NzbDrone.Core.Music;
@ -160,6 +162,35 @@ namespace NzbDrone.Core.Notifications.CustomScript
failures.Add(new NzbDroneValidationFailure("Path", "File does not exist")); failures.Add(new NzbDroneValidationFailure("Path", "File does not exist"));
} }
foreach (var systemFolder in SystemFolders.GetSystemFolders())
{
if (systemFolder.IsParentPath(Settings.Path))
{
failures.Add(new NzbDroneValidationFailure("Path", $"Must not be a descendant of '{systemFolder}'"));
}
}
if (failures.Empty())
{
try
{
var environmentVariables = new StringDictionary();
environmentVariables.Add("Sonarr_EventType", "Test");
var processOutput = ExecuteScript(environmentVariables);
if (processOutput.ExitCode != 0)
{
failures.Add(new NzbDroneValidationFailure(string.Empty, $"Script exited with code: {processOutput.ExitCode}"));
}
}
catch (Exception ex)
{
_logger.Error(ex);
failures.Add(new NzbDroneValidationFailure(string.Empty, ex.Message));
}
}
return new ValidationResult(failures); return new ValidationResult(failures);
} }
@ -172,5 +203,10 @@ namespace NzbDrone.Core.Notifications.CustomScript
_logger.Debug("Executed external script: {0} - Status: {1}", Settings.Path, process.ExitCode); _logger.Debug("Executed external script: {0} - Status: {1}", Settings.Path, process.ExitCode);
_logger.Debug($"Script Output: {System.Environment.NewLine}{string.Join(System.Environment.NewLine, process.Lines)}"); _logger.Debug($"Script Output: {System.Environment.NewLine}{string.Join(System.Environment.NewLine, process.Lines)}");
} }
private bool ValidatePathParent(string possibleParent, string path)
{
return possibleParent.IsParentPath(path);
}
} }
} }

@ -11,6 +11,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
public CustomScriptSettingsValidator() public CustomScriptSettingsValidator()
{ {
RuleFor(c => c.Path).IsValidPath(); RuleFor(c => c.Path).IsValidPath();
RuleFor(c => c.Arguments).Empty().WithMessage("Arguments are no longer supported for custom scripts");
} }
} }
@ -21,7 +22,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
[FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)] [FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)]
public string Path { get; set; } public string Path { get; set; }
[FieldDefinition(1, Label = "Arguments", HelpText = "Arguments to pass to the script")] [FieldDefinition(1, Label = "Arguments", HelpText = "Arguments to pass to the script", Hidden = HiddenType.HiddenIfNotSet)]
public string Arguments { get; set; } public string Arguments { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -13,22 +13,22 @@ namespace NzbDrone.Core.Notifications.Plex.HomeTheater
//These need to be kept in the same order as XBMC Settings, but we don't want them displayed //These need to be kept in the same order as XBMC Settings, but we don't want them displayed
[FieldDefinition(2, Label = "Username", Type = FieldType.Hidden)] [FieldDefinition(2, Label = "Username", Hidden = HiddenType.Hidden)]
public new string Username { get; set; } public new string Username { get; set; }
[FieldDefinition(3, Label = "Password", Type = FieldType.Hidden)] [FieldDefinition(3, Label = "Password", Hidden = HiddenType.Hidden)]
public new string Password { get; set; } public new string Password { get; set; }
[FieldDefinition(5, Label = "GUI Notification", Type = FieldType.Hidden)] [FieldDefinition(5, Label = "GUI Notification", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
public new bool Notify { get; set; } public new bool Notify { get; set; }
[FieldDefinition(6, Label = "Update Library", HelpText = "Update Library on Download & Rename?", Type = FieldType.Hidden)] [FieldDefinition(6, Label = "Update Library", HelpText = "Update Library on Download & Rename?", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
public new bool UpdateLibrary { get; set; } public new bool UpdateLibrary { get; set; }
[FieldDefinition(7, Label = "Clean Library", HelpText = "Clean Library after update?", Type = FieldType.Hidden)] [FieldDefinition(7, Label = "Clean Library", HelpText = "Clean Library after update?", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
public new bool CleanLibrary { get; set; } public new bool CleanLibrary { get; set; }
[FieldDefinition(8, Label = "Always Update", HelpText = "Update Library even when a video is playing?", Type = FieldType.Hidden)] [FieldDefinition(8, Label = "Always Update", HelpText = "Update Library even when a video is playing?", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
public new bool AlwaysUpdate { get; set; } public new bool AlwaysUpdate { get; set; }
} }
} }

@ -71,7 +71,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
return new return new
{ {
devices = devices.Where(d => d.Nickname.IsNotNullOrWhiteSpace()) options = devices.Where(d => d.Nickname.IsNotNullOrWhiteSpace())
.OrderBy(d => d.Nickname, StringComparer.InvariantCultureIgnoreCase) .OrderBy(d => d.Nickname, StringComparer.InvariantCultureIgnoreCase)
.Select(d => new .Select(d => new
{ {

@ -1,6 +1,5 @@
using System;
using FluentValidation.Validators; using FluentValidation.Validators;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
namespace NzbDrone.Core.Validation.Paths namespace NzbDrone.Core.Validation.Paths
@ -16,33 +15,13 @@ namespace NzbDrone.Core.Validation.Paths
{ {
var folder = context.PropertyValue.ToString(); var folder = context.PropertyValue.ToString();
if (OsInfo.IsWindows) foreach (var systemFolder in SystemFolders.GetSystemFolders())
{ {
var windowsFolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
context.MessageFormatter.AppendArgument("systemFolder", windowsFolder);
if (windowsFolder.PathEquals(folder))
{
context.MessageFormatter.AppendArgument("relationship", "set to");
return false;
}
if (windowsFolder.IsParentPath(folder))
{
context.MessageFormatter.AppendArgument("relationship", "child of");
return false;
}
}
else if (OsInfo.IsOsx)
{
var systemFolder = "/System";
context.MessageFormatter.AppendArgument("systemFolder", systemFolder); context.MessageFormatter.AppendArgument("systemFolder", systemFolder);
if (systemFolder.PathEquals(folder)) if (systemFolder.PathEquals(folder))
{ {
context.MessageFormatter.AppendArgument("relationship", "child of"); context.MessageFormatter.AppendArgument("relationship", "set to");
return false; return false;
} }
@ -54,36 +33,6 @@ namespace NzbDrone.Core.Validation.Paths
return false; return false;
} }
} }
else
{
var folders = new[]
{
"/bin",
"/boot",
"/lib",
"/sbin",
"/proc"
};
foreach (var f in folders)
{
context.MessageFormatter.AppendArgument("systemFolder", f);
if (f.PathEquals(folder))
{
context.MessageFormatter.AppendArgument("relationship", "child of");
return false;
}
if (f.IsParentPath(folder))
{
context.MessageFormatter.AppendArgument("relationship", "child of");
return false;
}
}
}
return true; return true;
} }

Loading…
Cancel
Save