diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs index 5b454ae3c..16639271d 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/DeleteBadMediaCovers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -11,7 +11,7 @@ using NzbDrone.Core.Extras.Metadata; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.Housekeeping.Housekeepers; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.HealthCheck.Checks @@ -20,27 +20,27 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks public class DeleteBadMediaCoversFixture : CoreTest { private List _metadata; - private List _series; + private List _artist; [SetUp] public void Setup() { - _series = Builder.CreateListOfSize(1) + _artist = Builder.CreateListOfSize(1) .All() - .With(c => c.Path = "C:\\TV\\".AsOsAgnostic()) + .With(c => c.Path = "C:\\Music\\".AsOsAgnostic()) .Build().ToList(); _metadata = Builder.CreateListOfSize(1) .Build().ToList(); - Mocker.GetMock() - .Setup(c => c.GetAllSeries()) - .Returns(_series); + Mocker.GetMock() + .Setup(c => c.GetAllArtists()) + .Returns(_artist); Mocker.GetMock() - .Setup(c => c.GetFilesBySeries(_series.First().Id)) + .Setup(c => c.GetFilesByArtist(_artist.First().Id)) .Returns(_metadata); @@ -51,8 +51,8 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks [Test] public void should_not_process_non_image_files() { - _metadata.First().RelativePath = "season\\file.xml".AsOsAgnostic(); - _metadata.First().Type = MetadataType.EpisodeMetadata; + _metadata.First().RelativePath = "album\\file.xml".AsOsAgnostic(); + _metadata.First().Type = MetadataType.TrackMetadata; Subject.Clean(); @@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks Subject.Clean(); Mocker.GetMock().VerifySet(c => c.CleanupMetadataImages = true, Times.Never()); - Mocker.GetMock().Verify(c => c.GetAllSeries(), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAllArtists(), Times.Never()); AssertImageWasNotRemoved(); } @@ -101,10 +101,10 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks public void should_delete_html_images() { - var imagePath = "C:\\TV\\Season\\image.jpg".AsOsAgnostic(); + var imagePath = "C:\\Music\\Album\\image.jpg".AsOsAgnostic(); _metadata.First().LastUpdated = new DateTime(2014, 12, 29); - _metadata.First().RelativePath = "Season\\image.jpg".AsOsAgnostic(); - _metadata.First().Type = MetadataType.SeriesImage; + _metadata.First().RelativePath = "Album\\image.jpg".AsOsAgnostic(); + _metadata.First().Type = MetadataType.ArtistImage; Mocker.GetMock() .Setup(c => c.OpenReadStream(imagePath)) @@ -123,10 +123,10 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks public void should_delete_empty_images() { - var imagePath = "C:\\TV\\Season\\image.jpg".AsOsAgnostic(); + var imagePath = "C:\\Music\\Album\\image.jpg".AsOsAgnostic(); _metadata.First().LastUpdated = new DateTime(2014, 12, 29); - _metadata.First().Type = MetadataType.SeasonImage; - _metadata.First().RelativePath = "Season\\image.jpg".AsOsAgnostic(); + _metadata.First().Type = MetadataType.AlbumImage; + _metadata.First().RelativePath = "Album\\image.jpg".AsOsAgnostic(); Mocker.GetMock() .Setup(c => c.OpenReadStream(imagePath)) @@ -144,9 +144,9 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks public void should_not_delete_non_html_files() { - var imagePath = "C:\\TV\\Season\\image.jpg".AsOsAgnostic(); + var imagePath = "C:\\Music\\Album\\image.jpg".AsOsAgnostic(); _metadata.First().LastUpdated = new DateTime(2014, 12, 29); - _metadata.First().RelativePath = "Season\\image.jpg".AsOsAgnostic(); + _metadata.First().RelativePath = "Album\\image.jpg".AsOsAgnostic(); Mocker.GetMock() .Setup(c => c.OpenReadStream(imagePath)) diff --git a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupDuplicateMetadataFilesFixture.cs b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupDuplicateMetadataFilesFixture.cs index 5bfeaefc0..2f4180a89 100644 --- a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupDuplicateMetadataFilesFixture.cs +++ b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupDuplicateMetadataFilesFixture.cs @@ -1,4 +1,4 @@ -using FizzWare.NBuilder; +using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Extras.Metadata; @@ -12,12 +12,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers public class CleanupDuplicateMetadataFilesFixture : DbTest { [Test] - public void should_not_delete_metadata_files_when_they_are_for_the_same_series_but_different_consumers() + public void should_not_delete_metadata_files_when_they_are_for_the_same_artist_but_different_consumers() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.SeriesMetadata) - .With(m => m.SeriesId = 1) + .With(m => m.Type = MetadataType.ArtistMetadata) + .With(m => m.ArtistId = 1) .BuildListOfNew(); Db.InsertMany(files); @@ -26,11 +26,11 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_for_different_series() + public void should_not_delete_metadata_files_for_different_artist() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.SeriesMetadata) + .With(m => m.Type = MetadataType.ArtistMetadata) .With(m => m.Consumer = "XbmcMetadata") .BuildListOfNew(); @@ -40,12 +40,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_delete_metadata_files_when_they_are_for_the_same_series_and_consumer() + public void should_delete_metadata_files_when_they_are_for_the_same_artist_and_consumer() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.SeriesMetadata) - .With(m => m.SeriesId = 1) + .With(m => m.Type = MetadataType.ArtistMetadata) + .With(m => m.ArtistId = 1) .With(m => m.Consumer = "XbmcMetadata") .BuildListOfNew(); @@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_when_there_is_only_one_for_that_series_and_consumer() + public void should_not_delete_metadata_files_when_there_is_only_one_for_that_artist_and_consumer() { var file = Builder.CreateNew() .BuildNew(); @@ -66,12 +66,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_when_they_are_for_the_same_episode_but_different_consumers() + public void should_not_delete_metadata_files_when_they_are_for_the_same_track_but_different_consumers() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.EpisodeMetadata) - .With(m => m.EpisodeFileId = 1) + .With(m => m.Type = MetadataType.TrackMetadata) + .With(m => m.TrackFileId = 1) .BuildListOfNew(); Db.InsertMany(files); @@ -80,11 +80,11 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_for_different_episode() + public void should_not_delete_metadata_files_for_different_track() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.EpisodeMetadata) + .With(m => m.Type = MetadataType.TrackMetadata) .With(m => m.Consumer = "XbmcMetadata") .BuildListOfNew(); @@ -94,12 +94,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_delete_metadata_files_when_they_are_for_the_same_episode_and_consumer() + public void should_delete_metadata_files_when_they_are_for_the_same_track_and_consumer() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.EpisodeMetadata) - .With(m => m.EpisodeFileId = 1) + .With(m => m.Type = MetadataType.TrackMetadata) + .With(m => m.TrackFileId = 1) .With(m => m.Consumer = "XbmcMetadata") .BuildListOfNew(); @@ -109,7 +109,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_when_there_is_only_one_for_that_episode_and_consumer() + public void should_not_delete_metadata_files_when_there_is_only_one_for_that_track_and_consumer() { var file = Builder.CreateNew() .BuildNew(); @@ -120,12 +120,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_image_when_they_are_for_the_same_episode_but_different_consumers() + public void should_not_delete_image_when_they_are_for_the_same_track_but_different_consumers() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.EpisodeImage) - .With(m => m.EpisodeFileId = 1) + .With(m => m.Type = MetadataType.TrackImage) + .With(m => m.TrackFileId = 1) .BuildListOfNew(); Db.InsertMany(files); @@ -134,11 +134,11 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_image_for_different_episode() + public void should_not_delete_image_for_different_track() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.EpisodeImage) + .With(m => m.Type = MetadataType.TrackImage) .With(m => m.Consumer = "XbmcMetadata") .BuildListOfNew(); @@ -148,12 +148,12 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_delete_image_when_they_are_for_the_same_episode_and_consumer() + public void should_delete_image_when_they_are_for_the_same_track_and_consumer() { var files = Builder.CreateListOfSize(2) .All() - .With(m => m.Type = MetadataType.EpisodeImage) - .With(m => m.EpisodeFileId = 1) + .With(m => m.Type = MetadataType.TrackImage) + .With(m => m.TrackFileId = 1) .With(m => m.Consumer = "XbmcMetadata") .BuildListOfNew(); @@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_image_when_there_is_only_one_for_that_episode_and_consumer() + public void should_not_delete_image_when_there_is_only_one_for_that_track_and_consumer() { var file = Builder.CreateNew() .BuildNew(); diff --git a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedMetadataFilesFixture.cs b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedMetadataFilesFixture.cs index 27679d8d3..843622445 100644 --- a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedMetadataFilesFixture.cs +++ b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedMetadataFilesFixture.cs @@ -1,4 +1,4 @@ -using FizzWare.NBuilder; +using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Extras.Metadata; @@ -7,7 +7,7 @@ using NzbDrone.Core.Housekeeping.Housekeepers; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Test.Housekeeping.Housekeepers { @@ -15,10 +15,10 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers public class CleanupOrphanedMetadataFilesFixture : DbTest { [Test] - public void should_delete_metadata_files_that_dont_have_a_coresponding_series() + public void should_delete_metadata_files_that_dont_have_a_coresponding_artist() { var metadataFile = Builder.CreateNew() - .With(m => m.EpisodeFileId = null) + .With(m => m.TrackFileId = null) .BuildNew(); Db.Insert(metadataFile); @@ -27,16 +27,59 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_that_have_a_coresponding_series() + public void should_delete_metadata_files_that_dont_have_a_coresponding_album() { - var series = Builder.CreateNew() + var artist = Builder.CreateNew() .BuildNew(); - Db.Insert(series); + Db.Insert(artist); var metadataFile = Builder.CreateNew() - .With(m => m.SeriesId = series.Id) - .With(m => m.EpisodeFileId = null) + .With(m => m.ArtistId = artist.Id) + .With(m => m.TrackFileId = null) + .BuildNew(); + + Db.Insert(metadataFile); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_metadata_files_that_have_a_coresponding_artist() + { + var artist = Builder.CreateNew() + .BuildNew(); + + Db.Insert(artist); + + var metadataFile = Builder.CreateNew() + .With(m => m.ArtistId = artist.Id) + .With(m => m.AlbumId = null) + .With(m => m.TrackFileId = null) + .BuildNew(); + + Db.Insert(metadataFile); + var countMods = AllStoredModels.Count; + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + } + + [Test] + public void should_not_delete_metadata_files_that_have_a_coresponding_album() + { + var artist = Builder.CreateNew() + .BuildNew(); + + var album = Builder.CreateNew() + .BuildNew(); + + Db.Insert(artist); + Db.Insert(album); + + var metadataFile = Builder.CreateNew() + .With(m => m.ArtistId = artist.Id) + .With(m => m.AlbumId = album.Id) + .With(m => m.TrackFileId = null) .BuildNew(); Db.Insert(metadataFile); @@ -45,16 +88,16 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_delete_metadata_files_that_dont_have_a_coresponding_episode_file() + public void should_delete_metadata_files_that_dont_have_a_coresponding_track_file() { - var series = Builder.CreateNew() + var artist = Builder.CreateNew() .BuildNew(); - Db.Insert(series); + Db.Insert(artist); var metadataFile = Builder.CreateNew() - .With(m => m.SeriesId = series.Id) - .With(m => m.EpisodeFileId = 10) + .With(m => m.ArtistId = artist.Id) + .With(m => m.TrackFileId = 10) .BuildNew(); Db.Insert(metadataFile); @@ -63,21 +106,26 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_not_delete_metadata_files_that_have_a_coresponding_episode_file() + public void should_not_delete_metadata_files_that_have_a_coresponding_track_file() { - var series = Builder.CreateNew() + var artist = Builder.CreateNew() + .BuildNew(); + + var album = Builder.CreateNew() .BuildNew(); - var episodeFile = Builder.CreateNew() + var trackFile = Builder.CreateNew() .With(h => h.Quality = new QualityModel()) .BuildNew(); - Db.Insert(series); - Db.Insert(episodeFile); + Db.Insert(artist); + Db.Insert(album); + Db.Insert(trackFile); var metadataFile = Builder.CreateNew() - .With(m => m.SeriesId = series.Id) - .With(m => m.EpisodeFileId = episodeFile.Id) + .With(m => m.ArtistId = artist.Id) + .With(m => m.AlbumId = album.Id) + .With(m => m.TrackFileId = trackFile.Id) .BuildNew(); Db.Insert(metadataFile); @@ -86,17 +134,17 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_delete_episode_metadata_files_that_have_episodefileid_of_zero() + public void should_delete_track_metadata_files_that_have_trackfileid_of_zero() { - var series = Builder.CreateNew() + var artist = Builder.CreateNew() .BuildNew(); - Db.Insert(series); + Db.Insert(artist); var metadataFile = Builder.CreateNew() - .With(m => m.SeriesId = series.Id) - .With(m => m.Type = MetadataType.EpisodeMetadata) - .With(m => m.EpisodeFileId = 0) + .With(m => m.ArtistId = artist.Id) + .With(m => m.Type = MetadataType.TrackMetadata) + .With(m => m.TrackFileId = 0) .BuildNew(); Db.Insert(metadataFile); @@ -105,17 +153,17 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers } [Test] - public void should_delete_episode_image_files_that_have_episodefileid_of_zero() + public void should_delete_track_image_files_that_have_trackfileid_of_zero() { - var series = Builder.CreateNew() + var artist = Builder.CreateNew() .BuildNew(); - Db.Insert(series); + Db.Insert(artist); var metadataFile = Builder.CreateNew() - .With(m => m.SeriesId = series.Id) - .With(m => m.Type = MetadataType.EpisodeImage) - .With(m => m.EpisodeFileId = 0) + .With(m => m.ArtistId = artist.Id) + .With(m => m.Type = MetadataType.TrackImage) + .With(m => m.TrackFileId = 0) .BuildNew(); Db.Insert(metadataFile); diff --git a/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs index 1f2dd20a9..03805aaa8 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs @@ -1,4 +1,4 @@ -using FizzWare.NBuilder; +using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.MediaFiles; @@ -11,7 +11,7 @@ namespace NzbDrone.Core.Test.MediaFiles public class MediaFileRepositoryFixture : DbTest { [Test] - public void get_files_by_series() + public void get_files_by_artist() { var files = Builder.CreateListOfSize(10) .All() @@ -24,11 +24,11 @@ namespace NzbDrone.Core.Test.MediaFiles Db.InsertMany(files); - var seriesFiles = Subject.GetFilesByArtist(12); + var artistFiles = Subject.GetFilesByArtist(12); - seriesFiles.Should().HaveCount(4); - seriesFiles.Should().OnlyContain(c => c.ArtistId == 12); + artistFiles.Should().HaveCount(4); + artistFiles.Should().OnlyContain(c => c.ArtistId == 12); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core.Test/MediaFiles/MediaFileTableCleanupServiceFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MediaFileTableCleanupServiceFixture.cs index 84c9ded48..db296276a 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MediaFileTableCleanupServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MediaFileTableCleanupServiceFixture.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.IO; using FizzWare.NBuilder; @@ -88,7 +88,7 @@ namespace NzbDrone.Core.Test.MediaFiles } [Test] - public void should_delete_files_that_dont_belong_to_any_episodes() + public void should_delete_files_that_dont_belong_to_any_tracks() { var trackFiles = Builder.CreateListOfSize(10) .Random(10) @@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.MediaFiles } [Test] - public void should_unlink_episode_when_episodeFile_does_not_exist() + public void should_unlink_track_when_trackFile_does_not_exist() { GivenTrackFiles(new List()); diff --git a/src/NzbDrone.Core.Test/Metadata/Consumers/Roksbox/FindMetadataFileFixture.cs b/src/NzbDrone.Core.Test/Metadata/Consumers/Roksbox/FindMetadataFileFixture.cs index 6d4328b32..9e7326d1f 100644 --- a/src/NzbDrone.Core.Test/Metadata/Consumers/Roksbox/FindMetadataFileFixture.cs +++ b/src/NzbDrone.Core.Test/Metadata/Consumers/Roksbox/FindMetadataFileFixture.cs @@ -1,11 +1,11 @@ -using System.IO; +using System.IO; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Extras.Metadata; using NzbDrone.Core.Extras.Metadata.Consumers.Roksbox; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox @@ -13,12 +13,12 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox [TestFixture] public class FindMetadataFileFixture : CoreTest { - private Series _series; + private Artist _series; [SetUp] public void Setup() { - _series = Builder.CreateNew() + _series = Builder.CreateNew() .With(s => s.Path = @"C:\Test\TV\The.Series".AsOsAgnostic()) .Build(); } @@ -38,11 +38,11 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox { var path = Path.Combine(_series.Path, folder, folder + ".jpg"); - Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeasonImage); + Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.AlbumImage); } - [TestCase(".xml", MetadataType.EpisodeMetadata)] - [TestCase(".jpg", MetadataType.EpisodeImage)] + [TestCase(".xml", MetadataType.TrackMetadata)] + [TestCase(".jpg", MetadataType.TrackImage)] public void should_return_metadata_for_episode_if_valid_file_for_episode(string extension, MetadataType type) { var path = Path.Combine(_series.Path, "the.series.s01e01.episode" + extension); @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox { var path = Path.Combine(_series.Path, new DirectoryInfo(_series.Path).Name + ".jpg"); - Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeriesImage); + Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.ArtistImage); } } } diff --git a/src/NzbDrone.Core.Test/Metadata/Consumers/Wdtv/FindMetadataFileFixture.cs b/src/NzbDrone.Core.Test/Metadata/Consumers/Wdtv/FindMetadataFileFixture.cs index 078744ec8..e3d956b71 100644 --- a/src/NzbDrone.Core.Test/Metadata/Consumers/Wdtv/FindMetadataFileFixture.cs +++ b/src/NzbDrone.Core.Test/Metadata/Consumers/Wdtv/FindMetadataFileFixture.cs @@ -1,11 +1,11 @@ -using System.IO; +using System.IO; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Extras.Metadata; using NzbDrone.Core.Extras.Metadata.Consumers.Wdtv; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv @@ -13,12 +13,12 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv [TestFixture] public class FindMetadataFileFixture : CoreTest { - private Series _series; + private Artist _series; [SetUp] public void Setup() { - _series = Builder.CreateNew() + _series = Builder.CreateNew() .With(s => s.Path = @"C:\Test\TV\The.Series".AsOsAgnostic()) .Build(); } @@ -38,11 +38,11 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv { var path = Path.Combine(_series.Path, folder, "folder.jpg"); - Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeasonImage); + Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.AlbumImage); } - [TestCase(".xml", MetadataType.EpisodeMetadata)] - [TestCase(".metathumb", MetadataType.EpisodeImage)] + [TestCase(".xml", MetadataType.TrackMetadata)] + [TestCase(".metathumb", MetadataType.TrackImage)] public void should_return_metadata_for_episode_if_valid_file_for_episode(string extension, MetadataType type) { var path = Path.Combine(_series.Path, "the.series.s01e01.episode" + extension); @@ -64,7 +64,7 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv { var path = Path.Combine(_series.Path, "folder.jpg"); - Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.SeriesImage); + Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.ArtistImage); } } } diff --git a/src/NzbDrone.Core/Datastore/Migration/123_music_extras.cs b/src/NzbDrone.Core/Datastore/Migration/123_music_extras.cs new file mode 100644 index 000000000..39ea2dc6b --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/123_music_extras.cs @@ -0,0 +1,44 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(123)] + public class music_extras : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("ExtraFiles") + .AddColumn("ArtistId").AsInt32().NotNullable().WithDefaultValue(0) + .AddColumn("AlbumId").AsInt32().NotNullable().WithDefaultValue(0) + .AddColumn("TrackFileId").AsInt32().NotNullable().WithDefaultValue(0); + + Delete.Column("SeriesId").FromTable("ExtraFiles"); + Delete.Column("SeasonNumber").FromTable("ExtraFiles"); + Delete.Column("EpisodeFileId").FromTable("ExtraFiles"); + + Alter.Table("SubtitleFiles") + .AddColumn("ArtistId").AsInt32().NotNullable().WithDefaultValue(0) + .AddColumn("AlbumId").AsInt32().NotNullable().WithDefaultValue(0) + .AddColumn("TrackFileId").AsInt32().NotNullable().WithDefaultValue(0); + + Delete.Column("SeriesId").FromTable("SubtitleFiles"); + Delete.Column("SeasonNumber").FromTable("SubtitleFiles"); + Delete.Column("EpisodeFileId").FromTable("SubtitleFiles"); + + Alter.Table("MetadataFiles") + .AddColumn("ArtistId").AsInt32().NotNullable().WithDefaultValue(0) + .AddColumn("AlbumId").AsInt32().Nullable() + .AddColumn("TrackFileId").AsInt32().Nullable(); + + Delete.Column("SeriesId").FromTable("MetadataFiles"); + Delete.Column("SeasonNumber").FromTable("MetadataFiles"); + Delete.Column("EpisodeFileId").FromTable("MetadataFiles"); + } + + } +} diff --git a/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs b/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs index 8e7716e6a..b2fb06980 100644 --- a/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs +++ b/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using NLog; @@ -48,14 +48,12 @@ namespace NzbDrone.Core.Extras foreach (var existingExtraFileImporter in _existingExtraFileImporters) { - // TODO Implement existingExtraFileImporter for Audio Files + var imported = existingExtraFileImporter.ProcessFiles(artist, filteredFiles, importedFiles); - //var imported = existingExtraFileImporter.ProcessFiles(artist, filteredFiles, importedFiles); - - //importedFiles.AddRange(imported.Select(f => Path.Combine(artist.Path, f.RelativePath))); + importedFiles.AddRange(imported.Select(f => Path.Combine(artist.Path, f.RelativePath))); } _logger.Info("Found {0} extra files", extraFiles.Count); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Extras/ExtraService.cs b/src/NzbDrone.Core/Extras/ExtraService.cs index 6716e25db..2432dbfcb 100644 --- a/src/NzbDrone.Core/Extras/ExtraService.cs +++ b/src/NzbDrone.Core/Extras/ExtraService.cs @@ -12,50 +12,55 @@ using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras { - // NOTE: Majora: ExtraService can be reserved for Music Videos, lyric files, etc for Plex. TODO: Implement Extras for Music public interface IExtraService { - void ImportExtraFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, bool isReadOnly); + void ImportExtraFiles(LocalTrack localEpisode, TrackFile episodeFile, bool isReadOnly); } public class ExtraService : IExtraService, IHandle, - IHandle, - IHandle + IHandle, + IHandle { private readonly IMediaFileService _mediaFileService; - private readonly IEpisodeService _episodeService; + //private readonly IEpisodeService _episodeService; + private readonly IAlbumService _albumService; + private readonly ITrackService _trackService; private readonly IDiskProvider _diskProvider; private readonly IConfigService _configService; private readonly List _extraFileManagers; private readonly Logger _logger; public ExtraService(IMediaFileService mediaFileService, - IEpisodeService episodeService, + //IEpisodeService episodeService, + IAlbumService albumService, + ITrackService trackService, IDiskProvider diskProvider, IConfigService configService, List extraFileManagers, Logger logger) { _mediaFileService = mediaFileService; - _episodeService = episodeService; + //_episodeService = episodeService; + _albumService = albumService; + _trackService = trackService; _diskProvider = diskProvider; _configService = configService; _extraFileManagers = extraFileManagers.OrderBy(e => e.Order).ToList(); _logger = logger; } - public void ImportExtraFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, bool isReadOnly) + public void ImportExtraFiles(LocalTrack localTrack, TrackFile trackFile, bool isReadOnly) { - var series = localEpisode.Series; + var artist = localTrack.Artist; foreach (var extraFileManager in _extraFileManagers) { - extraFileManager.CreateAfterEpisodeImport(series, episodeFile); + extraFileManager.CreateAfterTrackImport(artist, trackFile); } if (!_configService.ImportExtraFiles) @@ -63,7 +68,7 @@ namespace NzbDrone.Core.Extras return; } - var sourcePath = localEpisode.Path; + var sourcePath = localTrack.Path; var sourceFolder = _diskProvider.GetParentFolder(sourcePath); var sourceFileName = Path.GetFileNameWithoutExtension(sourcePath); var files = _diskProvider.GetFiles(sourceFolder, SearchOption.TopDirectoryOnly); @@ -88,7 +93,7 @@ namespace NzbDrone.Core.Extras foreach (var extraFileManager in _extraFileManagers) { var extension = Path.GetExtension(matchingFilename); - var extraFile = extraFileManager.Import(series, episodeFile, matchingFilename, extension, isReadOnly); + var extraFile = extraFileManager.Import(artist, trackFile, matchingFilename, extension, isReadOnly); if (extraFile != null) { @@ -105,49 +110,49 @@ namespace NzbDrone.Core.Extras public void Handle(MediaCoversUpdatedEvent message) { - //var artist = message.Artist; - //var episodeFiles = GetEpisodeFiles(artist.Id); + var artist = message.Artist; + var albums = _albumService.GetAlbumsByArtist(artist.Id); + var trackFiles = GetTrackFiles(artist.Id); - //foreach (var extraFileManager in _extraFileManagers) - //{ - // extraFileManager.CreateAfterSeriesScan(artist, episodeFiles); - //} + foreach (var extraFileManager in _extraFileManagers) + { + extraFileManager.CreateAfterArtistScan(artist, albums, trackFiles); + } } - public void Handle(EpisodeFolderCreatedEvent message) + public void Handle(TrackFolderCreatedEvent message) { - var series = message.Series; + var artist = message.Artist; foreach (var extraFileManager in _extraFileManagers) { - extraFileManager.CreateAfterEpisodeImport(series, message.SeriesFolder, message.SeasonFolder); + extraFileManager.CreateAfterTrackImport(artist, message.ArtistFolder, message.AlbumFolder); } } - public void Handle(SeriesRenamedEvent message) + public void Handle(ArtistRenamedEvent message) { - var series = message.Series; - var episodeFiles = GetEpisodeFiles(series.Id); + var artist = message.Artist; + var trackFiles = GetTrackFiles(artist.Id); foreach (var extraFileManager in _extraFileManagers) { - extraFileManager.MoveFilesAfterRename(series, episodeFiles); + extraFileManager.MoveFilesAfterRename(artist, trackFiles); } } - private List GetEpisodeFiles(int seriesId) + private List GetTrackFiles(int artistId) { - //var episodeFiles = _mediaFileService.GetFilesBySeries(seriesId); - //var episodes = _episodeService.GetEpisodeBySeries(seriesId); + var trackFiles = _mediaFileService.GetFilesByArtist(artistId); + var tracks = _trackService.GetTracksByArtist(artistId); - //foreach (var episodeFile in episodeFiles) - //{ - // var localEpisodeFile = episodeFile; - // episodeFile.Episodes = new LazyList(episodes.Where(e => e.EpisodeFileId == localEpisodeFile.Id)); - //} + foreach (var trackFile in trackFiles) + { + var localTrackFile = trackFile; + trackFile.Tracks = new LazyList(tracks.Where(e => e.TrackFileId == localTrackFile.Id)); + } - //return episodeFiles; - return new List(); + return trackFiles; } } } diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFile.cs b/src/NzbDrone.Core/Extras/Files/ExtraFile.cs index 036eaec33..1e3c2b8bf 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFile.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFile.cs @@ -1,13 +1,13 @@ -using System; +using System; using NzbDrone.Core.Datastore; namespace NzbDrone.Core.Extras.Files { public abstract class ExtraFile : ModelBase { - public int SeriesId { get; set; } - public int? EpisodeFileId { get; set; } - public int? SeasonNumber { get; set; } + public int ArtistId { get; set; } + public int? TrackFileId { get; set; } + public int? AlbumId { get; set; } public string RelativePath { get; set; } public DateTime Added { get; set; } public DateTime LastUpdated { get; set; } diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileManager.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileManager.cs index 9f8de2440..b0599bff6 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileManager.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileManager.cs @@ -7,18 +7,18 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Files { public interface IManageExtraFiles { int Order { get; } - IEnumerable CreateAfterSeriesScan(Series series, List episodeFiles); - IEnumerable CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile); - IEnumerable CreateAfterEpisodeImport(Series series, string seriesFolder, string seasonFolder); - IEnumerable MoveFilesAfterRename(Series series, List episodeFiles); - ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly); + IEnumerable CreateAfterArtistScan(Artist artist, List albums, List trackFiles); + IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile); + IEnumerable CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder); + IEnumerable MoveFilesAfterRename(Artist artist, List trackFiles); + ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly); } public abstract class ExtraFileManager : IManageExtraFiles @@ -42,16 +42,16 @@ namespace NzbDrone.Core.Extras.Files } public abstract int Order { get; } - public abstract IEnumerable CreateAfterSeriesScan(Series series, List episodeFiles); - public abstract IEnumerable CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile); - public abstract IEnumerable CreateAfterEpisodeImport(Series series, string seriesFolder, string seasonFolder); - public abstract IEnumerable MoveFilesAfterRename(Series series, List episodeFiles); - public abstract ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly); + public abstract IEnumerable CreateAfterArtistScan(Artist artist, List albums, List trackFiles); + public abstract IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile); + public abstract IEnumerable CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder); + public abstract IEnumerable MoveFilesAfterRename(Artist artist, List trackFiles); + public abstract ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly); - protected TExtraFile ImportFile(Series series, EpisodeFile episodeFile, string path, bool readOnly, string extension, string fileNameSuffix = null) + protected TExtraFile ImportFile(Artist artist, TrackFile trackFile, string path, bool readOnly, string extension, string fileNameSuffix = null) { - var newFolder = Path.GetDirectoryName(Path.Combine(series.Path, episodeFile.RelativePath)); - var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(episodeFile.RelativePath)); + var newFolder = Path.GetDirectoryName(Path.Combine(artist.Path, trackFile.RelativePath)); + var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(trackFile.RelativePath)); if (fileNameSuffix.IsNotNullOrWhiteSpace()) { @@ -72,18 +72,18 @@ namespace NzbDrone.Core.Extras.Files return new TExtraFile { - SeriesId = series.Id, - SeasonNumber = episodeFile.SeasonNumber, - EpisodeFileId = episodeFile.Id, - RelativePath = series.Path.GetRelativePath(newFileName), + ArtistId = artist.Id, + AlbumId = trackFile.AlbumId, + TrackFileId = trackFile.Id, + RelativePath = artist.Path.GetRelativePath(newFileName), Extension = extension }; } - protected TExtraFile MoveFile(Series series, EpisodeFile episodeFile, TExtraFile extraFile, string fileNameSuffix = null) + protected TExtraFile MoveFile(Artist artist, TrackFile trackFile, TExtraFile extraFile, string fileNameSuffix = null) { - var newFolder = Path.GetDirectoryName(Path.Combine(series.Path, episodeFile.RelativePath)); - var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(episodeFile.RelativePath)); + var newFolder = Path.GetDirectoryName(Path.Combine(artist.Path, trackFile.RelativePath)); + var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(trackFile.RelativePath)); if (fileNameSuffix.IsNotNullOrWhiteSpace()) { @@ -92,7 +92,7 @@ namespace NzbDrone.Core.Extras.Files filenameBuilder.Append(extraFile.Extension); - var existingFileName = Path.Combine(series.Path, extraFile.RelativePath); + var existingFileName = Path.Combine(artist.Path, extraFile.RelativePath); var newFileName = Path.Combine(newFolder, filenameBuilder.ToString()); if (newFileName.PathNotEquals(existingFileName)) @@ -100,7 +100,7 @@ namespace NzbDrone.Core.Extras.Files try { _diskProvider.MoveFile(existingFileName, newFileName); - extraFile.RelativePath = series.Path.GetRelativePath(newFileName); + extraFile.RelativePath = artist.Path.GetRelativePath(newFileName); return extraFile; } diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs index 7cb4644c3..5e3a900a6 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; @@ -7,12 +7,12 @@ namespace NzbDrone.Core.Extras.Files { public interface IExtraFileRepository : IBasicRepository where TExtraFile : ExtraFile, new() { - void DeleteForSeries(int seriesId); - void DeleteForSeason(int seriesId, int seasonNumber); - void DeleteForEpisodeFile(int episodeFileId); - List GetFilesBySeries(int seriesId); - List GetFilesBySeason(int seriesId, int seasonNumber); - List GetFilesByEpisodeFile(int episodeFileId); + void DeleteForArtist(int artistId); + void DeleteForAlbum(int artistId, int albumId); + void DeleteForTrackFile(int trackFileId); + List GetFilesByArtist(int artistId); + List GetFilesByAlbum(int artistId, int albumId); + List GetFilesByTrackFile(int trackFileId); TExtraFile FindByPath(string path); } @@ -24,34 +24,34 @@ namespace NzbDrone.Core.Extras.Files { } - public void DeleteForSeries(int seriesId) + public void DeleteForArtist(int artistId) { - Delete(c => c.SeriesId == seriesId); + Delete(c => c.ArtistId == artistId); } - public void DeleteForSeason(int seriesId, int seasonNumber) + public void DeleteForAlbum(int artistId, int albumId) { - Delete(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber); + Delete(c => c.ArtistId == artistId && c.AlbumId == albumId); } - public void DeleteForEpisodeFile(int episodeFileId) + public void DeleteForTrackFile(int trackFileId) { - Delete(c => c.EpisodeFileId == episodeFileId); + Delete(c => c.TrackFileId == trackFileId); } - public List GetFilesBySeries(int seriesId) + public List GetFilesByArtist(int artistId) { - return Query.Where(c => c.SeriesId == seriesId); + return Query.Where(c => c.ArtistId == artistId); } - public List GetFilesBySeason(int seriesId, int seasonNumber) + public List GetFilesByAlbum(int artistId, int albumId) { - return Query.Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber); + return Query.Where(c => c.ArtistId == artistId && c.AlbumId == albumId); } - public List GetFilesByEpisodeFile(int episodeFileId) + public List GetFilesByTrackFile(int trackFileId) { - return Query.Where(c => c.EpisodeFileId == episodeFileId); + return Query.Where(c => c.TrackFileId == trackFileId); } public TExtraFile FindByPath(string path) diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs index ac30f6536..0a8bdbb10 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,16 +8,16 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.Tv; -using NzbDrone.Core.Tv.Events; +using NzbDrone.Core.Music; +using NzbDrone.Core.Music.Events; namespace NzbDrone.Core.Extras.Files { public interface IExtraFileService where TExtraFile : ExtraFile, new() { - List GetFilesBySeries(int seriesId); - List GetFilesByEpisodeFile(int episodeFileId); + List GetFilesByArtist(int artistId); + List GetFilesByTrackFile(int trackFileId); TExtraFile FindByPath(string path); void Upsert(TExtraFile extraFile); void Upsert(List extraFiles); @@ -26,24 +26,24 @@ namespace NzbDrone.Core.Extras.Files } public abstract class ExtraFileService : IExtraFileService, - IHandleAsync, - IHandleAsync + IHandleAsync, + IHandleAsync where TExtraFile : ExtraFile, new() { private readonly IExtraFileRepository _repository; - private readonly ISeriesService _seriesService; + private readonly IArtistService _artistService; private readonly IDiskProvider _diskProvider; private readonly IRecycleBinProvider _recycleBinProvider; private readonly Logger _logger; public ExtraFileService(IExtraFileRepository repository, - ISeriesService seriesService, + IArtistService artistService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) { _repository = repository; - _seriesService = seriesService; + _artistService = artistService; _diskProvider = diskProvider; _recycleBinProvider = recycleBinProvider; _logger = logger; @@ -51,14 +51,14 @@ namespace NzbDrone.Core.Extras.Files public virtual bool PermanentlyDelete => false; - public List GetFilesBySeries(int seriesId) + public List GetFilesByArtist(int artistId) { - return _repository.GetFilesBySeries(seriesId); + return _repository.GetFilesByArtist(artistId); } - public List GetFilesByEpisodeFile(int episodeFileId) + public List GetFilesByTrackFile(int trackFileId) { - return _repository.GetFilesByEpisodeFile(episodeFileId); + return _repository.GetFilesByTrackFile(trackFileId); } public TExtraFile FindByPath(string path) @@ -97,28 +97,28 @@ namespace NzbDrone.Core.Extras.Files _repository.DeleteMany(ids); } - public void HandleAsync(SeriesDeletedEvent message) + public void HandleAsync(ArtistDeletedEvent message) { - _logger.Debug("Deleting Extra from database for series: {0}", message.Series); - _repository.DeleteForSeries(message.Series.Id); + _logger.Debug("Deleting Extra from database for artist: {0}", message.Artist); + _repository.DeleteForArtist(message.Artist.Id); } - public void HandleAsync(EpisodeFileDeletedEvent message) + public void HandleAsync(TrackFileDeletedEvent message) { - var episodeFile = message.EpisodeFile; + var trackFile = message.TrackFile; if (message.Reason == DeleteMediaFileReason.NoLinkedEpisodes) { - _logger.Debug("Removing episode file from DB as part of cleanup routine, not deleting extra files from disk."); + _logger.Debug("Removing track file from DB as part of cleanup routine, not deleting extra files from disk."); } else { - var series = _seriesService.GetSeries(message.EpisodeFile.SeriesId); + var artist = _artistService.GetArtist(message.TrackFile.ArtistId); - foreach (var extra in _repository.GetFilesByEpisodeFile(episodeFile.Id)) + foreach (var extra in _repository.GetFilesByTrackFile(trackFile.Id)) { - var path = Path.Combine(series.Path, extra.RelativePath); + var path = Path.Combine(artist.Path, extra.RelativePath); if (_diskProvider.FileExists(path)) { @@ -130,15 +130,15 @@ namespace NzbDrone.Core.Extras.Files else { // Send extra files to the recycling bin so they can be recovered if necessary - var subfolder = _diskProvider.GetParentFolder(series.Path).GetRelativePath(_diskProvider.GetParentFolder(path)); + var subfolder = _diskProvider.GetParentFolder(artist.Path).GetRelativePath(_diskProvider.GetParentFolder(path)); _recycleBinProvider.DeleteFile(path, subfolder); } } } } - _logger.Debug("Deleting Extra from database for episode file: {0}", episodeFile); - _repository.DeleteForEpisodeFile(episodeFile.Id); + _logger.Debug("Deleting Extra from database for track file: {0}", trackFile); + _repository.DeleteForTrackFile(trackFile.Id); } } } diff --git a/src/NzbDrone.Core/Extras/IImportExistingExtraFiles.cs b/src/NzbDrone.Core/Extras/IImportExistingExtraFiles.cs index ad14b60a5..cb5a7dcff 100644 --- a/src/NzbDrone.Core/Extras/IImportExistingExtraFiles.cs +++ b/src/NzbDrone.Core/Extras/IImportExistingExtraFiles.cs @@ -1,12 +1,12 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NzbDrone.Core.Extras.Files; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras { public interface IImportExistingExtraFiles { int Order { get; } - IEnumerable ProcessFiles(Series series, List filesOnDisk, List importedFiles); + IEnumerable ProcessFiles(Artist artist, List filesOnDisk, List importedFiles); } } diff --git a/src/NzbDrone.Core/Extras/ImportExistingExtraFilesBase.cs b/src/NzbDrone.Core/Extras/ImportExistingExtraFilesBase.cs index a2dddaa69..c232259c4 100644 --- a/src/NzbDrone.Core/Extras/ImportExistingExtraFilesBase.cs +++ b/src/NzbDrone.Core/Extras/ImportExistingExtraFilesBase.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using NzbDrone.Common; using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Files; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras { @@ -19,21 +19,21 @@ namespace NzbDrone.Core.Extras } public abstract int Order { get; } - public abstract IEnumerable ProcessFiles(Series series, List filesOnDisk, List importedFiles); + public abstract IEnumerable ProcessFiles(Artist artist, List filesOnDisk, List importedFiles); - public virtual ImportExistingExtraFileFilterResult FilterAndClean(Series series, List filesOnDisk, List importedFiles) + public virtual ImportExistingExtraFileFilterResult FilterAndClean(Artist artist, List filesOnDisk, List importedFiles) { - var seriesFiles = _extraFileService.GetFilesBySeries(series.Id); + var artistFiles = _extraFileService.GetFilesByArtist(artist.Id); - Clean(series, filesOnDisk, importedFiles, seriesFiles); + Clean(artist, filesOnDisk, importedFiles, artistFiles); - return Filter(series, filesOnDisk, importedFiles, seriesFiles); + return Filter(artist, filesOnDisk, importedFiles, artistFiles); } - private ImportExistingExtraFileFilterResult Filter(Series series, List filesOnDisk, List importedFiles, List seriesFiles) + private ImportExistingExtraFileFilterResult Filter(Artist artist, List filesOnDisk, List importedFiles, List artistFiles) { - var previouslyImported = seriesFiles.IntersectBy(s => Path.Combine(series.Path, s.RelativePath), filesOnDisk, f => f, PathEqualityComparer.Instance).ToList(); - var filteredFiles = filesOnDisk.Except(previouslyImported.Select(f => Path.Combine(series.Path, f.RelativePath)).ToList(), PathEqualityComparer.Instance) + var previouslyImported = artistFiles.IntersectBy(s => Path.Combine(artist.Path, s.RelativePath), filesOnDisk, f => f, PathEqualityComparer.Instance).ToList(); + var filteredFiles = filesOnDisk.Except(previouslyImported.Select(f => Path.Combine(artist.Path, f.RelativePath)).ToList(), PathEqualityComparer.Instance) .Except(importedFiles, PathEqualityComparer.Instance) .ToList(); @@ -42,12 +42,12 @@ namespace NzbDrone.Core.Extras return new ImportExistingExtraFileFilterResult(previouslyImported, filteredFiles); } - private void Clean(Series series, List filesOnDisk, List importedFiles, List seriesFiles) + private void Clean(Artist artist, List filesOnDisk, List importedFiles, List artistFiles) { - var alreadyImportedFileIds = seriesFiles.IntersectBy(f => Path.Combine(series.Path, f.RelativePath), importedFiles, i => i, PathEqualityComparer.Instance) + var alreadyImportedFileIds = artistFiles.IntersectBy(f => Path.Combine(artist.Path, f.RelativePath), importedFiles, i => i, PathEqualityComparer.Instance) .Select(f => f.Id); - var deletedFiles = seriesFiles.ExceptBy(f => Path.Combine(series.Path, f.RelativePath), filesOnDisk, i => i, PathEqualityComparer.Instance) + var deletedFiles = artistFiles.ExceptBy(f => Path.Combine(artist.Path, f.RelativePath), filesOnDisk, i => i, PathEqualityComparer.Instance) .Select(f => f.Id); _extraFileService.DeleteMany(alreadyImportedFileIds); diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadata.cs index d2ea82bae..9c1dd86a7 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadata.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -9,7 +9,7 @@ using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser { @@ -25,7 +25,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser public override string Name => "Emby (Legacy)"; - public override MetadataFile FindMetadataFile(Series series, string path) + public override MetadataFile FindMetadataFile(Artist artist, string path) { var filename = Path.GetFileName(path); @@ -33,28 +33,28 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser var metadata = new MetadataFile { - SeriesId = series.Id, + ArtistId = artist.Id, Consumer = GetType().Name, - RelativePath = series.Path.GetRelativePath(path) + RelativePath = artist.Path.GetRelativePath(path) }; - if (filename.Equals("series.xml", StringComparison.InvariantCultureIgnoreCase)) + if (filename.Equals("artist.xml", StringComparison.InvariantCultureIgnoreCase)) { - metadata.Type = MetadataType.SeriesMetadata; + metadata.Type = MetadataType.ArtistMetadata; return metadata; } return null; } - public override MetadataFileResult SeriesMetadata(Series series) + public override MetadataFileResult ArtistMetadata(Artist artist) { - if (!Settings.SeriesMetadata) + if (!Settings.ArtistMetadata) { return null; } - _logger.Debug("Generating series.xml for: {0}", series.Title); + _logger.Debug("Generating artist.xml for: {0}", artist.Name); var sb = new StringBuilder(); var xws = new XmlWriterSettings(); xws.OmitXmlDeclaration = true; @@ -62,85 +62,73 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser using (var xw = XmlWriter.Create(sb, xws)) { - var tvShow = new XElement("Series"); + var artistElement = new XElement("Artist"); - tvShow.Add(new XElement("id", series.TvdbId)); - tvShow.Add(new XElement("Status", series.Status)); - tvShow.Add(new XElement("Network", series.Network)); - tvShow.Add(new XElement("Airs_Time", series.AirTime)); + artistElement.Add(new XElement("id", artist.ForeignArtistId)); + artistElement.Add(new XElement("Status", artist.Status)); - if (series.FirstAired.HasValue) - { - tvShow.Add(new XElement("FirstAired", series.FirstAired.Value.ToString("yyyy-MM-dd"))); - } - - tvShow.Add(new XElement("ContentRating", series.Certification)); - tvShow.Add(new XElement("Added", series.Added.ToString("MM/dd/yyyy HH:mm:ss tt"))); - tvShow.Add(new XElement("LockData", "false")); - tvShow.Add(new XElement("Overview", series.Overview)); - tvShow.Add(new XElement("LocalTitle", series.Title)); - - if (series.FirstAired.HasValue) - { - tvShow.Add(new XElement("PremiereDate", series.FirstAired.Value.ToString("yyyy-MM-dd"))); - } + artistElement.Add(new XElement("Added", artist.Added.ToString("MM/dd/yyyy HH:mm:ss tt"))); + artistElement.Add(new XElement("LockData", "false")); + artistElement.Add(new XElement("Overview", artist.Overview)); + artistElement.Add(new XElement("LocalTitle", artist.Name)); - tvShow.Add(new XElement("Rating", series.Ratings.Value)); - tvShow.Add(new XElement("ProductionYear", series.Year)); - tvShow.Add(new XElement("RunningTime", series.Runtime)); - tvShow.Add(new XElement("IMDB", series.ImdbId)); - tvShow.Add(new XElement("TVRageId", series.TvRageId)); - tvShow.Add(new XElement("Genres", series.Genres.Select(genre => new XElement("Genre", genre)))); + artistElement.Add(new XElement("Rating", artist.Ratings.Value)); + artistElement.Add(new XElement("Genres", artist.Genres.Select(genre => new XElement("Genre", genre)))); var persons = new XElement("Persons"); - foreach (var person in series.Actors) + foreach (var person in artist.Members) { persons.Add(new XElement("Person", new XElement("Name", person.Name), new XElement("Type", "Actor"), - new XElement("Role", person.Character) + new XElement("Role", person.Instrument) )); } - tvShow.Add(persons); + artistElement.Add(persons); - var doc = new XDocument(tvShow); + var doc = new XDocument(artistElement); doc.Save(xw); - _logger.Debug("Saving series.xml for {0}", series.Title); + _logger.Debug("Saving artist.xml for {0}", artist.Name); - return new MetadataFileResult("series.xml", doc.ToString()); + return new MetadataFileResult("artist.xml", doc.ToString()); } } - - public override MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile) + + public override MetadataFileResult AlbumMetadata(Artist artist, Album album) + { + return null; + } + + public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile) { return null; } - public override List SeriesImages(Series series) + public override List ArtistImages(Artist artist) { return new List(); } - public override List SeasonImages(Series series, Season season) + public override List AlbumImages(Artist artist, Album season) { return new List(); } - public override List EpisodeImages(Series series, EpisodeFile episodeFile) + public override List TrackImages(Artist artist, TrackFile trackFile) { return new List(); } - private IEnumerable ProcessSeriesImages(Series series) + private IEnumerable ProcessArtistImages(Artist artist) { return new List(); } - private IEnumerable ProcessSeasonImages(Series series, Season season) + private IEnumerable ProcessAlbumImages(Artist artist, Album album) { return new List(); } @@ -155,4 +143,4 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser return null; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs index 91f680f9d..c81e4924b 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs @@ -18,11 +18,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser public MediaBrowserMetadataSettings() { - SeriesMetadata = true; + ArtistMetadata = true; } - [FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox, HelpText = "series.xml")] - public bool SeriesMetadata { get; set; } + [FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox, HelpText = "artist.xml")] + public bool ArtistMetadata { get; set; } public bool IsValid => true; diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadata.cs index cf5d5e61d..8416b5564 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadata.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -12,7 +12,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox { @@ -36,25 +36,25 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox public override string Name => "Roksbox"; - public override string GetFilenameAfterMove(Series series, EpisodeFile episodeFile, MetadataFile metadataFile) + public override string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile) { - var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath); + var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath); - if (metadataFile.Type == MetadataType.EpisodeImage) + if (metadataFile.Type == MetadataType.TrackImage) { - return GetEpisodeImageFilename(episodeFilePath); + return GetTrackImageFilename(trackFilePath); } - if (metadataFile.Type == MetadataType.EpisodeMetadata) + if (metadataFile.Type == MetadataType.TrackMetadata) { - return GetEpisodeMetadataFilename(episodeFilePath); + return GetTrackMetadataFilename(trackFilePath); } - _logger.Debug("Unknown episode file metadata: {0}", metadataFile.RelativePath); - return Path.Combine(series.Path, metadataFile.RelativePath); + _logger.Debug("Unknown track file metadata: {0}", metadataFile.RelativePath); + return Path.Combine(artist.Path, metadataFile.RelativePath); } - public override MetadataFile FindMetadataFile(Series series, string path) + public override MetadataFile FindMetadataFile(Artist artist, string path) { var filename = Path.GetFileName(path); @@ -63,9 +63,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox var metadata = new MetadataFile { - SeriesId = series.Id, + ArtistId = artist.Id, Consumer = GetType().Name, - RelativePath = series.Path.GetRelativePath(path) + RelativePath = artist.Path.GetRelativePath(path) }; //Series and season images are both named folder.jpg, only season ones sit in season folders @@ -75,22 +75,22 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox if (seasonMatch.Success) { - metadata.Type = MetadataType.SeasonImage; + metadata.Type = MetadataType.AlbumImage; if (seasonMatch.Groups["specials"].Success) { - metadata.SeasonNumber = 0; + metadata.AlbumId = 0; } else { - metadata.SeasonNumber = Convert.ToInt32(seasonMatch.Groups["season"].Value); + metadata.AlbumId = Convert.ToInt32(seasonMatch.Groups["season"].Value); } return metadata; } - metadata.Type = MetadataType.SeriesImage; + metadata.Type = MetadataType.ArtistImage; return metadata; } @@ -103,7 +103,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox if (extension == ".xml") { - metadata.Type = MetadataType.EpisodeMetadata; + metadata.Type = MetadataType.TrackMetadata; return metadata; } @@ -111,7 +111,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox { if (!Path.GetFileNameWithoutExtension(filename).EndsWith("-thumb")) { - metadata.Type = MetadataType.EpisodeImage; + metadata.Type = MetadataType.TrackImage; return metadata; } } @@ -120,23 +120,28 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox return null; } - public override MetadataFileResult SeriesMetadata(Series series) + public override MetadataFileResult ArtistMetadata(Artist artist) { - //Series metadata is not supported + //Artist metadata is not supported return null; } - public override MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile) + public override MetadataFileResult AlbumMetadata(Artist artist, Album album) + { + return null; + } + + public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile) { if (!Settings.EpisodeMetadata) { return null; } - _logger.Debug("Generating Episode Metadata for: {0}", episodeFile.RelativePath); + _logger.Debug("Generating Track Metadata for: {0}", trackFile.RelativePath); var xmlResult = string.Empty; - foreach (var episode in episodeFile.Episodes.Value) + foreach (var track in trackFile.Tracks.Value) { var sb = new StringBuilder(); var xws = new XmlWriterSettings(); @@ -148,24 +153,10 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox var doc = new XDocument(); var details = new XElement("video"); - details.Add(new XElement("title", string.Format("{0} - {1}x{2} - {3}", series.Title, episode.SeasonNumber, episode.EpisodeNumber, episode.Title))); - details.Add(new XElement("year", episode.AirDate)); - details.Add(new XElement("genre", string.Join(" / ", series.Genres))); - var actors = string.Join(" , ", series.Actors.ConvertAll(c => c.Name + " - " + c.Character).GetRange(0, Math.Min(3, series.Actors.Count))); + details.Add(new XElement("title", string.Format("{0} - {1} - {2}", artist.Name, track.TrackNumber, track.Title))); + details.Add(new XElement("genre", string.Join(" / ", artist.Genres))); + var actors = string.Join(" , ", artist.Members.ConvertAll(c => c.Name + " - " + c.Instrument).GetRange(0, Math.Min(3, artist.Members.Count))); details.Add(new XElement("actors", actors)); - details.Add(new XElement("description", episode.Overview)); - details.Add(new XElement("length", series.Runtime)); - - if (series.Certification.IsNotNullOrWhiteSpace() && - ValidCertification.Contains(series.Certification.ToUpperInvariant())) - { - details.Add(new XElement("mpaa", series.Certification.ToUpperInvariant())); - } - - else - { - details.Add(new XElement("mpaa", "UNRATED")); - } doc.Add(details); doc.Save(xw); @@ -175,77 +166,78 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox } } - return new MetadataFileResult(GetEpisodeMetadataFilename(episodeFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray())); + return new MetadataFileResult(GetTrackMetadataFilename(trackFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray())); } - public override List SeriesImages(Series series) + public override List ArtistImages(Artist artist) { - var image = series.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? series.Images.FirstOrDefault(); + var image = artist.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? artist.Images.FirstOrDefault(); if (image == null) { - _logger.Trace("Failed to find suitable Series image for series {0}.", series.Title); + _logger.Trace("Failed to find suitable Artist image for artist {0}.", artist.Name); return null; } - var source = _mediaCoverService.GetCoverPath(series.Id, image.CoverType); - var destination = Path.GetFileName(series.Path) + Path.GetExtension(source); + var source = _mediaCoverService.GetCoverPath(artist.Id, image.CoverType); + var destination = Path.GetFileName(artist.Path) + Path.GetExtension(source); return new List{ new ImageFileResult(destination, source) }; } - public override List SeasonImages(Series series, Season season) + public override List AlbumImages(Artist artist, Album album) { - var seasonFolders = GetSeasonFolders(series); + var seasonFolders = GetAlbumFolders(artist); string seasonFolder; - if (!seasonFolders.TryGetValue(season.SeasonNumber, out seasonFolder)) + if (!seasonFolders.TryGetValue(album.ArtistId, out seasonFolder)) { - _logger.Trace("Failed to find season folder for series {0}, season {1}.", series.Title, season.SeasonNumber); + _logger.Trace("Failed to find season folder for series {0}, season {1}.", artist.Name, album.Title); return new List(); } //Roksbox only supports one season image, so first of all try for poster otherwise just use whatever is first in the collection - var image = season.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? season.Images.FirstOrDefault(); + var image = album.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? album.Images.FirstOrDefault(); if (image == null) { - _logger.Trace("Failed to find suitable season image for series {0}, season {1}.", series.Title, season.SeasonNumber); + _logger.Trace("Failed to find suitable season image for series {0}, season {1}.", artist.Name, album.Title); return new List(); } var filename = Path.GetFileName(seasonFolder) + ".jpg"; - var path = series.Path.GetRelativePath(Path.Combine(series.Path, seasonFolder, filename)); + var path = artist.Path.GetRelativePath(Path.Combine(artist.Path, seasonFolder, filename)); return new List { new ImageFileResult(path, image.Url) }; } - public override List EpisodeImages(Series series, EpisodeFile episodeFile) + public override List TrackImages(Artist artist, TrackFile trackFile) { - var screenshot = episodeFile.Episodes.Value.First().Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot); + //var screenshot = episodeFile.Tracks.Value.First().Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot); - if (screenshot == null) - { - _logger.Trace("Episode screenshot not available"); - return new List(); - } + //if (screenshot == null) + //{ + // _logger.Trace("Episode screenshot not available"); + // return new List(); + //} - return new List {new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url)}; + //return new List {new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url)}; + return new List(); } - private string GetEpisodeMetadataFilename(string episodeFilePath) + private string GetTrackMetadataFilename(string trackFilePath) { - return Path.ChangeExtension(episodeFilePath, "xml"); + return Path.ChangeExtension(trackFilePath, "xml"); } - private string GetEpisodeImageFilename(string episodeFilePath) + private string GetTrackImageFilename(string trackFilePath) { - return Path.ChangeExtension(episodeFilePath, "jpg"); + return Path.ChangeExtension(trackFilePath, "jpg"); } - private Dictionary GetSeasonFolders(Series series) + private Dictionary GetAlbumFolders(Artist artist) { var seasonFolderMap = new Dictionary(); - foreach (var folder in _diskProvider.GetDirectories(series.Path)) + foreach (var folder in _diskProvider.GetDirectories(artist.Path)) { var directoryinfo = new DirectoryInfo(folder); var seasonMatch = SeasonImagesRegex.Match(directoryinfo.Name); @@ -267,13 +259,13 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox } else { - _logger.Debug("Failed to parse season number from {0} for series {1}.", folder, series.Title); + _logger.Debug("Failed to parse season number from {0} for artist {1}.", folder, artist.Name); } } } else { - _logger.Debug("Rejecting folder {0} for series {1}.", Path.GetDirectoryName(folder), series.Title); + _logger.Debug("Rejecting folder {0} for artist {1}.", Path.GetDirectoryName(folder), artist.Name); } } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs index 569a7922c..9e5f18eaf 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs @@ -19,19 +19,19 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox public RoksboxMetadataSettings() { EpisodeMetadata = true; - SeriesImages = true; - SeasonImages = true; + ArtistImages = true; + AlbumImages = true; EpisodeImages = true; } [FieldDefinition(0, Label = "Episode Metadata", Type = FieldType.Checkbox, HelpText = "Season##\\filename.xml")] public bool EpisodeMetadata { get; set; } - [FieldDefinition(1, Label = "Series Images", Type = FieldType.Checkbox, HelpText = "Series Title.jpg")] - public bool SeriesImages { get; set; } + [FieldDefinition(1, Label = "Artist Images", Type = FieldType.Checkbox, HelpText = "Artist Title.jpg")] + public bool ArtistImages { get; set; } - [FieldDefinition(2, Label = "Season Images", Type = FieldType.Checkbox, HelpText = "Season ##.jpg")] - public bool SeasonImages { get; set; } + [FieldDefinition(2, Label = "Album Images", Type = FieldType.Checkbox, HelpText = "Album Title.jpg")] + public bool AlbumImages { get; set; } [FieldDefinition(3, Label = "Episode Images", Type = FieldType.Checkbox, HelpText = "Season##\\filename.jpg")] public bool EpisodeImages { get; set; } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadata.cs index d1846c963..cd69f6cac 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadata.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -12,7 +12,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv { @@ -35,26 +35,26 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv public override string Name => "WDTV"; - public override string GetFilenameAfterMove(Series series, EpisodeFile episodeFile, MetadataFile metadataFile) + public override string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile) { - var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath); + var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath); - if (metadataFile.Type == MetadataType.EpisodeImage) + if (metadataFile.Type == MetadataType.TrackImage) { - return GetEpisodeImageFilename(episodeFilePath); + return GetTrackImageFilename(trackFilePath); } - if (metadataFile.Type == MetadataType.EpisodeMetadata) + if (metadataFile.Type == MetadataType.TrackMetadata) { - return GetEpisodeMetadataFilename(episodeFilePath); + return GetTrackMetadataFilename(trackFilePath); } - _logger.Debug("Unknown episode file metadata: {0}", metadataFile.RelativePath); - return Path.Combine(series.Path, metadataFile.RelativePath); + _logger.Debug("Unknown track file metadata: {0}", metadataFile.RelativePath); + return Path.Combine(artist.Path, metadataFile.RelativePath); } - public override MetadataFile FindMetadataFile(Series series, string path) + public override MetadataFile FindMetadataFile(Artist artist, string path) { var filename = Path.GetFileName(path); @@ -62,9 +62,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv var metadata = new MetadataFile { - SeriesId = series.Id, + ArtistId = artist.Id, Consumer = GetType().Name, - RelativePath = series.Path.GetRelativePath(path) + RelativePath = artist.Path.GetRelativePath(path) }; //Series and season images are both named folder.jpg, only season ones sit in season folders @@ -74,22 +74,22 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv var seasonMatch = SeasonImagesRegex.Match(parentdir.Name); if (seasonMatch.Success) { - metadata.Type = MetadataType.SeasonImage; + metadata.Type = MetadataType.AlbumImage; if (seasonMatch.Groups["specials"].Success) { - metadata.SeasonNumber = 0; + metadata.AlbumId = 0; } else { - metadata.SeasonNumber = Convert.ToInt32(seasonMatch.Groups["season"].Value); + metadata.AlbumId = Convert.ToInt32(seasonMatch.Groups["season"].Value); } return metadata; } - metadata.Type = MetadataType.SeriesImage; + metadata.Type = MetadataType.ArtistImage; return metadata; } @@ -101,10 +101,10 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv switch (Path.GetExtension(filename).ToLowerInvariant()) { case ".xml": - metadata.Type = MetadataType.EpisodeMetadata; + metadata.Type = MetadataType.TrackMetadata; return metadata; case ".metathumb": - metadata.Type = MetadataType.EpisodeImage; + metadata.Type = MetadataType.TrackImage; return metadata; } @@ -113,23 +113,28 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv return null; } - public override MetadataFileResult SeriesMetadata(Series series) + public override MetadataFileResult ArtistMetadata(Artist artist) { - //Series metadata is not supported + //Artist metadata is not supported return null; } - public override MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile) + public override MetadataFileResult AlbumMetadata(Artist artist, Album album) + { + return null; + } + + public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile) { if (!Settings.EpisodeMetadata) { return null; } - _logger.Debug("Generating Episode Metadata for: {0}", Path.Combine(series.Path, episodeFile.RelativePath)); + _logger.Debug("Generating Track Metadata for: {0}", Path.Combine(artist.Path, trackFile.RelativePath)); var xmlResult = string.Empty; - foreach (var episode in episodeFile.Episodes.Value) + foreach (var track in trackFile.Tracks.Value) { var sb = new StringBuilder(); var xws = new XmlWriterSettings(); @@ -141,16 +146,13 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv var doc = new XDocument(); var details = new XElement("details"); - details.Add(new XElement("id", series.Id)); - details.Add(new XElement("title", string.Format("{0} - {1}x{2:00} - {3}", series.Title, episode.SeasonNumber, episode.EpisodeNumber, episode.Title))); - details.Add(new XElement("series_name", series.Title)); - details.Add(new XElement("episode_name", episode.Title)); - details.Add(new XElement("season_number", episode.SeasonNumber.ToString("00"))); - details.Add(new XElement("episode_number", episode.EpisodeNumber.ToString("00"))); - details.Add(new XElement("firstaired", episode.AirDate)); - details.Add(new XElement("genre", string.Join(" / ", series.Genres))); - details.Add(new XElement("actor", string.Join(" / ", series.Actors.ConvertAll(c => c.Name + " - " + c.Character)))); - details.Add(new XElement("overview", episode.Overview)); + details.Add(new XElement("id", artist.Id)); + details.Add(new XElement("title", string.Format("{0} - {1} - {2}", artist.Name, track.TrackNumber, track.Title))); + details.Add(new XElement("artist_name", artist.Name)); + details.Add(new XElement("track_name", track.Title)); + details.Add(new XElement("track_number", track.TrackNumber.ToString("00"))); + details.Add(new XElement("genre", string.Join(" / ", artist.Genres))); + details.Add(new XElement("member", string.Join(" / ", artist.Members.ConvertAll(c => c.Name + " - " + c.Instrument)))); //Todo: get guest stars, writer and director @@ -165,27 +167,27 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv } } - var filename = GetEpisodeMetadataFilename(episodeFile.RelativePath); + var filename = GetTrackMetadataFilename(trackFile.RelativePath); return new MetadataFileResult(filename, xmlResult.Trim(Environment.NewLine.ToCharArray())); } - public override List SeriesImages(Series series) + public override List ArtistImages(Artist artist) { - if (!Settings.SeriesImages) + if (!Settings.ArtistImages) { return new List(); } //Because we only support one image, attempt to get the Poster type, then if that fails grab the first - var image = series.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? series.Images.FirstOrDefault(); + var image = artist.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? artist.Images.FirstOrDefault(); if (image == null) { - _logger.Trace("Failed to find suitable Series image for series {0}.", series.Title); + _logger.Trace("Failed to find suitable Artist image for artist {0}.", artist.Name); return new List(); } - var source = _mediaCoverService.GetCoverPath(series.Id, image.CoverType); + var source = _mediaCoverService.GetCoverPath(artist.Id, image.CoverType); var destination = "folder" + Path.GetExtension(source); return new List @@ -194,28 +196,28 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv }; } - public override List SeasonImages(Series series, Season season) + public override List AlbumImages(Artist artist, Album album) { - if (!Settings.SeasonImages) + if (!Settings.AlbumImages) { return new List(); } - var seasonFolders = GetSeasonFolders(series); + var seasonFolders = GetAlbumFolders(artist); //Work out the path to this season - if we don't have a matching path then skip this season. string seasonFolder; - if (!seasonFolders.TryGetValue(season.SeasonNumber, out seasonFolder)) + if (!seasonFolders.TryGetValue(album.Id, out seasonFolder)) { - _logger.Trace("Failed to find season folder for series {0}, season {1}.", series.Title, season.SeasonNumber); + _logger.Trace("Failed to find album folder for artist {0}, album {1}.", artist.Name, album.Title); return new List(); } //WDTV only supports one season image, so first of all try for poster otherwise just use whatever is first in the collection - var image = season.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? season.Images.FirstOrDefault(); + var image = album.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? album.Images.FirstOrDefault(); if (image == null) { - _logger.Trace("Failed to find suitable season image for series {0}, season {1}.", series.Title, season.SeasonNumber); + _logger.Trace("Failed to find suitable album image for artist {0}, album {1}.", artist.Name, album.Title); return new List(); } @@ -224,39 +226,27 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv return new List{ new ImageFileResult(path, image.Url) }; } - public override List EpisodeImages(Series series, EpisodeFile episodeFile) + public override List TrackImages(Artist artist, TrackFile trackFile) { - if (!Settings.EpisodeImages) - { - return new List(); - } - - var screenshot = episodeFile.Episodes.Value.First().Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot); - - if (screenshot == null) - { - _logger.Trace("Episode screenshot not available"); - return new List(); - } - return new List{ new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url) }; + return new List(); } - private string GetEpisodeMetadataFilename(string episodeFilePath) + private string GetTrackMetadataFilename(string trackFilePath) { - return Path.ChangeExtension(episodeFilePath, "xml"); + return Path.ChangeExtension(trackFilePath, "xml"); } - private string GetEpisodeImageFilename(string episodeFilePath) + private string GetTrackImageFilename(string trackFilePath) { - return Path.ChangeExtension(episodeFilePath, "metathumb"); + return Path.ChangeExtension(trackFilePath, "metathumb"); } - private Dictionary GetSeasonFolders(Series series) + private Dictionary GetAlbumFolders(Artist artist) { var seasonFolderMap = new Dictionary(); - foreach (var folder in _diskProvider.GetDirectories(series.Path)) + foreach (var folder in _diskProvider.GetDirectories(artist.Path)) { var directoryinfo = new DirectoryInfo(folder); var seasonMatch = SeasonImagesRegex.Match(directoryinfo.Name); @@ -278,14 +268,14 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv } else { - _logger.Debug("Failed to parse season number from {0} for series {1}.", folder, series.Title); + _logger.Debug("Failed to parse season number from {0} for artist {1}.", folder, artist.Name); } } } else { - _logger.Debug("Rejecting folder {0} for series {1}.", Path.GetDirectoryName(folder), series.Title); + _logger.Debug("Rejecting folder {0} for artist {1}.", Path.GetDirectoryName(folder), artist.Name); } } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs index e010ff7e5..8b954c653 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs @@ -1,4 +1,4 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -19,19 +19,19 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv public WdtvMetadataSettings() { EpisodeMetadata = true; - SeriesImages = true; - SeasonImages = true; + ArtistImages = true; + AlbumImages = true; EpisodeImages = true; } [FieldDefinition(0, Label = "Episode Metadata", Type = FieldType.Checkbox)] public bool EpisodeMetadata { get; set; } - [FieldDefinition(1, Label = "Series Images", Type = FieldType.Checkbox)] - public bool SeriesImages { get; set; } + [FieldDefinition(1, Label = "Artist Images", Type = FieldType.Checkbox)] + public bool ArtistImages { get; set; } - [FieldDefinition(2, Label = "Season Images", Type = FieldType.Checkbox)] - public bool SeasonImages { get; set; } + [FieldDefinition(2, Label = "Album Images", Type = FieldType.Checkbox)] + public bool AlbumImages { get; set; } [FieldDefinition(3, Label = "Episode Images", Type = FieldType.Checkbox)] public bool EpisodeImages { get; set; } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs index ca7a366cd..9f6ecc3f7 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs @@ -11,7 +11,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc { @@ -27,31 +27,31 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc _logger = logger; } - private static readonly Regex SeriesImagesRegex = new Regex(@"^(?poster|banner|fanart)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex SeasonImagesRegex = new Regex(@"^season(?\d{2,}|-all|-specials)-(?poster|banner|fanart)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex ArtistImagesRegex = new Regex(@"^(?poster|banner|fanart|logo)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex AlbumImagesRegex = new Regex(@"^season(?\d{2,}|-all|-specials)-(?poster|banner|fanart|cover)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex EpisodeImageRegex = new Regex(@"-thumb\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase); public override string Name => "Kodi (XBMC) / Emby"; - public override string GetFilenameAfterMove(Series series, EpisodeFile episodeFile, MetadataFile metadataFile) + public override string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile) { - var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath); + var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath); - if (metadataFile.Type == MetadataType.EpisodeImage) + if (metadataFile.Type == MetadataType.TrackImage) { - return GetEpisodeImageFilename(episodeFilePath); + return GetEpisodeImageFilename(trackFilePath); } - if (metadataFile.Type == MetadataType.EpisodeMetadata) + if (metadataFile.Type == MetadataType.TrackMetadata) { - return GetEpisodeMetadataFilename(episodeFilePath); + return GetEpisodeMetadataFilename(trackFilePath); } _logger.Debug("Unknown episode file metadata: {0}", metadataFile.RelativePath); - return Path.Combine(series.Path, metadataFile.RelativePath); + return Path.Combine(artist.Path, metadataFile.RelativePath); } - public override MetadataFile FindMetadataFile(Series series, string path) + public override MetadataFile FindMetadataFile(Artist artist, string path) { var filename = Path.GetFileName(path); @@ -59,34 +59,34 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc var metadata = new MetadataFile { - SeriesId = series.Id, + ArtistId = artist.Id, Consumer = GetType().Name, - RelativePath = series.Path.GetRelativePath(path) + RelativePath = artist.Path.GetRelativePath(path) }; - if (SeriesImagesRegex.IsMatch(filename)) + if (ArtistImagesRegex.IsMatch(filename)) { - metadata.Type = MetadataType.SeriesImage; + metadata.Type = MetadataType.ArtistImage; return metadata; } - var seasonMatch = SeasonImagesRegex.Match(filename); + var seasonMatch = AlbumImagesRegex.Match(filename); if (seasonMatch.Success) { - metadata.Type = MetadataType.SeasonImage; + metadata.Type = MetadataType.AlbumImage; var seasonNumberMatch = seasonMatch.Groups["season"].Value; int seasonNumber; if (seasonNumberMatch.Contains("specials")) { - metadata.SeasonNumber = 0; + metadata.AlbumId = 0; } else if (int.TryParse(seasonNumberMatch, out seasonNumber)) { - metadata.SeasonNumber = seasonNumber; + metadata.AlbumId = seasonNumber; } else @@ -99,13 +99,19 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc if (EpisodeImageRegex.IsMatch(filename)) { - metadata.Type = MetadataType.EpisodeImage; + metadata.Type = MetadataType.TrackImage; return metadata; } - if (filename.Equals("tvshow.nfo", StringComparison.InvariantCultureIgnoreCase)) + if (filename.Equals("artist.nfo", StringComparison.InvariantCultureIgnoreCase)) { - metadata.Type = MetadataType.SeriesMetadata; + metadata.Type = MetadataType.ArtistMetadata; + return metadata; + } + + if (filename.Equals("album.nfo", StringComparison.InvariantCultureIgnoreCase)) + { + metadata.Type = MetadataType.AlbumMetadata; return metadata; } @@ -115,91 +121,120 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc !parseResult.FullSeason && Path.GetExtension(filename) == ".nfo") { - metadata.Type = MetadataType.EpisodeMetadata; + metadata.Type = MetadataType.TrackMetadata; return metadata; } return null; } - public override MetadataFileResult SeriesMetadata(Series series) + public override MetadataFileResult ArtistMetadata(Artist artist) { - if (!Settings.SeriesMetadata) + if (!Settings.ArtistMetadata) { return null; } - _logger.Debug("Generating tvshow.nfo for: {0}", series.Title); + _logger.Debug("Generating artist.nfo for: {0}", artist.Name); var sb = new StringBuilder(); var xws = new XmlWriterSettings(); xws.OmitXmlDeclaration = true; xws.Indent = false; - var episodeGuideUrl = string.Format("http://www.thetvdb.com/api/1D62F2F90030C444/series/{0}/all/en.zip", series.TvdbId); - using (var xw = XmlWriter.Create(sb, xws)) { - var tvShow = new XElement("tvshow"); + var artistElement = new XElement("artist"); - tvShow.Add(new XElement("title", series.Title)); + artistElement.Add(new XElement("title", artist.Name)); - if (series.Ratings != null && series.Ratings.Votes > 0) + if (artist.Ratings != null && artist.Ratings.Votes > 0) { - tvShow.Add(new XElement("rating", series.Ratings.Value)); + artistElement.Add(new XElement("rating", artist.Ratings.Value)); } - tvShow.Add(new XElement("plot", series.Overview)); - tvShow.Add(new XElement("episodeguide", new XElement("url", episodeGuideUrl))); - tvShow.Add(new XElement("episodeguideurl", episodeGuideUrl)); - tvShow.Add(new XElement("mpaa", series.Certification)); - tvShow.Add(new XElement("id", series.TvdbId)); + artistElement.Add(new XElement("musicbrainzartistid", artist.ForeignArtistId)); + artistElement.Add(new XElement("biography", artist.Overview)); + artistElement.Add(new XElement("outline", artist.Overview)); + //tvShow.Add(new XElement("episodeguide", new XElement("url", episodeGuideUrl))); + //tvShow.Add(new XElement("episodeguideurl", episodeGuideUrl)); + + //foreach (var genre in artist.Genres) + //{ + // tvShow.Add(new XElement("genre", genre)); + //} + + + //foreach (var actor in artist.Members) + //{ + // var xmlActor = new XElement("actor", + // new XElement("name", actor.Name), + // new XElement("role", actor.Instrument)); + + // if (actor.Images.Any()) + // { + // xmlActor.Add(new XElement("thumb", actor.Images.First().Url)); + // } + + // tvShow.Add(xmlActor); + //} + + var doc = new XDocument(artistElement); + doc.Save(xw); - foreach (var genre in series.Genres) - { - tvShow.Add(new XElement("genre", genre)); - } + _logger.Debug("Saving artist.nfo for {0}", artist.Name); - if (series.FirstAired.HasValue) - { - tvShow.Add(new XElement("premiered", series.FirstAired.Value.ToString("yyyy-MM-dd"))); - } + return new MetadataFileResult("artist.nfo", doc.ToString()); + } + } - tvShow.Add(new XElement("studio", series.Network)); + public override MetadataFileResult AlbumMetadata(Artist artist, Album album) + { + if (!Settings.AlbumMetadata) + { + return null; + } - foreach (var actor in series.Actors) - { - var xmlActor = new XElement("actor", - new XElement("name", actor.Name), - new XElement("role", actor.Character)); + _logger.Debug("Generating album.nfo for: {0}", album.Title); + var sb = new StringBuilder(); + var xws = new XmlWriterSettings(); + xws.OmitXmlDeclaration = true; + xws.Indent = false; - if (actor.Images.Any()) - { - xmlActor.Add(new XElement("thumb", actor.Images.First().Url)); - } + using (var xw = XmlWriter.Create(sb, xws)) + { + var albumElement = new XElement("album"); - tvShow.Add(xmlActor); + albumElement.Add(new XElement("title", album.Title)); + + if (album.Ratings != null && album.Ratings.Votes > 0) + { + albumElement.Add(new XElement("rating", album.Ratings.Value)); } - var doc = new XDocument(tvShow); + albumElement.Add(new XElement("musicbrainzalbumid", album.ForeignAlbumId)); + albumElement.Add(new XElement("artistdesc", artist.Overview)); + albumElement.Add(new XElement("releasedate", album.ReleaseDate.Value.ToShortDateString())); + + var doc = new XDocument(albumElement); doc.Save(xw); - _logger.Debug("Saving tvshow.nfo for {0}", series.Title); + _logger.Debug("Saving album.nfo for {0}", artist.Name); - return new MetadataFileResult("tvshow.nfo", doc.ToString()); + return new MetadataFileResult("album.nfo", doc.ToString()); } } - public override MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile) + public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile) { - if (!Settings.EpisodeMetadata) + if (!Settings.TrackMetadata) { return null; } - _logger.Debug("Generating Episode Metadata for: {0}", Path.Combine(series.Path, episodeFile.RelativePath)); + _logger.Debug("Generating Track Metadata for: {0}", Path.Combine(artist.Path, trackFile.RelativePath)); var xmlResult = string.Empty; - foreach (var episode in episodeFile.Episodes.Value) + foreach (var episode in trackFile.Tracks.Value) { var sb = new StringBuilder(); var xws = new XmlWriterSettings(); @@ -209,29 +244,15 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc using (var xw = XmlWriter.Create(sb, xws)) { var doc = new XDocument(); - var image = episode.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot); var details = new XElement("episodedetails"); details.Add(new XElement("title", episode.Title)); - details.Add(new XElement("season", episode.SeasonNumber)); - details.Add(new XElement("episode", episode.EpisodeNumber)); - details.Add(new XElement("aired", episode.AirDate)); - details.Add(new XElement("plot", episode.Overview)); + details.Add(new XElement("episode", episode.TrackNumber)); //If trakt ever gets airs before information for specials we should add set it details.Add(new XElement("displayseason")); details.Add(new XElement("displayepisode")); - if (image == null) - { - details.Add(new XElement("thumb")); - } - - else - { - details.Add(new XElement("thumb", image.Url)); - } - details.Add(new XElement("watched", "false")); if (episode.Ratings != null && episode.Ratings.Votes > 0) @@ -239,39 +260,39 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc details.Add(new XElement("rating", episode.Ratings.Value)); } - if (episodeFile.MediaInfo != null) + if (trackFile.MediaInfo != null) { var fileInfo = new XElement("fileinfo"); var streamDetails = new XElement("streamdetails"); var video = new XElement("video"); - video.Add(new XElement("aspect", (float)episodeFile.MediaInfo.Width / (float)episodeFile.MediaInfo.Height)); - video.Add(new XElement("bitrate", episodeFile.MediaInfo.VideoBitrate)); - video.Add(new XElement("codec", episodeFile.MediaInfo.VideoCodec)); - video.Add(new XElement("framerate", episodeFile.MediaInfo.VideoFps)); - video.Add(new XElement("height", episodeFile.MediaInfo.Height)); - video.Add(new XElement("scantype", episodeFile.MediaInfo.ScanType)); - video.Add(new XElement("width", episodeFile.MediaInfo.Width)); - - if (episodeFile.MediaInfo.RunTime != null) + video.Add(new XElement("aspect", (float)trackFile.MediaInfo.Width / (float)trackFile.MediaInfo.Height)); + video.Add(new XElement("bitrate", trackFile.MediaInfo.VideoBitrate)); + video.Add(new XElement("codec", trackFile.MediaInfo.VideoCodec)); + video.Add(new XElement("framerate", trackFile.MediaInfo.VideoFps)); + video.Add(new XElement("height", trackFile.MediaInfo.Height)); + video.Add(new XElement("scantype", trackFile.MediaInfo.ScanType)); + video.Add(new XElement("width", trackFile.MediaInfo.Width)); + + if (trackFile.MediaInfo.RunTime != null) { - video.Add(new XElement("duration", episodeFile.MediaInfo.RunTime.TotalMinutes)); - video.Add(new XElement("durationinseconds", episodeFile.MediaInfo.RunTime.TotalSeconds)); + video.Add(new XElement("duration", trackFile.MediaInfo.RunTime.TotalMinutes)); + video.Add(new XElement("durationinseconds", trackFile.MediaInfo.RunTime.TotalSeconds)); } streamDetails.Add(video); var audio = new XElement("audio"); - audio.Add(new XElement("bitrate", episodeFile.MediaInfo.AudioBitrate)); - audio.Add(new XElement("channels", episodeFile.MediaInfo.AudioChannels)); - audio.Add(new XElement("codec", GetAudioCodec(episodeFile.MediaInfo.AudioFormat))); - audio.Add(new XElement("language", episodeFile.MediaInfo.AudioLanguages)); + audio.Add(new XElement("bitrate", trackFile.MediaInfo.AudioBitrate)); + audio.Add(new XElement("channels", trackFile.MediaInfo.AudioChannels)); + audio.Add(new XElement("codec", GetAudioCodec(trackFile.MediaInfo.AudioFormat))); + audio.Add(new XElement("language", trackFile.MediaInfo.AudioLanguages)); streamDetails.Add(audio); - if (episodeFile.MediaInfo.Subtitles != null && episodeFile.MediaInfo.Subtitles.Length > 0) + if (trackFile.MediaInfo.Subtitles != null && trackFile.MediaInfo.Subtitles.Length > 0) { var subtitle = new XElement("subtitle"); - subtitle.Add(new XElement("language", episodeFile.MediaInfo.Subtitles)); + subtitle.Add(new XElement("language", trackFile.MediaInfo.Subtitles)); streamDetails.Add(subtitle); } @@ -291,80 +312,52 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc } } - return new MetadataFileResult(GetEpisodeMetadataFilename(episodeFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray())); + return new MetadataFileResult(GetEpisodeMetadataFilename(trackFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray())); } - public override List SeriesImages(Series series) + public override List ArtistImages(Artist artist) { - if (!Settings.SeriesImages) + if (!Settings.ArtistImages) { return new List(); } - return ProcessSeriesImages(series).ToList(); + return ProcessArtistImages(artist).ToList(); } - public override List SeasonImages(Series series, Season season) + public override List AlbumImages(Artist artist, Album album) { - if (!Settings.SeasonImages) + if (!Settings.AlbumImages) { return new List(); } - return ProcessSeasonImages(series, season).ToList(); + return ProcessAlbumImages(artist, album).ToList(); } - public override List EpisodeImages(Series series, EpisodeFile episodeFile) + public override List TrackImages(Artist artist, TrackFile trackFile) { - if (!Settings.EpisodeImages) - { - return new List(); - } - try - { - var screenshot = episodeFile.Episodes.Value.First().Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot); - - if (screenshot == null) - { - _logger.Debug("Episode screenshot not available"); - return new List(); - } - - return new List - { - new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url) - }; - } - catch (Exception ex) - { - _logger.Error(ex, "Unable to process episode image for file: {0}", Path.Combine(series.Path, episodeFile.RelativePath)); - - return new List(); - } + return new List(); } - private IEnumerable ProcessSeriesImages(Series series) + private IEnumerable ProcessArtistImages(Artist artist) { - foreach (var image in series.Images) + foreach (var image in artist.Images) { - var source = _mediaCoverService.GetCoverPath(series.Id, image.CoverType); + var source = _mediaCoverService.GetCoverPath(artist.Id, image.CoverType); var destination = image.CoverType.ToString().ToLowerInvariant() + Path.GetExtension(source); yield return new ImageFileResult(destination, source); } } - private IEnumerable ProcessSeasonImages(Series series, Season season) + private IEnumerable ProcessAlbumImages(Artist artist, Album album) { - foreach (var image in season.Images) + foreach (var image in album.Images) { - var filename = string.Format("season{0:00}-{1}.jpg", season.SeasonNumber, image.CoverType.ToString().ToLower()); - - if (season.SeasonNumber == 0) - { - filename = string.Format("season-specials-{0}.jpg", image.CoverType.ToString().ToLower()); - } + var destination = Path.GetFileName(album.Path); + var filename = string.Format("{0}\\{1}{2}", destination, image.CoverType.ToString().ToLower(), Path.GetExtension(image.Url)); yield return new ImageFileResult(filename, image.Url); } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs index cd4b833ae..f093f82ca 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs @@ -1,4 +1,4 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -18,28 +18,32 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc public XbmcMetadataSettings() { - SeriesMetadata = true; - EpisodeMetadata = true; - SeriesImages = true; - SeasonImages = true; + ArtistMetadata = true; + AlbumMetadata = true; + TrackMetadata = true; + ArtistImages = true; + AlbumImages = true; EpisodeImages = true; } - [FieldDefinition(0, Label = "Series Metadata", Type = FieldType.Checkbox)] - public bool SeriesMetadata { get; set; } + [FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox)] + public bool ArtistMetadata { get; set; } - [FieldDefinition(1, Label = "Episode Metadata", Type = FieldType.Checkbox)] - public bool EpisodeMetadata { get; set; } + [FieldDefinition(1, Label = "Album Metadata", Type = FieldType.Checkbox)] + public bool AlbumMetadata { get; set; } - [FieldDefinition(2, Label = "Series Images", Type = FieldType.Checkbox)] - public bool SeriesImages { get; set; } + [FieldDefinition(2, Label = "Track Metadata", Type = FieldType.Checkbox)] + public bool TrackMetadata { get; set; } - [FieldDefinition(3, Label = "Season Images", Type = FieldType.Checkbox)] - public bool SeasonImages { get; set; } + [FieldDefinition(3, Label = "Artist Images", Type = FieldType.Checkbox)] + public bool ArtistImages { get; set; } - [FieldDefinition(4, Label = "Episode Images", Type = FieldType.Checkbox)] + [FieldDefinition(4, Label = "Album Images", Type = FieldType.Checkbox)] + public bool AlbumImages { get; set; } + + [FieldDefinition(5, Label = "Episode Images", Type = FieldType.Checkbox)] public bool EpisodeImages { get; set; } - + public bool IsValid => true; public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Extras/Metadata/ExistingMetadataImporter.cs b/src/NzbDrone.Core/Extras/Metadata/ExistingMetadataImporter.cs index fa271f575..d52680922 100644 --- a/src/NzbDrone.Core/Extras/Metadata/ExistingMetadataImporter.cs +++ b/src/NzbDrone.Core/Extras/Metadata/ExistingMetadataImporter.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using NLog; @@ -7,7 +7,7 @@ using NzbDrone.Core.Extras.Files; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.Extras.Subtitles; using NzbDrone.Core.Parser; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata { @@ -32,12 +32,12 @@ namespace NzbDrone.Core.Extras.Metadata public override int Order => 0; - public override IEnumerable ProcessFiles(Series series, List filesOnDisk, List importedFiles) + public override IEnumerable ProcessFiles(Artist artist, List filesOnDisk, List importedFiles) { - _logger.Debug("Looking for existing metadata in {0}", series.Path); + _logger.Debug("Looking for existing metadata in {0}", artist.Path); var metadataFiles = new List(); - var filterResult = FilterAndClean(series, filesOnDisk, importedFiles); + var filterResult = FilterAndClean(artist, filesOnDisk, importedFiles); foreach (var possibleMetadataFile in filterResult.FilesOnDisk) { @@ -50,38 +50,38 @@ namespace NzbDrone.Core.Extras.Metadata foreach (var consumer in _consumers) { - var metadata = consumer.FindMetadataFile(series, possibleMetadataFile); + var metadata = consumer.FindMetadataFile(artist, possibleMetadataFile); if (metadata == null) { continue; } - if (metadata.Type == MetadataType.EpisodeImage || - metadata.Type == MetadataType.EpisodeMetadata) + if (metadata.Type == MetadataType.TrackImage || + metadata.Type == MetadataType.TrackMetadata) { - var localEpisode = _parsingService.GetLocalEpisode(possibleMetadataFile, series); + var localTrack = _parsingService.GetLocalTrack(possibleMetadataFile, artist); - if (localEpisode == null) + if (localTrack == null) { _logger.Debug("Unable to parse extra file: {0}", possibleMetadataFile); continue; } - if (localEpisode.Episodes.Empty()) + if (localTrack.Tracks.Empty()) { _logger.Debug("Cannot find related episodes for: {0}", possibleMetadataFile); continue; } - if (localEpisode.Episodes.DistinctBy(e => e.EpisodeFileId).Count() > 1) + if (localTrack.Tracks.DistinctBy(e => e.TrackFileId).Count() > 1) { _logger.Debug("Extra file: {0} does not match existing files.", possibleMetadataFile); continue; } - metadata.SeasonNumber = localEpisode.SeasonNumber; - metadata.EpisodeFileId = localEpisode.Episodes.First().EpisodeFileId; + metadata.AlbumId = localTrack.Album.Id; + metadata.TrackFileId = localTrack.Tracks.First().TrackFileId; } metadata.Extension = Path.GetExtension(possibleMetadataFile); diff --git a/src/NzbDrone.Core/Extras/Metadata/Files/CleanMetadataFileService.cs b/src/NzbDrone.Core/Extras/Metadata/Files/CleanMetadataFileService.cs index 6166ae20b..1fe7ea41a 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Files/CleanMetadataFileService.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Files/CleanMetadataFileService.cs @@ -1,13 +1,13 @@ -using System.IO; +using System.IO; using NLog; using NzbDrone.Common.Disk; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata.Files { public interface ICleanMetadataService { - void Clean(Series series); + void Clean(Artist artist); } public class CleanExtraFileService : ICleanMetadataService @@ -25,15 +25,15 @@ namespace NzbDrone.Core.Extras.Metadata.Files _logger = logger; } - public void Clean(Series series) + public void Clean(Artist artist) { - _logger.Debug("Cleaning missing metadata files for series: {0}", series.Title); + _logger.Debug("Cleaning missing metadata files for artist: {0}", artist.Name); - var metadataFiles = _metadataFileService.GetFilesBySeries(series.Id); + var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id); foreach (var metadataFile in metadataFiles) { - if (!_diskProvider.FileExists(Path.Combine(series.Path, metadataFile.RelativePath))) + if (!_diskProvider.FileExists(Path.Combine(artist.Path, metadataFile.RelativePath))) { _logger.Debug("Deleting metadata file from database: {0}", metadataFile.RelativePath); _metadataFileService.Delete(metadataFile.Id); diff --git a/src/NzbDrone.Core/Extras/Metadata/Files/MetadataFileService.cs b/src/NzbDrone.Core/Extras/Metadata/Files/MetadataFileService.cs index f5fc2ba69..571fec828 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Files/MetadataFileService.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Files/MetadataFileService.cs @@ -1,8 +1,8 @@ -using NLog; +using NLog; using NzbDrone.Common.Disk; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata.Files { @@ -12,8 +12,8 @@ namespace NzbDrone.Core.Extras.Metadata.Files public class MetadataFileService : ExtraFileService, IMetadataFileService { - public MetadataFileService(IExtraFileRepository repository, ISeriesService seriesService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) - : base(repository, seriesService, diskProvider, recycleBinProvider, logger) + public MetadataFileService(IExtraFileRepository repository, IArtistService artistService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) + : base(repository, artistService, diskProvider, recycleBinProvider, logger) { } diff --git a/src/NzbDrone.Core/Extras/Metadata/IMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/IMetadata.cs index b631425e6..31c3cc17f 100644 --- a/src/NzbDrone.Core/Extras/Metadata/IMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/IMetadata.cs @@ -1,19 +1,20 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.ThingiProvider; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata { public interface IMetadata : IProvider { - string GetFilenameAfterMove(Series series, EpisodeFile episodeFile, MetadataFile metadataFile); - MetadataFile FindMetadataFile(Series series, string path); - MetadataFileResult SeriesMetadata(Series series); - MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile); - List SeriesImages(Series series); - List SeasonImages(Series series, Season season); - List EpisodeImages(Series series, EpisodeFile episodeFile); + string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile); + MetadataFile FindMetadataFile(Artist artist, string path); + MetadataFileResult ArtistMetadata(Artist artist); + MetadataFileResult AlbumMetadata(Artist artist, Album album); + MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile); + List ArtistImages(Artist artist); + List AlbumImages(Artist artist, Album album); + List TrackImages(Artist artist, TrackFile trackFile); } } diff --git a/src/NzbDrone.Core/Extras/Metadata/MetadataBase.cs b/src/NzbDrone.Core/Extras/Metadata/MetadataBase.cs index f60928703..4897d2cdf 100644 --- a/src/NzbDrone.Core/Extras/Metadata/MetadataBase.cs +++ b/src/NzbDrone.Core/Extras/Metadata/MetadataBase.cs @@ -1,11 +1,11 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using FluentValidation.Results; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.ThingiProvider; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata { @@ -26,22 +26,23 @@ namespace NzbDrone.Core.Extras.Metadata return new ValidationResult(); } - public virtual string GetFilenameAfterMove(Series series, EpisodeFile episodeFile, MetadataFile metadataFile) + public virtual string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile) { - var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath); + var existingFilename = Path.Combine(artist.Path, metadataFile.RelativePath); var extension = Path.GetExtension(existingFilename).TrimStart('.'); - var newFileName = Path.ChangeExtension(Path.Combine(series.Path, episodeFile.RelativePath), extension); + var newFileName = Path.ChangeExtension(Path.Combine(artist.Path, trackFile.RelativePath), extension); return newFileName; } - public abstract MetadataFile FindMetadataFile(Series series, string path); + public abstract MetadataFile FindMetadataFile(Artist artist, string path); - public abstract MetadataFileResult SeriesMetadata(Series series); - public abstract MetadataFileResult EpisodeMetadata(Series series, EpisodeFile episodeFile); - public abstract List SeriesImages(Series series); - public abstract List SeasonImages(Series series, Season season); - public abstract List EpisodeImages(Series series, EpisodeFile episodeFile); + public abstract MetadataFileResult ArtistMetadata(Artist artist); + public abstract MetadataFileResult AlbumMetadata(Artist artist, Album album); + public abstract MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile); + public abstract List ArtistImages(Artist artist); + public abstract List AlbumImages(Artist artist, Album album); + public abstract List TrackImages(Artist artist, TrackFile trackFile); public virtual object RequestAction(string action, IDictionary query) { return null; } diff --git a/src/NzbDrone.Core/Extras/Metadata/MetadataService.cs b/src/NzbDrone.Core/Extras/Metadata/MetadataService.cs index dbe4c1fba..003350eaf 100644 --- a/src/NzbDrone.Core/Extras/Metadata/MetadataService.cs +++ b/src/NzbDrone.Core/Extras/Metadata/MetadataService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -11,7 +11,7 @@ using NzbDrone.Core.Configuration; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Metadata { @@ -24,6 +24,7 @@ namespace NzbDrone.Core.Extras.Metadata private readonly IHttpClient _httpClient; private readonly IMediaFileAttributeService _mediaFileAttributeService; private readonly IMetadataFileService _metadataFileService; + private readonly IAlbumService _albumService; private readonly Logger _logger; public MetadataService(IConfigService configService, @@ -34,6 +35,7 @@ namespace NzbDrone.Core.Extras.Metadata IHttpClient httpClient, IMediaFileAttributeService mediaFileAttributeService, IMetadataFileService metadataFileService, + IAlbumService albumService, Logger logger) : base(configService, diskProvider, diskTransferService, logger) { @@ -44,19 +46,20 @@ namespace NzbDrone.Core.Extras.Metadata _httpClient = httpClient; _mediaFileAttributeService = mediaFileAttributeService; _metadataFileService = metadataFileService; + _albumService = albumService; _logger = logger; } public override int Order => 0; - public override IEnumerable CreateAfterSeriesScan(Series series, List episodeFiles) + public override IEnumerable CreateAfterArtistScan(Artist artist, List albums, List trackFiles) { - var metadataFiles = _metadataFileService.GetFilesBySeries(series.Id); - _cleanMetadataService.Clean(series); + var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id); + _cleanMetadataService.Clean(artist); - if (!_diskProvider.FolderExists(series.Path)) + if (!_diskProvider.FolderExists(artist.Path)) { - _logger.Info("Series folder does not exist, skipping metadata creation"); + _logger.Info("Artist folder does not exist, skipping metadata creation"); return Enumerable.Empty(); } @@ -66,14 +69,20 @@ namespace NzbDrone.Core.Extras.Metadata { var consumerFiles = GetMetadataFilesForConsumer(consumer, metadataFiles); - files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles)); - files.AddRange(ProcessSeriesImages(consumer, series, consumerFiles)); - files.AddRange(ProcessSeasonImages(consumer, series, consumerFiles)); + files.AddIfNotNull(ProcessArtistMetadata(consumer, artist, consumerFiles)); + files.AddRange(ProcessArtistImages(consumer, artist, consumerFiles)); + files.AddRange(ProcessAlbumImages(consumer, artist, consumerFiles)); - foreach (var episodeFile in episodeFiles) + foreach (var album in albums) { - files.AddIfNotNull(ProcessEpisodeMetadata(consumer, series, episodeFile, consumerFiles)); - files.AddRange(ProcessEpisodeImages(consumer, series, episodeFile, consumerFiles)); + album.Artist = artist; + files.AddIfNotNull(ProcessAlbumMetadata(consumer, album, consumerFiles)); + } + + foreach (var trackFile in trackFiles) + { + files.AddIfNotNull(ProcessEpisodeMetadata(consumer, artist, trackFile, consumerFiles)); + files.AddRange(ProcessEpisodeImages(consumer, artist, trackFile, consumerFiles)); } } @@ -82,15 +91,15 @@ namespace NzbDrone.Core.Extras.Metadata return files; } - public override IEnumerable CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile) + public override IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile) { var files = new List(); foreach (var consumer in _metadataFactory.Enabled()) { - files.AddIfNotNull(ProcessEpisodeMetadata(consumer, series, episodeFile, new List())); - files.AddRange(ProcessEpisodeImages(consumer, series, episodeFile, new List())); + files.AddIfNotNull(ProcessEpisodeMetadata(consumer, artist, trackFile, new List())); + files.AddRange(ProcessEpisodeImages(consumer, artist, trackFile, new List())); } _metadataFileService.Upsert(files); @@ -98,11 +107,11 @@ namespace NzbDrone.Core.Extras.Metadata return files; } - public override IEnumerable CreateAfterEpisodeImport(Series series, string seriesFolder, string seasonFolder) + public override IEnumerable CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder) { - var metadataFiles = _metadataFileService.GetFilesBySeries(series.Id); + var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id); - if (seriesFolder.IsNullOrWhiteSpace() && seasonFolder.IsNullOrWhiteSpace()) + if (artistFolder.IsNullOrWhiteSpace() && albumFolder.IsNullOrWhiteSpace()) { return new List(); } @@ -113,15 +122,15 @@ namespace NzbDrone.Core.Extras.Metadata { var consumerFiles = GetMetadataFilesForConsumer(consumer, metadataFiles); - if (seriesFolder.IsNotNullOrWhiteSpace()) + if (artistFolder.IsNotNullOrWhiteSpace()) { - files.AddIfNotNull(ProcessSeriesMetadata(consumer, series, consumerFiles)); - files.AddRange(ProcessSeriesImages(consumer, series, consumerFiles)); + files.AddIfNotNull(ProcessArtistMetadata(consumer, artist, consumerFiles)); + files.AddRange(ProcessArtistImages(consumer, artist, consumerFiles)); } - if (seasonFolder.IsNotNullOrWhiteSpace()) + if (albumFolder.IsNotNullOrWhiteSpace()) { - files.AddRange(ProcessSeasonImages(consumer, series, consumerFiles)); + files.AddRange(ProcessAlbumImages(consumer, artist, consumerFiles)); } } @@ -130,9 +139,9 @@ namespace NzbDrone.Core.Extras.Metadata return files; } - public override IEnumerable MoveFilesAfterRename(Series series, List episodeFiles) + public override IEnumerable MoveFilesAfterRename(Artist artist, List trackFiles) { - var metadataFiles = _metadataFileService.GetFilesBySeries(series.Id); + var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id); var movedFiles = new List(); // TODO: Move EpisodeImage and EpisodeMetadata metadata files, instead of relying on consumers to do it @@ -140,21 +149,21 @@ namespace NzbDrone.Core.Extras.Metadata foreach (var consumer in _metadataFactory.GetAvailableProviders()) { - foreach (var episodeFile in episodeFiles) + foreach (var trackFile in trackFiles) { - var metadataFilesForConsumer = GetMetadataFilesForConsumer(consumer, metadataFiles).Where(m => m.EpisodeFileId == episodeFile.Id).ToList(); + var metadataFilesForConsumer = GetMetadataFilesForConsumer(consumer, metadataFiles).Where(m => m.TrackFileId == trackFile.Id).ToList(); foreach (var metadataFile in metadataFilesForConsumer) { - var newFileName = consumer.GetFilenameAfterMove(series, episodeFile, metadataFile); - var existingFileName = Path.Combine(series.Path, metadataFile.RelativePath); + var newFileName = consumer.GetFilenameAfterMove(artist, trackFile, metadataFile); + var existingFileName = Path.Combine(artist.Path, metadataFile.RelativePath); if (newFileName.PathNotEquals(existingFileName)) { try { _diskProvider.MoveFile(existingFileName, newFileName); - metadataFile.RelativePath = series.Path.GetRelativePath(newFileName); + metadataFile.RelativePath = artist.Path.GetRelativePath(newFileName); movedFiles.Add(metadataFile); } catch (Exception ex) @@ -171,40 +180,84 @@ namespace NzbDrone.Core.Extras.Metadata return movedFiles; } - public override ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly) + public override ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly) { return null; } - private List GetMetadataFilesForConsumer(IMetadata consumer, List seriesMetadata) + private List GetMetadataFilesForConsumer(IMetadata consumer, List artistMetadata) { - return seriesMetadata.Where(c => c.Consumer == consumer.GetType().Name).ToList(); + return artistMetadata.Where(c => c.Consumer == consumer.GetType().Name).ToList(); + } + + private MetadataFile ProcessArtistMetadata(IMetadata consumer, Artist artist, List existingMetadataFiles) + { + var artistMetadata = consumer.ArtistMetadata(artist); + + if (artistMetadata == null) + { + return null; + } + + var hash = artistMetadata.Contents.SHA256Hash(); + + var metadata = GetMetadataFile(artist, existingMetadataFiles, e => e.Type == MetadataType.ArtistMetadata) ?? + new MetadataFile + { + ArtistId = artist.Id, + Consumer = consumer.GetType().Name, + Type = MetadataType.ArtistMetadata + }; + + if (hash == metadata.Hash) + { + if (artistMetadata.RelativePath != metadata.RelativePath) + { + metadata.RelativePath = artistMetadata.RelativePath; + + return metadata; + } + + return null; + } + + var fullPath = Path.Combine(artist.Path, artistMetadata.RelativePath); + + _logger.Debug("Writing Artist Metadata to: {0}", fullPath); + SaveMetadataFile(fullPath, artistMetadata.Contents); + + metadata.Hash = hash; + metadata.RelativePath = artistMetadata.RelativePath; + metadata.Extension = Path.GetExtension(fullPath); + + return metadata; } - private MetadataFile ProcessSeriesMetadata(IMetadata consumer, Series series, List existingMetadataFiles) + private MetadataFile ProcessAlbumMetadata(IMetadata consumer, Album album, List existingMetadataFiles) { - var seriesMetadata = consumer.SeriesMetadata(series); + var albumMetadata = consumer.AlbumMetadata(album.Artist, album); - if (seriesMetadata == null) + if (albumMetadata == null) { return null; } - var hash = seriesMetadata.Contents.SHA256Hash(); + var hash = albumMetadata.Contents.SHA256Hash(); - var metadata = GetMetadataFile(series, existingMetadataFiles, e => e.Type == MetadataType.SeriesMetadata) ?? + var metadata = GetMetadataFile(album.Artist, existingMetadataFiles, e => e.Type == MetadataType.AlbumMetadata && e.AlbumId == album.Id) ?? new MetadataFile { - SeriesId = series.Id, + ArtistId = album.ArtistId, + AlbumId = album.Id, Consumer = consumer.GetType().Name, - Type = MetadataType.SeriesMetadata + Type = MetadataType.AlbumMetadata }; if (hash == metadata.Hash) { - if (seriesMetadata.RelativePath != metadata.RelativePath) + if (albumMetadata.RelativePath != metadata.RelativePath) { - metadata.RelativePath = seriesMetadata.RelativePath; + metadata.RelativePath = albumMetadata.RelativePath; return metadata; } @@ -212,35 +265,35 @@ namespace NzbDrone.Core.Extras.Metadata return null; } - var fullPath = Path.Combine(series.Path, seriesMetadata.RelativePath); + var fullPath = Path.Combine(album.Path, albumMetadata.RelativePath); - _logger.Debug("Writing Series Metadata to: {0}", fullPath); - SaveMetadataFile(fullPath, seriesMetadata.Contents); + _logger.Debug("Writing Album Metadata to: {0}", fullPath); + SaveMetadataFile(fullPath, albumMetadata.Contents); metadata.Hash = hash; - metadata.RelativePath = seriesMetadata.RelativePath; + metadata.RelativePath = albumMetadata.RelativePath; metadata.Extension = Path.GetExtension(fullPath); return metadata; } - private MetadataFile ProcessEpisodeMetadata(IMetadata consumer, Series series, EpisodeFile episodeFile, List existingMetadataFiles) + private MetadataFile ProcessEpisodeMetadata(IMetadata consumer, Artist artist, TrackFile trackFile, List existingMetadataFiles) { - var episodeMetadata = consumer.EpisodeMetadata(series, episodeFile); + var episodeMetadata = consumer.TrackMetadata(artist, trackFile); if (episodeMetadata == null) { return null; } - var fullPath = Path.Combine(series.Path, episodeMetadata.RelativePath); + var fullPath = Path.Combine(artist.Path, episodeMetadata.RelativePath); - var existingMetadata = GetMetadataFile(series, existingMetadataFiles, c => c.Type == MetadataType.EpisodeMetadata && - c.EpisodeFileId == episodeFile.Id); + var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackMetadata && + c.TrackFileId == trackFile.Id); if (existingMetadata != null) { - var existingFullPath = Path.Combine(series.Path, existingMetadata.RelativePath); + var existingFullPath = Path.Combine(artist.Path, existingMetadata.RelativePath); if (fullPath.PathNotEquals(existingFullPath)) { _diskTransferService.TransferFile(existingFullPath, fullPath, TransferMode.Move); @@ -253,11 +306,11 @@ namespace NzbDrone.Core.Extras.Metadata var metadata = existingMetadata ?? new MetadataFile { - SeriesId = series.Id, - SeasonNumber = episodeFile.SeasonNumber, - EpisodeFileId = episodeFile.Id, + ArtistId = artist.Id, + AlbumId = trackFile.AlbumId, + TrackFileId = trackFile.Id, Consumer = consumer.GetType().Name, - Type = MetadataType.EpisodeMetadata, + Type = MetadataType.TrackMetadata, RelativePath = episodeMetadata.RelativePath, Extension = Path.GetExtension(fullPath) }; @@ -267,7 +320,7 @@ namespace NzbDrone.Core.Extras.Metadata return null; } - _logger.Debug("Writing Episode Metadata to: {0}", fullPath); + _logger.Debug("Writing Track Metadata to: {0}", fullPath); SaveMetadataFile(fullPath, episodeMetadata.Contents); metadata.Hash = hash; @@ -275,32 +328,32 @@ namespace NzbDrone.Core.Extras.Metadata return metadata; } - private List ProcessSeriesImages(IMetadata consumer, Series series, List existingMetadataFiles) + private List ProcessArtistImages(IMetadata consumer, Artist artist, List existingMetadataFiles) { var result = new List(); - foreach (var image in consumer.SeriesImages(series)) + foreach (var image in consumer.ArtistImages(artist)) { - var fullPath = Path.Combine(series.Path, image.RelativePath); + var fullPath = Path.Combine(artist.Path, image.RelativePath); if (_diskProvider.FileExists(fullPath)) { - _logger.Debug("Series image already exists: {0}", fullPath); + _logger.Debug("Artist image already exists: {0}", fullPath); continue; } - var metadata = GetMetadataFile(series, existingMetadataFiles, c => c.Type == MetadataType.SeriesImage && + var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.ArtistImage && c.RelativePath == image.RelativePath) ?? new MetadataFile { - SeriesId = series.Id, + ArtistId = artist.Id, Consumer = consumer.GetType().Name, - Type = MetadataType.SeriesImage, + Type = MetadataType.ArtistImage, RelativePath = image.RelativePath, Extension = Path.GetExtension(fullPath) }; - DownloadImage(series, image); + DownloadImage(artist, image); result.Add(metadata); } @@ -308,36 +361,38 @@ namespace NzbDrone.Core.Extras.Metadata return result; } - private List ProcessSeasonImages(IMetadata consumer, Series series, List existingMetadataFiles) + private List ProcessAlbumImages(IMetadata consumer, Artist artist, List existingMetadataFiles) { var result = new List(); - foreach (var season in series.Seasons) + var albums = _albumService.GetAlbumsByArtist(artist.Id); + + foreach (var album in albums) { - foreach (var image in consumer.SeasonImages(series, season)) + foreach (var image in consumer.AlbumImages(artist, album)) { - var fullPath = Path.Combine(series.Path, image.RelativePath); + var fullPath = Path.Combine(artist.Path, image.RelativePath); if (_diskProvider.FileExists(fullPath)) { - _logger.Debug("Season image already exists: {0}", fullPath); + _logger.Debug("Album image already exists: {0}", fullPath); continue; } - var metadata = GetMetadataFile(series, existingMetadataFiles, c => c.Type == MetadataType.SeasonImage && - c.SeasonNumber == season.SeasonNumber && + var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.AlbumImage && + c.AlbumId == album.Id && c.RelativePath == image.RelativePath) ?? new MetadataFile { - SeriesId = series.Id, - SeasonNumber = season.SeasonNumber, + ArtistId = artist.Id, + AlbumId = album.Id, Consumer = consumer.GetType().Name, - Type = MetadataType.SeasonImage, + Type = MetadataType.AlbumImage, RelativePath = image.RelativePath, Extension = Path.GetExtension(fullPath) }; - DownloadImage(series, image); + DownloadImage(artist, image); result.Add(metadata); } @@ -346,26 +401,26 @@ namespace NzbDrone.Core.Extras.Metadata return result; } - private List ProcessEpisodeImages(IMetadata consumer, Series series, EpisodeFile episodeFile, List existingMetadataFiles) + private List ProcessEpisodeImages(IMetadata consumer, Artist artist, TrackFile trackFile, List existingMetadataFiles) { var result = new List(); - foreach (var image in consumer.EpisodeImages(series, episodeFile)) + foreach (var image in consumer.TrackImages(artist, trackFile)) { - var fullPath = Path.Combine(series.Path, image.RelativePath); + var fullPath = Path.Combine(artist.Path, image.RelativePath); if (_diskProvider.FileExists(fullPath)) { - _logger.Debug("Episode image already exists: {0}", fullPath); + _logger.Debug("Track image already exists: {0}", fullPath); continue; } - var existingMetadata = GetMetadataFile(series, existingMetadataFiles, c => c.Type == MetadataType.EpisodeImage && - c.EpisodeFileId == episodeFile.Id); + var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackImage && + c.TrackFileId == trackFile.Id); if (existingMetadata != null) { - var existingFullPath = Path.Combine(series.Path, existingMetadata.RelativePath); + var existingFullPath = Path.Combine(artist.Path, existingMetadata.RelativePath); if (fullPath.PathNotEquals(existingFullPath)) { _diskTransferService.TransferFile(existingFullPath, fullPath, TransferMode.Move); @@ -378,16 +433,16 @@ namespace NzbDrone.Core.Extras.Metadata var metadata = existingMetadata ?? new MetadataFile { - SeriesId = series.Id, - SeasonNumber = episodeFile.SeasonNumber, - EpisodeFileId = episodeFile.Id, + ArtistId = artist.Id, + AlbumId = trackFile.AlbumId, + TrackFileId = trackFile.Id, Consumer = consumer.GetType().Name, - Type = MetadataType.EpisodeImage, + Type = MetadataType.TrackImage, RelativePath = image.RelativePath, Extension = Path.GetExtension(fullPath) }; - DownloadImage(series, image); + DownloadImage(artist, image); result.Add(metadata); } @@ -395,9 +450,9 @@ namespace NzbDrone.Core.Extras.Metadata return result; } - private void DownloadImage(Series series, ImageFileResult image) + private void DownloadImage(Artist artist, ImageFileResult image) { - var fullPath = Path.Combine(series.Path, image.RelativePath); + var fullPath = Path.Combine(artist.Path, image.RelativePath); try { @@ -413,11 +468,11 @@ namespace NzbDrone.Core.Extras.Metadata } catch (WebException ex) { - _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, series, ex.Message); + _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, artist, ex.Message); } catch (Exception ex) { - _logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, series, ex.Message); + _logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, artist, ex.Message); } } @@ -427,7 +482,7 @@ namespace NzbDrone.Core.Extras.Metadata _mediaFileAttributeService.SetFilePermissions(path); } - private MetadataFile GetMetadataFile(Series series, List existingMetadataFiles, Func predicate) + private MetadataFile GetMetadataFile(Artist artist, List existingMetadataFiles, Func predicate) { var matchingMetadataFiles = existingMetadataFiles.Where(predicate).ToList(); @@ -439,7 +494,7 @@ namespace NzbDrone.Core.Extras.Metadata //Remove duplicate metadata files from DB and disk foreach (var file in matchingMetadataFiles.Skip(1)) { - var path = Path.Combine(series.Path, file.RelativePath); + var path = Path.Combine(artist.Path, file.RelativePath); _logger.Debug("Removing duplicate Metadata file: {0}", path); diff --git a/src/NzbDrone.Core/Extras/Metadata/MetadataType.cs b/src/NzbDrone.Core/Extras/Metadata/MetadataType.cs index 849bc31dd..2a827b48e 100644 --- a/src/NzbDrone.Core/Extras/Metadata/MetadataType.cs +++ b/src/NzbDrone.Core/Extras/Metadata/MetadataType.cs @@ -1,12 +1,13 @@ -namespace NzbDrone.Core.Extras.Metadata +namespace NzbDrone.Core.Extras.Metadata { public enum MetadataType { Unknown = 0, - SeriesMetadata = 1, - EpisodeMetadata = 2, - SeriesImage = 3, - SeasonImage = 4, - EpisodeImage = 5 + ArtistMetadata = 1, + TrackMetadata = 2, + ArtistImage = 3, + AlbumImage = 4, + TrackImage = 5, + AlbumMetadata = 6 } } diff --git a/src/NzbDrone.Core/Extras/Others/ExistingOtherExtraImporter.cs b/src/NzbDrone.Core/Extras/Others/ExistingOtherExtraImporter.cs index 05afb5645..95abfebdc 100644 --- a/src/NzbDrone.Core/Extras/Others/ExistingOtherExtraImporter.cs +++ b/src/NzbDrone.Core/Extras/Others/ExistingOtherExtraImporter.cs @@ -1,11 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.Parser; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Others { @@ -27,12 +27,12 @@ namespace NzbDrone.Core.Extras.Others public override int Order => 2; - public override IEnumerable ProcessFiles(Series series, List filesOnDisk, List importedFiles) + public override IEnumerable ProcessFiles(Artist artist, List filesOnDisk, List importedFiles) { - _logger.Debug("Looking for existing extra files in {0}", series.Path); + _logger.Debug("Looking for existing extra files in {0}", artist.Path); var extraFiles = new List(); - var filterResult = FilterAndClean(series, filesOnDisk, importedFiles); + var filterResult = FilterAndClean(artist, filesOnDisk, importedFiles); foreach (var possibleExtraFile in filterResult.FilesOnDisk) { @@ -44,21 +44,21 @@ namespace NzbDrone.Core.Extras.Others continue; } - var localEpisode = _parsingService.GetLocalEpisode(possibleExtraFile, series); + var localTrack = _parsingService.GetLocalTrack(possibleExtraFile, artist); - if (localEpisode == null) + if (localTrack == null) { _logger.Debug("Unable to parse extra file: {0}", possibleExtraFile); continue; } - if (localEpisode.Episodes.Empty()) + if (localTrack.Tracks.Empty()) { - _logger.Debug("Cannot find related episodes for: {0}", possibleExtraFile); + _logger.Debug("Cannot find related tracks for: {0}", possibleExtraFile); continue; } - if (localEpisode.Episodes.DistinctBy(e => e.EpisodeFileId).Count() > 1) + if (localTrack.Tracks.DistinctBy(e => e.TrackFileId).Count() > 1) { _logger.Debug("Extra file: {0} does not match existing files.", possibleExtraFile); continue; @@ -66,10 +66,10 @@ namespace NzbDrone.Core.Extras.Others var extraFile = new OtherExtraFile { - SeriesId = series.Id, - SeasonNumber = localEpisode.SeasonNumber, - EpisodeFileId = localEpisode.Episodes.First().EpisodeFileId, - RelativePath = series.Path.GetRelativePath(possibleExtraFile), + ArtistId = artist.Id, + AlbumId = localTrack.Album.Id, + TrackFileId = localTrack.Tracks.First().TrackFileId, + RelativePath = artist.Path.GetRelativePath(possibleExtraFile), Extension = extension }; diff --git a/src/NzbDrone.Core/Extras/Others/OtherExtraFileService.cs b/src/NzbDrone.Core/Extras/Others/OtherExtraFileService.cs index ceeb15ff8..063d75f86 100644 --- a/src/NzbDrone.Core/Extras/Others/OtherExtraFileService.cs +++ b/src/NzbDrone.Core/Extras/Others/OtherExtraFileService.cs @@ -1,8 +1,8 @@ -using NLog; +using NLog; using NzbDrone.Common.Disk; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Others { @@ -12,8 +12,8 @@ namespace NzbDrone.Core.Extras.Others public class OtherExtraFileService : ExtraFileService, IOtherExtraFileService { - public OtherExtraFileService(IExtraFileRepository repository, ISeriesService seriesService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) - : base(repository, seriesService, diskProvider, recycleBinProvider, logger) + public OtherExtraFileService(IExtraFileRepository repository, IArtistService artistService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) + : base(repository, artistService, diskProvider, recycleBinProvider, logger) { } } diff --git a/src/NzbDrone.Core/Extras/Others/OtherExtraService.cs b/src/NzbDrone.Core/Extras/Others/OtherExtraService.cs index f3e331c30..08d356425 100644 --- a/src/NzbDrone.Core/Extras/Others/OtherExtraService.cs +++ b/src/NzbDrone.Core/Extras/Others/OtherExtraService.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using NLog; @@ -7,7 +7,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Others { @@ -27,33 +27,33 @@ namespace NzbDrone.Core.Extras.Others public override int Order => 2; - public override IEnumerable CreateAfterSeriesScan(Series series, List episodeFiles) + public override IEnumerable CreateAfterArtistScan(Artist artist, List albums, List trackFiles) { return Enumerable.Empty(); } - public override IEnumerable CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile) + public override IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile) { return Enumerable.Empty(); } - public override IEnumerable CreateAfterEpisodeImport(Series series, string seriesFolder, string seasonFolder) + public override IEnumerable CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder) { return Enumerable.Empty(); } - public override IEnumerable MoveFilesAfterRename(Series series, List episodeFiles) + public override IEnumerable MoveFilesAfterRename(Artist artist, List episodeFiles) { - var extraFiles = _otherExtraFileService.GetFilesBySeries(series.Id); + var extraFiles = _otherExtraFileService.GetFilesByArtist(artist.Id); var movedFiles = new List(); foreach (var episodeFile in episodeFiles) { - var extraFilesForEpisodeFile = extraFiles.Where(m => m.EpisodeFileId == episodeFile.Id).ToList(); + var extraFilesForEpisodeFile = extraFiles.Where(m => m.TrackFileId == episodeFile.Id).ToList(); foreach (var extraFile in extraFilesForEpisodeFile) { - movedFiles.AddIfNotNull(MoveFile(series, episodeFile, extraFile)); + movedFiles.AddIfNotNull(MoveFile(artist, episodeFile, extraFile)); } } @@ -62,7 +62,7 @@ namespace NzbDrone.Core.Extras.Others return movedFiles; } - public override ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly) + public override ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly) { // If the extension is .nfo we need to change it to .nfo-orig if (Path.GetExtension(path).Equals(".nfo")) @@ -70,7 +70,7 @@ namespace NzbDrone.Core.Extras.Others extension += "-orig"; } - var extraFile = ImportFile(series, episodeFile, path, readOnly, extension, null); + var extraFile = ImportFile(artist, trackFile, path, readOnly, extension, null); _otherExtraFileService.Upsert(extraFile); diff --git a/src/NzbDrone.Core/Extras/Subtitles/ExistingSubtitleImporter.cs b/src/NzbDrone.Core/Extras/Subtitles/ExistingSubtitleImporter.cs index d3ae8d46b..4d6bf2604 100644 --- a/src/NzbDrone.Core/Extras/Subtitles/ExistingSubtitleImporter.cs +++ b/src/NzbDrone.Core/Extras/Subtitles/ExistingSubtitleImporter.cs @@ -1,11 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.Parser; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Subtitles { @@ -27,12 +27,12 @@ namespace NzbDrone.Core.Extras.Subtitles public override int Order => 1; - public override IEnumerable ProcessFiles(Series series, List filesOnDisk, List importedFiles) + public override IEnumerable ProcessFiles(Artist artist, List filesOnDisk, List importedFiles) { - _logger.Debug("Looking for existing subtitle files in {0}", series.Path); + _logger.Debug("Looking for existing subtitle files in {0}", artist.Path); var subtitleFiles = new List(); - var filterResult = FilterAndClean(series, filesOnDisk, importedFiles); + var filterResult = FilterAndClean(artist, filesOnDisk, importedFiles); foreach (var possibleSubtitleFile in filterResult.FilesOnDisk) { @@ -40,21 +40,21 @@ namespace NzbDrone.Core.Extras.Subtitles if (SubtitleFileExtensions.Extensions.Contains(extension)) { - var localEpisode = _parsingService.GetLocalEpisode(possibleSubtitleFile, series); + var localTrack = _parsingService.GetLocalTrack(possibleSubtitleFile, artist); - if (localEpisode == null) + if (localTrack == null) { _logger.Debug("Unable to parse subtitle file: {0}", possibleSubtitleFile); continue; } - if (localEpisode.Episodes.Empty()) + if (localTrack.Tracks.Empty()) { - _logger.Debug("Cannot find related episodes for: {0}", possibleSubtitleFile); + _logger.Debug("Cannot find related tracks for: {0}", possibleSubtitleFile); continue; } - if (localEpisode.Episodes.DistinctBy(e => e.EpisodeFileId).Count() > 1) + if (localTrack.Tracks.DistinctBy(e => e.TrackFileId).Count() > 1) { _logger.Debug("Subtitle file: {0} does not match existing files.", possibleSubtitleFile); continue; @@ -62,10 +62,10 @@ namespace NzbDrone.Core.Extras.Subtitles var subtitleFile = new SubtitleFile { - SeriesId = series.Id, - SeasonNumber = localEpisode.SeasonNumber, - EpisodeFileId = localEpisode.Episodes.First().EpisodeFileId, - RelativePath = series.Path.GetRelativePath(possibleSubtitleFile), + ArtistId = artist.Id, + AlbumId = localTrack.Album.Id, + TrackFileId = localTrack.Tracks.First().TrackFileId, + RelativePath = artist.Path.GetRelativePath(possibleSubtitleFile), Language = LanguageParser.ParseSubtitleLanguage(possibleSubtitleFile), Extension = extension }; diff --git a/src/NzbDrone.Core/Extras/Subtitles/SubtitleFileService.cs b/src/NzbDrone.Core/Extras/Subtitles/SubtitleFileService.cs index ac7d4da2b..5194a3139 100644 --- a/src/NzbDrone.Core/Extras/Subtitles/SubtitleFileService.cs +++ b/src/NzbDrone.Core/Extras/Subtitles/SubtitleFileService.cs @@ -1,8 +1,8 @@ -using NLog; +using NLog; using NzbDrone.Common.Disk; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Subtitles { @@ -12,8 +12,8 @@ namespace NzbDrone.Core.Extras.Subtitles public class SubtitleFileService : ExtraFileService, ISubtitleFileService { - public SubtitleFileService(IExtraFileRepository repository, ISeriesService seriesService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) - : base(repository, seriesService, diskProvider, recycleBinProvider, logger) + public SubtitleFileService(IExtraFileRepository repository, IArtistService artistService, IDiskProvider diskProvider, IRecycleBinProvider recycleBinProvider, Logger logger) + : base(repository, artistService, diskProvider, recycleBinProvider, logger) { } } diff --git a/src/NzbDrone.Core/Extras/Subtitles/SubtitleService.cs b/src/NzbDrone.Core/Extras/Subtitles/SubtitleService.cs index 4bdc25638..b77dad041 100644 --- a/src/NzbDrone.Core/Extras/Subtitles/SubtitleService.cs +++ b/src/NzbDrone.Core/Extras/Subtitles/SubtitleService.cs @@ -9,7 +9,7 @@ using NzbDrone.Core.Configuration; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Parser; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; using NzbDrone.Core.Languages; namespace NzbDrone.Core.Extras.Subtitles @@ -32,46 +32,46 @@ namespace NzbDrone.Core.Extras.Subtitles public override int Order => 1; - public override IEnumerable CreateAfterSeriesScan(Series series, List episodeFiles) + public override IEnumerable CreateAfterArtistScan(Artist artist, List albums, List trackFiles) { return Enumerable.Empty(); } - public override IEnumerable CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile) + public override IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile) { return Enumerable.Empty(); } - public override IEnumerable CreateAfterEpisodeImport(Series series, string seriesFolder, string seasonFolder) + public override IEnumerable CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder) { return Enumerable.Empty(); } - public override IEnumerable MoveFilesAfterRename(Series series, List episodeFiles) + public override IEnumerable MoveFilesAfterRename(Artist artist, List trackFiles) { - var subtitleFiles = _subtitleFileService.GetFilesBySeries(series.Id); + var subtitleFiles = _subtitleFileService.GetFilesByArtist(artist.Id); var movedFiles = new List(); - foreach (var episodeFile in episodeFiles) + foreach (var trackFile in trackFiles) { - var groupedExtraFilesForEpisodeFile = subtitleFiles.Where(m => m.EpisodeFileId == episodeFile.Id) + var groupedExtraFilesForTrackFile = subtitleFiles.Where(m => m.TrackFileId == trackFile.Id) .GroupBy(s => s.Language + s.Extension).ToList(); - foreach (var group in groupedExtraFilesForEpisodeFile) + foreach (var group in groupedExtraFilesForTrackFile) { var groupCount = group.Count(); var copy = 1; if (groupCount > 1) { - _logger.Warn("Multiple subtitle files found with the same language and extension for {0}", Path.Combine(series.Path, episodeFile.RelativePath)); + _logger.Warn("Multiple subtitle files found with the same language and extension for {0}", Path.Combine(artist.Path, trackFile.RelativePath)); } foreach (var subtitleFile in group) { var suffix = GetSuffix(subtitleFile.Language, copy, groupCount > 1); - movedFiles.AddIfNotNull(MoveFile(series, episodeFile, subtitleFile, suffix)); + movedFiles.AddIfNotNull(MoveFile(artist, trackFile, subtitleFile, suffix)); copy++; } @@ -83,13 +83,13 @@ namespace NzbDrone.Core.Extras.Subtitles return movedFiles; } - public override ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly) + public override ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly) { if (SubtitleFileExtensions.Extensions.Contains(Path.GetExtension(path))) { var language = LanguageParser.ParseSubtitleLanguage(path); var suffix = GetSuffix(language, 1, false); - var subtitleFile = ImportFile(series, episodeFile, path, readOnly, extension, suffix); + var subtitleFile = ImportFile(artist, trackFile, path, readOnly, extension, suffix); subtitleFile.Language = language; _subtitleFileService.Upsert(subtitleFile); diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMetadataFiles.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMetadataFiles.cs index e65a117a1..5f21924ed 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMetadataFiles.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMetadataFiles.cs @@ -1,4 +1,4 @@ -using NzbDrone.Core.Datastore; +using NzbDrone.Core.Datastore; namespace NzbDrone.Core.Housekeeping.Housekeepers { @@ -13,12 +13,12 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - DeleteDuplicateSeriesMetadata(); - DeleteDuplicateEpisodeMetadata(); - DeleteDuplicateEpisodeImages(); + DeleteDuplicateArtistMetadata(); + DeleteDuplicateTrackMetadata(); + DeleteDuplicateTrackImages(); } - private void DeleteDuplicateSeriesMetadata() + private void DeleteDuplicateArtistMetadata() { var mapper = _database.GetDataMapper(); @@ -26,12 +26,25 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers WHERE Id IN ( SELECT Id FROM MetadataFiles WHERE Type = 1 - GROUP BY SeriesId, Consumer - HAVING COUNT(SeriesId) > 1 + GROUP BY ArtistId, Consumer + HAVING COUNT(ArtistId) > 1 )"); } - private void DeleteDuplicateEpisodeMetadata() + private void DeleteDuplicateAlbumMetadata() + { + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM MetadataFiles + WHERE Id IN ( + SELECT Id FROM MetadataFiles + WHERE Type = 6 + GROUP BY AlbumId, Consumer + HAVING COUNT(AlbumId) > 1 + )"); + } + + private void DeleteDuplicateTrackMetadata() { var mapper = _database.GetDataMapper(); @@ -39,12 +52,12 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers WHERE Id IN ( SELECT Id FROM MetadataFiles WHERE Type = 2 - GROUP BY EpisodeFileId, Consumer - HAVING COUNT(EpisodeFileId) > 1 + GROUP BY TrackFileId, Consumer + HAVING COUNT(TrackFileId) > 1 )"); } - private void DeleteDuplicateEpisodeImages() + private void DeleteDuplicateTrackImages() { var mapper = _database.GetDataMapper(); @@ -52,8 +65,8 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers WHERE Id IN ( SELECT Id FROM MetadataFiles WHERE Type = 5 - GROUP BY EpisodeFileId, Consumer - HAVING COUNT(EpisodeFileId) > 1 + GROUP BY TrackFileId, Consumer + HAVING COUNT(TrackFileId) > 1 )"); } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMetadataFiles.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMetadataFiles.cs index 05ab54ea1..20fca61b7 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMetadataFiles.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMetadataFiles.cs @@ -1,4 +1,4 @@ -using NzbDrone.Core.Datastore; +using NzbDrone.Core.Datastore; namespace NzbDrone.Core.Housekeeping.Housekeepers { @@ -13,37 +13,51 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers public void Clean() { - DeleteOrphanedBySeries(); - DeleteOrphanedByEpisodeFile(); - DeleteWhereEpisodeFileIsZero(); + DeleteOrphanedByArtist(); + DeleteOrphanedByAlbum(); + DeleteOrphanedByTrackFile(); + DeleteWhereTrackFileIsZero(); } - private void DeleteOrphanedBySeries() + private void DeleteOrphanedByArtist() { var mapper = _database.GetDataMapper(); mapper.ExecuteNonQuery(@"DELETE FROM MetadataFiles WHERE Id IN ( SELECT MetadataFiles.Id FROM MetadataFiles - LEFT OUTER JOIN Series - ON MetadataFiles.SeriesId = Series.Id - WHERE Series.Id IS NULL)"); + LEFT OUTER JOIN Artists + ON MetadataFiles.ArtistId = Artists.Id + WHERE Artists.Id IS NULL)"); } - private void DeleteOrphanedByEpisodeFile() + private void DeleteOrphanedByAlbum() { var mapper = _database.GetDataMapper(); mapper.ExecuteNonQuery(@"DELETE FROM MetadataFiles WHERE Id IN ( SELECT MetadataFiles.Id FROM MetadataFiles - LEFT OUTER JOIN EpisodeFiles - ON MetadataFiles.EpisodeFileId = EpisodeFiles.Id - WHERE MetadataFiles.EpisodeFileId > 0 - AND EpisodeFiles.Id IS NULL)"); + LEFT OUTER JOIN Albums + ON MetadataFiles.AlbumId = Albums.Id + WHERE MetadataFiles.AlbumId > 0 + AND Albums.Id IS NULL)"); } - private void DeleteWhereEpisodeFileIsZero() + private void DeleteOrphanedByTrackFile() + { + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM MetadataFiles + WHERE Id IN ( + SELECT MetadataFiles.Id FROM MetadataFiles + LEFT OUTER JOIN TrackFiles + ON MetadataFiles.TrackFileId = TrackFiles.Id + WHERE MetadataFiles.TrackFileId > 0 + AND TrackFiles.Id IS NULL)"); + } + + private void DeleteWhereTrackFileIsZero() { var mapper = _database.GetDataMapper(); @@ -51,7 +65,7 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers WHERE Id IN ( SELECT Id FROM MetadataFiles WHERE Type IN (2, 5) - AND EpisodeFileId = 0)"); + AND TrackFileId = 0)"); } } } diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs index 3ae639b48..d61df11b3 100644 --- a/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/DeleteBadMediaCovers.cs @@ -38,7 +38,7 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers foreach (var artist in artists) { - var images = _metaFileService.GetFilesBySeries(artist.Id) + var images = _metaFileService.GetFilesByArtist(artist.Id) .Where(c => c.LastUpdated > new DateTime(2014, 12, 27) && c.RelativePath.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase)); foreach (var image in images) diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 4529ba57f..ec2568d21 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -252,6 +252,7 @@ + diff --git a/src/NzbDrone.Core/Organizer/SampleResult.cs b/src/NzbDrone.Core/Organizer/SampleResult.cs index e118f1037..fb85df202 100644 --- a/src/NzbDrone.Core/Organizer/SampleResult.cs +++ b/src/NzbDrone.Core/Organizer/SampleResult.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Tv; using NzbDrone.Core.Music; namespace NzbDrone.Core.Organizer @@ -10,8 +9,6 @@ namespace NzbDrone.Core.Organizer public string FileName { get; set; } public Artist Artist { get; set; } public Album Album { get; set; } - public List Episodes { get; set; } - public EpisodeFile EpisodeFile { get; set; } public List Tracks { get; set; } public TrackFile TrackFile { get; set; } } diff --git a/src/NzbDrone.Core/Profiles/Quality/ProfileService.cs b/src/NzbDrone.Core/Profiles/Quality/ProfileService.cs index 8461d25c6..6afbbd04c 100644 --- a/src/NzbDrone.Core/Profiles/Quality/ProfileService.cs +++ b/src/NzbDrone.Core/Profiles/Quality/ProfileService.cs @@ -4,7 +4,6 @@ using NLog; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Qualities; -using NzbDrone.Core.Tv; using NzbDrone.Core.Music; namespace NzbDrone.Core.Profiles.Qualities