mirror of
https://github.com/Readarr/Readarr.git
synced 2026-03-19 16:34:11 -04:00
Compare commits
18 Commits
v0.3.28.25
...
sonarr-pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
102481ed60 | ||
|
|
2fb1b8af20 | ||
|
|
af1f389f8e | ||
|
|
b5334da253 | ||
|
|
68b3904382 | ||
|
|
c8b09b9e29 | ||
|
|
d910fc42ab | ||
|
|
a6db8bfe0e | ||
|
|
2033d7e411 | ||
|
|
4a04e54ceb | ||
|
|
d57a9ab9b0 | ||
|
|
d333204194 | ||
|
|
c3676f8d33 | ||
|
|
932356be61 | ||
|
|
5b1b2a2d67 | ||
|
|
c362e8c467 | ||
|
|
67c00a8cc7 | ||
|
|
27a086dfff |
@@ -9,7 +9,7 @@ variables:
|
||||
testsFolder: './_tests'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||
majorVersion: '0.3.28'
|
||||
majorVersion: '0.3.32'
|
||||
minorVersion: $[counter('minorVersion', 1)]
|
||||
readarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(readarrVersion)'
|
||||
@@ -20,7 +20,7 @@ variables:
|
||||
innoVersion: '6.2.0'
|
||||
windowsImage: 'windows-2022'
|
||||
linuxImage: 'ubuntu-20.04'
|
||||
macImage: 'macOS-11'
|
||||
macImage: 'macOS-12'
|
||||
|
||||
trigger:
|
||||
branches:
|
||||
|
||||
14
docs.sh
14
docs.sh
@@ -1,3 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
FRAMEWORK="net6.0"
|
||||
PLATFORM=$1
|
||||
|
||||
if [ "$PLATFORM" = "Windows" ]; then
|
||||
@@ -21,15 +25,21 @@ slnFile=src/Readarr.sln
|
||||
|
||||
platform=Posix
|
||||
|
||||
if [ "$PLATFORM" = "Windows" ]; then
|
||||
application=Readarr.Console.dll
|
||||
else
|
||||
application=Readarr.dll
|
||||
fi
|
||||
|
||||
dotnet clean $slnFile -c Debug
|
||||
dotnet clean $slnFile -c Release
|
||||
|
||||
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
|
||||
|
||||
dotnet new tool-manifest
|
||||
dotnet tool install --version 6.5.0 Swashbuckle.AspNetCore.Cli
|
||||
dotnet tool install --version 6.6.2 Swashbuckle.AspNetCore.Cli
|
||||
|
||||
dotnet tool run swagger tofile --output ./src/Readarr.Api.V1/openapi.json "$outputFolder/net6.0/$RUNTIME/Readarr.console.dll" v1 &
|
||||
dotnet tool run swagger tofile --output ./src/Readarr.Api.V1/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v1 &
|
||||
|
||||
sleep 45
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import TagListConnector from 'Components/TagListConnector';
|
||||
import { createMetadataProfileSelectorForHook } from 'Store/Selectors/createMetadataProfileSelector';
|
||||
import { createQualityProfileSelectorForHook } from 'Store/Selectors/createQualityProfileSelector';
|
||||
import { SelectStateInputProps } from 'typings/props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ManageImportListsModalRow.css';
|
||||
|
||||
interface ManageImportListsModalRowProps {
|
||||
@@ -70,7 +71,7 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.qualityProfileId}>
|
||||
{qualityProfile?.name ?? 'None'}
|
||||
{qualityProfile?.name ?? translate('None')}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.metadataProfileId}>
|
||||
@@ -82,7 +83,7 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.enableAutomaticAdd}>
|
||||
{enableAutomaticAdd ? 'Yes' : 'No'}
|
||||
{enableAutomaticAdd ? translate('Yes') : translate('No')}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.tags}>
|
||||
|
||||
@@ -75,12 +75,12 @@ class RootFolder extends Component {
|
||||
{path}
|
||||
</Label>
|
||||
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
{qualityProfile.name}
|
||||
<Label kind={qualityProfile?.name ? kinds.SUCCESS : kinds.DANGER}>
|
||||
{qualityProfile?.name || translate('None')}
|
||||
</Label>
|
||||
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
{metadataProfile.name}
|
||||
<Label kind={metadataProfile?.name ? kinds.SUCCESS : kinds.DANGER}>
|
||||
{metadataProfile?.name || translate('None')}
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.1.118" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.6.2" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.2" />
|
||||
<PackageVersion Include="System.Buffers" Version="4.5.1" />
|
||||
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace NzbDrone.Core.Test.QueueTests
|
||||
|
||||
_trackedDownloads = Builder<TrackedDownload>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(v => v.IsTrackable = true)
|
||||
.With(v => v.DownloadItem = downloadItem)
|
||||
.With(v => v.RemoteBook = remoteBook)
|
||||
.Build()
|
||||
|
||||
@@ -15,18 +15,18 @@ namespace NzbDrone.Core.Books
|
||||
public class BookCutoffService : IBookCutoffService
|
||||
{
|
||||
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;
|
||||
_profileService = profileService;
|
||||
_qualityProfileService = qualityProfileService;
|
||||
}
|
||||
|
||||
public PagingSpec<Book> BooksWhereCutoffUnmet(PagingSpec<Book> pagingSpec)
|
||||
{
|
||||
var qualitiesBelowCutoff = new List<QualitiesBelowCutoff>();
|
||||
var profiles = _profileService.All();
|
||||
var profiles = _qualityProfileService.All();
|
||||
|
||||
//Get all items less than the cutoff
|
||||
foreach (var profile in profiles)
|
||||
|
||||
@@ -404,13 +404,21 @@ namespace NzbDrone.Core.Configuration
|
||||
throw new InvalidConfigFileException($"{_configFile} is corrupt. Please delete the config file and Readarr will recreate it.");
|
||||
}
|
||||
|
||||
return XDocument.Parse(_diskProvider.ReadAllText(_configFile));
|
||||
var xDoc = XDocument.Parse(_diskProvider.ReadAllText(_configFile));
|
||||
var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).ToList();
|
||||
|
||||
if (config.Count != 1)
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is invalid. Please delete the config file and Readarr will recreate it.");
|
||||
}
|
||||
|
||||
return xDoc;
|
||||
}
|
||||
|
||||
var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
|
||||
xDoc.Add(new XElement(CONFIG_ELEMENT_NAME));
|
||||
var newXDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
|
||||
newXDoc.Add(new XElement(CONFIG_ELEMENT_NAME));
|
||||
|
||||
return xDoc;
|
||||
return newXDoc;
|
||||
}
|
||||
}
|
||||
catch (XmlException ex)
|
||||
|
||||
@@ -122,14 +122,23 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
}
|
||||
|
||||
var items = new List<DownloadClientItem>();
|
||||
var ignoredCount = 0;
|
||||
|
||||
foreach (var torrent in torrents)
|
||||
{
|
||||
if (torrent.Hash == null)
|
||||
// Silently ignore torrents with no hash
|
||||
if (torrent.Hash.IsNullOrWhiteSpace())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore torrents without a name, but track to log a single warning for all invalid torrents.
|
||||
if (torrent.Name.IsNullOrWhiteSpace())
|
||||
{
|
||||
ignoredCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var item = new DownloadClientItem();
|
||||
item.DownloadId = torrent.Hash.ToUpper();
|
||||
item.Title = torrent.Name;
|
||||
@@ -187,6 +196,11 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||
items.Add(item);
|
||||
}
|
||||
|
||||
if (ignoredCount > 0)
|
||||
{
|
||||
_logger.Warn("{0} torrent(s) were ignored becuase they did not have a title, check Deluge and remove any invalid torrents");
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,6 +173,9 @@ namespace NzbDrone.Core.Download
|
||||
.Log();
|
||||
}
|
||||
|
||||
var episodes = _episodeService.GetEpisodes(trackedDownload.RemoteEpisode.Episodes.Select(e => e.Id));
|
||||
var files = _mediaFileService.GetFiles(episodes.Select(e => e.EpisodeFileId).Where(i => i > 0).Distinct());
|
||||
|
||||
trackedDownload.State = TrackedDownloadState.Imported;
|
||||
|
||||
var importedAuthorId = historyItems.Where(x => x.EventType == EntityHistoryEventType.BookFileImported)
|
||||
|
||||
@@ -68,16 +68,17 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||
protected override bool PostProcess(IndexerResponse indexerResponse, List<XElement> items, List<ReleaseInfo> releases)
|
||||
{
|
||||
var enclosureTypes = items.SelectMany(GetEnclosures).Select(v => v.Type).Distinct().ToArray();
|
||||
|
||||
if (enclosureTypes.Any() && enclosureTypes.Intersect(PreferredEnclosureMimeTypes).Empty())
|
||||
{
|
||||
if (enclosureTypes.Intersect(TorrentEnclosureMimeTypes).Any())
|
||||
{
|
||||
_logger.Warn("{0} does not contain {1}, found {2}, did you intend to add a Torznab indexer?", indexerResponse.Request.Url, NzbEnclosureMimeType, enclosureTypes[0]);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn("{1} does not contain {1}, found {2}.", indexerResponse.Request.Url, NzbEnclosureMimeType, enclosureTypes[0]);
|
||||
}
|
||||
|
||||
_logger.Warn("{0} does not contain {1}, found {2}.", indexerResponse.Request.Url, NzbEnclosureMimeType, enclosureTypes[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -268,26 +268,26 @@ namespace NzbDrone.Core.Indexers
|
||||
protected virtual RssEnclosure[] GetEnclosures(XElement item)
|
||||
{
|
||||
var enclosures = item.Elements("enclosure")
|
||||
.Select(v =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return new RssEnclosure
|
||||
{
|
||||
Url = v.Attribute("url")?.Value,
|
||||
Type = v.Attribute("type")?.Value,
|
||||
Length = v.Attribute("length")?.Value?.ParseInt64() ?? 0
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Warn(e, "Failed to get enclosure for: {0}", item.Title());
|
||||
}
|
||||
.Select(v =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return new RssEnclosure
|
||||
{
|
||||
Url = v.Attribute("url")?.Value,
|
||||
Type = v.Attribute("type")?.Value,
|
||||
Length = v.Attribute("length")?.Value?.ParseInt64() ?? 0
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to get enclosure for: {0}", item.Title());
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.Where(v => v != null)
|
||||
.ToArray();
|
||||
return null;
|
||||
})
|
||||
.Where(v => v != null)
|
||||
.ToArray();
|
||||
|
||||
return enclosures;
|
||||
}
|
||||
|
||||
@@ -59,16 +59,17 @@ namespace NzbDrone.Core.Indexers.Torznab
|
||||
protected override bool PostProcess(IndexerResponse indexerResponse, List<XElement> items, List<ReleaseInfo> releases)
|
||||
{
|
||||
var enclosureTypes = items.SelectMany(GetEnclosures).Select(v => v.Type).Distinct().ToArray();
|
||||
|
||||
if (enclosureTypes.Any() && enclosureTypes.Intersect(PreferredEnclosureMimeTypes).Empty())
|
||||
{
|
||||
if (enclosureTypes.Intersect(UsenetEnclosureMimeTypes).Any())
|
||||
{
|
||||
_logger.Warn("{0} does not contain {1}, found {2}, did you intend to add a Newznab indexer?", indexerResponse.Request.Url, TorrentEnclosureMimeType, enclosureTypes[0]);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn("{1} does not contain {1}, found {2}.", indexerResponse.Request.Url, TorrentEnclosureMimeType, enclosureTypes[0]);
|
||||
}
|
||||
|
||||
_logger.Warn("{0} does not contain {1}, found {2}.", indexerResponse.Request.Url, TorrentEnclosureMimeType, enclosureTypes[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace NzbDrone.Core.MediaFiles.BookImport
|
||||
private readonly IAugmentingService _augmentingService;
|
||||
private readonly IIdentificationService _identificationService;
|
||||
private readonly IRootFolderService _rootFolderService;
|
||||
private readonly IProfileService _qualityProfileService;
|
||||
private readonly IQualityProfileService _qualityProfileService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification<LocalBook>> trackSpecifications,
|
||||
@@ -63,7 +63,7 @@ namespace NzbDrone.Core.MediaFiles.BookImport
|
||||
IAugmentingService augmentingService,
|
||||
IIdentificationService identificationService,
|
||||
IRootFolderService rootFolderService,
|
||||
IProfileService qualityProfileService,
|
||||
IQualityProfileService qualityProfileService,
|
||||
Logger logger)
|
||||
{
|
||||
_trackSpecifications = trackSpecifications;
|
||||
|
||||
@@ -13,7 +13,7 @@ using NzbDrone.Core.RootFolders;
|
||||
|
||||
namespace NzbDrone.Core.Profiles.Qualities
|
||||
{
|
||||
public interface IProfileService
|
||||
public interface IQualityProfileService
|
||||
{
|
||||
QualityProfile Add(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);
|
||||
}
|
||||
|
||||
public class QualityProfileService : IProfileService,
|
||||
public class QualityProfileService : IQualityProfileService,
|
||||
IHandle<ApplicationStartedEvent>,
|
||||
IHandle<CustomFormatAddedEvent>,
|
||||
IHandle<CustomFormatDeletedEvent>
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Queue
|
||||
public class QueueService : IQueueService, IHandle<TrackedDownloadRefreshedEvent>
|
||||
{
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private static List<Queue> _queue = new List<Queue>();
|
||||
private static List<Queue> _queue = new ();
|
||||
private readonly IHistoryService _historyService;
|
||||
|
||||
public QueueService(IEventAggregator eventAggregator,
|
||||
@@ -105,8 +105,11 @@ namespace NzbDrone.Core.Queue
|
||||
|
||||
public void Handle(TrackedDownloadRefreshedEvent message)
|
||||
{
|
||||
_queue = message.TrackedDownloads.OrderBy(c => c.DownloadItem.RemainingTime).SelectMany(MapQueue)
|
||||
.ToList();
|
||||
_queue = message.TrackedDownloads
|
||||
.Where(t => t.IsTrackable)
|
||||
.OrderBy(c => c.DownloadItem.RemainingTime)
|
||||
.SelectMany(MapQueue)
|
||||
.ToList();
|
||||
|
||||
_eventAggregator.PublishEvent(new QueueUpdatedEvent());
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace NzbDrone.Core.RootFolders
|
||||
public int DefaultQualityProfileId { get; set; }
|
||||
public MonitorTypes DefaultMonitorOption { get; set; }
|
||||
public NewItemMonitorTypes DefaultNewItemMonitorOption { get; set; }
|
||||
public HashSet<int> DefaultTags { get; set; }
|
||||
public HashSet<int> DefaultTags { get; set; } = new ();
|
||||
public bool IsCalibreLibrary { get; set; }
|
||||
public CalibreSettings CalibreSettings { get; set; }
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ namespace NzbDrone.Core.Validation
|
||||
{
|
||||
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";
|
||||
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Validation
|
||||
return true;
|
||||
}
|
||||
|
||||
return _profileService.Exists((int)context.PropertyValue);
|
||||
return _qualityProfileService.Exists((int)context.PropertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using NzbDrone.Core.Books;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using Readarr.Api.V1.Author;
|
||||
using Readarr.Http.REST;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace Readarr.Api.V1.Books
|
||||
{
|
||||
@@ -38,6 +39,7 @@ namespace Readarr.Api.V1.Books
|
||||
|
||||
//Hiding this so people don't think its usable (only used to set the initial state)
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
[SwaggerIgnore]
|
||||
public bool Grabbed { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Newtonsoft.Json;
|
||||
using NzbDrone.Core.Books;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using Readarr.Http.REST;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace Readarr.Api.V1.Books
|
||||
{
|
||||
@@ -33,6 +34,7 @@ namespace Readarr.Api.V1.Books
|
||||
|
||||
//Hiding this so people don't think its usable (only used to set the initial state)
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
[SwaggerIgnore]
|
||||
public bool Grabbed { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,8 @@ namespace Readarr.Api.V1.Indexers
|
||||
{
|
||||
if (release.IndexerId == 0 && release.Indexer.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var indexer = _indexerFactory.All().FirstOrDefault(v => v.Name == release.Indexer);
|
||||
var indexer = _indexerFactory.All().FirstOrDefault(v => v.Name.EqualsIgnoreCase(release.Indexer));
|
||||
|
||||
if (indexer != null)
|
||||
{
|
||||
release.IndexerId = indexer.Id;
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace Readarr.Api.V1.Profiles.Quality
|
||||
[V1ApiController]
|
||||
public class QualityProfileController : RestController<QualityProfileResource>
|
||||
{
|
||||
private readonly IProfileService _qualityProfileService;
|
||||
private readonly IQualityProfileService _qualityProfileService;
|
||||
private readonly ICustomFormatService _formatService;
|
||||
|
||||
public QualityProfileController(IProfileService qualityProfileService, ICustomFormatService formatService)
|
||||
public QualityProfileController(IQualityProfileService qualityProfileService, ICustomFormatService formatService)
|
||||
{
|
||||
_qualityProfileService = qualityProfileService;
|
||||
_formatService = formatService;
|
||||
|
||||
@@ -7,17 +7,17 @@ namespace Readarr.Api.V1.Profiles.Quality
|
||||
[V1ApiController("qualityprofile/schema")]
|
||||
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]
|
||||
public QualityProfileResource GetSchema()
|
||||
{
|
||||
var qualityProfile = _profileService.GetDefaultProfile(string.Empty);
|
||||
var qualityProfile = _qualityProfileService.GetDefaultProfile(string.Empty);
|
||||
|
||||
return qualityProfile.ToResource();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
@@ -32,7 +33,7 @@ namespace Readarr.Api.V1
|
||||
_bulkResourceMapper = bulkResourceMapper;
|
||||
|
||||
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.Name).Must((v, c) => !_providerFactory.All().Any(p => p.Name == c && p.Id != v.Id)).WithMessage("Should be unique");
|
||||
SharedValidator.RuleFor(c => c.Name).Must((v, c) => !_providerFactory.All().Any(p => p.Name.EqualsIgnoreCase(c) && p.Id != v.Id)).WithMessage("Should be unique");
|
||||
SharedValidator.RuleFor(c => c.Implementation).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.ConfigContract).NotEmpty();
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
<ProjectReference Include="..\NzbDrone.SignalR\Readarr.SignalR.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Reflection.TypeExtensions" />
|
||||
<PackageReference Include="FluentValidation" />
|
||||
<PackageReference Include="Ical.Net" />
|
||||
<PackageReference Include="NLog" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
|
||||
<PackageReference Include="System.IO.Abstractions" />
|
||||
<PackageReference Include="System.Reflection.TypeExtensions" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -60,10 +60,12 @@ namespace Readarr.Api.V1.RootFolders
|
||||
SharedValidator.RuleFor(c => c.Name)
|
||||
.NotEmpty();
|
||||
|
||||
SharedValidator.RuleFor(c => c.DefaultMetadataProfileId)
|
||||
SharedValidator.RuleFor(c => c.DefaultMetadataProfileId).Cascade(CascadeMode.Stop)
|
||||
.ValidId()
|
||||
.SetValidator(metadataProfileExistsValidator);
|
||||
|
||||
SharedValidator.RuleFor(c => c.DefaultQualityProfileId)
|
||||
SharedValidator.RuleFor(c => c.DefaultQualityProfileId).Cascade(CascadeMode.Stop)
|
||||
.ValidId()
|
||||
.SetValidator(qualityProfileExistsValidator);
|
||||
|
||||
SharedValidator.RuleFor(c => c.Host).ValidHost().When(x => x.IsCalibreLibrary);
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Readarr.Api.V1.RootFolders
|
||||
DefaultQualityProfileId = resource.DefaultQualityProfileId,
|
||||
DefaultMonitorOption = resource.DefaultMonitorOption,
|
||||
DefaultNewItemMonitorOption = resource.DefaultNewItemMonitorOption,
|
||||
DefaultTags = resource.DefaultTags,
|
||||
DefaultTags = resource.DefaultTags ?? new HashSet<int>(),
|
||||
IsCalibreLibrary = resource.IsCalibreLibrary,
|
||||
CalibreSettings = cs
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
22
yarn.lock
22
yarn.lock
@@ -2197,11 +2197,11 @@ brace-expansion@^2.0.1:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
braces@^3.0.2, braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
|
||||
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
fill-range "^7.1.1"
|
||||
|
||||
browserslist@^4.14.5, browserslist@^4.21.5, browserslist@^4.22.2, browserslist@^4.23.0:
|
||||
version "4.23.0"
|
||||
@@ -3438,10 +3438,10 @@ filesize@10.0.7:
|
||||
resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.0.7.tgz#2237a816ee60a83fd0c3382ae70800e54eced3ad"
|
||||
integrity sha512-iMRG7Qo9nayLoU3PNCiLizYtsy4W1ClrapeCwEgtiQelOAOuRJiw4QaLI+sSr8xr901dgHv+EYP2bCusGZgoiA==
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
fill-range@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
|
||||
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
@@ -7268,9 +7268,9 @@ write-file-atomic@^5.0.1:
|
||||
signal-exit "^4.0.1"
|
||||
|
||||
ws@^7.4.5:
|
||||
version "7.5.9"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
|
||||
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
|
||||
version "7.5.10"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9"
|
||||
integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==
|
||||
|
||||
xxhashjs@~0.2.2:
|
||||
version "0.2.2"
|
||||
|
||||
Reference in New Issue
Block a user