diff --git a/src/NzbDrone.Automation.Test/MainPagesTest.cs b/src/NzbDrone.Automation.Test/MainPagesTest.cs index f11a72199..88fcd2dbd 100644 --- a/src/NzbDrone.Automation.Test/MainPagesTest.cs +++ b/src/NzbDrone.Automation.Test/MainPagesTest.cs @@ -21,7 +21,7 @@ namespace NzbDrone.Automation.Test { _page.LibraryNavIcon.Click(); _page.WaitForNoSpinner(); - _page.Find(By.CssSelector("div[class*='ArtistIndex']")).Should().NotBeNull(); + _page.Find(By.CssSelector("div[class*='AuthorIndex']")).Should().NotBeNull(); } [Test] diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedTrackFileSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedTrackFileSpecificationFixture.cs index 327803e41..953f3b35f 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedTrackFileSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DeletedTrackFileSpecificationFixture.cs @@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync private void GivenUnmonitorDeletedTracks(bool enabled) { Mocker.GetMock<IConfigService>() - .SetupGet(v => v.AutoUnmonitorPreviouslyDownloadedTracks) + .SetupGet(v => v.AutoUnmonitorPreviouslyDownloadedBooks) .Returns(enabled); } diff --git a/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs b/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs index 74d72a9b2..c66a722f9 100644 --- a/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs @@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests .Returns(_artist); Mocker.GetMock<ISearchForNzb>() - .Setup(s => s.ArtistSearch(_artist.Id, false, true, false)) + .Setup(s => s.AuthorSearch(_artist.Id, false, true, false)) .Returns(new List<DownloadDecision>()); Mocker.GetMock<IProcessDownloadDecisions>() @@ -46,7 +46,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests Subject.Execute(new AuthorSearchCommand { AuthorId = _artist.Id, Trigger = CommandTrigger.Manual }); Mocker.GetMock<ISearchForNzb>() - .Verify(v => v.ArtistSearch(_artist.Id, false, true, false), + .Verify(v => v.AuthorSearch(_artist.Id, false, true, false), Times.Exactly(_artist.Books.Value.Count(s => s.Monitored))); } } diff --git a/src/NzbDrone.Core/AuthorStats/AuthorStatisticsService.cs b/src/NzbDrone.Core/AuthorStats/AuthorStatisticsService.cs index 77d4bb947..a986d6880 100644 --- a/src/NzbDrone.Core/AuthorStats/AuthorStatisticsService.cs +++ b/src/NzbDrone.Core/AuthorStats/AuthorStatisticsService.cs @@ -105,7 +105,7 @@ namespace NzbDrone.Core.AuthorStats public void Handle(BookEditedEvent message) { _cache.Remove("AllAuthors"); - _cache.Remove(message.Album.AuthorId.ToString()); + _cache.Remove(message.Book.AuthorId.ToString()); } [EventHandleOrder(EventHandleOrder.First)] diff --git a/src/NzbDrone.Core/Books/Events/BookEditedEvent.cs b/src/NzbDrone.Core/Books/Events/BookEditedEvent.cs index 0b7b4b98b..174466535 100644 --- a/src/NzbDrone.Core/Books/Events/BookEditedEvent.cs +++ b/src/NzbDrone.Core/Books/Events/BookEditedEvent.cs @@ -4,12 +4,12 @@ namespace NzbDrone.Core.Books.Events { public class BookEditedEvent : IEvent { - public Book Album { get; private set; } + public Book Book { get; private set; } public Book OldAlbum { get; private set; } public BookEditedEvent(Book book, Book oldAlbum) { - Album = book; + Book = book; OldAlbum = oldAlbum; } } diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 7e79f1ec9..279aa9dd6 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -78,7 +78,7 @@ namespace NzbDrone.Core.Configuration return _repository.Get(key.ToLower()) != null; } - public bool AutoUnmonitorPreviouslyDownloadedTracks + public bool AutoUnmonitorPreviouslyDownloadedBooks { get { return GetValueBoolean("AutoUnmonitorPreviouslyDownloadedTracks"); } set { SetValue("AutoUnmonitorPreviouslyDownloadedTracks", value); } @@ -158,7 +158,7 @@ namespace NzbDrone.Core.Configuration set { SetValue("RemoveFailedDownloads", value); } } - public bool CreateEmptyArtistFolders + public bool CreateEmptyAuthorFolders { get { return GetValueBoolean("CreateEmptyArtistFolders", false); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 3ec13925b..30cb979a4 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -24,11 +24,11 @@ namespace NzbDrone.Core.Configuration bool RemoveFailedDownloads { get; set; } //Media Management - bool AutoUnmonitorPreviouslyDownloadedTracks { get; set; } + bool AutoUnmonitorPreviouslyDownloadedBooks { get; set; } string RecycleBin { get; set; } int RecycleBinCleanupDays { get; set; } ProperDownloadTypes DownloadPropersAndRepacks { get; set; } - bool CreateEmptyArtistFolders { get; set; } + bool CreateEmptyAuthorFolders { get; set; } bool DeleteEmptyFolders { get; set; } FileDateType FileDate { get; set; } bool SkipFreeSpaceCheckWhenImporting { get; set; } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DeletedBookFileSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DeletedBookFileSpecification.cs index 9827ea12e..9d8267598 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DeletedBookFileSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DeletedBookFileSpecification.cs @@ -33,7 +33,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync public virtual Decision IsSatisfiedBy(RemoteBook subject, SearchCriteriaBase searchCriteria) { - if (!_configService.AutoUnmonitorPreviouslyDownloadedTracks) + if (!_configService.AutoUnmonitorPreviouslyDownloadedBooks) { return Decision.Accept(); } diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs index 0bdc7a3d1..68c84f504 100644 --- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs +++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadAlreadyImported.cs @@ -33,7 +33,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads return false; } - return new[] { HistoryEventType.DownloadImported, HistoryEventType.TrackFileImported }.Contains(lastHistoryItem.EventType); + return new[] { HistoryEventType.DownloadImported, HistoryEventType.BookFileImported }.Contains(lastHistoryItem.EventType); }); return allAlbumsImportedInHistory; diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs index 9bf8883f9..0c3ac9e75 100644 --- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs +++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs @@ -257,7 +257,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads } // Since DownloadComplete is a new event type, we can't assume it exists for old downloads - if (history.EventType == HistoryEventType.TrackFileImported) + if (history.EventType == HistoryEventType.BookFileImported) { return DateTime.UtcNow.Subtract(history.Date).TotalSeconds < 60 ? TrackedDownloadState.Importing : TrackedDownloadState.Imported; } diff --git a/src/NzbDrone.Core/History/History.cs b/src/NzbDrone.Core/History/History.cs index bebed95f0..a0f547a27 100644 --- a/src/NzbDrone.Core/History/History.cs +++ b/src/NzbDrone.Core/History/History.cs @@ -32,14 +32,14 @@ namespace NzbDrone.Core.History { Unknown = 0, Grabbed = 1, - ArtistFolderImported = 2, - TrackFileImported = 3, + AuthorFolderImported = 2, + BookFileImported = 3, DownloadFailed = 4, - TrackFileDeleted = 5, - TrackFileRenamed = 6, + BookFileDeleted = 5, + BookFileRenamed = 6, BookImportIncomplete = 7, DownloadImported = 8, - TrackFileRetagged = 9, + BookFileRetagged = 9, DownloadIgnored = 10 } } diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index c7d5b0ab5..61cddb484 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -90,7 +90,7 @@ namespace NzbDrone.Core.History public List<History> FindDownloadHistory(int idAuthorId, QualityModel quality) { - var allowed = new[] { HistoryEventType.Grabbed, HistoryEventType.DownloadFailed, HistoryEventType.TrackFileImported }; + var allowed = new[] { HistoryEventType.Grabbed, HistoryEventType.DownloadFailed, HistoryEventType.BookFileImported }; return Query(h => h.AuthorId == idAuthorId && h.Quality == quality && diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index a4ad30f94..d72350a9b 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -215,7 +215,7 @@ namespace NzbDrone.Core.History var history = new History { - EventType = HistoryEventType.TrackFileImported, + EventType = HistoryEventType.BookFileImported, Date = DateTime.UtcNow, Quality = message.BookInfo.Quality, SourceTitle = message.ImportedBook.SceneName ?? Path.GetFileNameWithoutExtension(message.BookInfo.Path), @@ -289,7 +289,7 @@ namespace NzbDrone.Core.History var history = new History { - EventType = HistoryEventType.TrackFileDeleted, + EventType = HistoryEventType.BookFileDeleted, Date = DateTime.UtcNow, Quality = message.BookFile.Quality, SourceTitle = message.BookFile.Path, @@ -309,7 +309,7 @@ namespace NzbDrone.Core.History var history = new History { - EventType = HistoryEventType.TrackFileRenamed, + EventType = HistoryEventType.BookFileRenamed, Date = DateTime.UtcNow, Quality = message.BookFile.Quality, SourceTitle = message.OriginalPath, @@ -329,7 +329,7 @@ namespace NzbDrone.Core.History var history = new History { - EventType = HistoryEventType.TrackFileRetagged, + EventType = HistoryEventType.BookFileRetagged, Date = DateTime.UtcNow, Quality = message.BookFile.Quality, SourceTitle = path, diff --git a/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs b/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs index 7893a7a26..d75f9d0ce 100644 --- a/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Core.IndexerSearch public void Execute(AuthorSearchCommand message) { - var decisions = _nzbSearchService.ArtistSearch(message.AuthorId, false, message.Trigger == CommandTrigger.Manual, false); + var decisions = _nzbSearchService.AuthorSearch(message.AuthorId, false, message.Trigger == CommandTrigger.Manual, false); var processed = _processDownloadDecisions.ProcessDecisions(decisions); _logger.ProgressInfo("Author search completed. {0} reports downloaded.", processed.Grabbed.Count); diff --git a/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs b/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs index 4bad2da65..5b432a5ab 100644 --- a/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs @@ -47,7 +47,7 @@ namespace NzbDrone.Core.IndexerSearch foreach (var book in books) { List<DownloadDecision> decisions; - decisions = _nzbSearchService.AlbumSearch(book.Id, false, userInvokedSearch, false); + decisions = _nzbSearchService.BookSearch(book.Id, false, userInvokedSearch, false); var processed = _processDownloadDecisions.ProcessDecisions(decisions); downloadedCount += processed.Grabbed.Count; @@ -61,7 +61,7 @@ namespace NzbDrone.Core.IndexerSearch foreach (var bookId in message.BookIds) { var decisions = - _nzbSearchService.AlbumSearch(bookId, false, message.Trigger == CommandTrigger.Manual, false); + _nzbSearchService.BookSearch(bookId, false, message.Trigger == CommandTrigger.Manual, false); var processed = _processDownloadDecisions.ProcessDecisions(decisions); _logger.ProgressInfo("Book search completed. {0} reports downloaded.", processed.Grabbed.Count); diff --git a/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs b/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs index 4b13f9359..6b7ee6866 100644 --- a/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs @@ -16,8 +16,8 @@ namespace NzbDrone.Core.IndexerSearch { public interface ISearchForNzb { - List<DownloadDecision> AlbumSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); - List<DownloadDecision> ArtistSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); + List<DownloadDecision> BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); + List<DownloadDecision> AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); } public class NzbSearchService : ISearchForNzb @@ -41,13 +41,13 @@ namespace NzbDrone.Core.IndexerSearch _logger = logger; } - public List<DownloadDecision> AlbumSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public List<DownloadDecision> BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var book = _bookService.GetBook(bookId); return AlbumSearch(book, missingOnly, userInvokedSearch, interactiveSearch); } - public List<DownloadDecision> ArtistSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public List<DownloadDecision> AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var author = _authorService.GetAuthor(authorId); return ArtistSearch(author, missingOnly, userInvokedSearch, interactiveSearch); diff --git a/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs b/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs index ac54f74a8..da913c251 100644 --- a/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs @@ -15,13 +15,13 @@ using NzbDrone.Core.Organizer; namespace NzbDrone.Core.MediaFiles { - public interface IRenameTrackFileService + public interface IRenameBookFileService { List<RenameBookFilePreview> GetRenamePreviews(int authorId); List<RenameBookFilePreview> GetRenamePreviews(int authorId, int bookId); } - public class RenameBookFileService : IRenameTrackFileService, IExecute<RenameFilesCommand>, IExecute<RenameAuthorCommand> + public class RenameBookFileService : IRenameBookFileService, IExecute<RenameFilesCommand>, IExecute<RenameAuthorCommand> { private readonly IAuthorService _authorService; private readonly IMediaFileService _mediaFileService; diff --git a/src/NzbDrone.Core/Validation/Paths/ArtistAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs similarity index 100% rename from src/NzbDrone.Core/Validation/Paths/ArtistAncestorValidator.cs rename to src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs diff --git a/src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs similarity index 83% rename from src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs rename to src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs index f68bea0ee..6a9b1958f 100644 --- a/src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs @@ -3,11 +3,11 @@ using NzbDrone.Core.Books; namespace NzbDrone.Core.Validation.Paths { - public class ArtistExistsValidator : PropertyValidator + public class AuthorExistsValidator : PropertyValidator { private readonly IAuthorService _authorService; - public ArtistExistsValidator(IAuthorService authorService) + public AuthorExistsValidator(IAuthorService authorService) : base("This author has already been added.") { _authorService = authorService; diff --git a/src/NzbDrone.Core/Validation/Paths/ArtistPathValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs similarity index 100% rename from src/NzbDrone.Core/Validation/Paths/ArtistPathValidator.cs rename to src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs diff --git a/src/NzbDrone.Integration.Test/ApiTests/ArtistEditorFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/ArtistEditorFixture.cs deleted file mode 100644 index e9c8772f3..000000000 --- a/src/NzbDrone.Integration.Test/ApiTests/ArtistEditorFixture.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Linq; -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Test.Common; -using Readarr.Api.V1.Artist; - -namespace NzbDrone.Integration.Test.ApiTests -{ - [TestFixture] - public class ArtistEditorFixture : IntegrationTest - { - private void GivenExistingArtist() - { - foreach (var name in new[] { "Alien Ant Farm", "Kiss" }) - { - var newArtist = Artist.Lookup(name).First(); - - newArtist.QualityProfileId = 1; - newArtist.MetadataProfileId = 1; - newArtist.Path = string.Format(@"C:\Test\{0}", name).AsOsAgnostic(); - - Artist.Post(newArtist); - } - } - - [Test] - public void should_be_able_to_update_multiple_artist() - { - GivenExistingArtist(); - - var artist = Artist.All(); - - var artistEditor = new ArtistEditorResource - { - QualityProfileId = 2, - AuthorIds = artist.Select(o => o.Id).ToList() - }; - - var result = Artist.Editor(artistEditor); - - result.Should().HaveCount(2); - result.TrueForAll(s => s.QualityProfileId == 2).Should().BeTrue(); - } - } -} diff --git a/src/NzbDrone.Integration.Test/ApiTests/ArtistLookupFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/ArtistLookupFixture.cs deleted file mode 100644 index 16954aa9c..000000000 --- a/src/NzbDrone.Integration.Test/ApiTests/ArtistLookupFixture.cs +++ /dev/null @@ -1,28 +0,0 @@ -using FluentAssertions; -using NUnit.Framework; - -namespace NzbDrone.Integration.Test.ApiTests -{ - [TestFixture] - public class ArtistLookupFixture : IntegrationTest - { - [TestCase("Robert Harris", "Robert Harris")] - [TestCase("J.K. Rowling", "J.K. Rowling")] - public void lookup_new_artist_by_name(string term, string name) - { - var artist = Artist.Lookup(term); - - artist.Should().NotBeEmpty(); - artist.Should().Contain(c => c.ArtistName == name); - } - - [Test] - public void lookup_new_artist_by_goodreads_book_id() - { - var artist = Artist.Lookup("readarr:1"); - - artist.Should().NotBeEmpty(); - artist.Should().Contain(c => c.ArtistName == "J.K. Rowling"); - } - } -} diff --git a/src/NzbDrone.Integration.Test/ApiTests/AuthorEditorFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/AuthorEditorFixture.cs new file mode 100644 index 000000000..cd08d7fdc --- /dev/null +++ b/src/NzbDrone.Integration.Test/ApiTests/AuthorEditorFixture.cs @@ -0,0 +1,45 @@ +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Test.Common; +using Readarr.Api.V1.Author; + +namespace NzbDrone.Integration.Test.ApiTests +{ + [TestFixture] + public class AuthorEditorFixture : IntegrationTest + { + private void GivenExistingAuthor() + { + foreach (var name in new[] { "Alien Ant Farm", "Kiss" }) + { + var newAuthor = Author.Lookup(name).First(); + + newAuthor.QualityProfileId = 1; + newAuthor.MetadataProfileId = 1; + newAuthor.Path = string.Format(@"C:\Test\{0}", name).AsOsAgnostic(); + + Author.Post(newAuthor); + } + } + + [Test] + public void should_be_able_to_update_multiple_artist() + { + GivenExistingAuthor(); + + var author = Author.All(); + + var artistEditor = new AuthorEditorResource + { + QualityProfileId = 2, + AuthorIds = author.Select(o => o.Id).ToList() + }; + + var result = Author.Editor(artistEditor); + + result.Should().HaveCount(2); + result.TrueForAll(s => s.QualityProfileId == 2).Should().BeTrue(); + } + } +} diff --git a/src/NzbDrone.Integration.Test/ApiTests/ArtistFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/AuthorFixture.cs similarity index 64% rename from src/NzbDrone.Integration.Test/ApiTests/ArtistFixture.cs rename to src/NzbDrone.Integration.Test/ApiTests/AuthorFixture.cs index 0f443e514..3a682d56f 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/ArtistFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/AuthorFixture.cs @@ -7,7 +7,7 @@ using NUnit.Framework; namespace NzbDrone.Integration.Test.ApiTests { [TestFixture] - public class ArtistFixture : IntegrationTest + public class AuthorFixture : IntegrationTest { [Test] [Order(0)] @@ -16,15 +16,15 @@ namespace NzbDrone.Integration.Test.ApiTests EnsureNoArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "J.K. Rowling"); var tag = EnsureTag("abc"); - var artist = Artist.Lookup("readarr:1").Single(); + var author = Author.Lookup("readarr:1").Single(); - artist.QualityProfileId = 1; - artist.MetadataProfileId = 1; - artist.Path = Path.Combine(ArtistRootFolder, artist.ArtistName); - artist.Tags = new HashSet<int>(); - artist.Tags.Add(tag.Id); + author.QualityProfileId = 1; + author.MetadataProfileId = 1; + author.Path = Path.Combine(AuthorRootFolder, author.AuthorName); + author.Tags = new HashSet<int>(); + author.Tags.Add(tag.Id); - var result = Artist.Post(artist); + var result = Author.Post(author); result.Should().NotBeNull(); result.Tags.Should().Equal(tag.Id); @@ -38,11 +38,11 @@ namespace NzbDrone.Integration.Test.ApiTests EnsureNoArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "J.K. Rowling"); - var artist = Artist.Lookup("readarr:1").Single(); + var artist = Author.Lookup("readarr:1").Single(); - artist.Path = Path.Combine(ArtistRootFolder, artist.ArtistName); + artist.Path = Path.Combine(AuthorRootFolder, artist.AuthorName); - Artist.InvalidPost(artist); + Author.InvalidPost(artist); } [Test] @@ -53,11 +53,11 @@ namespace NzbDrone.Integration.Test.ApiTests EnsureNoArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "J.K. Rowling"); - var artist = Artist.Lookup("readarr:1").Single(); + var artist = Author.Lookup("readarr:1").Single(); artist.QualityProfileId = 1; - Artist.InvalidPost(artist); + Author.InvalidPost(artist); } [Test] @@ -66,29 +66,29 @@ namespace NzbDrone.Integration.Test.ApiTests { EnsureNoArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "J.K. Rowling"); - var artist = Artist.Lookup("readarr:1").Single(); + var artist = Author.Lookup("readarr:1").Single(); artist.QualityProfileId = 1; artist.MetadataProfileId = 1; - artist.Path = Path.Combine(ArtistRootFolder, artist.ArtistName); + artist.Path = Path.Combine(AuthorRootFolder, artist.AuthorName); - var result = Artist.Post(artist); + var result = Author.Post(artist); result.Should().NotBeNull(); result.Id.Should().NotBe(0); result.QualityProfileId.Should().Be(1); result.MetadataProfileId.Should().Be(1); - result.Path.Should().Be(Path.Combine(ArtistRootFolder, artist.ArtistName)); + result.Path.Should().Be(Path.Combine(AuthorRootFolder, artist.AuthorName)); } [Test] [Order(2)] public void get_all_artist() { - EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); - EnsureArtist("amzn1.gr.author.v1.qTrNu9-PIaaBj5gYRDmN4Q", "34497", "Terry Pratchett"); + EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); + EnsureAuthor("amzn1.gr.author.v1.qTrNu9-PIaaBj5gYRDmN4Q", "34497", "Terry Pratchett"); - var artists = Artist.All(); + var artists = Author.All(); artists.Should().NotBeNullOrEmpty(); artists.Should().Contain(v => v.ForeignAuthorId == "amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ"); @@ -99,9 +99,9 @@ namespace NzbDrone.Integration.Test.ApiTests [Order(2)] public void get_artist_by_id() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); - var result = Artist.Get(artist.Id); + var result = Author.Get(artist.Id); result.ForeignAuthorId.Should().Be("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ"); } @@ -111,14 +111,14 @@ namespace NzbDrone.Integration.Test.ApiTests { IgnoreOnMonoVersions("5.12", "5.14"); - var result = Artist.InvalidGet(1000000); + var result = Author.InvalidGet(1000000); } [Test] [Order(2)] public void update_artist_profile_id() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); var profileId = 1; if (artist.QualityProfileId == profileId) @@ -128,16 +128,16 @@ namespace NzbDrone.Integration.Test.ApiTests artist.QualityProfileId = profileId; - var result = Artist.Put(artist); + var result = Author.Put(artist); - Artist.Get(artist.Id).QualityProfileId.Should().Be(profileId); + Author.Get(artist.Id).QualityProfileId.Should().Be(profileId); } [Test] [Order(3)] public void update_artist_monitored() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); artist.Monitored.Should().BeFalse(); @@ -148,7 +148,7 @@ namespace NzbDrone.Integration.Test.ApiTests //{ // season.Monitored = true; //}); - var result = Artist.Put(artist); + var result = Author.Put(artist); result.Monitored.Should().BeTrue(); @@ -159,22 +159,22 @@ namespace NzbDrone.Integration.Test.ApiTests [Order(3)] public void update_artist_tags() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); var tag = EnsureTag("abc"); if (artist.Tags.Contains(tag.Id)) { artist.Tags.Remove(tag.Id); - var result = Artist.Put(artist); - Artist.Get(artist.Id).Tags.Should().NotContain(tag.Id); + var result = Author.Put(artist); + Author.Get(artist.Id).Tags.Should().NotContain(tag.Id); } else { artist.Tags.Add(tag.Id); - var result = Artist.Put(artist); - Artist.Get(artist.Id).Tags.Should().Contain(tag.Id); + var result = Author.Put(artist); + Author.Get(artist.Id).Tags.Should().Contain(tag.Id); } } @@ -182,13 +182,13 @@ namespace NzbDrone.Integration.Test.ApiTests [Order(4)] public void delete_artist() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); - Artist.Get(artist.Id).Should().NotBeNull(); + Author.Get(artist.Id).Should().NotBeNull(); - Artist.Delete(artist.Id); + Author.Delete(artist.Id); - Artist.All().Should().NotContain(v => v.ForeignAuthorId == "amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ"); + Author.All().Should().NotContain(v => v.ForeignAuthorId == "amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ"); } } } diff --git a/src/NzbDrone.Integration.Test/ApiTests/AuthorLookupFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/AuthorLookupFixture.cs new file mode 100644 index 000000000..9173edda3 --- /dev/null +++ b/src/NzbDrone.Integration.Test/ApiTests/AuthorLookupFixture.cs @@ -0,0 +1,28 @@ +using FluentAssertions; +using NUnit.Framework; + +namespace NzbDrone.Integration.Test.ApiTests +{ + [TestFixture] + public class AuthorLookupFixture : IntegrationTest + { + [TestCase("Robert Harris", "Robert Harris")] + [TestCase("J.K. Rowling", "J.K. Rowling")] + public void lookup_new_author_by_name(string term, string name) + { + var author = Author.Lookup(term); + + author.Should().NotBeEmpty(); + author.Should().Contain(c => c.AuthorName == name); + } + + [Test] + public void lookup_new_author_by_goodreads_book_id() + { + var author = Author.Lookup("readarr:1"); + + author.Should().NotBeEmpty(); + author.Should().Contain(c => c.AuthorName == "J.K. Rowling"); + } + } +} diff --git a/src/NzbDrone.Integration.Test/ApiTests/BlacklistFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/BlacklistFixture.cs index f5777761b..c1980fe05 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/BlacklistFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/BlacklistFixture.cs @@ -1,6 +1,6 @@ using FluentAssertions; using NUnit.Framework; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; using Readarr.Api.V1.Blacklist; namespace NzbDrone.Integration.Test.ApiTests @@ -8,13 +8,13 @@ namespace NzbDrone.Integration.Test.ApiTests [TestFixture] public class BlacklistFixture : IntegrationTest { - private ArtistResource _artist; + private AuthorResource _artist; [Test] [Ignore("Adding to blacklist not supported")] public void should_be_able_to_add_to_blacklist() { - _artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); + _artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling"); Blacklist.Post(new BlacklistResource { diff --git a/src/NzbDrone.Integration.Test/ApiTests/TrackFileFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/BookFileFixture.cs similarity index 55% rename from src/NzbDrone.Integration.Test/ApiTests/TrackFileFixture.cs rename to src/NzbDrone.Integration.Test/ApiTests/BookFileFixture.cs index 226c8910c..c1fbf7e16 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/TrackFileFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/BookFileFixture.cs @@ -1,12 +1,12 @@ -using NUnit.Framework; +using NUnit.Framework; namespace NzbDrone.Integration.Test.ApiTests { [TestFixture] - public class TrackFileFixture : IntegrationTest + public class BookFileFixture : IntegrationTest { [Test] - public void get_all_trackfiles() + public void get_all_bookfiles() { Assert.Ignore("TODO"); } diff --git a/src/NzbDrone.Integration.Test/ApiTests/CalendarFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/CalendarFixture.cs index c877c37dd..8e344ee32 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/CalendarFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/CalendarFixture.cs @@ -4,31 +4,31 @@ using System.Linq; using FluentAssertions; using NUnit.Framework; using NzbDrone.Integration.Test.Client; -using Readarr.Api.V1.Albums; +using Readarr.Api.V1.Books; namespace NzbDrone.Integration.Test.ApiTests { [TestFixture] public class CalendarFixture : IntegrationTest { - public ClientBase<AlbumResource> Calendar; + public ClientBase<BookResource> Calendar; protected override void InitRestClients() { base.InitRestClients(); - Calendar = new ClientBase<AlbumResource>(RestClient, ApiKey, "calendar"); + Calendar = new ClientBase<BookResource>(RestClient, ApiKey, "calendar"); } [Test] public void should_be_able_to_get_albums() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); var request = Calendar.BuildRequest(); request.AddParameter("start", new DateTime(2003, 06, 20).ToString("s") + "Z"); request.AddParameter("end", new DateTime(2003, 06, 22).ToString("s") + "Z"); - var items = Calendar.Get<List<AlbumResource>>(request); + var items = Calendar.Get<List<BookResource>>(request); items = items.Where(v => v.AuthorId == artist.Id).ToList(); @@ -39,13 +39,13 @@ namespace NzbDrone.Integration.Test.ApiTests [Test] public void should_not_be_able_to_get_unmonitored_albums() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); var request = Calendar.BuildRequest(); request.AddParameter("start", new DateTime(2003, 06, 20).ToString("s") + "Z"); request.AddParameter("end", new DateTime(2003, 06, 22).ToString("s") + "Z"); request.AddParameter("unmonitored", "false"); - var items = Calendar.Get<List<AlbumResource>>(request); + var items = Calendar.Get<List<BookResource>>(request); items = items.Where(v => v.AuthorId == artist.Id).ToList(); @@ -55,13 +55,13 @@ namespace NzbDrone.Integration.Test.ApiTests [Test] public void should_be_able_to_get_unmonitored_albums() { - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); var request = Calendar.BuildRequest(); request.AddParameter("start", new DateTime(2003, 06, 20).ToString("s") + "Z"); request.AddParameter("end", new DateTime(2003, 06, 22).ToString("s") + "Z"); request.AddParameter("unmonitored", "true"); - var items = Calendar.Get<List<AlbumResource>>(request); + var items = Calendar.Get<List<BookResource>>(request); items = items.Where(v => v.AuthorId == artist.Id).ToList(); diff --git a/src/NzbDrone.Integration.Test/ApiTests/ReleaseFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/ReleaseFixture.cs index f9bd57a80..6faf557cf 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/ReleaseFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/ReleaseFixture.cs @@ -47,7 +47,7 @@ namespace NzbDrone.Integration.Test.ApiTests releaseResource.Age.Should().BeGreaterOrEqualTo(-1); releaseResource.Title.Should().NotBeNullOrWhiteSpace(); releaseResource.DownloadUrl.Should().NotBeNullOrWhiteSpace(); - releaseResource.ArtistName.Should().NotBeNullOrWhiteSpace(); + releaseResource.AuthorName.Should().NotBeNullOrWhiteSpace(); //TODO: uncomment these after moving to restsharp for rss //releaseResource.NzbInfoUrl.Should().NotBeNullOrWhiteSpace(); diff --git a/src/NzbDrone.Integration.Test/ApiTests/WantedFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/WantedFixture.cs index f59870719..3be5c9014 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/WantedFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/WantedFixture.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Integration.Test.ApiTests RootFolders.Post(new RootFolderResource { Name = "TestLibrary", - Path = ArtistRootFolder, + Path = AuthorRootFolder, DefaultMetadataProfileId = 1, DefaultQualityProfileId = 1, DefaultMonitorOption = MonitorTypes.All @@ -39,7 +39,7 @@ namespace NzbDrone.Integration.Test.ApiTests [Order(1)] public void missing_should_have_monitored_items() { - EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); + EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); var result = WantedMissing.GetPaged(0, 15, "releaseDate", "desc"); @@ -50,12 +50,12 @@ namespace NzbDrone.Integration.Test.ApiTests [Order(1)] public void missing_should_have_artist() { - EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); + EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); var result = WantedMissing.GetPaged(0, 15, "releaseDate", "desc"); - result.Records.First().Artist.Should().NotBeNull(); - result.Records.First().Artist.ArtistName.Should().Be("J.K. Rowling"); + result.Records.First().Author.Should().NotBeNull(); + result.Records.First().Author.AuthorName.Should().Be("J.K. Rowling"); } [Test] @@ -63,8 +63,8 @@ namespace NzbDrone.Integration.Test.ApiTests public void cutoff_should_have_monitored_items() { EnsureProfileCutoff(1, Quality.AZW3); - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); - EnsureTrackFile(artist, 1, Quality.MOBI); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); + EnsureBookFile(artist, 1, Quality.MOBI); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc"); @@ -75,7 +75,7 @@ namespace NzbDrone.Integration.Test.ApiTests [Order(1)] public void missing_should_not_have_unmonitored_items() { - EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); var result = WantedMissing.GetPaged(0, 15, "releaseDate", "desc"); @@ -87,8 +87,8 @@ namespace NzbDrone.Integration.Test.ApiTests public void cutoff_should_not_have_unmonitored_items() { EnsureProfileCutoff(1, Quality.AZW3); - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); - EnsureTrackFile(artist, 1, Quality.MOBI); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + EnsureBookFile(artist, 1, Quality.MOBI); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc"); @@ -100,20 +100,20 @@ namespace NzbDrone.Integration.Test.ApiTests public void cutoff_should_have_artist() { EnsureProfileCutoff(1, Quality.AZW3); - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); - EnsureTrackFile(artist, 1, Quality.MOBI); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", true); + EnsureBookFile(artist, 1, Quality.MOBI); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc"); - result.Records.First().Artist.Should().NotBeNull(); - result.Records.First().Artist.ArtistName.Should().Be("J.K. Rowling"); + result.Records.First().Author.Should().NotBeNull(); + result.Records.First().Author.AuthorName.Should().Be("J.K. Rowling"); } [Test] [Order(2)] public void missing_should_have_unmonitored_items() { - EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); var result = WantedMissing.GetPaged(0, 15, "releaseDate", "desc", "monitored", "false"); @@ -125,8 +125,8 @@ namespace NzbDrone.Integration.Test.ApiTests public void cutoff_should_have_unmonitored_items() { EnsureProfileCutoff(1, Quality.AZW3); - var artist = EnsureArtist("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); - EnsureTrackFile(artist, 1, Quality.MOBI); + var artist = EnsureAuthor("amzn1.gr.author.v1.SHA8asP5mFyLIP9NlujvLQ", "1", "J.K. Rowling", false); + EnsureBookFile(artist, 1, Quality.MOBI); var result = WantedCutoffUnmet.GetPaged(0, 15, "releaseDate", "desc", "monitored", "false"); diff --git a/src/NzbDrone.Integration.Test/Client/AlbumClient.cs b/src/NzbDrone.Integration.Test/Client/AlbumClient.cs deleted file mode 100644 index ebc0df11f..000000000 --- a/src/NzbDrone.Integration.Test/Client/AlbumClient.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using Readarr.Api.V1.Albums; -using RestSharp; - -namespace NzbDrone.Integration.Test.Client -{ - public class AlbumClient : ClientBase<AlbumResource> - { - public AlbumClient(IRestClient restClient, string apiKey) - : base(restClient, apiKey, "album") - { - } - - public List<AlbumResource> GetAlbumsInArtist(int authorId) - { - var request = BuildRequest("?authorId=" + authorId.ToString()); - return Get<List<AlbumResource>>(request); - } - } -} diff --git a/src/NzbDrone.Integration.Test/Client/ArtistClient.cs b/src/NzbDrone.Integration.Test/Client/AuthorClient.cs similarity index 54% rename from src/NzbDrone.Integration.Test/Client/ArtistClient.cs rename to src/NzbDrone.Integration.Test/Client/AuthorClient.cs index 593405208..bf2c5256e 100644 --- a/src/NzbDrone.Integration.Test/Client/ArtistClient.cs +++ b/src/NzbDrone.Integration.Test/Client/AuthorClient.cs @@ -1,39 +1,39 @@ using System.Collections.Generic; using System.Net; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; using RestSharp; namespace NzbDrone.Integration.Test.Client { - public class ArtistClient : ClientBase<ArtistResource> + public class AuthorClient : ClientBase<AuthorResource> { - public ArtistClient(IRestClient restClient, string apiKey) + public AuthorClient(IRestClient restClient, string apiKey) : base(restClient, apiKey) { } - public List<ArtistResource> Lookup(string term) + public List<AuthorResource> Lookup(string term) { var request = BuildRequest("lookup"); request.AddQueryParameter("term", term); - return Get<List<ArtistResource>>(request); + return Get<List<AuthorResource>>(request); } - public List<ArtistResource> Editor(ArtistEditorResource artist) + public List<AuthorResource> Editor(AuthorEditorResource artist) { var request = BuildRequest("editor"); request.AddJsonBody(artist); - return Put<List<ArtistResource>>(request); + return Put<List<AuthorResource>>(request); } - public ArtistResource Get(string slug, HttpStatusCode statusCode = HttpStatusCode.OK) + public AuthorResource Get(string slug, HttpStatusCode statusCode = HttpStatusCode.OK) { var request = BuildRequest(slug); - return Get<ArtistResource>(request, statusCode); + return Get<AuthorResource>(request, statusCode); } } - public class SystemInfoClient : ClientBase<ArtistResource> + public class SystemInfoClient : ClientBase<AuthorResource> { public SystemInfoClient(IRestClient restClient, string apiKey) : base(restClient, apiKey) diff --git a/src/NzbDrone.Integration.Test/Client/BookClient.cs b/src/NzbDrone.Integration.Test/Client/BookClient.cs new file mode 100644 index 000000000..a25a47562 --- /dev/null +++ b/src/NzbDrone.Integration.Test/Client/BookClient.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using Readarr.Api.V1.Books; +using RestSharp; + +namespace NzbDrone.Integration.Test.Client +{ + public class BookClient : ClientBase<BookResource> + { + public BookClient(IRestClient restClient, string apiKey) + : base(restClient, apiKey, "book") + { + } + + public List<BookResource> GetBooksInAuthor(int authorId) + { + var request = BuildRequest("?authorId=" + authorId.ToString()); + return Get<List<BookResource>>(request); + } + } +} diff --git a/src/NzbDrone.Integration.Test/CorsFixture.cs b/src/NzbDrone.Integration.Test/CorsFixture.cs index 6aa98c428..19f864c61 100644 --- a/src/NzbDrone.Integration.Test/CorsFixture.cs +++ b/src/NzbDrone.Integration.Test/CorsFixture.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Integration.Test [TestFixture] public class CorsFixture : IntegrationTest { - private RestRequest BuildGet(string route = "artist") + private RestRequest BuildGet(string route = "author") { var request = new RestRequest(route, Method.GET); request.AddHeader(AccessControlHeaders.RequestMethod, "POST"); @@ -16,7 +16,7 @@ namespace NzbDrone.Integration.Test return request; } - private RestRequest BuildOptions(string route = "artist") + private RestRequest BuildOptions(string route = "author") { var request = new RestRequest(route, Method.OPTIONS); diff --git a/src/NzbDrone.Integration.Test/HttpLogFixture.cs b/src/NzbDrone.Integration.Test/HttpLogFixture.cs index 0bcc61f0b..15d3d2fdc 100644 --- a/src/NzbDrone.Integration.Test/HttpLogFixture.cs +++ b/src/NzbDrone.Integration.Test/HttpLogFixture.cs @@ -17,20 +17,20 @@ namespace NzbDrone.Integration.Test config.LogLevel = "Trace"; HostConfig.Put(config); - var resultGet = Artist.All(); + var resultGet = Author.All(); var logFile = "Readarr.trace.txt"; var logLines = Logs.GetLogFileLines(logFile); - var result = Artist.InvalidPost(new Readarr.Api.V1.Artist.ArtistResource()); + var result = Author.InvalidPost(new Readarr.Api.V1.Author.AuthorResource()); // Skip 2 and 1 to ignore the logs endpoint logLines = Logs.GetLogFileLines(logFile).Skip(logLines.Length + 2).ToArray(); Array.Resize(ref logLines, logLines.Length - 1); - logLines.Should().Contain(v => v.Contains("|Trace|Http|Req") && v.Contains("/api/v1/artist/")); - logLines.Should().Contain(v => v.Contains("|Trace|Http|Res") && v.Contains("/api/v1/artist/: 400.BadRequest")); - logLines.Should().Contain(v => v.Contains("|Debug|Api|") && v.Contains("/api/v1/artist/: 400.BadRequest")); + logLines.Should().Contain(v => v.Contains("|Trace|Http|Req") && v.Contains("/api/v1/author/")); + logLines.Should().Contain(v => v.Contains("|Trace|Http|Res") && v.Contains("/api/v1/author/: 400.BadRequest")); + logLines.Should().Contain(v => v.Contains("|Debug|Api|") && v.Contains("/api/v1/author/: 400.BadRequest")); } } } diff --git a/src/NzbDrone.Integration.Test/IntegrationTest.cs b/src/NzbDrone.Integration.Test/IntegrationTest.cs index 0fb225bdb..7659b7958 100644 --- a/src/NzbDrone.Integration.Test/IntegrationTest.cs +++ b/src/NzbDrone.Integration.Test/IntegrationTest.cs @@ -9,7 +9,7 @@ namespace NzbDrone.Integration.Test { protected NzbDroneRunner _runner; - public override string ArtistRootFolder => GetTempDirectory("ArtistRootFolder"); + public override string AuthorRootFolder => GetTempDirectory("AuthorRootFolder"); protected override string RootUrl => "http://localhost:8787/"; diff --git a/src/NzbDrone.Integration.Test/IntegrationTestBase.cs b/src/NzbDrone.Integration.Test/IntegrationTestBase.cs index d989e89f2..6fe2932b8 100644 --- a/src/NzbDrone.Integration.Test/IntegrationTestBase.cs +++ b/src/NzbDrone.Integration.Test/IntegrationTestBase.cs @@ -17,9 +17,9 @@ using NzbDrone.Integration.Test.Client; using NzbDrone.SignalR; using NzbDrone.Test.Common; using NzbDrone.Test.Common.Categories; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; using Readarr.Api.V1.Blacklist; +using Readarr.Api.V1.Books; using Readarr.Api.V1.Config; using Readarr.Api.V1.DownloadClient; using Readarr.Api.V1.History; @@ -38,7 +38,7 @@ namespace NzbDrone.Integration.Test public ClientBase<BlacklistResource> Blacklist; public CommandClient Commands; public DownloadClientClient DownloadClients; - public AlbumClient Albums; + public BookClient Books; public ClientBase<HistoryResource> History; public ClientBase<HostConfigResource> HostConfig; public IndexerClient Indexers; @@ -49,10 +49,10 @@ namespace NzbDrone.Integration.Test public ReleaseClient Releases; public ReleasePushClient ReleasePush; public ClientBase<RootFolderResource> RootFolders; - public ArtistClient Artist; + public AuthorClient Author; public ClientBase<TagResource> Tags; - public ClientBase<AlbumResource> WantedMissing; - public ClientBase<AlbumResource> WantedCutoffUnmet; + public ClientBase<BookResource> WantedMissing; + public ClientBase<BookResource> WantedCutoffUnmet; private List<SignalRMessage> _signalRReceived; @@ -72,7 +72,7 @@ namespace NzbDrone.Integration.Test public string TempDirectory { get; private set; } - public abstract string ArtistRootFolder { get; } + public abstract string AuthorRootFolder { get; } protected abstract string RootUrl { get; } @@ -101,7 +101,7 @@ namespace NzbDrone.Integration.Test Blacklist = new ClientBase<BlacklistResource>(RestClient, ApiKey); Commands = new CommandClient(RestClient, ApiKey); DownloadClients = new DownloadClientClient(RestClient, ApiKey); - Albums = new AlbumClient(RestClient, ApiKey); + Books = new BookClient(RestClient, ApiKey); History = new ClientBase<HistoryResource>(RestClient, ApiKey); HostConfig = new ClientBase<HostConfigResource>(RestClient, ApiKey, "config/host"); Indexers = new IndexerClient(RestClient, ApiKey); @@ -112,10 +112,10 @@ namespace NzbDrone.Integration.Test Releases = new ReleaseClient(RestClient, ApiKey); ReleasePush = new ReleasePushClient(RestClient, ApiKey); RootFolders = new ClientBase<RootFolderResource>(RestClient, ApiKey); - Artist = new ArtistClient(RestClient, ApiKey); + Author = new AuthorClient(RestClient, ApiKey); Tags = new ClientBase<TagResource>(RestClient, ApiKey); - WantedMissing = new ClientBase<AlbumResource>(RestClient, ApiKey, "wanted/missing"); - WantedCutoffUnmet = new ClientBase<AlbumResource>(RestClient, ApiKey, "wanted/cutoff"); + WantedMissing = new ClientBase<BookResource>(RestClient, ApiKey, "wanted/missing"); + WantedCutoffUnmet = new ClientBase<BookResource>(RestClient, ApiKey, "wanted/cutoff"); } [OneTimeTearDown] @@ -249,33 +249,33 @@ namespace NzbDrone.Integration.Test Assert.Fail("Timed on wait"); } - public ArtistResource EnsureArtist(string authorId, string goodreadsBookId, string artistName, bool? monitored = null) + public AuthorResource EnsureAuthor(string authorId, string goodreadsBookId, string authorName, bool? monitored = null) { - var result = Artist.All().FirstOrDefault(v => v.ForeignAuthorId == authorId); + var result = Author.All().FirstOrDefault(v => v.ForeignAuthorId == authorId); if (result == null) { - var lookup = Artist.Lookup("readarr:" + goodreadsBookId); - var artist = lookup.First(); - artist.QualityProfileId = 1; - artist.MetadataProfileId = 1; - artist.Path = Path.Combine(ArtistRootFolder, artist.ArtistName); - artist.Monitored = true; - artist.AddOptions = new Core.Books.AddAuthorOptions(); - Directory.CreateDirectory(artist.Path); - - result = Artist.Post(artist); + var lookup = Author.Lookup("readarr:" + goodreadsBookId); + var author = lookup.First(); + author.QualityProfileId = 1; + author.MetadataProfileId = 1; + author.Path = Path.Combine(AuthorRootFolder, author.AuthorName); + author.Monitored = true; + author.AddOptions = new Core.Books.AddAuthorOptions(); + Directory.CreateDirectory(author.Path); + + result = Author.Post(author); Commands.WaitAll(); - WaitForCompletion(() => Albums.GetAlbumsInArtist(result.Id).Count > 0); + WaitForCompletion(() => Books.GetBooksInAuthor(result.Id).Count > 0); } var changed = false; - if (result.RootFolderPath != ArtistRootFolder) + if (result.RootFolderPath != AuthorRootFolder) { changed = true; - result.RootFolderPath = ArtistRootFolder; - result.Path = Path.Combine(ArtistRootFolder, result.ArtistName); + result.RootFolderPath = AuthorRootFolder; + result.Path = Path.Combine(AuthorRootFolder, result.AuthorName); } if (monitored.HasValue) @@ -289,7 +289,7 @@ namespace NzbDrone.Integration.Test if (changed) { - Artist.Put(result); + Author.Put(result); } return result; @@ -297,22 +297,22 @@ namespace NzbDrone.Integration.Test public void EnsureNoArtist(string readarrId, string artistTitle) { - var result = Artist.All().FirstOrDefault(v => v.ForeignAuthorId == readarrId); + var result = Author.All().FirstOrDefault(v => v.ForeignAuthorId == readarrId); if (result != null) { - Artist.Delete(result.Id); + Author.Delete(result.Id); } } - public void EnsureTrackFile(ArtistResource artist, int bookId, Quality quality) + public void EnsureBookFile(AuthorResource artist, int bookId, Quality quality) { - var result = Albums.GetAlbumsInArtist(artist.Id).Single(v => v.Id == bookId); + var result = Books.GetBooksInAuthor(artist.Id).Single(v => v.Id == bookId); // if (result.BookFile == null) if (true) { - var path = Path.Combine(ArtistRootFolder, artist.ArtistName, "Track.mp3"); + var path = Path.Combine(AuthorRootFolder, artist.AuthorName, "Track.mp3"); Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllText(path, "Fake Track"); @@ -332,7 +332,7 @@ namespace NzbDrone.Integration.Test }); Commands.WaitAll(); - var track = Albums.GetAlbumsInArtist(artist.Id).Single(x => x.Id == bookId); + var track = Books.GetBooksInAuthor(artist.Id).Single(x => x.Id == bookId); // track.BookFileId.Should().NotBe(0); } diff --git a/src/Readarr.Api.V1/AlbumStudio/AlbumStudioArtistResource.cs b/src/Readarr.Api.V1/AlbumStudio/AlbumStudioArtistResource.cs deleted file mode 100644 index e341d061d..000000000 --- a/src/Readarr.Api.V1/AlbumStudio/AlbumStudioArtistResource.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using Readarr.Api.V1.Albums; - -namespace Readarr.Api.V1.AlbumStudio -{ - public class AlbumStudioArtistResource - { - public int Id { get; set; } - public bool? Monitored { get; set; } - public List<AlbumResource> Albums { get; set; } - } -} diff --git a/src/Readarr.Api.V1/AlbumStudio/AlbumStudioModule.cs b/src/Readarr.Api.V1/AlbumStudio/AlbumStudioModule.cs deleted file mode 100644 index 5e5829311..000000000 --- a/src/Readarr.Api.V1/AlbumStudio/AlbumStudioModule.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Linq; -using Nancy; -using NzbDrone.Core.Books; -using Readarr.Http.Extensions; - -namespace Readarr.Api.V1.AlbumStudio -{ - public class AlbumStudioModule : ReadarrV1Module - { - private readonly IAuthorService _authorService; - private readonly IBookMonitoredService _albumMonitoredService; - - public AlbumStudioModule(IAuthorService authorService, IBookMonitoredService albumMonitoredService) - : base("/albumstudio") - { - _authorService = authorService; - _albumMonitoredService = albumMonitoredService; - Post("/", artist => UpdateAll()); - } - - private object UpdateAll() - { - //Read from request - var request = Request.Body.FromJson<AlbumStudioResource>(); - var artistToUpdate = _authorService.GetAuthors(request.Artist.Select(s => s.Id)); - - foreach (var s in request.Artist) - { - var artist = artistToUpdate.Single(c => c.Id == s.Id); - - if (s.Monitored.HasValue) - { - artist.Monitored = s.Monitored.Value; - } - - if (request.MonitoringOptions != null && request.MonitoringOptions.Monitor == MonitorTypes.None) - { - artist.Monitored = false; - } - - _albumMonitoredService.SetBookMonitoredStatus(artist, request.MonitoringOptions); - } - - return ResponseWithCode("ok", HttpStatusCode.Accepted); - } - } -} diff --git a/src/Readarr.Api.V1/Albums/AlbumModuleWithSignalR.cs b/src/Readarr.Api.V1/Albums/AlbumModuleWithSignalR.cs deleted file mode 100644 index e492e0ac3..000000000 --- a/src/Readarr.Api.V1/Albums/AlbumModuleWithSignalR.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using NzbDrone.Common.Extensions; -using NzbDrone.Core.AuthorStats; -using NzbDrone.Core.Books; -using NzbDrone.Core.DecisionEngine.Specifications; -using NzbDrone.Core.MediaCover; -using NzbDrone.SignalR; -using Readarr.Api.V1.Artist; -using Readarr.Http; - -namespace Readarr.Api.V1.Albums -{ - public abstract class AlbumModuleWithSignalR : ReadarrRestModuleWithSignalR<AlbumResource, Book> - { - protected readonly IBookService _bookService; - protected readonly IAuthorStatisticsService _artistStatisticsService; - protected readonly IUpgradableSpecification _qualityUpgradableSpecification; - protected readonly IMapCoversToLocal _coverMapper; - - protected AlbumModuleWithSignalR(IBookService bookService, - IAuthorStatisticsService artistStatisticsService, - IMapCoversToLocal coverMapper, - IUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster) - : base(signalRBroadcaster) - { - _bookService = bookService; - _artistStatisticsService = artistStatisticsService; - _coverMapper = coverMapper; - _qualityUpgradableSpecification = qualityUpgradableSpecification; - - GetResourceById = GetAlbum; - } - - protected AlbumModuleWithSignalR(IBookService bookService, - IAuthorStatisticsService artistStatisticsService, - IMapCoversToLocal coverMapper, - IUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster, - string resource) - : base(signalRBroadcaster, resource) - { - _bookService = bookService; - _artistStatisticsService = artistStatisticsService; - _coverMapper = coverMapper; - _qualityUpgradableSpecification = qualityUpgradableSpecification; - - GetResourceById = GetAlbum; - } - - protected AlbumResource GetAlbum(int id) - { - var album = _bookService.GetBook(id); - var resource = MapToResource(album, true); - return resource; - } - - protected AlbumResource MapToResource(Book album, bool includeArtist) - { - var resource = album.ToResource(); - - if (includeArtist) - { - var artist = album.Author.Value; - - resource.Artist = artist.ToResource(); - } - - FetchAndLinkAlbumStatistics(resource); - MapCoversToLocal(resource); - - return resource; - } - - protected List<AlbumResource> MapToResource(List<Book> albums, bool includeArtist) - { - var result = albums.ToResource(); - - if (includeArtist) - { - var artistDict = new Dictionary<int, NzbDrone.Core.Books.Author>(); - for (var i = 0; i < albums.Count; i++) - { - var album = albums[i]; - var resource = result[i]; - var artist = artistDict.GetValueOrDefault(albums[i].AuthorMetadataId) ?? album.Author?.Value; - artistDict[artist.AuthorMetadataId] = artist; - - resource.Artist = artist.ToResource(); - } - } - - var artistStats = _artistStatisticsService.AuthorStatistics(); - LinkArtistStatistics(result, artistStats); - MapCoversToLocal(result.ToArray()); - - return result; - } - - private void FetchAndLinkAlbumStatistics(AlbumResource resource) - { - LinkArtistStatistics(resource, _artistStatisticsService.AuthorStatistics(resource.AuthorId)); - } - - private void LinkArtistStatistics(List<AlbumResource> resources, List<AuthorStatistics> artistStatistics) - { - foreach (var album in resources) - { - var stats = artistStatistics.SingleOrDefault(ss => ss.AuthorId == album.AuthorId); - LinkArtistStatistics(album, stats); - } - } - - private void LinkArtistStatistics(AlbumResource resource, AuthorStatistics artistStatistics) - { - if (artistStatistics?.BookStatistics != null) - { - var dictAlbumStats = artistStatistics.BookStatistics.ToDictionary(v => v.BookId); - - resource.Statistics = dictAlbumStats.GetValueOrDefault(resource.Id).ToResource(); - } - } - - private void MapCoversToLocal(params AlbumResource[] albums) - { - foreach (var albumResource in albums) - { - _coverMapper.ConvertToLocalUrls(albumResource.Id, MediaCoverEntity.Book, albumResource.Images); - } - } - } -} diff --git a/src/Readarr.Api.V1/Albums/AlbumStatisticsResource.cs b/src/Readarr.Api.V1/Albums/AlbumStatisticsResource.cs deleted file mode 100644 index b7c96f72f..000000000 --- a/src/Readarr.Api.V1/Albums/AlbumStatisticsResource.cs +++ /dev/null @@ -1,43 +0,0 @@ -using NzbDrone.Core.AuthorStats; - -namespace Readarr.Api.V1.Albums -{ - public class AlbumStatisticsResource - { - public int TrackFileCount { get; set; } - public int TrackCount { get; set; } - public int TotalTrackCount { get; set; } - public long SizeOnDisk { get; set; } - - public decimal PercentOfTracks - { - get - { - if (TrackCount == 0) - { - return 0; - } - - return TrackFileCount / (decimal)TrackCount * 100; - } - } - } - - public static class AlbumStatisticsResourceMapper - { - public static AlbumStatisticsResource ToResource(this BookStatistics model) - { - if (model == null) - { - return null; - } - - return new AlbumStatisticsResource - { - TrackFileCount = model.BookFileCount, - TrackCount = model.BookCount, - SizeOnDisk = model.SizeOnDisk - }; - } - } -} diff --git a/src/Readarr.Api.V1/Artist/AlternateTitleResource.cs b/src/Readarr.Api.V1/Author/AlternateTitleResource.cs similarity index 86% rename from src/Readarr.Api.V1/Artist/AlternateTitleResource.cs rename to src/Readarr.Api.V1/Author/AlternateTitleResource.cs index 1bfc62553..8713b9adb 100644 --- a/src/Readarr.Api.V1/Artist/AlternateTitleResource.cs +++ b/src/Readarr.Api.V1/Author/AlternateTitleResource.cs @@ -1,4 +1,4 @@ -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { public class AlternateTitleResource { diff --git a/src/Readarr.Api.V1/Artist/ArtistEditorDeleteResource.cs b/src/Readarr.Api.V1/Author/AuthorEditorDeleteResource.cs similarity index 65% rename from src/Readarr.Api.V1/Artist/ArtistEditorDeleteResource.cs rename to src/Readarr.Api.V1/Author/AuthorEditorDeleteResource.cs index 2465a91a5..b52159b71 100644 --- a/src/Readarr.Api.V1/Artist/ArtistEditorDeleteResource.cs +++ b/src/Readarr.Api.V1/Author/AuthorEditorDeleteResource.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistEditorDeleteResource + public class AuthorEditorDeleteResource { public List<int> AuthorIds { get; set; } public bool DeleteFiles { get; set; } diff --git a/src/Readarr.Api.V1/Artist/ArtistEditorModule.cs b/src/Readarr.Api.V1/Author/AuthorEditorModule.cs similarity index 61% rename from src/Readarr.Api.V1/Artist/ArtistEditorModule.cs rename to src/Readarr.Api.V1/Author/AuthorEditorModule.cs index 3b9e7b354..1e8aa2760 100644 --- a/src/Readarr.Api.V1/Artist/ArtistEditorModule.cs +++ b/src/Readarr.Api.V1/Author/AuthorEditorModule.cs @@ -7,52 +7,52 @@ using NzbDrone.Core.Books.Commands; using NzbDrone.Core.Messaging.Commands; using Readarr.Http.Extensions; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistEditorModule : ReadarrV1Module + public class AuthorEditorModule : ReadarrV1Module { private readonly IAuthorService _authorService; private readonly IManageCommandQueue _commandQueueManager; - public ArtistEditorModule(IAuthorService authorService, IManageCommandQueue commandQueueManager) - : base("/artist/editor") + public AuthorEditorModule(IAuthorService authorService, IManageCommandQueue commandQueueManager) + : base("/author/editor") { _authorService = authorService; _commandQueueManager = commandQueueManager; - Put("/", artist => SaveAll()); - Delete("/", artist => DeleteArtist()); + Put("/", author => SaveAll()); + Delete("/", author => DeleteAuthor()); } private object SaveAll() { - var resource = Request.Body.FromJson<ArtistEditorResource>(); - var artistToUpdate = _authorService.GetAuthors(resource.AuthorIds); - var artistToMove = new List<BulkMoveAuthor>(); + var resource = Request.Body.FromJson<AuthorEditorResource>(); + var authorsToUpdate = _authorService.GetAuthors(resource.AuthorIds); + var authorsToMove = new List<BulkMoveAuthor>(); - foreach (var artist in artistToUpdate) + foreach (var author in authorsToUpdate) { if (resource.Monitored.HasValue) { - artist.Monitored = resource.Monitored.Value; + author.Monitored = resource.Monitored.Value; } if (resource.QualityProfileId.HasValue) { - artist.QualityProfileId = resource.QualityProfileId.Value; + author.QualityProfileId = resource.QualityProfileId.Value; } if (resource.MetadataProfileId.HasValue) { - artist.MetadataProfileId = resource.MetadataProfileId.Value; + author.MetadataProfileId = resource.MetadataProfileId.Value; } if (resource.RootFolderPath.IsNotNullOrWhiteSpace()) { - artist.RootFolderPath = resource.RootFolderPath; - artistToMove.Add(new BulkMoveAuthor + author.RootFolderPath = resource.RootFolderPath; + authorsToMove.Add(new BulkMoveAuthor { - AuthorId = artist.Id, - SourcePath = artist.Path + AuthorId = author.Id, + SourcePath = author.Path }); } @@ -64,35 +64,35 @@ namespace Readarr.Api.V1.Artist switch (applyTags) { case ApplyTags.Add: - newTags.ForEach(t => artist.Tags.Add(t)); + newTags.ForEach(t => author.Tags.Add(t)); break; case ApplyTags.Remove: - newTags.ForEach(t => artist.Tags.Remove(t)); + newTags.ForEach(t => author.Tags.Remove(t)); break; case ApplyTags.Replace: - artist.Tags = new HashSet<int>(newTags); + author.Tags = new HashSet<int>(newTags); break; } } } - if (resource.MoveFiles && artistToMove.Any()) + if (resource.MoveFiles && authorsToMove.Any()) { _commandQueueManager.Push(new BulkMoveAuthorCommand { DestinationRootFolder = resource.RootFolderPath, - Author = artistToMove + Author = authorsToMove }); } - return ResponseWithCode(_authorService.UpdateAuthors(artistToUpdate, !resource.MoveFiles) + return ResponseWithCode(_authorService.UpdateAuthors(authorsToUpdate, !resource.MoveFiles) .ToResource(), HttpStatusCode.Accepted); } - private object DeleteArtist() + private object DeleteAuthor() { - var resource = Request.Body.FromJson<ArtistEditorResource>(); + var resource = Request.Body.FromJson<AuthorEditorResource>(); foreach (var authorId in resource.AuthorIds) { diff --git a/src/Readarr.Api.V1/Artist/ArtistEditorResource.cs b/src/Readarr.Api.V1/Author/AuthorEditorResource.cs similarity index 81% rename from src/Readarr.Api.V1/Artist/ArtistEditorResource.cs rename to src/Readarr.Api.V1/Author/AuthorEditorResource.cs index b558ed1ef..5d224636a 100644 --- a/src/Readarr.Api.V1/Artist/ArtistEditorResource.cs +++ b/src/Readarr.Api.V1/Author/AuthorEditorResource.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistEditorResource + public class AuthorEditorResource { public List<int> AuthorIds { get; set; } public bool? Monitored { get; set; } public int? QualityProfileId { get; set; } public int? MetadataProfileId { get; set; } - public bool? AlbumFolder { get; set; } public string RootFolderPath { get; set; } public List<int> Tags { get; set; } public ApplyTags ApplyTags { get; set; } diff --git a/src/Readarr.Api.V1/Artist/ArtistImportModule.cs b/src/Readarr.Api.V1/Author/AuthorImportModule.cs similarity index 51% rename from src/Readarr.Api.V1/Artist/ArtistImportModule.cs rename to src/Readarr.Api.V1/Author/AuthorImportModule.cs index e8d5249d6..e0d63cd0c 100644 --- a/src/Readarr.Api.V1/Artist/ArtistImportModule.cs +++ b/src/Readarr.Api.V1/Author/AuthorImportModule.cs @@ -4,14 +4,14 @@ using NzbDrone.Core.Books; using Readarr.Http; using Readarr.Http.Extensions; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistImportModule : ReadarrRestModule<ArtistResource> + public class AuthorImportModule : ReadarrRestModule<AuthorResource> { private readonly IAddAuthorService _addAuthorService; - public ArtistImportModule(IAddAuthorService addAuthorService) - : base("/artist/import") + public AuthorImportModule(IAddAuthorService addAuthorService) + : base("/author/import") { _addAuthorService = addAuthorService; Post("/", x => Import()); @@ -19,10 +19,10 @@ namespace Readarr.Api.V1.Artist private object Import() { - var resource = Request.Body.FromJson<List<ArtistResource>>(); - var newArtists = resource.ToModel(); + var resource = Request.Body.FromJson<List<AuthorResource>>(); + var newAuthors = resource.ToModel(); - return _addAuthorService.AddAuthors(newArtists).ToResource(); + return _addAuthorService.AddAuthors(newAuthors).ToResource(); } } } diff --git a/src/Readarr.Api.V1/Artist/ArtistLookupModule.cs b/src/Readarr.Api.V1/Author/AuthorLookupModule.cs similarity index 62% rename from src/Readarr.Api.V1/Artist/ArtistLookupModule.cs rename to src/Readarr.Api.V1/Author/AuthorLookupModule.cs index 73a9a3309..a0061ffca 100644 --- a/src/Readarr.Api.V1/Artist/ArtistLookupModule.cs +++ b/src/Readarr.Api.V1/Author/AuthorLookupModule.cs @@ -5,14 +5,14 @@ using NzbDrone.Core.MediaCover; using NzbDrone.Core.MetadataSource; using Readarr.Http; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistLookupModule : ReadarrRestModule<ArtistResource> + public class AuthorLookupModule : ReadarrRestModule<AuthorResource> { private readonly ISearchForNewAuthor _searchProxy; - public ArtistLookupModule(ISearchForNewAuthor searchProxy) - : base("/artist/lookup") + public AuthorLookupModule(ISearchForNewAuthor searchProxy) + : base("/author/lookup") { _searchProxy = searchProxy; Get("/", x => Search()); @@ -24,12 +24,12 @@ namespace Readarr.Api.V1.Artist return MapToResource(searchResults).ToList(); } - private static IEnumerable<ArtistResource> MapToResource(IEnumerable<NzbDrone.Core.Books.Author> artist) + private static IEnumerable<AuthorResource> MapToResource(IEnumerable<NzbDrone.Core.Books.Author> author) { - foreach (var currentArtist in artist) + foreach (var currentAuthor in author) { - var resource = currentArtist.ToResource(); - var poster = currentArtist.Metadata.Value.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster); + var resource = currentAuthor.ToResource(); + var poster = currentAuthor.Metadata.Value.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster); if (poster != null) { resource.RemotePoster = poster.Url; diff --git a/src/Readarr.Api.V1/Artist/ArtistModule.cs b/src/Readarr.Api.V1/Author/AuthorModule.cs similarity index 66% rename from src/Readarr.Api.V1/Artist/ArtistModule.cs rename to src/Readarr.Api.V1/Author/AuthorModule.cs index 7bce63dd3..a92ce8a62 100644 --- a/src/Readarr.Api.V1/Artist/ArtistModule.cs +++ b/src/Readarr.Api.V1/Author/AuthorModule.cs @@ -19,9 +19,9 @@ using NzbDrone.SignalR; using Readarr.Http; using Readarr.Http.Extensions; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistModule : ReadarrRestModuleWithSignalR<ArtistResource, NzbDrone.Core.Books.Author>, + public class AuthorModule : ReadarrRestModuleWithSignalR<AuthorResource, NzbDrone.Core.Books.Author>, IHandle<BookImportedEvent>, IHandle<BookEditedEvent>, IHandle<BookFileDeletedEvent>, @@ -34,24 +34,24 @@ namespace Readarr.Api.V1.Artist private readonly IAuthorService _authorService; private readonly IBookService _bookService; private readonly IAddAuthorService _addAuthorService; - private readonly IAuthorStatisticsService _artistStatisticsService; + private readonly IAuthorStatisticsService _authorStatisticsService; private readonly IMapCoversToLocal _coverMapper; private readonly IManageCommandQueue _commandQueueManager; private readonly IRootFolderService _rootFolderService; - public ArtistModule(IBroadcastSignalRMessage signalRBroadcaster, + public AuthorModule(IBroadcastSignalRMessage signalRBroadcaster, IAuthorService authorService, IBookService bookService, IAddAuthorService addAuthorService, - IAuthorStatisticsService artistStatisticsService, + IAuthorStatisticsService authorStatisticsService, IMapCoversToLocal coverMapper, IManageCommandQueue commandQueueManager, IRootFolderService rootFolderService, RootFolderValidator rootFolderValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, - AuthorPathValidator artistPathValidator, - ArtistExistsValidator artistExistsValidator, - AuthorAncestorValidator artistAncestorValidator, + AuthorPathValidator authorPathValidator, + AuthorExistsValidator authorExistsValidator, + AuthorAncestorValidator authorAncestorValidator, SystemFolderValidator systemFolderValidator, QualityProfileExistsValidator qualityProfileExistsValidator, MetadataProfileExistsValidator metadataProfileExistsValidator) @@ -60,17 +60,17 @@ namespace Readarr.Api.V1.Artist _authorService = authorService; _bookService = bookService; _addAuthorService = addAuthorService; - _artistStatisticsService = artistStatisticsService; + _authorStatisticsService = authorStatisticsService; _coverMapper = coverMapper; _commandQueueManager = commandQueueManager; _rootFolderService = rootFolderService; - GetResourceAll = AllArtists; - GetResourceById = GetArtist; - CreateResource = AddArtist; - UpdateResource = UpdateArtist; - DeleteResource = DeleteArtist; + GetResourceAll = AllAuthors; + GetResourceById = GetAuthor; + CreateResource = AddAuthor; + UpdateResource = UpdateAuthor; + DeleteResource = DeleteAuthor; Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.QualityProfileId)); Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.MetadataProfileId)); @@ -80,8 +80,8 @@ namespace Readarr.Api.V1.Artist .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) - .SetValidator(artistPathValidator) - .SetValidator(artistAncestorValidator) + .SetValidator(authorPathValidator) + .SetValidator(authorAncestorValidator) .SetValidator(systemFolderValidator) .When(s => !s.Path.IsNullOrWhiteSpace()); @@ -90,26 +90,26 @@ namespace Readarr.Api.V1.Artist PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace()); PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.ArtistName).NotEmpty(); - PostValidator.RuleFor(s => s.ForeignAuthorId).NotEmpty().SetValidator(artistExistsValidator); + PostValidator.RuleFor(s => s.AuthorName).NotEmpty(); + PostValidator.RuleFor(s => s.ForeignAuthorId).NotEmpty().SetValidator(authorExistsValidator); PutValidator.RuleFor(s => s.Path).IsValidPath(); } - private ArtistResource GetArtist(int id) + private AuthorResource GetAuthor(int id) { - var artist = _authorService.GetAuthor(id); - return GetArtistResource(artist); + var author = _authorService.GetAuthor(id); + return GetArtistResource(author); } - private ArtistResource GetArtistResource(NzbDrone.Core.Books.Author artist) + private AuthorResource GetArtistResource(NzbDrone.Core.Books.Author author) { - if (artist == null) + if (author == null) { return null; } - var resource = artist.ToResource(); + var resource = author.ToResource(); MapCoversToLocal(resource); FetchAndLinkArtistStatistics(resource); LinkNextPreviousAlbums(resource); @@ -120,53 +120,53 @@ namespace Readarr.Api.V1.Artist return resource; } - private List<ArtistResource> AllArtists() + private List<AuthorResource> AllAuthors() { - var artistStats = _artistStatisticsService.AuthorStatistics(); - var artistsResources = _authorService.GetAllAuthors().ToResource(); + var authorStats = _authorStatisticsService.AuthorStatistics(); + var authorResources = _authorService.GetAllAuthors().ToResource(); - MapCoversToLocal(artistsResources.ToArray()); - LinkNextPreviousAlbums(artistsResources.ToArray()); - LinkArtistStatistics(artistsResources, artistStats); + MapCoversToLocal(authorResources.ToArray()); + LinkNextPreviousAlbums(authorResources.ToArray()); + LinkArtistStatistics(authorResources, authorStats); //PopulateAlternateTitles(seriesResources); - return artistsResources; + return authorResources; } - private int AddArtist(ArtistResource artistResource) + private int AddAuthor(AuthorResource authorResource) { - var artist = _addAuthorService.AddAuthor(artistResource.ToModel()); + var author = _addAuthorService.AddAuthor(authorResource.ToModel()); - return artist.Id; + return author.Id; } - private void UpdateArtist(ArtistResource artistResource) + private void UpdateAuthor(AuthorResource authorResource) { var moveFiles = Request.GetBooleanQueryParameter("moveFiles"); - var artist = _authorService.GetAuthor(artistResource.Id); + var author = _authorService.GetAuthor(authorResource.Id); if (moveFiles) { - var sourcePath = artist.Path; - var destinationPath = artistResource.Path; + var sourcePath = author.Path; + var destinationPath = authorResource.Path; _commandQueueManager.Push(new MoveAuthorCommand { - AuthorId = artist.Id, + AuthorId = author.Id, SourcePath = sourcePath, DestinationPath = destinationPath, Trigger = CommandTrigger.Manual }); } - var model = artistResource.ToModel(artist); + var model = authorResource.ToModel(author); _authorService.UpdateAuthor(model); - BroadcastResourceChange(ModelAction.Updated, artistResource); + BroadcastResourceChange(ModelAction.Updated, authorResource); } - private void DeleteArtist(int id) + private void DeleteAuthor(int id) { var deleteFiles = Request.GetBooleanQueryParameter("deleteFiles"); var addImportListExclusion = Request.GetBooleanQueryParameter("addImportListExclusion"); @@ -174,48 +174,48 @@ namespace Readarr.Api.V1.Artist _authorService.DeleteAuthor(id, deleteFiles, addImportListExclusion); } - private void MapCoversToLocal(params ArtistResource[] artists) + private void MapCoversToLocal(params AuthorResource[] authors) { - foreach (var artistResource in artists) + foreach (var authorResource in authors) { - _coverMapper.ConvertToLocalUrls(artistResource.Id, MediaCoverEntity.Author, artistResource.Images); + _coverMapper.ConvertToLocalUrls(authorResource.Id, MediaCoverEntity.Author, authorResource.Images); } } - private void LinkNextPreviousAlbums(params ArtistResource[] artists) + private void LinkNextPreviousAlbums(params AuthorResource[] authors) { - var nextAlbums = _bookService.GetNextBooksByAuthorMetadataId(artists.Select(x => x.ArtistMetadataId)); - var lastAlbums = _bookService.GetLastBooksByAuthorMetadataId(artists.Select(x => x.ArtistMetadataId)); + var nextBooks = _bookService.GetNextBooksByAuthorMetadataId(authors.Select(x => x.AuthorMetadataId)); + var lastBooks = _bookService.GetLastBooksByAuthorMetadataId(authors.Select(x => x.AuthorMetadataId)); - foreach (var artistResource in artists) + foreach (var authorResource in authors) { - artistResource.NextAlbum = nextAlbums.FirstOrDefault(x => x.AuthorMetadataId == artistResource.ArtistMetadataId); - artistResource.LastAlbum = lastAlbums.FirstOrDefault(x => x.AuthorMetadataId == artistResource.ArtistMetadataId); + authorResource.NextBook = nextBooks.FirstOrDefault(x => x.AuthorMetadataId == authorResource.AuthorMetadataId); + authorResource.LastBook = lastBooks.FirstOrDefault(x => x.AuthorMetadataId == authorResource.AuthorMetadataId); } } - private void FetchAndLinkArtistStatistics(ArtistResource resource) + private void FetchAndLinkArtistStatistics(AuthorResource resource) { - LinkArtistStatistics(resource, _artistStatisticsService.AuthorStatistics(resource.Id)); + LinkArtistStatistics(resource, _authorStatisticsService.AuthorStatistics(resource.Id)); } - private void LinkArtistStatistics(List<ArtistResource> resources, List<AuthorStatistics> artistStatistics) + private void LinkArtistStatistics(List<AuthorResource> resources, List<AuthorStatistics> authorStatistics) { - foreach (var artist in resources) + foreach (var author in resources) { - var stats = artistStatistics.SingleOrDefault(ss => ss.AuthorId == artist.Id); + var stats = authorStatistics.SingleOrDefault(ss => ss.AuthorId == author.Id); if (stats == null) { continue; } - LinkArtistStatistics(artist, stats); + LinkArtistStatistics(author, stats); } } - private void LinkArtistStatistics(ArtistResource resource, AuthorStatistics artistStatistics) + private void LinkArtistStatistics(AuthorResource resource, AuthorStatistics authorStatistics) { - resource.Statistics = artistStatistics.ToResource(); + resource.Statistics = authorStatistics.ToResource(); } //private void PopulateAlternateTitles(List<ArtistResource> resources) @@ -234,7 +234,7 @@ namespace Readarr.Api.V1.Artist // resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList(); //} - private void LinkRootFolderPath(ArtistResource resource) + private void LinkRootFolderPath(AuthorResource resource) { resource.RootFolderPath = _rootFolderService.GetBestRootFolderPath(resource.Path); } @@ -246,7 +246,7 @@ namespace Readarr.Api.V1.Artist public void Handle(BookEditedEvent message) { - BroadcastResourceChange(ModelAction.Updated, GetArtistResource(message.Album.Author.Value)); + BroadcastResourceChange(ModelAction.Updated, GetArtistResource(message.Book.Author.Value)); } public void Handle(BookFileDeletedEvent message) diff --git a/src/Readarr.Api.V1/Artist/ArtistResource.cs b/src/Readarr.Api.V1/Author/AuthorResource.cs similarity index 76% rename from src/Readarr.Api.V1/Artist/ArtistResource.cs rename to src/Readarr.Api.V1/Author/AuthorResource.cs index 6ebff5ae9..b554716bf 100644 --- a/src/Readarr.Api.V1/Artist/ArtistResource.cs +++ b/src/Readarr.Api.V1/Author/AuthorResource.cs @@ -7,30 +7,30 @@ using NzbDrone.Core.Books; using NzbDrone.Core.MediaCover; using Readarr.Http.REST; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Author { - public class ArtistResource : RestResource + public class AuthorResource : RestResource { //Todo: Sorters should be done completely on the client //Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing? //Todo: We should get the entire Profile instead of ID and Name separately [JsonIgnore] - public int ArtistMetadataId { get; set; } + public int AuthorMetadataId { get; set; } public AuthorStatusType Status { get; set; } public bool Ended => Status == AuthorStatusType.Ended; - public string ArtistName { get; set; } + public string AuthorName { get; set; } public string ForeignAuthorId { get; set; } public int GoodreadsId { get; set; } public string TitleSlug { get; set; } public string Overview { get; set; } - public string ArtistType { get; set; } + public string AuthorType { get; set; } public string Disambiguation { get; set; } public List<Links> Links { get; set; } - public Book NextAlbum { get; set; } - public Book LastAlbum { get; set; } + public Book NextBook { get; set; } + public Book LastBook { get; set; } public List<MediaCover> Images { get; set; } @@ -42,7 +42,6 @@ namespace Readarr.Api.V1.Artist public int MetadataProfileId { get; set; } //Editing Only - public bool AlbumFolder { get; set; } public bool Monitored { get; set; } public string RootFolderPath { get; set; } @@ -54,31 +53,31 @@ namespace Readarr.Api.V1.Artist public AddAuthorOptions AddOptions { get; set; } public Ratings Ratings { get; set; } - public ArtistStatisticsResource Statistics { get; set; } + public AuthorStatisticsResource Statistics { get; set; } } - public static class ArtistResourceMapper + public static class AuthorResourceMapper { - public static ArtistResource ToResource(this NzbDrone.Core.Books.Author model) + public static AuthorResource ToResource(this NzbDrone.Core.Books.Author model) { if (model == null) { return null; } - return new ArtistResource + return new AuthorResource { Id = model.Id, - ArtistMetadataId = model.AuthorMetadataId, + AuthorMetadataId = model.AuthorMetadataId, - ArtistName = model.Name, + AuthorName = model.Name, //AlternateTitles SortName = model.SortName, Status = model.Metadata.Value.Status, Overview = model.Metadata.Value.Overview, - ArtistType = model.Metadata.Value.Type, + AuthorType = model.Metadata.Value.Type, Disambiguation = model.Metadata.Value.Disambiguation, Images = model.Metadata.Value.Images.JsonClone(), @@ -103,11 +102,11 @@ namespace Readarr.Api.V1.Artist AddOptions = model.AddOptions, Ratings = model.Metadata.Value.Ratings, - Statistics = new ArtistStatisticsResource() + Statistics = new AuthorStatisticsResource() }; } - public static NzbDrone.Core.Books.Author ToModel(this ArtistResource resource) + public static NzbDrone.Core.Books.Author ToModel(this AuthorResource resource) { if (resource == null) { @@ -123,14 +122,14 @@ namespace Readarr.Api.V1.Artist ForeignAuthorId = resource.ForeignAuthorId, GoodreadsId = resource.GoodreadsId, TitleSlug = resource.TitleSlug, - Name = resource.ArtistName, + Name = resource.AuthorName, Status = resource.Status, Overview = resource.Overview, Links = resource.Links, Images = resource.Images, Genres = resource.Genres, Ratings = resource.Ratings, - Type = resource.ArtistType + Type = resource.AuthorType }, //AlternateTitles @@ -150,21 +149,21 @@ namespace Readarr.Api.V1.Artist }; } - public static NzbDrone.Core.Books.Author ToModel(this ArtistResource resource, NzbDrone.Core.Books.Author artist) + public static NzbDrone.Core.Books.Author ToModel(this AuthorResource resource, NzbDrone.Core.Books.Author author) { - var updatedArtist = resource.ToModel(); + var updatedAuthor = resource.ToModel(); - artist.ApplyChanges(updatedArtist); + author.ApplyChanges(updatedAuthor); - return artist; + return author; } - public static List<ArtistResource> ToResource(this IEnumerable<NzbDrone.Core.Books.Author> artist) + public static List<AuthorResource> ToResource(this IEnumerable<NzbDrone.Core.Books.Author> author) { - return artist.Select(ToResource).ToList(); + return author.Select(ToResource).ToList(); } - public static List<NzbDrone.Core.Books.Author> ToModel(this IEnumerable<ArtistResource> resources) + public static List<NzbDrone.Core.Books.Author> ToModel(this IEnumerable<AuthorResource> resources) { return resources.Select(ToModel).ToList(); } diff --git a/src/Readarr.Api.V1/Author/AuthorStatisticsResource.cs b/src/Readarr.Api.V1/Author/AuthorStatisticsResource.cs new file mode 100644 index 000000000..013bd5f48 --- /dev/null +++ b/src/Readarr.Api.V1/Author/AuthorStatisticsResource.cs @@ -0,0 +1,43 @@ +using NzbDrone.Core.AuthorStats; + +namespace Readarr.Api.V1.Author +{ + public class AuthorStatisticsResource + { + public int BookCount { get; set; } + public int BookFileCount { get; set; } + public int TotalBookCount { get; set; } + public long SizeOnDisk { get; set; } + + public decimal PercentOfBooks + { + get + { + if (BookCount == 0) + { + return 0; + } + + return BookFileCount / (decimal)BookCount * 100; + } + } + } + + public static class AuthorStatisticsResourceMapper + { + public static AuthorStatisticsResource ToResource(this AuthorStatistics model) + { + if (model == null) + { + return null; + } + + return new AuthorStatisticsResource + { + BookCount = model.BookCount, + BookFileCount = model.BookFileCount, + SizeOnDisk = model.SizeOnDisk + }; + } + } +} diff --git a/src/Readarr.Api.V1/Blacklist/BlacklistResource.cs b/src/Readarr.Api.V1/Blacklist/BlacklistResource.cs index 0e728ff94..65049fb08 100644 --- a/src/Readarr.Api.V1/Blacklist/BlacklistResource.cs +++ b/src/Readarr.Api.V1/Blacklist/BlacklistResource.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using NzbDrone.Core.Indexers; using NzbDrone.Core.Qualities; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; using Readarr.Http.REST; namespace Readarr.Api.V1.Blacklist @@ -18,7 +18,7 @@ namespace Readarr.Api.V1.Blacklist public string Indexer { get; set; } public string Message { get; set; } - public ArtistResource Artist { get; set; } + public AuthorResource Author { get; set; } } public static class BlacklistResourceMapper @@ -43,7 +43,7 @@ namespace Readarr.Api.V1.Blacklist Indexer = model.Indexer, Message = model.Message, - Artist = model.Author.ToResource() + Author = model.Author.ToResource() }; } } diff --git a/src/Readarr.Api.V1/TrackFiles/TrackFileListResource.cs b/src/Readarr.Api.V1/BookFiles/BookFileListResource.cs similarity index 50% rename from src/Readarr.Api.V1/TrackFiles/TrackFileListResource.cs rename to src/Readarr.Api.V1/BookFiles/BookFileListResource.cs index 472d0b477..c0976e8be 100644 --- a/src/Readarr.Api.V1/TrackFiles/TrackFileListResource.cs +++ b/src/Readarr.Api.V1/BookFiles/BookFileListResource.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; using NzbDrone.Core.Qualities; -namespace Readarr.Api.V1.TrackFiles +namespace Readarr.Api.V1.BookFiles { - public class TrackFileListResource + public class BookFileListResource { - public List<int> TrackFileIds { get; set; } + public List<int> BookFileIds { get; set; } public QualityModel Quality { get; set; } } } diff --git a/src/Readarr.Api.V1/TrackFiles/TrackFileModule.cs b/src/Readarr.Api.V1/BookFiles/BookFileModule.cs similarity index 57% rename from src/Readarr.Api.V1/TrackFiles/TrackFileModule.cs rename to src/Readarr.Api.V1/BookFiles/BookFileModule.cs index ab48e5c66..4da739ec3 100644 --- a/src/Readarr.Api.V1/TrackFiles/TrackFileModule.cs +++ b/src/Readarr.Api.V1/BookFiles/BookFileModule.cs @@ -14,9 +14,9 @@ using Readarr.Http; using Readarr.Http.Extensions; using HttpStatusCode = System.Net.HttpStatusCode; -namespace Readarr.Api.V1.TrackFiles +namespace Readarr.Api.V1.BookFiles { - public class TrackFileModule : ReadarrRestModuleWithSignalR<TrackFileResource, BookFile>, + public class BookFileModule : ReadarrRestModuleWithSignalR<BookFileResource, BookFile>, IHandle<BookFileAddedEvent>, IHandle<BookFileDeletedEvent> { @@ -27,7 +27,7 @@ namespace Readarr.Api.V1.TrackFiles private readonly IBookService _bookService; private readonly IUpgradableSpecification _upgradableSpecification; - public TrackFileModule(IBroadcastSignalRMessage signalRBroadcaster, + public BookFileModule(IBroadcastSignalRMessage signalRBroadcaster, IMediaFileService mediaFileService, IDeleteMediaFiles mediaFileDeletionService, IAudioTagService audioTagService, @@ -43,44 +43,44 @@ namespace Readarr.Api.V1.TrackFiles _bookService = bookService; _upgradableSpecification = upgradableSpecification; - GetResourceById = GetTrackFile; - GetResourceAll = GetTrackFiles; + GetResourceById = GetBookFile; + GetResourceAll = GetBookFiles; UpdateResource = SetQuality; - DeleteResource = DeleteTrackFile; + DeleteResource = DeleteBookFile; Put("/editor", trackFiles => SetQuality()); - Delete("/bulk", trackFiles => DeleteTrackFiles()); + Delete("/bulk", trackFiles => DeleteBookFiles()); } - private TrackFileResource MapToResource(BookFile trackFile) + private BookFileResource MapToResource(BookFile bookFile) { - if (trackFile.BookId > 0 && trackFile.Author != null && trackFile.Author.Value != null) + if (bookFile.BookId > 0 && bookFile.Author != null && bookFile.Author.Value != null) { - return trackFile.ToResource(trackFile.Author.Value, _upgradableSpecification); + return bookFile.ToResource(bookFile.Author.Value, _upgradableSpecification); } else { - return trackFile.ToResource(); + return bookFile.ToResource(); } } - private TrackFileResource GetTrackFile(int id) + private BookFileResource GetBookFile(int id) { var resource = MapToResource(_mediaFileService.Get(id)); resource.AudioTags = _audioTagService.ReadTags(resource.Path); return resource; } - private List<TrackFileResource> GetTrackFiles() + private List<BookFileResource> GetBookFiles() { var authorIdQuery = Request.Query.AuthorId; - var trackFileIdsQuery = Request.Query.TrackFileIds; + var bookFileIdsQuery = Request.Query.TrackFileIds; var bookIdQuery = Request.Query.BookId; var unmappedQuery = Request.Query.Unmapped; - if (!authorIdQuery.HasValue && !trackFileIdsQuery.HasValue && !bookIdQuery.HasValue && !unmappedQuery.HasValue) + if (!authorIdQuery.HasValue && !bookFileIdsQuery.HasValue && !bookIdQuery.HasValue && !unmappedQuery.HasValue) { - throw new Readarr.Http.REST.BadRequestException("authorId, bookId, trackFileIds or unmapped must be provided"); + throw new Readarr.Http.REST.BadRequestException("authorId, bookId, bookFileIds or unmapped must be provided"); } if (unmappedQuery.HasValue && Convert.ToBoolean(unmappedQuery.Value)) @@ -92,9 +92,9 @@ namespace Readarr.Api.V1.TrackFiles if (authorIdQuery.HasValue && !bookIdQuery.HasValue) { int authorId = Convert.ToInt32(authorIdQuery.Value); - var artist = _authorService.GetAuthor(authorId); + var author = _authorService.GetAuthor(authorId); - return _mediaFileService.GetFilesByAuthor(authorId).ConvertAll(f => f.ToResource(artist, _upgradableSpecification)); + return _mediaFileService.GetFilesByAuthor(authorId).ConvertAll(f => f.ToResource(author, _upgradableSpecification)); } if (bookIdQuery.HasValue) @@ -105,84 +105,84 @@ namespace Readarr.Api.V1.TrackFiles .Select(e => Convert.ToInt32(e)) .ToList(); - var result = new List<TrackFileResource>(); + var result = new List<BookFileResource>(); foreach (var bookId in bookIds) { - var album = _bookService.GetBook(bookId); - var albumArtist = _authorService.GetAuthor(album.AuthorId); - result.AddRange(_mediaFileService.GetFilesByBook(album.Id).ConvertAll(f => f.ToResource(albumArtist, _upgradableSpecification))); + var book = _bookService.GetBook(bookId); + var bookAuthor = _authorService.GetAuthor(book.AuthorId); + result.AddRange(_mediaFileService.GetFilesByBook(book.Id).ConvertAll(f => f.ToResource(bookAuthor, _upgradableSpecification))); } return result; } else { - string trackFileIdsValue = trackFileIdsQuery.Value.ToString(); + string bookFileIdsValue = bookFileIdsQuery.Value.ToString(); - var trackFileIds = trackFileIdsValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + var bookFileIds = bookFileIdsValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(e => Convert.ToInt32(e)) .ToList(); // trackfiles will come back with the artist already populated - var trackFiles = _mediaFileService.Get(trackFileIds); - return trackFiles.ConvertAll(e => MapToResource(e)); + var bookFiles = _mediaFileService.Get(bookFileIds); + return bookFiles.ConvertAll(e => MapToResource(e)); } } - private void SetQuality(TrackFileResource trackFileResource) + private void SetQuality(BookFileResource bookFileResource) { - var trackFile = _mediaFileService.Get(trackFileResource.Id); - trackFile.Quality = trackFileResource.Quality; - _mediaFileService.Update(trackFile); + var bookFile = _mediaFileService.Get(bookFileResource.Id); + bookFile.Quality = bookFileResource.Quality; + _mediaFileService.Update(bookFile); } private object SetQuality() { - var resource = Request.Body.FromJson<TrackFileListResource>(); - var trackFiles = _mediaFileService.Get(resource.TrackFileIds); + var resource = Request.Body.FromJson<BookFileListResource>(); + var bookFiles = _mediaFileService.Get(resource.BookFileIds); - foreach (var trackFile in trackFiles) + foreach (var bookFile in bookFiles) { if (resource.Quality != null) { - trackFile.Quality = resource.Quality; + bookFile.Quality = resource.Quality; } } - _mediaFileService.Update(trackFiles); + _mediaFileService.Update(bookFiles); - return ResponseWithCode(trackFiles.ConvertAll(f => f.ToResource(trackFiles.First().Author.Value, _upgradableSpecification)), + return ResponseWithCode(bookFiles.ConvertAll(f => f.ToResource(bookFiles.First().Author.Value, _upgradableSpecification)), Nancy.HttpStatusCode.Accepted); } - private void DeleteTrackFile(int id) + private void DeleteBookFile(int id) { - var trackFile = _mediaFileService.Get(id); + var bookFile = _mediaFileService.Get(id); - if (trackFile == null) + if (bookFile == null) { - throw new NzbDroneClientException(HttpStatusCode.NotFound, "Track file not found"); + throw new NzbDroneClientException(HttpStatusCode.NotFound, "Book file not found"); } - if (trackFile.BookId > 0 && trackFile.Author != null && trackFile.Author.Value != null) + if (bookFile.BookId > 0 && bookFile.Author != null && bookFile.Author.Value != null) { - _mediaFileDeletionService.DeleteTrackFile(trackFile.Author.Value, trackFile); + _mediaFileDeletionService.DeleteTrackFile(bookFile.Author.Value, bookFile); } else { - _mediaFileDeletionService.DeleteTrackFile(trackFile, "Unmapped_Files"); + _mediaFileDeletionService.DeleteTrackFile(bookFile, "Unmapped_Files"); } } - private object DeleteTrackFiles() + private object DeleteBookFiles() { - var resource = Request.Body.FromJson<TrackFileListResource>(); - var trackFiles = _mediaFileService.Get(resource.TrackFileIds); - var artist = trackFiles.First().Author.Value; + var resource = Request.Body.FromJson<BookFileListResource>(); + var bookFiles = _mediaFileService.Get(resource.BookFileIds); + var author = bookFiles.First().Author.Value; - foreach (var trackFile in trackFiles) + foreach (var bookFile in bookFiles) { - _mediaFileDeletionService.DeleteTrackFile(artist, trackFile); + _mediaFileDeletionService.DeleteTrackFile(author, bookFile); } return new object(); diff --git a/src/Readarr.Api.V1/TrackFiles/TrackFileResource.cs b/src/Readarr.Api.V1/BookFiles/BookFileResource.cs similarity index 80% rename from src/Readarr.Api.V1/TrackFiles/TrackFileResource.cs rename to src/Readarr.Api.V1/BookFiles/BookFileResource.cs index 2ea38a282..968b4d5c2 100644 --- a/src/Readarr.Api.V1/TrackFiles/TrackFileResource.cs +++ b/src/Readarr.Api.V1/BookFiles/BookFileResource.cs @@ -7,9 +7,9 @@ using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; using Readarr.Http.REST; -namespace Readarr.Api.V1.TrackFiles +namespace Readarr.Api.V1.BookFiles { - public class TrackFileResource : RestResource + public class BookFileResource : RestResource { public int AuthorId { get; set; } public int BookId { get; set; } @@ -24,7 +24,7 @@ namespace Readarr.Api.V1.TrackFiles public ParsedTrackInfo AudioTags { get; set; } } - public static class TrackFileResourceMapper + public static class BookFileResourceMapper { private static int QualityWeight(QualityModel quality) { @@ -39,14 +39,14 @@ namespace Readarr.Api.V1.TrackFiles return qualityWeight; } - public static TrackFileResource ToResource(this BookFile model) + public static BookFileResource ToResource(this BookFile model) { if (model == null) { return null; } - return new TrackFileResource + return new BookFileResource { Id = model.Id, BookId = model.BookId, @@ -59,18 +59,18 @@ namespace Readarr.Api.V1.TrackFiles }; } - public static TrackFileResource ToResource(this BookFile model, NzbDrone.Core.Books.Author artist, IUpgradableSpecification upgradableSpecification) + public static BookFileResource ToResource(this BookFile model, NzbDrone.Core.Books.Author author, IUpgradableSpecification upgradableSpecification) { if (model == null) { return null; } - return new TrackFileResource + return new BookFileResource { Id = model.Id, - AuthorId = artist.Id, + AuthorId = author.Id, BookId = model.BookId, Path = model.Path, Size = model.Size, @@ -78,7 +78,7 @@ namespace Readarr.Api.V1.TrackFiles Quality = model.Quality, QualityWeight = QualityWeight(model.Quality), MediaInfo = model.MediaInfo.ToResource(), - QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(artist.QualityProfile.Value, model.Quality) + QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(author.QualityProfile.Value, model.Quality) }; } } diff --git a/src/Readarr.Api.V1/TrackFiles/MediaInfoResource.cs b/src/Readarr.Api.V1/BookFiles/MediaInfoResource.cs similarity index 96% rename from src/Readarr.Api.V1/TrackFiles/MediaInfoResource.cs rename to src/Readarr.Api.V1/BookFiles/MediaInfoResource.cs index 83c35329a..20d765f61 100644 --- a/src/Readarr.Api.V1/TrackFiles/MediaInfoResource.cs +++ b/src/Readarr.Api.V1/BookFiles/MediaInfoResource.cs @@ -2,7 +2,7 @@ using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Parser.Model; using Readarr.Http.REST; -namespace Readarr.Api.V1.TrackFiles +namespace Readarr.Api.V1.BookFiles { public class MediaInfoResource : RestResource { diff --git a/src/Readarr.Api.V1/BookShelf/BookshelfAuthorResource1.cs b/src/Readarr.Api.V1/BookShelf/BookshelfAuthorResource1.cs new file mode 100644 index 000000000..7712528af --- /dev/null +++ b/src/Readarr.Api.V1/BookShelf/BookshelfAuthorResource1.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Readarr.Api.V1.Books; + +namespace Readarr.Api.V1.Bookshelf +{ + public class BookshelfAuthorResource + { + public int Id { get; set; } + public bool? Monitored { get; set; } + public List<BookResource> Books { get; set; } + } +} diff --git a/src/Readarr.Api.V1/BookShelf/BookshelfModule1.cs b/src/Readarr.Api.V1/BookShelf/BookshelfModule1.cs new file mode 100644 index 000000000..84f840bd2 --- /dev/null +++ b/src/Readarr.Api.V1/BookShelf/BookshelfModule1.cs @@ -0,0 +1,47 @@ +using System.Linq; +using Nancy; +using NzbDrone.Core.Books; +using Readarr.Http.Extensions; + +namespace Readarr.Api.V1.Bookshelf +{ + public class BookshelfModule : ReadarrV1Module + { + private readonly IAuthorService _authorService; + private readonly IBookMonitoredService _bookMonitoredService; + + public BookshelfModule(IAuthorService authorService, IBookMonitoredService bookMonitoredService) + : base("/bookshelf") + { + _authorService = authorService; + _bookMonitoredService = bookMonitoredService; + Post("/", artist => UpdateAll()); + } + + private object UpdateAll() + { + //Read from request + var request = Request.Body.FromJson<BookshelfResource>(); + var authorToUpdate = _authorService.GetAuthors(request.Authors.Select(s => s.Id)); + + foreach (var s in request.Authors) + { + var author = authorToUpdate.Single(c => c.Id == s.Id); + + if (s.Monitored.HasValue) + { + author.Monitored = s.Monitored.Value; + } + + if (request.MonitoringOptions != null && request.MonitoringOptions.Monitor == MonitorTypes.None) + { + author.Monitored = false; + } + + _bookMonitoredService.SetBookMonitoredStatus(author, request.MonitoringOptions); + } + + return ResponseWithCode("ok", HttpStatusCode.Accepted); + } + } +} diff --git a/src/Readarr.Api.V1/AlbumStudio/AlbumStudioResource.cs b/src/Readarr.Api.V1/BookShelf/BookshelfResource1.cs similarity index 50% rename from src/Readarr.Api.V1/AlbumStudio/AlbumStudioResource.cs rename to src/Readarr.Api.V1/BookShelf/BookshelfResource1.cs index 746606495..78d46a5e0 100644 --- a/src/Readarr.Api.V1/AlbumStudio/AlbumStudioResource.cs +++ b/src/Readarr.Api.V1/BookShelf/BookshelfResource1.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; using NzbDrone.Core.Books; -namespace Readarr.Api.V1.AlbumStudio +namespace Readarr.Api.V1.Bookshelf { - public class AlbumStudioResource + public class BookshelfResource { - public List<AlbumStudioArtistResource> Artist { get; set; } + public List<BookshelfAuthorResource> Authors { get; set; } public MonitoringOptions MonitoringOptions { get; set; } } } diff --git a/src/Readarr.Api.V1/Albums/AlbumLookupModule.cs b/src/Readarr.Api.V1/Books/BookLookupModule.cs similarity index 58% rename from src/Readarr.Api.V1/Albums/AlbumLookupModule.cs rename to src/Readarr.Api.V1/Books/BookLookupModule.cs index 311f1ac27..f099aa9a2 100644 --- a/src/Readarr.Api.V1/Albums/AlbumLookupModule.cs +++ b/src/Readarr.Api.V1/Books/BookLookupModule.cs @@ -5,14 +5,14 @@ using NzbDrone.Core.MediaCover; using NzbDrone.Core.MetadataSource; using Readarr.Http; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class AlbumLookupModule : ReadarrRestModule<AlbumResource> + public class BookLookupModule : ReadarrRestModule<BookResource> { private readonly ISearchForNewBook _searchProxy; - public AlbumLookupModule(ISearchForNewBook searchProxy) - : base("/album/lookup") + public BookLookupModule(ISearchForNewBook searchProxy) + : base("/book/lookup") { _searchProxy = searchProxy; Get("/", x => Search()); @@ -24,12 +24,12 @@ namespace Readarr.Api.V1.Albums return MapToResource(searchResults).ToList(); } - private static IEnumerable<AlbumResource> MapToResource(IEnumerable<NzbDrone.Core.Books.Book> albums) + private static IEnumerable<BookResource> MapToResource(IEnumerable<NzbDrone.Core.Books.Book> books) { - foreach (var currentAlbum in albums) + foreach (var currentBook in books) { - var resource = currentAlbum.ToResource(); - var cover = currentAlbum.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Cover); + var resource = currentBook.ToResource(); + var cover = currentBook.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Cover); if (cover != null) { resource.RemoteCover = cover.Url; diff --git a/src/Readarr.Api.V1/Albums/AlbumModule.cs b/src/Readarr.Api.V1/Books/BookModule.cs similarity index 70% rename from src/Readarr.Api.V1/Albums/AlbumModule.cs rename to src/Readarr.Api.V1/Books/BookModule.cs index 5aa15c3d5..bf7cb69e7 100644 --- a/src/Readarr.Api.V1/Albums/AlbumModule.cs +++ b/src/Readarr.Api.V1/Books/BookModule.cs @@ -19,9 +19,9 @@ using NzbDrone.Core.Validation.Paths; using NzbDrone.SignalR; using Readarr.Http.Extensions; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class AlbumModule : AlbumModuleWithSignalR, + public class BookModule : BookModuleWithSignalR, IHandle<BookGrabbedEvent>, IHandle<BookEditedEvent>, IHandle<BookUpdatedEvent>, @@ -32,53 +32,53 @@ namespace Readarr.Api.V1.Albums protected readonly IAuthorService _authorService; protected readonly IAddBookService _addBookService; - public AlbumModule(IAuthorService authorService, + public BookModule(IAuthorService authorService, IBookService bookService, IAddBookService addBookService, - IAuthorStatisticsService artistStatisticsService, + IAuthorStatisticsService authorStatisticsService, IMapCoversToLocal coverMapper, IUpgradableSpecification upgradableSpecification, IBroadcastSignalRMessage signalRBroadcaster, QualityProfileExistsValidator qualityProfileExistsValidator, MetadataProfileExistsValidator metadataProfileExistsValidator) - : base(bookService, artistStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster) + : base(bookService, authorStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster) { _authorService = authorService; _addBookService = addBookService; - GetResourceAll = GetAlbums; - CreateResource = AddAlbum; - UpdateResource = UpdateAlbum; - DeleteResource = DeleteAlbum; - Put("/monitor", x => SetAlbumsMonitored()); + GetResourceAll = GetBooks; + CreateResource = AddBook; + UpdateResource = UpdateBook; + DeleteResource = DeleteBook; + Put("/monitor", x => SetBooksMonitored()); PostValidator.RuleFor(s => s.ForeignBookId).NotEmpty(); - PostValidator.RuleFor(s => s.Artist.QualityProfileId).SetValidator(qualityProfileExistsValidator); - PostValidator.RuleFor(s => s.Artist.MetadataProfileId).SetValidator(metadataProfileExistsValidator); - PostValidator.RuleFor(s => s.Artist.RootFolderPath).IsValidPath().When(s => s.Artist.Path.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.Artist.ForeignAuthorId).NotEmpty(); + PostValidator.RuleFor(s => s.Author.QualityProfileId).SetValidator(qualityProfileExistsValidator); + PostValidator.RuleFor(s => s.Author.MetadataProfileId).SetValidator(metadataProfileExistsValidator); + PostValidator.RuleFor(s => s.Author.RootFolderPath).IsValidPath().When(s => s.Author.Path.IsNullOrWhiteSpace()); + PostValidator.RuleFor(s => s.Author.ForeignAuthorId).NotEmpty(); } - private List<AlbumResource> GetAlbums() + private List<BookResource> GetBooks() { var authorIdQuery = Request.Query.AuthorId; var bookIdsQuery = Request.Query.BookIds; var slugQuery = Request.Query.TitleSlug; - var includeAllArtistAlbumsQuery = Request.Query.IncludeAllArtistAlbums; + var includeAllAuthorBooksQuery = Request.Query.IncludeAllAuthorBooks; if (!Request.Query.AuthorId.HasValue && !bookIdsQuery.HasValue && !slugQuery.HasValue) { - var albums = _bookService.GetAllBooks(); + var books = _bookService.GetAllBooks(); - var artists = _authorService.GetAllAuthors().ToDictionary(x => x.AuthorMetadataId); + var authors = _authorService.GetAllAuthors().ToDictionary(x => x.AuthorMetadataId); - foreach (var album in albums) + foreach (var book in books) { - album.Author = artists[album.AuthorMetadataId]; + book.Author = authors[book.AuthorMetadataId]; } - return MapToResource(albums, false); + return MapToResource(books, false); } if (authorIdQuery.HasValue) @@ -92,20 +92,20 @@ namespace Readarr.Api.V1.Albums { string titleSlug = slugQuery.Value.ToString(); - var album = _bookService.FindBySlug(titleSlug); + var book = _bookService.FindBySlug(titleSlug); - if (album == null) + if (book == null) { return MapToResource(new List<Book>(), false); } - if (includeAllArtistAlbumsQuery.HasValue && Convert.ToBoolean(includeAllArtistAlbumsQuery.Value)) + if (includeAllAuthorBooksQuery.HasValue && Convert.ToBoolean(includeAllAuthorBooksQuery.Value)) { - return MapToResource(_bookService.GetBooksByAuthor(album.AuthorId), false); + return MapToResource(_bookService.GetBooksByAuthor(book.AuthorId), false); } else { - return MapToResource(new List<Book> { album }, false); + return MapToResource(new List<Book> { book }, false); } } @@ -118,25 +118,25 @@ namespace Readarr.Api.V1.Albums return MapToResource(_bookService.GetBooks(bookIds), false); } - private int AddAlbum(AlbumResource albumResource) + private int AddBook(BookResource bookResource) { - var album = _addBookService.AddBook(albumResource.ToModel()); + var book = _addBookService.AddBook(bookResource.ToModel()); - return album.Id; + return book.Id; } - private void UpdateAlbum(AlbumResource albumResource) + private void UpdateBook(BookResource bookResource) { - var album = _bookService.GetBook(albumResource.Id); + var book = _bookService.GetBook(bookResource.Id); - var model = albumResource.ToModel(album); + var model = bookResource.ToModel(book); _bookService.UpdateBook(model); BroadcastResourceChange(ModelAction.Updated, model.Id); } - private void DeleteAlbum(int id) + private void DeleteBook(int id) { var deleteFiles = Request.GetBooleanQueryParameter("deleteFiles"); var addImportListExclusion = Request.GetBooleanQueryParameter("addImportListExclusion"); @@ -144,9 +144,9 @@ namespace Readarr.Api.V1.Albums _bookService.DeleteBook(id, deleteFiles, addImportListExclusion); } - private object SetAlbumsMonitored() + private object SetBooksMonitored() { - var resource = Request.Body.FromJson<AlbumsMonitoredResource>(); + var resource = Request.Body.FromJson<BooksMonitoredResource>(); _bookService.SetMonitored(resource.BookIds, resource.Monitored); @@ -155,9 +155,9 @@ namespace Readarr.Api.V1.Albums public void Handle(BookGrabbedEvent message) { - foreach (var album in message.Book.Books) + foreach (var book in message.Book.Books) { - var resource = album.ToResource(); + var resource = book.ToResource(); resource.Grabbed = true; BroadcastResourceChange(ModelAction.Updated, resource); @@ -166,7 +166,7 @@ namespace Readarr.Api.V1.Albums public void Handle(BookEditedEvent message) { - BroadcastResourceChange(ModelAction.Updated, MapToResource(message.Album, true)); + BroadcastResourceChange(ModelAction.Updated, MapToResource(message.Book, true)); } public void Handle(BookUpdatedEvent message) diff --git a/src/Readarr.Api.V1/Books/BookModuleWithSignalR.cs b/src/Readarr.Api.V1/Books/BookModuleWithSignalR.cs new file mode 100644 index 000000000..6cf516c87 --- /dev/null +++ b/src/Readarr.Api.V1/Books/BookModuleWithSignalR.cs @@ -0,0 +1,133 @@ +using System.Collections.Generic; +using System.Linq; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.AuthorStats; +using NzbDrone.Core.Books; +using NzbDrone.Core.DecisionEngine.Specifications; +using NzbDrone.Core.MediaCover; +using NzbDrone.SignalR; +using Readarr.Api.V1.Author; +using Readarr.Http; + +namespace Readarr.Api.V1.Books +{ + public abstract class BookModuleWithSignalR : ReadarrRestModuleWithSignalR<BookResource, Book> + { + protected readonly IBookService _bookService; + protected readonly IAuthorStatisticsService _authorStatisticsService; + protected readonly IUpgradableSpecification _qualityUpgradableSpecification; + protected readonly IMapCoversToLocal _coverMapper; + + protected BookModuleWithSignalR(IBookService bookService, + IAuthorStatisticsService authorStatisticsService, + IMapCoversToLocal coverMapper, + IUpgradableSpecification qualityUpgradableSpecification, + IBroadcastSignalRMessage signalRBroadcaster) + : base(signalRBroadcaster) + { + _bookService = bookService; + _authorStatisticsService = authorStatisticsService; + _coverMapper = coverMapper; + _qualityUpgradableSpecification = qualityUpgradableSpecification; + + GetResourceById = GetBook; + } + + protected BookModuleWithSignalR(IBookService bookService, + IAuthorStatisticsService authorStatisticsService, + IMapCoversToLocal coverMapper, + IUpgradableSpecification qualityUpgradableSpecification, + IBroadcastSignalRMessage signalRBroadcaster, + string resource) + : base(signalRBroadcaster, resource) + { + _bookService = bookService; + _authorStatisticsService = authorStatisticsService; + _coverMapper = coverMapper; + _qualityUpgradableSpecification = qualityUpgradableSpecification; + + GetResourceById = GetBook; + } + + protected BookResource GetBook(int id) + { + var book = _bookService.GetBook(id); + var resource = MapToResource(book, true); + return resource; + } + + protected BookResource MapToResource(Book book, bool includeAuthor) + { + var resource = book.ToResource(); + + if (includeAuthor) + { + var artist = book.Author.Value; + + resource.Author = artist.ToResource(); + } + + FetchAndLinkAlbumStatistics(resource); + MapCoversToLocal(resource); + + return resource; + } + + protected List<BookResource> MapToResource(List<Book> books, bool includeAuthor) + { + var result = books.ToResource(); + + if (includeAuthor) + { + var authorDict = new Dictionary<int, NzbDrone.Core.Books.Author>(); + for (var i = 0; i < books.Count; i++) + { + var book = books[i]; + var resource = result[i]; + var author = authorDict.GetValueOrDefault(books[i].AuthorMetadataId) ?? book.Author?.Value; + authorDict[author.AuthorMetadataId] = author; + + resource.Author = author.ToResource(); + } + } + + var authorStats = _authorStatisticsService.AuthorStatistics(); + LinkAuthorStatistics(result, authorStats); + MapCoversToLocal(result.ToArray()); + + return result; + } + + private void FetchAndLinkAlbumStatistics(BookResource resource) + { + LinkAuthorStatistics(resource, _authorStatisticsService.AuthorStatistics(resource.AuthorId)); + } + + private void LinkAuthorStatistics(List<BookResource> resources, List<AuthorStatistics> authorStatistics) + { + foreach (var book in resources) + { + var stats = authorStatistics.SingleOrDefault(ss => ss.AuthorId == book.AuthorId); + LinkAuthorStatistics(book, stats); + } + } + + private void LinkAuthorStatistics(BookResource resource, AuthorStatistics authorStatistics) + { + if (authorStatistics?.BookStatistics != null) + { + var dictBookStats = authorStatistics.BookStatistics.ToDictionary(v => v.BookId); + + resource.Statistics = dictBookStats.GetValueOrDefault(resource.Id).ToResource(); + } + } + + private void MapCoversToLocal(params BookResource[] books) + { + foreach (var bookResource in books) + { + _coverMapper.ConvertToLocalUrls(bookResource.Id, MediaCoverEntity.Book, bookResource.Images); + } + } + } +} diff --git a/src/Readarr.Api.V1/Albums/AlbumResource.cs b/src/Readarr.Api.V1/Books/BookResource.cs similarity index 75% rename from src/Readarr.Api.V1/Albums/AlbumResource.cs rename to src/Readarr.Api.V1/Books/BookResource.cs index 30491ce2f..1cf0dc4c8 100644 --- a/src/Readarr.Api.V1/Albums/AlbumResource.cs +++ b/src/Readarr.Api.V1/Books/BookResource.cs @@ -4,13 +4,13 @@ using System.Linq; using Newtonsoft.Json; using NzbDrone.Core.Books; using NzbDrone.Core.MediaCover; -using Readarr.Api.V1.Artist; -using Readarr.Api.V1.TrackFiles; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.BookFiles; using Readarr.Http.REST; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class AlbumResource : RestResource + public class BookResource : RestResource { public string Title { get; set; } public string Disambiguation { get; set; } @@ -27,10 +27,10 @@ namespace Readarr.Api.V1.Albums public Ratings Ratings { get; set; } public DateTime? ReleaseDate { get; set; } public List<string> Genres { get; set; } - public ArtistResource Artist { get; set; } + public AuthorResource Author { get; set; } public List<MediaCover> Images { get; set; } public List<Links> Links { get; set; } - public AlbumStatisticsResource Statistics { get; set; } + public BookStatisticsResource Statistics { get; set; } public AddBookOptions AddOptions { get; set; } public string RemoteCover { get; set; } @@ -39,16 +39,16 @@ namespace Readarr.Api.V1.Albums public bool Grabbed { get; set; } } - public static class AlbumResourceMapper + public static class BookResourceMapper { - public static AlbumResource ToResource(this Book model) + public static BookResource ToResource(this Book model) { if (model == null) { return null; } - return new AlbumResource + return new BookResource { Id = model.Id, AuthorId = model.AuthorId, @@ -68,18 +68,18 @@ namespace Readarr.Api.V1.Albums Images = model.Images, Links = model.Links, Ratings = model.Ratings, - Artist = model.Author?.Value.ToResource() + Author = model.Author?.Value.ToResource() }; } - public static Book ToModel(this AlbumResource resource) + public static Book ToModel(this BookResource resource) { if (resource == null) { return null; } - var artist = resource.Artist?.ToModel() ?? new NzbDrone.Core.Books.Author(); + var author = resource.Author?.ToModel() ?? new NzbDrone.Core.Books.Author(); return new Book { @@ -97,26 +97,26 @@ namespace Readarr.Api.V1.Albums Images = resource.Images, Monitored = resource.Monitored, AddOptions = resource.AddOptions, - Author = artist, - AuthorMetadata = artist.Metadata.Value + Author = author, + AuthorMetadata = author.Metadata.Value }; } - public static Book ToModel(this AlbumResource resource, Book album) + public static Book ToModel(this BookResource resource, Book book) { - var updatedAlbum = resource.ToModel(); + var updatedBook = resource.ToModel(); - album.ApplyChanges(updatedAlbum); + book.ApplyChanges(updatedBook); - return album; + return book; } - public static List<AlbumResource> ToResource(this IEnumerable<Book> models) + public static List<BookResource> ToResource(this IEnumerable<Book> models) { return models?.Select(ToResource).ToList(); } - public static List<Book> ToModel(this IEnumerable<AlbumResource> resources) + public static List<Book> ToModel(this IEnumerable<BookResource> resources) { return resources.Select(ToModel).ToList(); } diff --git a/src/Readarr.Api.V1/Artist/ArtistStatisticsResource.cs b/src/Readarr.Api.V1/Books/BookStatisticsResource.cs similarity index 63% rename from src/Readarr.Api.V1/Artist/ArtistStatisticsResource.cs rename to src/Readarr.Api.V1/Books/BookStatisticsResource.cs index 9b760a4a9..79ad8f07c 100644 --- a/src/Readarr.Api.V1/Artist/ArtistStatisticsResource.cs +++ b/src/Readarr.Api.V1/Books/BookStatisticsResource.cs @@ -1,12 +1,11 @@ using NzbDrone.Core.AuthorStats; -namespace Readarr.Api.V1.Artist +namespace Readarr.Api.V1.Books { - public class ArtistStatisticsResource + public class BookStatisticsResource { - public int BookCount { get; set; } public int BookFileCount { get; set; } - public int TrackCount { get; set; } + public int BookCount { get; set; } public int TotalTrackCount { get; set; } public long SizeOnDisk { get; set; } @@ -14,29 +13,29 @@ namespace Readarr.Api.V1.Artist { get { - if (TrackCount == 0) + if (BookCount == 0) { return 0; } - return BookFileCount / (decimal)TrackCount * 100; + return BookFileCount / (decimal)BookCount * 100; } } } - public static class ArtistStatisticsResourceMapper + public static class BookStatisticsResourceMapper { - public static ArtistStatisticsResource ToResource(this AuthorStatistics model) + public static BookStatisticsResource ToResource(this BookStatistics model) { if (model == null) { return null; } - return new ArtistStatisticsResource + return new BookStatisticsResource { - BookCount = model.BookCount, BookFileCount = model.BookFileCount, + BookCount = model.BookCount, SizeOnDisk = model.SizeOnDisk }; } diff --git a/src/Readarr.Api.V1/Albums/AlbumsMonitoredResource.cs b/src/Readarr.Api.V1/Books/BooksMonitoredResource.cs similarity index 66% rename from src/Readarr.Api.V1/Albums/AlbumsMonitoredResource.cs rename to src/Readarr.Api.V1/Books/BooksMonitoredResource.cs index e789f33da..da3f90d6c 100644 --- a/src/Readarr.Api.V1/Albums/AlbumsMonitoredResource.cs +++ b/src/Readarr.Api.V1/Books/BooksMonitoredResource.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class AlbumsMonitoredResource + public class BooksMonitoredResource { public List<int> BookIds { get; set; } public bool Monitored { get; set; } diff --git a/src/Readarr.Api.V1/Albums/RenameBookModule.cs b/src/Readarr.Api.V1/Books/RenameBookModule.cs similarity index 50% rename from src/Readarr.Api.V1/Albums/RenameBookModule.cs rename to src/Readarr.Api.V1/Books/RenameBookModule.cs index 9a4d10d69..fe29a4b56 100644 --- a/src/Readarr.Api.V1/Albums/RenameBookModule.cs +++ b/src/Readarr.Api.V1/Books/RenameBookModule.cs @@ -3,21 +3,21 @@ using NzbDrone.Core.MediaFiles; using Readarr.Http; using Readarr.Http.REST; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class RenameTrackModule : ReadarrRestModule<RenameTrackResource> + public class RenameBookModule : ReadarrRestModule<RenameBookResource> { - private readonly IRenameTrackFileService _renameTrackFileService; + private readonly IRenameBookFileService _renameBookFileService; - public RenameTrackModule(IRenameTrackFileService renameTrackFileService) + public RenameBookModule(IRenameBookFileService renameBookFileService) : base("rename") { - _renameTrackFileService = renameTrackFileService; + _renameBookFileService = renameBookFileService; - GetResourceAll = GetTracks; + GetResourceAll = GetBookFiles; } - private List<RenameTrackResource> GetTracks() + private List<RenameBookResource> GetBookFiles() { int authorId; @@ -33,10 +33,10 @@ namespace Readarr.Api.V1.Albums if (Request.Query.bookId.HasValue) { var bookId = (int)Request.Query.bookId; - return _renameTrackFileService.GetRenamePreviews(authorId, bookId).ToResource(); + return _renameBookFileService.GetRenamePreviews(authorId, bookId).ToResource(); } - return _renameTrackFileService.GetRenamePreviews(authorId).ToResource(); + return _renameBookFileService.GetRenamePreviews(authorId).ToResource(); } } } diff --git a/src/Readarr.Api.V1/Albums/RenameBookResource.cs b/src/Readarr.Api.V1/Books/RenameBookResource.cs similarity index 56% rename from src/Readarr.Api.V1/Albums/RenameBookResource.cs rename to src/Readarr.Api.V1/Books/RenameBookResource.cs index 95dde854b..ccd697e68 100644 --- a/src/Readarr.Api.V1/Albums/RenameBookResource.cs +++ b/src/Readarr.Api.V1/Books/RenameBookResource.cs @@ -2,37 +2,37 @@ using System.Collections.Generic; using System.Linq; using Readarr.Http.REST; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class RenameTrackResource : RestResource + public class RenameBookResource : RestResource { public int AuthorId { get; set; } public int BookId { get; set; } - public int TrackFileId { get; set; } + public int BookFileId { get; set; } public string ExistingPath { get; set; } public string NewPath { get; set; } } - public static class RenameTrackResourceMapper + public static class RenameBookResourceMapper { - public static RenameTrackResource ToResource(this NzbDrone.Core.MediaFiles.RenameBookFilePreview model) + public static RenameBookResource ToResource(this NzbDrone.Core.MediaFiles.RenameBookFilePreview model) { if (model == null) { return null; } - return new RenameTrackResource + return new RenameBookResource { AuthorId = model.AuthorId, BookId = model.BookId, - TrackFileId = model.BookFileId, + BookFileId = model.BookFileId, ExistingPath = model.ExistingPath, NewPath = model.NewPath }; } - public static List<RenameTrackResource> ToResource(this IEnumerable<NzbDrone.Core.MediaFiles.RenameBookFilePreview> models) + public static List<RenameBookResource> ToResource(this IEnumerable<NzbDrone.Core.MediaFiles.RenameBookFilePreview> models) { return models.Select(ToResource).ToList(); } diff --git a/src/Readarr.Api.V1/Albums/RetagBookModule.cs b/src/Readarr.Api.V1/Books/RetagBookModule.cs similarity index 78% rename from src/Readarr.Api.V1/Albums/RetagBookModule.cs rename to src/Readarr.Api.V1/Books/RetagBookModule.cs index ecef7aed9..3775aa9f6 100644 --- a/src/Readarr.Api.V1/Albums/RetagBookModule.cs +++ b/src/Readarr.Api.V1/Books/RetagBookModule.cs @@ -4,21 +4,21 @@ using NzbDrone.Core.MediaFiles; using Readarr.Http; using Readarr.Http.REST; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { - public class RetagTrackModule : ReadarrRestModule<RetagTrackResource> + public class RetagBookModule : ReadarrRestModule<RetagBookResource> { private readonly IAudioTagService _audioTagService; - public RetagTrackModule(IAudioTagService audioTagService) + public RetagBookModule(IAudioTagService audioTagService) : base("retag") { _audioTagService = audioTagService; - GetResourceAll = GetTracks; + GetResourceAll = GetBooks; } - private List<RetagTrackResource> GetTracks() + private List<RetagBookResource> GetBooks() { if (Request.Query.bookId.HasValue) { diff --git a/src/Readarr.Api.V1/Albums/RetagBookResource.cs b/src/Readarr.Api.V1/Books/RetagBookResource.cs similarity index 72% rename from src/Readarr.Api.V1/Albums/RetagBookResource.cs rename to src/Readarr.Api.V1/Books/RetagBookResource.cs index d13e74396..2d5902f43 100644 --- a/src/Readarr.Api.V1/Albums/RetagBookResource.cs +++ b/src/Readarr.Api.V1/Books/RetagBookResource.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using Readarr.Http.REST; -namespace Readarr.Api.V1.Albums +namespace Readarr.Api.V1.Books { public class TagDifference { @@ -11,31 +11,31 @@ namespace Readarr.Api.V1.Albums public string NewValue { get; set; } } - public class RetagTrackResource : RestResource + public class RetagBookResource : RestResource { public int AuthorId { get; set; } public int BookId { get; set; } public List<int> TrackNumbers { get; set; } - public int TrackFileId { get; set; } + public int BookFileId { get; set; } public string Path { get; set; } public List<TagDifference> Changes { get; set; } } public static class RetagTrackResourceMapper { - public static RetagTrackResource ToResource(this NzbDrone.Core.MediaFiles.RetagBookFilePreview model) + public static RetagBookResource ToResource(this NzbDrone.Core.MediaFiles.RetagBookFilePreview model) { if (model == null) { return null; } - return new RetagTrackResource + return new RetagBookResource { AuthorId = model.AuthorId, BookId = model.BookId, TrackNumbers = model.TrackNumbers.ToList(), - TrackFileId = model.BookFileId, + BookFileId = model.BookFileId, Path = model.Path, Changes = model.Changes.Select(x => new TagDifference { @@ -46,7 +46,7 @@ namespace Readarr.Api.V1.Albums }; } - public static List<RetagTrackResource> ToResource(this IEnumerable<NzbDrone.Core.MediaFiles.RetagBookFilePreview> models) + public static List<RetagBookResource> ToResource(this IEnumerable<NzbDrone.Core.MediaFiles.RetagBookFilePreview> models) { return models.Select(ToResource).ToList(); } diff --git a/src/Readarr.Api.V1/Calendar/CalendarFeedModule.cs b/src/Readarr.Api.V1/Calendar/CalendarFeedModule.cs index 13138bf3a..e670e46e4 100644 --- a/src/Readarr.Api.V1/Calendar/CalendarFeedModule.cs +++ b/src/Readarr.Api.V1/Calendar/CalendarFeedModule.cs @@ -61,35 +61,35 @@ namespace Readarr.Api.V1.Calendar tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id)); } - var albums = _bookService.BooksBetweenDates(start, end, unmonitored); + var books = _bookService.BooksBetweenDates(start, end, unmonitored); var calendar = new Ical.Net.Calendar { ProductId = "-//readarr.com//Readarr//EN" }; - var calendarName = "Readarr Music Schedule"; + var calendarName = "Readarr Book Schedule"; calendar.AddProperty(new CalendarProperty("NAME", calendarName)); calendar.AddProperty(new CalendarProperty("X-WR-CALNAME", calendarName)); - foreach (var album in albums.OrderBy(v => v.ReleaseDate.Value)) + foreach (var book in books.OrderBy(v => v.ReleaseDate.Value)) { - var artist = _authorService.GetAuthor(album.AuthorId); // Temp fix TODO: Figure out why Album.Artist is not populated during AlbumsBetweenDates Query + var author = _authorService.GetAuthor(book.AuthorId); // Temp fix TODO: Figure out why Album.Artist is not populated during AlbumsBetweenDates Query - if (tags.Any() && tags.None(artist.Tags.Contains)) + if (tags.Any() && tags.None(author.Tags.Contains)) { continue; } var occurrence = calendar.Create<CalendarEvent>(); - occurrence.Uid = "Readarr_album_" + album.Id; + occurrence.Uid = "Readarr_book_" + book.Id; //occurrence.Status = album.HasFile ? EventStatus.Confirmed : EventStatus.Tentative; - occurrence.Description = album.Overview; - occurrence.Categories = album.Genres; + occurrence.Description = book.Overview; + occurrence.Categories = book.Genres; - occurrence.Start = new CalDateTime(album.ReleaseDate.Value.ToLocalTime()) { HasTime = false }; + occurrence.Start = new CalDateTime(book.ReleaseDate.Value.ToLocalTime()) { HasTime = false }; - occurrence.Summary = $"{artist.Name} - {album.Title}"; + occurrence.Summary = $"{author.Name} - {book.Title}"; } var serializer = (IStringSerializer)new SerializerFactory().Build(calendar.GetType(), new SerializationContext()); diff --git a/src/Readarr.Api.V1/Calendar/CalendarModule.cs b/src/Readarr.Api.V1/Calendar/CalendarModule.cs index 22a6b7360..444ddbadc 100644 --- a/src/Readarr.Api.V1/Calendar/CalendarModule.cs +++ b/src/Readarr.Api.V1/Calendar/CalendarModule.cs @@ -6,32 +6,32 @@ using NzbDrone.Core.Books; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.MediaCover; using NzbDrone.SignalR; -using Readarr.Api.V1.Albums; +using Readarr.Api.V1.Books; using Readarr.Http.Extensions; namespace Readarr.Api.V1.Calendar { - public class CalendarModule : AlbumModuleWithSignalR + public class CalendarModule : BookModuleWithSignalR { public CalendarModule(IBookService bookService, - IAuthorStatisticsService artistStatisticsService, + IAuthorStatisticsService authorStatisticsService, IMapCoversToLocal coverMapper, IUpgradableSpecification upgradableSpecification, IBroadcastSignalRMessage signalRBroadcaster) - : base(bookService, artistStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "calendar") + : base(bookService, authorStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "calendar") { GetResourceAll = GetCalendar; } - private List<AlbumResource> GetCalendar() + private List<BookResource> GetCalendar() { var start = DateTime.Today; var end = DateTime.Today.AddDays(2); var includeUnmonitored = Request.GetBooleanQueryParameter("unmonitored"); - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); //TODO: Add Album Image support to AlbumModuleWithSignalR - var includeAlbumImages = Request.GetBooleanQueryParameter("includeAlbumImages"); + var includeBookImages = Request.GetBooleanQueryParameter("includeBookImages"); var queryStart = Request.Query.Start; var queryEnd = Request.Query.End; @@ -46,7 +46,7 @@ namespace Readarr.Api.V1.Calendar end = DateTime.Parse(queryEnd.Value); } - var resources = MapToResource(_bookService.BooksBetweenDates(start, end, includeUnmonitored), includeArtist); + var resources = MapToResource(_bookService.BooksBetweenDates(start, end, includeUnmonitored), includeAuthor); return resources.OrderBy(e => e.ReleaseDate).ToList(); } diff --git a/src/Readarr.Api.V1/Config/MediaManagementConfigResource.cs b/src/Readarr.Api.V1/Config/MediaManagementConfigResource.cs index a371fb2d4..8e4147493 100644 --- a/src/Readarr.Api.V1/Config/MediaManagementConfigResource.cs +++ b/src/Readarr.Api.V1/Config/MediaManagementConfigResource.cs @@ -7,11 +7,11 @@ namespace Readarr.Api.V1.Config { public class MediaManagementConfigResource : RestResource { - public bool AutoUnmonitorPreviouslyDownloadedTracks { get; set; } + public bool AutoUnmonitorPreviouslyDownloadedBooks { get; set; } public string RecycleBin { get; set; } public int RecycleBinCleanupDays { get; set; } public ProperDownloadTypes DownloadPropersAndRepacks { get; set; } - public bool CreateEmptyArtistFolders { get; set; } + public bool CreateEmptyAuthorFolders { get; set; } public bool DeleteEmptyFolders { get; set; } public FileDateType FileDate { get; set; } public bool WatchLibraryForChanges { get; set; } @@ -37,11 +37,11 @@ namespace Readarr.Api.V1.Config { return new MediaManagementConfigResource { - AutoUnmonitorPreviouslyDownloadedTracks = model.AutoUnmonitorPreviouslyDownloadedTracks, + AutoUnmonitorPreviouslyDownloadedBooks = model.AutoUnmonitorPreviouslyDownloadedBooks, RecycleBin = model.RecycleBin, RecycleBinCleanupDays = model.RecycleBinCleanupDays, DownloadPropersAndRepacks = model.DownloadPropersAndRepacks, - CreateEmptyArtistFolders = model.CreateEmptyArtistFolders, + CreateEmptyAuthorFolders = model.CreateEmptyAuthorFolders, DeleteEmptyFolders = model.DeleteEmptyFolders, FileDate = model.FileDate, WatchLibraryForChanges = model.WatchLibraryForChanges, diff --git a/src/Readarr.Api.V1/Config/NamingConfigModule.cs b/src/Readarr.Api.V1/Config/NamingConfigModule.cs index 2b62943eb..8ddd71448 100644 --- a/src/Readarr.Api.V1/Config/NamingConfigModule.cs +++ b/src/Readarr.Api.V1/Config/NamingConfigModule.cs @@ -75,11 +75,11 @@ namespace Readarr.Api.V1.Config var singleTrackSampleResult = _filenameSampleService.GetStandardTrackSample(nameSpec); - sampleResource.SingleTrackExample = _filenameValidationService.ValidateTrackFilename(singleTrackSampleResult) != null + sampleResource.SingleBookExample = _filenameValidationService.ValidateTrackFilename(singleTrackSampleResult) != null ? null : singleTrackSampleResult.FileName; - sampleResource.ArtistFolderExample = nameSpec.AuthorFolderFormat.IsNullOrWhiteSpace() + sampleResource.AuthorFolderExample = nameSpec.AuthorFolderFormat.IsNullOrWhiteSpace() ? null : _filenameSampleService.GetAuthorFolderSample(nameSpec); diff --git a/src/Readarr.Api.V1/Config/NamingExampleResource.cs b/src/Readarr.Api.V1/Config/NamingExampleResource.cs index f95102853..473ed17e7 100644 --- a/src/Readarr.Api.V1/Config/NamingExampleResource.cs +++ b/src/Readarr.Api.V1/Config/NamingExampleResource.cs @@ -4,8 +4,8 @@ namespace Readarr.Api.V1.Config { public class NamingExampleResource { - public string SingleTrackExample { get; set; } - public string ArtistFolderExample { get; set; } + public string SingleBookExample { get; set; } + public string AuthorFolderExample { get; set; } } public static class NamingConfigResourceMapper diff --git a/src/Readarr.Api.V1/History/HistoryModule.cs b/src/Readarr.Api.V1/History/HistoryModule.cs index 35fd1a4d1..a11d1e36f 100644 --- a/src/Readarr.Api.V1/History/HistoryModule.cs +++ b/src/Readarr.Api.V1/History/HistoryModule.cs @@ -6,8 +6,8 @@ using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.Download; using NzbDrone.Core.History; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http; using Readarr.Http.Extensions; using Readarr.Http.REST; @@ -30,7 +30,7 @@ namespace Readarr.Api.V1.History GetResourcePaged = GetHistory; Get("/since", x => GetHistorySince()); - Get("/artist", x => GetArtistHistory()); + Get("/author", x => GetArtistHistory()); Post("/failed", x => MarkAsFailed()); } @@ -40,12 +40,12 @@ namespace Readarr.Api.V1.History if (includeArtist) { - resource.Artist = model.Author.ToResource(); + resource.Author = model.Author.ToResource(); } if (includeAlbum) { - resource.Album = model.Book.ToResource(); + resource.Book = model.Book.ToResource(); } if (model.Author != null) @@ -59,8 +59,8 @@ namespace Readarr.Api.V1.History private PagingResource<HistoryResource> GetHistory(PagingResource<HistoryResource> pagingResource) { var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, NzbDrone.Core.History.History>("date", SortDirection.Descending); - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); - var includeAlbum = Request.GetBooleanQueryParameter("includeAlbum"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); + var includeBook = Request.GetBooleanQueryParameter("includeBook"); var eventTypeFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "eventType"); var bookIdFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "bookId"); @@ -84,7 +84,7 @@ namespace Readarr.Api.V1.History pagingSpec.FilterExpressions.Add(h => h.DownloadId == downloadId); } - return ApplyToPage(_historyService.Paged, pagingSpec, h => MapToResource(h, includeArtist, includeAlbum)); + return ApplyToPage(_historyService.Paged, pagingSpec, h => MapToResource(h, includeAuthor, includeBook)); } private List<HistoryResource> GetHistorySince() @@ -99,15 +99,15 @@ namespace Readarr.Api.V1.History DateTime date = DateTime.Parse(queryDate.Value); HistoryEventType? eventType = null; - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); - var includeAlbum = Request.GetBooleanQueryParameter("includeAlbum"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); + var includeBook = Request.GetBooleanQueryParameter("includeBook"); if (queryEventType.HasValue) { eventType = (HistoryEventType)Convert.ToInt32(queryEventType.Value); } - return _historyService.Since(date, eventType).Select(h => MapToResource(h, includeArtist, includeAlbum)).ToList(); + return _historyService.Since(date, eventType).Select(h => MapToResource(h, includeAuthor, includeBook)).ToList(); } private List<HistoryResource> GetArtistHistory() @@ -123,8 +123,8 @@ namespace Readarr.Api.V1.History int authorId = Convert.ToInt32(queryAuthorId.Value); HistoryEventType? eventType = null; - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); - var includeAlbum = Request.GetBooleanQueryParameter("includeAlbum"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); + var includeBook = Request.GetBooleanQueryParameter("includeBook"); if (queryEventType.HasValue) { @@ -135,10 +135,10 @@ namespace Readarr.Api.V1.History { int bookId = Convert.ToInt32(queryBookId.Value); - return _historyService.GetByBook(bookId, eventType).Select(h => MapToResource(h, includeArtist, includeAlbum)).ToList(); + return _historyService.GetByBook(bookId, eventType).Select(h => MapToResource(h, includeAuthor, includeBook)).ToList(); } - return _historyService.GetByAuthor(authorId, eventType).Select(h => MapToResource(h, includeArtist, includeAlbum)).ToList(); + return _historyService.GetByAuthor(authorId, eventType).Select(h => MapToResource(h, includeAuthor, includeBook)).ToList(); } private object MarkAsFailed() diff --git a/src/Readarr.Api.V1/History/HistoryResource.cs b/src/Readarr.Api.V1/History/HistoryResource.cs index 83fdd034a..61f78d878 100644 --- a/src/Readarr.Api.V1/History/HistoryResource.cs +++ b/src/Readarr.Api.V1/History/HistoryResource.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using NzbDrone.Core.History; using NzbDrone.Core.Qualities; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http.REST; namespace Readarr.Api.V1.History @@ -22,8 +22,8 @@ namespace Readarr.Api.V1.History public Dictionary<string, string> Data { get; set; } - public AlbumResource Album { get; set; } - public ArtistResource Artist { get; set; } + public BookResource Book { get; set; } + public AuthorResource Author { get; set; } } public static class HistoryResourceMapper diff --git a/src/Readarr.Api.V1/ImportLists/ImportListExclusionModule.cs b/src/Readarr.Api.V1/ImportLists/ImportListExclusionModule.cs index ff0315665..40fdae059 100644 --- a/src/Readarr.Api.V1/ImportLists/ImportListExclusionModule.cs +++ b/src/Readarr.Api.V1/ImportLists/ImportListExclusionModule.cs @@ -23,7 +23,7 @@ namespace Readarr.Api.V1.ImportLists DeleteResource = DeleteImportListExclusionResource; SharedValidator.RuleFor(c => c.ForeignId).NotEmpty().SetValidator(guidValidator).SetValidator(importListExclusionExistsValidator); - SharedValidator.RuleFor(c => c.ArtistName).NotEmpty(); + SharedValidator.RuleFor(c => c.AuthorName).NotEmpty(); } private ImportListExclusionResource GetImportListExclusion(int id) diff --git a/src/Readarr.Api.V1/ImportLists/ImportListExclusionResource.cs b/src/Readarr.Api.V1/ImportLists/ImportListExclusionResource.cs index 2a017c219..432e4a84a 100644 --- a/src/Readarr.Api.V1/ImportLists/ImportListExclusionResource.cs +++ b/src/Readarr.Api.V1/ImportLists/ImportListExclusionResource.cs @@ -8,7 +8,7 @@ namespace Readarr.Api.V1.ImportLists public class ImportListExclusionResource : RestResource { public string ForeignId { get; set; } - public string ArtistName { get; set; } + public string AuthorName { get; set; } } public static class ImportListExclusionResourceMapper @@ -24,7 +24,7 @@ namespace Readarr.Api.V1.ImportLists { Id = model.Id, ForeignId = model.ForeignId, - ArtistName = model.Name, + AuthorName = model.Name, }; } @@ -39,7 +39,7 @@ namespace Readarr.Api.V1.ImportLists { Id = resource.Id, ForeignId = resource.ForeignId, - Name = resource.ArtistName + Name = resource.AuthorName }; } diff --git a/src/Readarr.Api.V1/Indexers/ReleaseModule.cs b/src/Readarr.Api.V1/Indexers/ReleaseModule.cs index 6152303ac..53adf1f54 100644 --- a/src/Readarr.Api.V1/Indexers/ReleaseModule.cs +++ b/src/Readarr.Api.V1/Indexers/ReleaseModule.cs @@ -24,7 +24,7 @@ namespace Readarr.Api.V1.Indexers private readonly IDownloadService _downloadService; private readonly Logger _logger; - private readonly ICached<RemoteBook> _remoteAlbumCache; + private readonly ICached<RemoteBook> _remoteBookCache; public ReleaseModule(IFetchAndParseRss rssFetcherAndParser, ISearchForNzb nzbSearchService, @@ -47,12 +47,12 @@ namespace Readarr.Api.V1.Indexers PostValidator.RuleFor(s => s.IndexerId).ValidId(); PostValidator.RuleFor(s => s.Guid).NotEmpty(); - _remoteAlbumCache = cacheManager.GetCache<RemoteBook>(GetType(), "remoteAlbums"); + _remoteBookCache = cacheManager.GetCache<RemoteBook>(GetType(), "remoteBooks"); } private object DownloadRelease(ReleaseResource release) { - var remoteAlbum = _remoteAlbumCache.Find(GetCacheKey(release)); + var remoteAlbum = _remoteBookCache.Find(GetCacheKey(release)); if (remoteAlbum == null) { @@ -78,46 +78,46 @@ namespace Readarr.Api.V1.Indexers { if (Request.Query.bookId.HasValue) { - return GetAlbumReleases(Request.Query.bookId); + return GetBookReleases(Request.Query.bookId); } if (Request.Query.authorId.HasValue) { - return GetArtistReleases(Request.Query.authorId); + return GetAuthorReleases(Request.Query.authorId); } return GetRss(); } - private List<ReleaseResource> GetAlbumReleases(int bookId) + private List<ReleaseResource> GetBookReleases(int bookId) { try { - var decisions = _nzbSearchService.AlbumSearch(bookId, true, true, true); + var decisions = _nzbSearchService.BookSearch(bookId, true, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); return MapDecisions(prioritizedDecisions); } catch (Exception ex) { - _logger.Error(ex, "Album search failed"); + _logger.Error(ex, "Book search failed"); } return new List<ReleaseResource>(); } - private List<ReleaseResource> GetArtistReleases(int authorId) + private List<ReleaseResource> GetAuthorReleases(int authorId) { try { - var decisions = _nzbSearchService.ArtistSearch(authorId, false, true, true); + var decisions = _nzbSearchService.AuthorSearch(authorId, false, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); return MapDecisions(prioritizedDecisions); } catch (Exception ex) { - _logger.Error(ex, "Artist search failed"); + _logger.Error(ex, "Author search failed"); } return new List<ReleaseResource>(); @@ -135,7 +135,7 @@ namespace Readarr.Api.V1.Indexers protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight) { var resource = base.MapDecision(decision, initialWeight); - _remoteAlbumCache.Set(GetCacheKey(resource), decision.RemoteBook, TimeSpan.FromMinutes(30)); + _remoteBookCache.Set(GetCacheKey(resource), decision.RemoteBook, TimeSpan.FromMinutes(30)); return resource; } diff --git a/src/Readarr.Api.V1/Indexers/ReleaseResource.cs b/src/Readarr.Api.V1/Indexers/ReleaseResource.cs index c019a9987..e26b22f18 100644 --- a/src/Readarr.Api.V1/Indexers/ReleaseResource.cs +++ b/src/Readarr.Api.V1/Indexers/ReleaseResource.cs @@ -28,8 +28,8 @@ namespace Readarr.Api.V1.Indexers public bool Discography { get; set; } public bool SceneSource { get; set; } public string AirDate { get; set; } - public string ArtistName { get; set; } - public string AlbumTitle { get; set; } + public string AuthorName { get; set; } + public string BookTitle { get; set; } public bool Approved { get; set; } public bool TemporarilyRejected { get; set; } public bool Rejected { get; set; } @@ -65,15 +65,15 @@ namespace Readarr.Api.V1.Indexers public static ReleaseResource ToResource(this DownloadDecision model) { var releaseInfo = model.RemoteBook.Release; - var parsedAlbumInfo = model.RemoteBook.ParsedBookInfo; - var remoteAlbum = model.RemoteBook; + var parsedBookInfo = model.RemoteBook.ParsedBookInfo; + var remoteBook = model.RemoteBook; var torrentInfo = (model.RemoteBook.Release as TorrentInfo) ?? new TorrentInfo(); // TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?) return new ReleaseResource { Guid = releaseInfo.Guid, - Quality = parsedAlbumInfo.Quality, + Quality = parsedBookInfo.Quality, //QualityWeight Age = releaseInfo.Age, @@ -82,12 +82,12 @@ namespace Readarr.Api.V1.Indexers Size = releaseInfo.Size, IndexerId = releaseInfo.IndexerId, Indexer = releaseInfo.Indexer, - ReleaseGroup = parsedAlbumInfo.ReleaseGroup, - ReleaseHash = parsedAlbumInfo.ReleaseHash, + ReleaseGroup = parsedBookInfo.ReleaseGroup, + ReleaseHash = parsedBookInfo.ReleaseHash, Title = releaseInfo.Title, - ArtistName = parsedAlbumInfo.AuthorName, - AlbumTitle = parsedAlbumInfo.BookTitle, - Discography = parsedAlbumInfo.Discography, + AuthorName = parsedBookInfo.AuthorName, + BookTitle = parsedBookInfo.BookTitle, + Discography = parsedBookInfo.Discography, Approved = model.Approved, TemporarilyRejected = model.TemporarilyRejected, Rejected = model.Rejected, @@ -96,10 +96,10 @@ namespace Readarr.Api.V1.Indexers CommentUrl = releaseInfo.CommentUrl, DownloadUrl = releaseInfo.DownloadUrl, InfoUrl = releaseInfo.InfoUrl, - DownloadAllowed = remoteAlbum.DownloadAllowed, + DownloadAllowed = remoteBook.DownloadAllowed, //ReleaseWeight - PreferredWordScore = remoteAlbum.PreferredWordScore, + PreferredWordScore = remoteBook.PreferredWordScore, MagnetUrl = torrentInfo.MagnetUrl, InfoHash = torrentInfo.InfoHash, diff --git a/src/Readarr.Api.V1/ManualImport/ManualImportModule.cs b/src/Readarr.Api.V1/ManualImport/ManualImportModule.cs index 5307f20ed..4d1702c99 100644 --- a/src/Readarr.Api.V1/ManualImport/ManualImportModule.cs +++ b/src/Readarr.Api.V1/ManualImport/ManualImportModule.cs @@ -70,8 +70,8 @@ namespace Readarr.Api.V1.ManualImport Path = resource.Path, Name = resource.Name, Size = resource.Size, - Author = resource.Artist == null ? null : _authorService.GetAuthor(resource.Artist.Id), - Book = resource.Album == null ? null : _bookService.GetBook(resource.Album.Id), + Author = resource.Author == null ? null : _authorService.GetAuthor(resource.Author.Id), + Book = resource.Book == null ? null : _bookService.GetBook(resource.Book.Id), Quality = resource.Quality, DownloadId = resource.DownloadId, AdditionalFile = resource.AdditionalFile, diff --git a/src/Readarr.Api.V1/ManualImport/ManualImportResource.cs b/src/Readarr.Api.V1/ManualImport/ManualImportResource.cs index 51275939a..91ecc35b2 100644 --- a/src/Readarr.Api.V1/ManualImport/ManualImportResource.cs +++ b/src/Readarr.Api.V1/ManualImport/ManualImportResource.cs @@ -4,8 +4,8 @@ using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.MediaFiles.BookImport.Manual; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http.REST; namespace Readarr.Api.V1.ManualImport @@ -15,8 +15,8 @@ namespace Readarr.Api.V1.ManualImport public string Path { get; set; } public string Name { get; set; } public long Size { get; set; } - public ArtistResource Artist { get; set; } - public AlbumResource Album { get; set; } + public AuthorResource Author { get; set; } + public BookResource Book { get; set; } public QualityModel Quality { get; set; } public int QualityWeight { get; set; } public string DownloadId { get; set; } @@ -41,8 +41,8 @@ namespace Readarr.Api.V1.ManualImport Path = model.Path, Name = model.Name, Size = model.Size, - Artist = model.Author.ToResource(), - Album = model.Book.ToResource(), + Author = model.Author.ToResource(), + Book = model.Book.ToResource(), Quality = model.Quality, //QualityWeight diff --git a/src/Readarr.Api.V1/MediaCovers/MediaCoverModule.cs b/src/Readarr.Api.V1/MediaCovers/MediaCoverModule.cs index d90611ddc..378a53d97 100644 --- a/src/Readarr.Api.V1/MediaCovers/MediaCoverModule.cs +++ b/src/Readarr.Api.V1/MediaCovers/MediaCoverModule.cs @@ -10,8 +10,8 @@ namespace Readarr.Api.V1.MediaCovers { public class MediaCoverModule : ReadarrV1Module { - private const string MEDIA_COVER_ARTIST_ROUTE = @"/Artist/(?<authorId>\d+)/(?<filename>(.+)\.(jpg|png|gif))"; - private const string MEDIA_COVER_ALBUM_ROUTE = @"/Album/(?<authorId>\d+)/(?<filename>(.+)\.(jpg|png|gif))"; + private const string MEDIA_COVER_AUTHOR_ROUTE = @"/Author/(?<authorId>\d+)/(?<filename>(.+)\.(jpg|png|gif))"; + private const string MEDIA_COVER_BOOK_ROUTE = @"/Book/(?<authorId>\d+)/(?<filename>(.+)\.(jpg|png|gif))"; private static readonly Regex RegexResizedImage = new Regex(@"-\d+(?=\.(jpg|png|gif)$)", RegexOptions.Compiled | RegexOptions.IgnoreCase); @@ -24,8 +24,8 @@ namespace Readarr.Api.V1.MediaCovers _appFolderInfo = appFolderInfo; _diskProvider = diskProvider; - Get(MEDIA_COVER_ARTIST_ROUTE, options => GetArtistMediaCover(options.authorId, options.filename)); - Get(MEDIA_COVER_ALBUM_ROUTE, options => GetAlbumMediaCover(options.authorId, options.filename)); + Get(MEDIA_COVER_AUTHOR_ROUTE, options => GetArtistMediaCover(options.authorId, options.filename)); + Get(MEDIA_COVER_BOOK_ROUTE, options => GetAlbumMediaCover(options.authorId, options.filename)); } private object GetArtistMediaCover(int authorId, string filename) @@ -50,7 +50,7 @@ namespace Readarr.Api.V1.MediaCovers private object GetAlbumMediaCover(int bookId, string filename) { - var filePath = Path.Combine(_appFolderInfo.GetAppDataPath(), "MediaCover", "Albums", bookId.ToString(), filename); + var filePath = Path.Combine(_appFolderInfo.GetAppDataPath(), "MediaCover", "Books", bookId.ToString(), filename); if (!_diskProvider.FileExists(filePath) || _diskProvider.GetFileSize(filePath) == 0) { diff --git a/src/Readarr.Api.V1/Parse/ParseModule.cs b/src/Readarr.Api.V1/Parse/ParseModule.cs index 6a07c2619..1dddf75f2 100644 --- a/src/Readarr.Api.V1/Parse/ParseModule.cs +++ b/src/Readarr.Api.V1/Parse/ParseModule.cs @@ -1,6 +1,6 @@ using NzbDrone.Core.Parser; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http; namespace Readarr.Api.V1.Parse @@ -33,9 +33,9 @@ namespace Readarr.Api.V1.Parse return new ParseResource { Title = title, - ParsedAlbumInfo = remoteAlbum.ParsedBookInfo, - Artist = remoteAlbum.Author.ToResource(), - Albums = remoteAlbum.Books.ToResource() + ParsedBookInfo = remoteAlbum.ParsedBookInfo, + Author = remoteAlbum.Author.ToResource(), + Books = remoteAlbum.Books.ToResource() }; } else @@ -43,7 +43,7 @@ namespace Readarr.Api.V1.Parse return new ParseResource { Title = title, - ParsedAlbumInfo = parsedAlbumInfo + ParsedBookInfo = parsedAlbumInfo }; } } diff --git a/src/Readarr.Api.V1/Parse/ParseResource.cs b/src/Readarr.Api.V1/Parse/ParseResource.cs index 67152b497..7abcb4234 100644 --- a/src/Readarr.Api.V1/Parse/ParseResource.cs +++ b/src/Readarr.Api.V1/Parse/ParseResource.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using NzbDrone.Core.Parser.Model; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http.REST; namespace Readarr.Api.V1.Parse @@ -9,8 +9,8 @@ namespace Readarr.Api.V1.Parse public class ParseResource : RestResource { public string Title { get; set; } - public ParsedBookInfo ParsedAlbumInfo { get; set; } - public ArtistResource Artist { get; set; } - public List<AlbumResource> Albums { get; set; } + public ParsedBookInfo ParsedBookInfo { get; set; } + public AuthorResource Author { get; set; } + public List<BookResource> Books { get; set; } } } diff --git a/src/Readarr.Api.V1/Queue/QueueDetailsModule.cs b/src/Readarr.Api.V1/Queue/QueueDetailsModule.cs index 28640441c..2c41d4c20 100644 --- a/src/Readarr.Api.V1/Queue/QueueDetailsModule.cs +++ b/src/Readarr.Api.V1/Queue/QueueDetailsModule.cs @@ -27,8 +27,8 @@ namespace Readarr.Api.V1.Queue private List<QueueResource> GetQueue() { - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); - var includeAlbum = Request.GetBooleanQueryParameter("includeAlbum", true); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); + var includeBook = Request.GetBooleanQueryParameter("includeBook", true); var queue = _queueService.GetQueue(); var pending = _pendingReleaseService.GetPendingQueue(); var fullQueue = queue.Concat(pending); @@ -38,7 +38,7 @@ namespace Readarr.Api.V1.Queue if (authorIdQuery.HasValue) { - return fullQueue.Where(q => q.Author?.Id == (int)authorIdQuery).ToResource(includeArtist, includeAlbum); + return fullQueue.Where(q => q.Author?.Id == (int)authorIdQuery).ToResource(includeAuthor, includeBook); } if (bookIdsQuery.HasValue) @@ -49,10 +49,10 @@ namespace Readarr.Api.V1.Queue .Select(e => Convert.ToInt32(e)) .ToList(); - return fullQueue.Where(q => q.Book != null && bookIds.Contains(q.Book.Id)).ToResource(includeArtist, includeAlbum); + return fullQueue.Where(q => q.Book != null && bookIds.Contains(q.Book.Id)).ToResource(includeAuthor, includeBook); } - return fullQueue.ToResource(includeArtist, includeAlbum); + return fullQueue.ToResource(includeAuthor, includeBook); } public void Handle(QueueUpdatedEvent message) diff --git a/src/Readarr.Api.V1/Queue/QueueModule.cs b/src/Readarr.Api.V1/Queue/QueueModule.cs index 53360bf92..2f36666ea 100644 --- a/src/Readarr.Api.V1/Queue/QueueModule.cs +++ b/src/Readarr.Api.V1/Queue/QueueModule.cs @@ -38,20 +38,20 @@ namespace Readarr.Api.V1.Queue private PagingResource<QueueResource> GetQueue(PagingResource<QueueResource> pagingResource) { var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>("timeleft", SortDirection.Ascending); - var includeUnknownArtistItems = Request.GetBooleanQueryParameter("includeUnknownArtistItems"); - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); - var includeAlbum = Request.GetBooleanQueryParameter("includeAlbum"); + var includeUnknownAuthorItems = Request.GetBooleanQueryParameter("includeUnknownAuthorItems"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); + var includeBook = Request.GetBooleanQueryParameter("includeBook"); - return ApplyToPage((spec) => GetQueue(spec, includeUnknownArtistItems), pagingSpec, (q) => MapToResource(q, includeArtist, includeAlbum)); + return ApplyToPage((spec) => GetQueue(spec, includeUnknownAuthorItems), pagingSpec, (q) => MapToResource(q, includeAuthor, includeBook)); } - private PagingSpec<NzbDrone.Core.Queue.Queue> GetQueue(PagingSpec<NzbDrone.Core.Queue.Queue> pagingSpec, bool includeUnknownArtistItems) + private PagingSpec<NzbDrone.Core.Queue.Queue> GetQueue(PagingSpec<NzbDrone.Core.Queue.Queue> pagingSpec, bool includeUnknownAuthorItems) { var ascending = pagingSpec.SortDirection == SortDirection.Ascending; var orderByFunc = GetOrderByFunc(pagingSpec); var queue = _queueService.GetQueue(); - var filteredQueue = includeUnknownArtistItems ? queue : queue.Where(q => q.Author != null); + var filteredQueue = includeUnknownAuthorItems ? queue : queue.Where(q => q.Author != null); var pending = _pendingReleaseService.GetPendingQueue(); var fullQueue = filteredQueue.Concat(pending).ToList(); IOrderedEnumerable<NzbDrone.Core.Queue.Queue> ordered; @@ -122,11 +122,11 @@ namespace Readarr.Api.V1.Queue return q => q.Author?.SortName; case "title": return q => q.Title; - case "album": + case "book": return q => q.Book; - case "books.title": + case "book.title": return q => q.Book?.Title; - case "album.releaseDate": + case "book.releaseDate": return q => q.Book?.ReleaseDate; case "quality": return q => q.Quality; @@ -138,9 +138,9 @@ namespace Readarr.Api.V1.Queue } } - private QueueResource MapToResource(NzbDrone.Core.Queue.Queue queueItem, bool includeArtist, bool includeAlbum) + private QueueResource MapToResource(NzbDrone.Core.Queue.Queue queueItem, bool includeAuthor, bool includeBook) { - return queueItem.ToResource(includeArtist, includeAlbum); + return queueItem.ToResource(includeAuthor, includeBook); } public void Handle(QueueUpdatedEvent message) diff --git a/src/Readarr.Api.V1/Queue/QueueResource.cs b/src/Readarr.Api.V1/Queue/QueueResource.cs index c10f84389..6a646bb19 100644 --- a/src/Readarr.Api.V1/Queue/QueueResource.cs +++ b/src/Readarr.Api.V1/Queue/QueueResource.cs @@ -5,8 +5,8 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Indexers; using NzbDrone.Core.Qualities; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http.REST; namespace Readarr.Api.V1.Queue @@ -15,8 +15,8 @@ namespace Readarr.Api.V1.Queue { public int? AuthorId { get; set; } public int? BookId { get; set; } - public ArtistResource Artist { get; set; } - public AlbumResource Album { get; set; } + public AuthorResource Author { get; set; } + public BookResource Book { get; set; } public QualityModel Quality { get; set; } public decimal Size { get; set; } public string Title { get; set; } @@ -50,8 +50,8 @@ namespace Readarr.Api.V1.Queue Id = model.Id, AuthorId = model.Author?.Id, BookId = model.Book?.Id, - Artist = includeArtist && model.Author != null ? model.Author.ToResource() : null, - Album = includeAlbum && model.Book != null ? model.Book.ToResource() : null, + Author = includeArtist && model.Author != null ? model.Author.ToResource() : null, + Book = includeAlbum && model.Book != null ? model.Book.ToResource() : null, Quality = model.Quality, Size = model.Size, Title = model.Title, @@ -72,9 +72,9 @@ namespace Readarr.Api.V1.Queue }; } - public static List<QueueResource> ToResource(this IEnumerable<NzbDrone.Core.Queue.Queue> models, bool includeArtist, bool includeAlbum) + public static List<QueueResource> ToResource(this IEnumerable<NzbDrone.Core.Queue.Queue> models, bool includeAuthor, bool includeBook) { - return models.Select((m) => ToResource(m, includeArtist, includeAlbum)).ToList(); + return models.Select((m) => ToResource(m, includeAuthor, includeBook)).ToList(); } } } diff --git a/src/Readarr.Api.V1/Search/SearchModule.cs b/src/Readarr.Api.V1/Search/SearchModule.cs index 816c2487c..e9b8c4ca4 100644 --- a/src/Readarr.Api.V1/Search/SearchModule.cs +++ b/src/Readarr.Api.V1/Search/SearchModule.cs @@ -4,8 +4,8 @@ using System.Linq; using Nancy; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MetadataSource; -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http; namespace Readarr.Api.V1.Search @@ -37,26 +37,26 @@ namespace Readarr.Api.V1.Search if (result is NzbDrone.Core.Books.Author) { - var artist = (NzbDrone.Core.Books.Author)result; - resource.Artist = artist.ToResource(); - resource.ForeignId = artist.ForeignAuthorId; + var author = (NzbDrone.Core.Books.Author)result; + resource.Author = author.ToResource(); + resource.ForeignId = author.ForeignAuthorId; - var poster = artist.Metadata.Value.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster); + var poster = author.Metadata.Value.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster); if (poster != null) { - resource.Artist.RemotePoster = poster.Url; + resource.Author.RemotePoster = poster.Url; } } else if (result is NzbDrone.Core.Books.Book) { - var album = (NzbDrone.Core.Books.Book)result; - resource.Album = album.ToResource(); - resource.ForeignId = album.ForeignBookId; + var book = (NzbDrone.Core.Books.Book)result; + resource.Book = book.ToResource(); + resource.ForeignId = book.ForeignBookId; - var cover = album.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Cover); + var cover = book.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Cover); if (cover != null) { - resource.Album.RemoteCover = cover.Url; + resource.Book.RemoteCover = cover.Url; } } else diff --git a/src/Readarr.Api.V1/Search/SearchResource.cs b/src/Readarr.Api.V1/Search/SearchResource.cs index fdd241dc3..eb5642ad7 100644 --- a/src/Readarr.Api.V1/Search/SearchResource.cs +++ b/src/Readarr.Api.V1/Search/SearchResource.cs @@ -1,5 +1,5 @@ -using Readarr.Api.V1.Albums; -using Readarr.Api.V1.Artist; +using Readarr.Api.V1.Author; +using Readarr.Api.V1.Books; using Readarr.Http.REST; namespace Readarr.Api.V1.Search @@ -8,7 +8,7 @@ namespace Readarr.Api.V1.Search SearchResource : RestResource { public string ForeignId { get; set; } - public ArtistResource Artist { get; set; } - public AlbumResource Album { get; set; } + public AuthorResource Author { get; set; } + public BookResource Book { get; set; } } } diff --git a/src/Readarr.Api.V1/Wanted/CutoffModule.cs b/src/Readarr.Api.V1/Wanted/CutoffModule.cs index 267bd6fce..e4f6437fc 100644 --- a/src/Readarr.Api.V1/Wanted/CutoffModule.cs +++ b/src/Readarr.Api.V1/Wanted/CutoffModule.cs @@ -5,29 +5,29 @@ using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.MediaCover; using NzbDrone.SignalR; -using Readarr.Api.V1.Albums; +using Readarr.Api.V1.Books; using Readarr.Http; using Readarr.Http.Extensions; namespace Readarr.Api.V1.Wanted { - public class CutoffModule : AlbumModuleWithSignalR + public class CutoffModule : BookModuleWithSignalR { - private readonly IBookCutoffService _albumCutoffService; + private readonly IBookCutoffService _bookCutoffService; - public CutoffModule(IBookCutoffService albumCutoffService, + public CutoffModule(IBookCutoffService bookCutoffService, IBookService bookService, - IAuthorStatisticsService artistStatisticsService, + IAuthorStatisticsService authorStatisticsService, IMapCoversToLocal coverMapper, IUpgradableSpecification upgradableSpecification, IBroadcastSignalRMessage signalRBroadcaster) - : base(bookService, artistStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "wanted/cutoff") + : base(bookService, authorStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "wanted/cutoff") { - _albumCutoffService = albumCutoffService; - GetResourcePaged = GetCutoffUnmetAlbums; + _bookCutoffService = bookCutoffService; + GetResourcePaged = GetCutoffUnmetBooks; } - private PagingResource<AlbumResource> GetCutoffUnmetAlbums(PagingResource<AlbumResource> pagingResource) + private PagingResource<BookResource> GetCutoffUnmetBooks(PagingResource<BookResource> pagingResource) { var pagingSpec = new PagingSpec<Book> { @@ -37,7 +37,7 @@ namespace Readarr.Api.V1.Wanted SortDirection = pagingResource.SortDirection }; - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); var filter = pagingResource.Filters.FirstOrDefault(f => f.Key == "monitored"); if (filter != null && filter.Value == "false") @@ -49,7 +49,7 @@ namespace Readarr.Api.V1.Wanted pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Author.Value.Monitored == true); } - var resource = ApplyToPage(_albumCutoffService.BooksWhereCutoffUnmet, pagingSpec, v => MapToResource(v, includeArtist)); + var resource = ApplyToPage(_bookCutoffService.BooksWhereCutoffUnmet, pagingSpec, v => MapToResource(v, includeAuthor)); return resource; } diff --git a/src/Readarr.Api.V1/Wanted/MissingModule.cs b/src/Readarr.Api.V1/Wanted/MissingModule.cs index 31f9d438a..a1e46457a 100644 --- a/src/Readarr.Api.V1/Wanted/MissingModule.cs +++ b/src/Readarr.Api.V1/Wanted/MissingModule.cs @@ -5,25 +5,25 @@ using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.MediaCover; using NzbDrone.SignalR; -using Readarr.Api.V1.Albums; +using Readarr.Api.V1.Books; using Readarr.Http; using Readarr.Http.Extensions; namespace Readarr.Api.V1.Wanted { - public class MissingModule : AlbumModuleWithSignalR + public class MissingModule : BookModuleWithSignalR { public MissingModule(IBookService bookService, - IAuthorStatisticsService artistStatisticsService, + IAuthorStatisticsService authorStatisticsService, IMapCoversToLocal coverMapper, IUpgradableSpecification upgradableSpecification, IBroadcastSignalRMessage signalRBroadcaster) - : base(bookService, artistStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "wanted/missing") + : base(bookService, authorStatisticsService, coverMapper, upgradableSpecification, signalRBroadcaster, "wanted/missing") { - GetResourcePaged = GetMissingAlbums; + GetResourcePaged = GetMissingBooks; } - private PagingResource<AlbumResource> GetMissingAlbums(PagingResource<AlbumResource> pagingResource) + private PagingResource<BookResource> GetMissingBooks(PagingResource<BookResource> pagingResource) { var pagingSpec = new PagingSpec<Book> { @@ -33,7 +33,7 @@ namespace Readarr.Api.V1.Wanted SortDirection = pagingResource.SortDirection }; - var includeArtist = Request.GetBooleanQueryParameter("includeArtist"); + var includeAuthor = Request.GetBooleanQueryParameter("includeAuthor"); var monitoredFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "monitored"); if (monitoredFilter != null && monitoredFilter.Value == "false") @@ -45,7 +45,7 @@ namespace Readarr.Api.V1.Wanted pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Author.Value.Monitored == true); } - var resource = ApplyToPage(_bookService.BooksWithoutFiles, pagingSpec, v => MapToResource(v, includeArtist)); + var resource = ApplyToPage(_bookService.BooksWithoutFiles, pagingSpec, v => MapToResource(v, includeAuthor)); return resource; }