Fixed: Validate metadata and quality profiles for root folders

Don't allow `0` as possible value for metadata and quality profiles, and permit to edit root folders with bad values in UI.
pull/3560/head v0.3.31.2578
Bogdan 7 months ago
parent b5334da253
commit af1f389f8e

@ -8,6 +8,7 @@ import TagListConnector from 'Components/TagListConnector';
import { createMetadataProfileSelectorForHook } from 'Store/Selectors/createMetadataProfileSelector'; import { createMetadataProfileSelectorForHook } from 'Store/Selectors/createMetadataProfileSelector';
import { createQualityProfileSelectorForHook } from 'Store/Selectors/createQualityProfileSelector'; import { createQualityProfileSelectorForHook } from 'Store/Selectors/createQualityProfileSelector';
import { SelectStateInputProps } from 'typings/props'; import { SelectStateInputProps } from 'typings/props';
import translate from 'Utilities/String/translate';
import styles from './ManageImportListsModalRow.css'; import styles from './ManageImportListsModalRow.css';
interface ManageImportListsModalRowProps { interface ManageImportListsModalRowProps {
@ -70,7 +71,7 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
</TableRowCell> </TableRowCell>
<TableRowCell className={styles.qualityProfileId}> <TableRowCell className={styles.qualityProfileId}>
{qualityProfile?.name ?? 'None'} {qualityProfile?.name ?? translate('None')}
</TableRowCell> </TableRowCell>
<TableRowCell className={styles.metadataProfileId}> <TableRowCell className={styles.metadataProfileId}>
@ -82,7 +83,7 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
</TableRowCell> </TableRowCell>
<TableRowCell className={styles.enableAutomaticAdd}> <TableRowCell className={styles.enableAutomaticAdd}>
{enableAutomaticAdd ? 'Yes' : 'No'} {enableAutomaticAdd ? translate('Yes') : translate('No')}
</TableRowCell> </TableRowCell>
<TableRowCell className={styles.tags}> <TableRowCell className={styles.tags}>

@ -75,12 +75,12 @@ class RootFolder extends Component {
{path} {path}
</Label> </Label>
<Label kind={kinds.SUCCESS}> <Label kind={qualityProfile?.name ? kinds.SUCCESS : kinds.DANGER}>
{qualityProfile.name} {qualityProfile?.name || translate('None')}
</Label> </Label>
<Label kind={kinds.SUCCESS}> <Label kind={metadataProfile?.name ? kinds.SUCCESS : kinds.DANGER}>
{metadataProfile.name} {metadataProfile?.name || translate('None')}
</Label> </Label>
</div> </div>

@ -15,18 +15,18 @@ namespace NzbDrone.Core.Books
public class BookCutoffService : IBookCutoffService public class BookCutoffService : IBookCutoffService
{ {
private readonly IBookRepository _bookRepository; private readonly IBookRepository _bookRepository;
private readonly IProfileService _profileService; private readonly IQualityProfileService _qualityProfileService;
public BookCutoffService(IBookRepository bookRepository, IProfileService profileService) public BookCutoffService(IBookRepository bookRepository, IQualityProfileService qualityProfileService)
{ {
_bookRepository = bookRepository; _bookRepository = bookRepository;
_profileService = profileService; _qualityProfileService = qualityProfileService;
} }
public PagingSpec<Book> BooksWhereCutoffUnmet(PagingSpec<Book> pagingSpec) public PagingSpec<Book> BooksWhereCutoffUnmet(PagingSpec<Book> pagingSpec)
{ {
var qualitiesBelowCutoff = new List<QualitiesBelowCutoff>(); var qualitiesBelowCutoff = new List<QualitiesBelowCutoff>();
var profiles = _profileService.All(); var profiles = _qualityProfileService.All();
//Get all items less than the cutoff //Get all items less than the cutoff
foreach (var profile in profiles) foreach (var profile in profiles)

@ -53,7 +53,7 @@ namespace NzbDrone.Core.MediaFiles.BookImport
private readonly IAugmentingService _augmentingService; private readonly IAugmentingService _augmentingService;
private readonly IIdentificationService _identificationService; private readonly IIdentificationService _identificationService;
private readonly IRootFolderService _rootFolderService; private readonly IRootFolderService _rootFolderService;
private readonly IProfileService _qualityProfileService; private readonly IQualityProfileService _qualityProfileService;
private readonly Logger _logger; private readonly Logger _logger;
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification<LocalBook>> trackSpecifications, public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification<LocalBook>> trackSpecifications,
@ -63,7 +63,7 @@ namespace NzbDrone.Core.MediaFiles.BookImport
IAugmentingService augmentingService, IAugmentingService augmentingService,
IIdentificationService identificationService, IIdentificationService identificationService,
IRootFolderService rootFolderService, IRootFolderService rootFolderService,
IProfileService qualityProfileService, IQualityProfileService qualityProfileService,
Logger logger) Logger logger)
{ {
_trackSpecifications = trackSpecifications; _trackSpecifications = trackSpecifications;

@ -13,7 +13,7 @@ using NzbDrone.Core.RootFolders;
namespace NzbDrone.Core.Profiles.Qualities namespace NzbDrone.Core.Profiles.Qualities
{ {
public interface IProfileService public interface IQualityProfileService
{ {
QualityProfile Add(QualityProfile profile); QualityProfile Add(QualityProfile profile);
void Update(QualityProfile profile); void Update(QualityProfile profile);
@ -24,7 +24,7 @@ namespace NzbDrone.Core.Profiles.Qualities
QualityProfile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed); QualityProfile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed);
} }
public class QualityProfileService : IProfileService, public class QualityProfileService : IQualityProfileService,
IHandle<ApplicationStartedEvent>, IHandle<ApplicationStartedEvent>,
IHandle<CustomFormatAddedEvent>, IHandle<CustomFormatAddedEvent>,
IHandle<CustomFormatDeletedEvent> IHandle<CustomFormatDeletedEvent>

@ -5,11 +5,11 @@ namespace NzbDrone.Core.Validation
{ {
public class QualityProfileExistsValidator : PropertyValidator public class QualityProfileExistsValidator : PropertyValidator
{ {
private readonly IProfileService _profileService; private readonly IQualityProfileService _qualityProfileService;
public QualityProfileExistsValidator(IProfileService profileService) public QualityProfileExistsValidator(IQualityProfileService qualityProfileService)
{ {
_profileService = profileService; _qualityProfileService = qualityProfileService;
} }
protected override string GetDefaultMessageTemplate() => "Quality Profile does not exist"; protected override string GetDefaultMessageTemplate() => "Quality Profile does not exist";
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Validation
return true; return true;
} }
return _profileService.Exists((int)context.PropertyValue); return _qualityProfileService.Exists((int)context.PropertyValue);
} }
} }
} }

@ -14,10 +14,10 @@ namespace Readarr.Api.V1.Profiles.Quality
[V1ApiController] [V1ApiController]
public class QualityProfileController : RestController<QualityProfileResource> public class QualityProfileController : RestController<QualityProfileResource>
{ {
private readonly IProfileService _qualityProfileService; private readonly IQualityProfileService _qualityProfileService;
private readonly ICustomFormatService _formatService; private readonly ICustomFormatService _formatService;
public QualityProfileController(IProfileService qualityProfileService, ICustomFormatService formatService) public QualityProfileController(IQualityProfileService qualityProfileService, ICustomFormatService formatService)
{ {
_qualityProfileService = qualityProfileService; _qualityProfileService = qualityProfileService;
_formatService = formatService; _formatService = formatService;

@ -7,17 +7,17 @@ namespace Readarr.Api.V1.Profiles.Quality
[V1ApiController("qualityprofile/schema")] [V1ApiController("qualityprofile/schema")]
public class QualityProfileSchemaController : Controller public class QualityProfileSchemaController : Controller
{ {
private readonly IProfileService _profileService; private readonly IQualityProfileService _qualityProfileService;
public QualityProfileSchemaController(IProfileService profileService) public QualityProfileSchemaController(IQualityProfileService qualityProfileService)
{ {
_profileService = profileService; _qualityProfileService = qualityProfileService;
} }
[HttpGet] [HttpGet]
public QualityProfileResource GetSchema() public QualityProfileResource GetSchema()
{ {
var qualityProfile = _profileService.GetDefaultProfile(string.Empty); var qualityProfile = _qualityProfileService.GetDefaultProfile(string.Empty);
return qualityProfile.ToResource(); return qualityProfile.ToResource();
} }

@ -60,10 +60,12 @@ namespace Readarr.Api.V1.RootFolders
SharedValidator.RuleFor(c => c.Name) SharedValidator.RuleFor(c => c.Name)
.NotEmpty(); .NotEmpty();
SharedValidator.RuleFor(c => c.DefaultMetadataProfileId) SharedValidator.RuleFor(c => c.DefaultMetadataProfileId).Cascade(CascadeMode.Stop)
.ValidId()
.SetValidator(metadataProfileExistsValidator); .SetValidator(metadataProfileExistsValidator);
SharedValidator.RuleFor(c => c.DefaultQualityProfileId) SharedValidator.RuleFor(c => c.DefaultQualityProfileId).Cascade(CascadeMode.Stop)
.ValidId()
.SetValidator(qualityProfileExistsValidator); .SetValidator(qualityProfileExistsValidator);
SharedValidator.RuleFor(c => c.Host).ValidHost().When(x => x.IsCalibreLibrary); SharedValidator.RuleFor(c => c.Host).ValidHost().When(x => x.IsCalibreLibrary);

Loading…
Cancel
Save