mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-04-24 13:57:11 -04:00
parent
5a1b82e195
commit
56184905a9
10 changed files with 79 additions and 19 deletions
|
@ -8,16 +8,28 @@ import DeviceInput from './DeviceInput';
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state, { value }) => value,
|
(state, { value }) => value,
|
||||||
|
(state, { name }) => name,
|
||||||
(state) => state.providerOptions,
|
(state) => state.providerOptions,
|
||||||
(value, devices) => {
|
(value, name, devices) => {
|
||||||
|
const {
|
||||||
|
isFetching,
|
||||||
|
isPopulated,
|
||||||
|
error,
|
||||||
|
items
|
||||||
|
} = devices;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...devices,
|
isFetching,
|
||||||
|
isPopulated,
|
||||||
|
error,
|
||||||
|
items: items[name] || [],
|
||||||
selectedDevices: value.map((valueDevice) => {
|
selectedDevices: value.map((valueDevice) => {
|
||||||
|
const sectionItems = items[name] || [];
|
||||||
|
|
||||||
// Disable equality ESLint rule so we don't need to worry about
|
// Disable equality ESLint rule so we don't need to worry about
|
||||||
// a type mismatch between the value items and the device ID.
|
// a type mismatch between the value items and the device ID.
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
const device = devices.items.find((d) => d.id == valueDevice);
|
const device = sectionItems.find((d) => d.id == valueDevice);
|
||||||
|
|
||||||
if (device) {
|
if (device) {
|
||||||
return {
|
return {
|
||||||
|
@ -61,11 +73,14 @@ class DeviceInputConnector extends Component {
|
||||||
const {
|
const {
|
||||||
provider,
|
provider,
|
||||||
providerData,
|
providerData,
|
||||||
dispatchFetchOptions
|
dispatchFetchOptions,
|
||||||
|
requestAction,
|
||||||
|
name
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
dispatchFetchOptions({
|
dispatchFetchOptions({
|
||||||
action: 'getDevices',
|
action: requestAction,
|
||||||
|
itemSection: name,
|
||||||
provider,
|
provider,
|
||||||
providerData
|
providerData
|
||||||
});
|
});
|
||||||
|
@ -94,6 +109,7 @@ class DeviceInputConnector extends Component {
|
||||||
DeviceInputConnector.propTypes = {
|
DeviceInputConnector.propTypes = {
|
||||||
provider: PropTypes.string.isRequired,
|
provider: PropTypes.string.isRequired,
|
||||||
providerData: PropTypes.object.isRequired,
|
providerData: PropTypes.object.isRequired,
|
||||||
|
requestAction: PropTypes.string.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
dispatchFetchOptions: PropTypes.func.isRequired,
|
dispatchFetchOptions: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -62,6 +62,7 @@ function ProviderFieldFormGroup(props) {
|
||||||
value,
|
value,
|
||||||
type,
|
type,
|
||||||
advanced,
|
advanced,
|
||||||
|
requestAction,
|
||||||
hidden,
|
hidden,
|
||||||
pending,
|
pending,
|
||||||
errors,
|
errors,
|
||||||
|
@ -98,6 +99,7 @@ function ProviderFieldFormGroup(props) {
|
||||||
pending={pending}
|
pending={pending}
|
||||||
includeFiles={type === 'filePath' ? true : undefined}
|
includeFiles={type === 'filePath' ? true : undefined}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
requestAction={requestAction}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -118,6 +120,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,
|
||||||
|
requestAction: PropTypes.string,
|
||||||
hidden: PropTypes.string,
|
hidden: PropTypes.string,
|
||||||
pending: PropTypes.bool.isRequired,
|
pending: PropTypes.bool.isRequired,
|
||||||
errors: PropTypes.arrayOf(PropTypes.object).isRequired,
|
errors: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
|
|
@ -14,7 +14,7 @@ export const section = 'providerOptions';
|
||||||
// State
|
// State
|
||||||
|
|
||||||
export const defaultState = {
|
export const defaultState = {
|
||||||
items: [],
|
items: {},
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
isPopulated: false,
|
isPopulated: false,
|
||||||
error: false
|
error: false
|
||||||
|
@ -43,15 +43,20 @@ export const actionHandlers = handleThunks({
|
||||||
isFetching: true
|
isFetching: true
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const oldItems = getState().providerOptions.items;
|
||||||
|
const itemSection = payload.itemSection;
|
||||||
|
|
||||||
const promise = requestAction(payload);
|
const promise = requestAction(payload);
|
||||||
|
|
||||||
promise.done((data) => {
|
promise.done((data) => {
|
||||||
|
oldItems[itemSection] = data.options || [];
|
||||||
|
|
||||||
dispatch(set({
|
dispatch(set({
|
||||||
section,
|
section,
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
isPopulated: true,
|
isPopulated: true,
|
||||||
error: null,
|
error: null,
|
||||||
items: data.options || []
|
items: oldItems
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace NzbDrone.Core.Annotations
|
||||||
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 HiddenType Hidden { get; set; }
|
||||||
|
public string RequestAction { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FieldType
|
public enum FieldType
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
public string TitleSlug { get; set; }
|
public string TitleSlug { get; set; }
|
||||||
public int QualityProfileId { get; set; }
|
public int QualityProfileId { get; set; }
|
||||||
|
public HashSet<int> Tags { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RadarrProfile
|
public class RadarrProfile
|
||||||
|
@ -23,4 +24,10 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RadarrTag
|
||||||
|
{
|
||||||
|
public string Label { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,8 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
|
|
||||||
foreach (var remoteMovie in remoteMovies)
|
foreach (var remoteMovie in remoteMovies)
|
||||||
{
|
{
|
||||||
if (!Settings.ProfileIds.Any() || Settings.ProfileIds.Contains(remoteMovie.QualityProfileId))
|
if ((!Settings.ProfileIds.Any() || Settings.ProfileIds.Contains(remoteMovie.QualityProfileId)) &&
|
||||||
|
(!Settings.TagIds.Any() || Settings.TagIds.Any(x => remoteMovie.Tags.Any(y => y == x))))
|
||||||
{
|
{
|
||||||
movies.Add(new Movie
|
movies.Add(new Movie
|
||||||
{
|
{
|
||||||
|
@ -76,19 +77,19 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
|
|
||||||
public override object RequestAction(string action, IDictionary<string, string> query)
|
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||||
{
|
{
|
||||||
if (action == "getDevices")
|
// Return early if there is not an API key
|
||||||
|
if (Settings.ApiKey.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
// Return early if there is not an API key
|
return new
|
||||||
if (Settings.ApiKey.IsNullOrWhiteSpace())
|
|
||||||
{
|
{
|
||||||
return new
|
devices = new List<object>()
|
||||||
{
|
};
|
||||||
devices = new List<object>()
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.Validate().Filter("ApiKey").ThrowOnError();
|
Settings.Validate().Filter("ApiKey").ThrowOnError();
|
||||||
|
|
||||||
|
if (action == "getProfiles")
|
||||||
|
{
|
||||||
var devices = _radarrV3Proxy.GetProfiles(Settings);
|
var devices = _radarrV3Proxy.GetProfiles(Settings);
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
@ -102,6 +103,21 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == "getTags")
|
||||||
|
{
|
||||||
|
var devices = _radarrV3Proxy.GetTags(Settings);
|
||||||
|
|
||||||
|
return new
|
||||||
|
{
|
||||||
|
options = devices.OrderBy(d => d.Label, StringComparer.InvariantCultureIgnoreCase)
|
||||||
|
.Select(d => new
|
||||||
|
{
|
||||||
|
id = d.Id,
|
||||||
|
name = d.Label
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return new { };
|
return new { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
BaseUrl = "";
|
BaseUrl = "";
|
||||||
ApiKey = "";
|
ApiKey = "";
|
||||||
ProfileIds = new int[] { };
|
ProfileIds = new int[] { };
|
||||||
|
TagIds = new int[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Full URL", HelpText = "URL, including port, of the Radarr V3 instance to import from")]
|
[FieldDefinition(0, Label = "Full URL", HelpText = "URL, including port, of the Radarr V3 instance to import from")]
|
||||||
|
@ -32,9 +33,12 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
[FieldDefinition(1, Label = "API Key", HelpText = "Apikey of the Radarr V3 instance to import from")]
|
[FieldDefinition(1, Label = "API Key", HelpText = "Apikey of the Radarr V3 instance to import from")]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Type = FieldType.Device, Label = "Profiles", HelpText = "Profiles from the source instance to import from")]
|
[FieldDefinition(2, Type = FieldType.Device, RequestAction = "getProfiles", Label = "Profiles", HelpText = "Profiles from the source instance to import from")]
|
||||||
public IEnumerable<int> ProfileIds { get; set; }
|
public IEnumerable<int> ProfileIds { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(3, Type = FieldType.Device, RequestAction = "getTags", Label = "Tags", HelpText = "Tags from the source instance to import from")]
|
||||||
|
public IEnumerable<int> TagIds { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
{
|
{
|
||||||
List<RadarrMovie> GetMovies(RadarrSettings settings);
|
List<RadarrMovie> GetMovies(RadarrSettings settings);
|
||||||
List<RadarrProfile> GetProfiles(RadarrSettings settings);
|
List<RadarrProfile> GetProfiles(RadarrSettings settings);
|
||||||
|
List<RadarrTag> GetTags(RadarrSettings settings);
|
||||||
ValidationFailure Test(RadarrSettings settings);
|
ValidationFailure Test(RadarrSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +38,11 @@ namespace NzbDrone.Core.NetImport.Radarr
|
||||||
return Execute<RadarrProfile>("/api/v3/qualityprofile", settings);
|
return Execute<RadarrProfile>("/api/v3/qualityprofile", settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<RadarrTag> GetTags(RadarrSettings settings)
|
||||||
|
{
|
||||||
|
return Execute<RadarrTag>("/api/v3/tag", settings);
|
||||||
|
}
|
||||||
|
|
||||||
public ValidationFailure Test(RadarrSettings settings)
|
public ValidationFailure Test(RadarrSettings settings)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Radarr.Http.ClientSchema
|
||||||
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 string Hidden { get; set; }
|
||||||
|
public string RequestAction { get; set; }
|
||||||
|
|
||||||
public Field Clone()
|
public Field Clone()
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,7 +100,8 @@ namespace Radarr.Http.ClientSchema
|
||||||
Order = fieldAttribute.Order,
|
Order = fieldAttribute.Order,
|
||||||
Advanced = fieldAttribute.Advanced,
|
Advanced = fieldAttribute.Advanced,
|
||||||
Type = fieldAttribute.Type.ToString().FirstCharToLower(),
|
Type = fieldAttribute.Type.ToString().FirstCharToLower(),
|
||||||
Section = fieldAttribute.Section
|
Section = fieldAttribute.Section,
|
||||||
|
RequestAction = fieldAttribute.RequestAction
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fieldAttribute.Type == FieldType.Select || fieldAttribute.Type == FieldType.TagSelect)
|
if (fieldAttribute.Type == FieldType.Select || fieldAttribute.Type == FieldType.TagSelect)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue