mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-16 10:03:51 -07:00
Fixes Misc Issues with Album Metadata Extrafiles (#145)
* Fixes Misc Issues with Album Metadata Extrafiles * Fixed: Move Empty Subfolders to after ArtistRenamedEvent and Metadata mover * Remove Path from Album Table, Fix Wdtv, MediaBrowser, Roksbox * Remove Album Path from UI * Remove Comments and add Jpeg extension to XMBC image regex
This commit is contained in:
parent
71cc80aef9
commit
b63d9d0146
34 changed files with 347 additions and 454 deletions
|
@ -67,7 +67,6 @@ class AlbumRow extends Component {
|
||||||
title,
|
title,
|
||||||
isSaving,
|
isSaving,
|
||||||
artistMonitored,
|
artistMonitored,
|
||||||
path,
|
|
||||||
columns
|
columns
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -122,16 +121,6 @@ class AlbumRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'path') {
|
|
||||||
return (
|
|
||||||
<TableRowCell key={name}>
|
|
||||||
{
|
|
||||||
path
|
|
||||||
}
|
|
||||||
</TableRowCell>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name === 'mediumCount') {
|
if (name === 'mediumCount') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
|
@ -221,7 +210,6 @@ AlbumRow.propTypes = {
|
||||||
unverifiedSceneNumbering: PropTypes.bool,
|
unverifiedSceneNumbering: PropTypes.bool,
|
||||||
artistMonitored: PropTypes.bool.isRequired,
|
artistMonitored: PropTypes.bool.isRequired,
|
||||||
statistics: PropTypes.object.isRequired,
|
statistics: PropTypes.object.isRequired,
|
||||||
path: PropTypes.string,
|
|
||||||
mediaInfo: PropTypes.object,
|
mediaInfo: PropTypes.object,
|
||||||
alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
|
|
@ -39,11 +39,6 @@ export const defaultState = {
|
||||||
label: 'Title',
|
label: 'Title',
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'path',
|
|
||||||
label: 'Path',
|
|
||||||
isVisible: false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'releaseDate',
|
name: 'releaseDate',
|
||||||
label: 'Release Date',
|
label: 'Release Date',
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace Lidarr.Api.V1.Albums
|
||||||
public List<string> AlbumLabel { get; set; }
|
public List<string> AlbumLabel { get; set; }
|
||||||
public string ForeignAlbumId { get; set; }
|
public string ForeignAlbumId { get; set; }
|
||||||
public bool Monitored { get; set; }
|
public bool Monitored { get; set; }
|
||||||
public string Path { get; set; }
|
|
||||||
public int ProfileId { get; set; }
|
public int ProfileId { get; set; }
|
||||||
public int Duration { get; set; }
|
public int Duration { get; set; }
|
||||||
public string AlbumType { get; set; }
|
public string AlbumType { get; set; }
|
||||||
|
@ -57,7 +56,6 @@ namespace Lidarr.Api.V1.Albums
|
||||||
ArtistId = model.ArtistId,
|
ArtistId = model.ArtistId,
|
||||||
AlbumLabel = model.Label,
|
AlbumLabel = model.Label,
|
||||||
ForeignAlbumId = model.ForeignAlbumId,
|
ForeignAlbumId = model.ForeignAlbumId,
|
||||||
Path = model.Path,
|
|
||||||
ProfileId = model.ProfileId,
|
ProfileId = model.ProfileId,
|
||||||
Monitored = model.Monitored,
|
Monitored = model.Monitored,
|
||||||
ReleaseDate = model.ReleaseDate,
|
ReleaseDate = model.ReleaseDate,
|
||||||
|
|
|
@ -65,6 +65,63 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
AllStoredModels.Count.Should().Be(1);
|
AllStoredModels.Count.Should().Be(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_delete_metadata_files_when_they_are_for_the_same_album_but_different_consumers()
|
||||||
|
{
|
||||||
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(m => m.Type = MetadataType.AlbumMetadata)
|
||||||
|
.With(m => m.ArtistId = 1)
|
||||||
|
.With(m => m.AlbumId = 1)
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
Db.InsertMany(files);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Count.Should().Be(files.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_delete_metadata_files_for_different_album()
|
||||||
|
{
|
||||||
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(m => m.Type = MetadataType.AlbumMetadata)
|
||||||
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
|
.With(m => m.ArtistId = 1)
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
Db.InsertMany(files);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Count.Should().Be(files.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_delete_metadata_files_when_they_are_for_the_same_album_and_consumer()
|
||||||
|
{
|
||||||
|
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(m => m.Type = MetadataType.AlbumMetadata)
|
||||||
|
.With(m => m.ArtistId = 1)
|
||||||
|
.With(m => m.AlbumId = 1)
|
||||||
|
.With(m => m.Consumer = "XbmcMetadata")
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
Db.InsertMany(files);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Count.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_delete_metadata_files_when_there_is_only_one_for_that_album_and_consumer()
|
||||||
|
{
|
||||||
|
var file = Builder<MetadataFile>.CreateNew()
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(file);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Count.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_delete_metadata_files_when_they_are_for_the_same_track_but_different_consumers()
|
public void should_not_delete_metadata_files_when_they_are_for_the_same_track_but_different_consumers()
|
||||||
{
|
{
|
||||||
|
@ -118,59 +175,5 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
Subject.Clean();
|
Subject.Clean();
|
||||||
AllStoredModels.Count.Should().Be(1);
|
AllStoredModels.Count.Should().Be(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_delete_image_when_they_are_for_the_same_track_but_different_consumers()
|
|
||||||
{
|
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
|
||||||
.All()
|
|
||||||
.With(m => m.Type = MetadataType.TrackImage)
|
|
||||||
.With(m => m.TrackFileId = 1)
|
|
||||||
.BuildListOfNew();
|
|
||||||
|
|
||||||
Db.InsertMany(files);
|
|
||||||
Subject.Clean();
|
|
||||||
AllStoredModels.Count.Should().Be(files.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_delete_image_for_different_track()
|
|
||||||
{
|
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
|
||||||
.All()
|
|
||||||
.With(m => m.Type = MetadataType.TrackImage)
|
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
|
||||||
.BuildListOfNew();
|
|
||||||
|
|
||||||
Db.InsertMany(files);
|
|
||||||
Subject.Clean();
|
|
||||||
AllStoredModels.Count.Should().Be(files.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_delete_image_when_they_are_for_the_same_track_and_consumer()
|
|
||||||
{
|
|
||||||
var files = Builder<MetadataFile>.CreateListOfSize(2)
|
|
||||||
.All()
|
|
||||||
.With(m => m.Type = MetadataType.TrackImage)
|
|
||||||
.With(m => m.TrackFileId = 1)
|
|
||||||
.With(m => m.Consumer = "XbmcMetadata")
|
|
||||||
.BuildListOfNew();
|
|
||||||
|
|
||||||
Db.InsertMany(files);
|
|
||||||
Subject.Clean();
|
|
||||||
AllStoredModels.Count.Should().Be(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_delete_image_when_there_is_only_one_for_that_track_and_consumer()
|
|
||||||
{
|
|
||||||
var file = Builder<MetadataFile>.CreateNew()
|
|
||||||
.BuildNew();
|
|
||||||
|
|
||||||
Db.Insert(file);
|
|
||||||
Subject.Clean();
|
|
||||||
AllStoredModels.Count.Should().Be(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,10 +93,15 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
var artist = Builder<Artist>.CreateNew()
|
var artist = Builder<Artist>.CreateNew()
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
|
var album = Builder<Album>.CreateNew()
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(artist);
|
Db.Insert(artist);
|
||||||
|
Db.Insert(album);
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
.With(m => m.ArtistId = artist.Id)
|
.With(m => m.ArtistId = artist.Id)
|
||||||
|
.With(m => m.AlbumId = album.Id)
|
||||||
.With(m => m.TrackFileId = 10)
|
.With(m => m.TrackFileId = 10)
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
|
@ -133,6 +138,46 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
AllStoredModels.Should().HaveCount(1);
|
AllStoredModels.Should().HaveCount(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_delete_album_metadata_files_that_have_albumid_of_zero()
|
||||||
|
{
|
||||||
|
var artist = Builder<Artist>.CreateNew()
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(artist);
|
||||||
|
|
||||||
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
|
.With(m => m.ArtistId = artist.Id)
|
||||||
|
.With(m => m.Type = MetadataType.AlbumMetadata)
|
||||||
|
.With(m => m.AlbumId = 0)
|
||||||
|
.With(m => m.TrackFileId = null)
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(metadataFile);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Should().HaveCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_delete_album_image_files_that_have_albumid_of_zero()
|
||||||
|
{
|
||||||
|
var artist = Builder<Artist>.CreateNew()
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(artist);
|
||||||
|
|
||||||
|
var metadataFile = Builder<MetadataFile>.CreateNew()
|
||||||
|
.With(m => m.ArtistId = artist.Id)
|
||||||
|
.With(m => m.Type = MetadataType.AlbumImage)
|
||||||
|
.With(m => m.AlbumId = 0)
|
||||||
|
.With(m => m.TrackFileId = null)
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(metadataFile);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Should().HaveCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_track_metadata_files_that_have_trackfileid_of_zero()
|
public void should_delete_track_metadata_files_that_have_trackfileid_of_zero()
|
||||||
{
|
{
|
||||||
|
@ -151,24 +196,5 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
Subject.Clean();
|
Subject.Clean();
|
||||||
AllStoredModels.Should().HaveCount(0);
|
AllStoredModels.Should().HaveCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_delete_track_image_files_that_have_trackfileid_of_zero()
|
|
||||||
{
|
|
||||||
var artist = Builder<Artist>.CreateNew()
|
|
||||||
.BuildNew();
|
|
||||||
|
|
||||||
Db.Insert(artist);
|
|
||||||
|
|
||||||
var metadataFile = Builder<MetadataFile>.CreateNew()
|
|
||||||
.With(m => m.ArtistId = artist.Id)
|
|
||||||
.With(m => m.Type = MetadataType.TrackImage)
|
|
||||||
.With(m => m.TrackFileId = 0)
|
|
||||||
.BuildNew();
|
|
||||||
|
|
||||||
Db.Insert(metadataFile);
|
|
||||||
Subject.Clean();
|
|
||||||
AllStoredModels.Should().HaveCount(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,66 +13,65 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FindMetadataFileFixture : CoreTest<RoksboxMetadata>
|
public class FindMetadataFileFixture : CoreTest<RoksboxMetadata>
|
||||||
{
|
{
|
||||||
private Artist _series;
|
private Artist _artist;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Artist>.CreateNew()
|
_artist = Builder<Artist>.CreateNew()
|
||||||
.With(s => s.Path = @"C:\Test\TV\The.Series".AsOsAgnostic())
|
.With(s => s.Path = @"C:\Test\Music\The.Artist".AsOsAgnostic())
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_null_if_filename_is_not_handled()
|
public void should_return_null_if_filename_is_not_handled()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "file.jpg");
|
var path = Path.Combine(_artist.Path, "file.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_artist, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Specials")]
|
[TestCase("Specials")]
|
||||||
[TestCase("specials")]
|
[TestCase("specials")]
|
||||||
[TestCase("Season 1")]
|
[TestCase("Season 1")]
|
||||||
public void should_return_season_image(string folder)
|
public void should_return_album_image(string folder)
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, folder, folder + ".jpg");
|
var path = Path.Combine(_artist.Path, folder, folder + ".jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.AlbumImage);
|
Subject.FindMetadataFile(_artist, path).Type.Should().Be(MetadataType.AlbumImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(".xml", MetadataType.TrackMetadata)]
|
[TestCase(".xml", MetadataType.TrackMetadata)]
|
||||||
[TestCase(".jpg", MetadataType.TrackImage)]
|
public void should_return_metadata_for_track_if_valid_file_for_track(string extension, MetadataType type)
|
||||||
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);
|
var path = Path.Combine(_artist.Path, "the.artist.s01e01.track" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(type);
|
Subject.FindMetadataFile(_artist, path).Type.Should().Be(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(".xml")]
|
[TestCase(".xml")]
|
||||||
[TestCase(".jpg")]
|
[TestCase(".jpg")]
|
||||||
public void should_return_null_if_not_valid_file_for_episode(string extension)
|
public void should_return_null_if_not_valid_file_for_track(string extension)
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "the.series.episode" + extension);
|
var path = Path.Combine(_artist.Path, "the.artist.track" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_artist, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_return_metadata_if_image_file_is_a_thumb()
|
public void should_not_return_metadata_if_image_file_is_a_thumb()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "the.series.s01e01.episode-thumb.jpg");
|
var path = Path.Combine(_artist.Path, "the.artist.s01e01.track-thumb.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_artist, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_series_image_for_folder_jpg_in_series_folder()
|
public void should_return_artist_image_for_folder_jpg_in_artist_folder()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, new DirectoryInfo(_series.Path).Name + ".jpg");
|
var path = Path.Combine(_artist.Path, new DirectoryInfo(_artist.Path).Name + ".jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.ArtistImage);
|
Subject.FindMetadataFile(_artist, path).Type.Should().Be(MetadataType.ArtistImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,58 +13,57 @@ namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FindMetadataFileFixture : CoreTest<WdtvMetadata>
|
public class FindMetadataFileFixture : CoreTest<WdtvMetadata>
|
||||||
{
|
{
|
||||||
private Artist _series;
|
private Artist _artist;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Artist>.CreateNew()
|
_artist = Builder<Artist>.CreateNew()
|
||||||
.With(s => s.Path = @"C:\Test\TV\The.Series".AsOsAgnostic())
|
.With(s => s.Path = @"C:\Test\Music\The.Artist".AsOsAgnostic())
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_null_if_filename_is_not_handled()
|
public void should_return_null_if_filename_is_not_handled()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "file.jpg");
|
var path = Path.Combine(_artist.Path, "file.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_artist, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Specials")]
|
[TestCase("Specials")]
|
||||||
[TestCase("specials")]
|
[TestCase("specials")]
|
||||||
[TestCase("Season 1")]
|
[TestCase("Season 1")]
|
||||||
public void should_return_season_image(string folder)
|
public void should_return_album_image(string folder)
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, folder, "folder.jpg");
|
var path = Path.Combine(_artist.Path, folder, "folder.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.AlbumImage);
|
Subject.FindMetadataFile(_artist, path).Type.Should().Be(MetadataType.AlbumImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(".xml", MetadataType.TrackMetadata)]
|
[TestCase(".xml", MetadataType.TrackMetadata)]
|
||||||
[TestCase(".metathumb", MetadataType.TrackImage)]
|
public void should_return_metadata_for_track_if_valid_file_for_track(string extension, MetadataType type)
|
||||||
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);
|
var path = Path.Combine(_artist.Path, "the.artist.s01e01.track" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(type);
|
Subject.FindMetadataFile(_artist, path).Type.Should().Be(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(".xml")]
|
[TestCase(".xml")]
|
||||||
[TestCase(".metathumb")]
|
[TestCase(".metathumb")]
|
||||||
public void should_return_null_if_not_valid_file_for_episode(string extension)
|
public void should_return_null_if_not_valid_file_for_track(string extension)
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "the.series.episode" + extension);
|
var path = Path.Combine(_artist.Path, "the.artist.track" + extension);
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Should().BeNull();
|
Subject.FindMetadataFile(_artist, path).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_series_image_for_folder_jpg_in_series_folder()
|
public void should_return_artist_image_for_folder_jpg_in_artist_folder()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_series.Path, "folder.jpg");
|
var path = Path.Combine(_artist.Path, "folder.jpg");
|
||||||
|
|
||||||
Subject.FindMetadataFile(_series, path).Type.Should().Be(MetadataType.ArtistImage);
|
Subject.FindMetadataFile(_artist, path).Type.Should().Be(MetadataType.ArtistImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
|
@ -37,7 +37,6 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
|
|
||||||
var fakeAlbum = Builder<Album>.CreateNew()
|
var fakeAlbum = Builder<Album>.CreateNew()
|
||||||
.With(s => s.Title = "Fake: Album")
|
.With(s => s.Title = "Fake: Album")
|
||||||
.With(s => s.Path = @"C:\Test\Fake- The Artist\Fake- Album".AsOsAgnostic())
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
namingConfig.AlbumFolderFormat = "{Artist Name} {Album Title}";
|
namingConfig.AlbumFolderFormat = "{Artist Name} {Album Title}";
|
||||||
|
@ -45,4 +44,4 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
Subject.BuildTrackFilePath(fakeArtist, fakeAlbum, filename, ".flac").Should().Be(expectedPath.AsOsAgnostic());
|
Subject.BuildTrackFilePath(fakeArtist, fakeAlbum, filename, ".flac").Should().Be(expectedPath.AsOsAgnostic());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(7)]
|
||||||
|
public class change_album_path_to_relative : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.Column("Path").FromTable("Albums");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,6 @@ namespace NzbDrone.Core.Extras
|
||||||
IHandle<ArtistRenamedEvent>
|
IHandle<ArtistRenamedEvent>
|
||||||
{
|
{
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
//private readonly IEpisodeService _episodeService;
|
|
||||||
private readonly IAlbumService _albumService;
|
private readonly IAlbumService _albumService;
|
||||||
private readonly ITrackService _trackService;
|
private readonly ITrackService _trackService;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
@ -36,7 +35,6 @@ namespace NzbDrone.Core.Extras
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ExtraService(IMediaFileService mediaFileService,
|
public ExtraService(IMediaFileService mediaFileService,
|
||||||
//IEpisodeService episodeService,
|
|
||||||
IAlbumService albumService,
|
IAlbumService albumService,
|
||||||
ITrackService trackService,
|
ITrackService trackService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
|
@ -45,7 +43,6 @@ namespace NzbDrone.Core.Extras
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_mediaFileService = mediaFileService;
|
_mediaFileService = mediaFileService;
|
||||||
//_episodeService = episodeService;
|
|
||||||
_albumService = albumService;
|
_albumService = albumService;
|
||||||
_trackService = trackService;
|
_trackService = trackService;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
|
@ -111,22 +108,23 @@ namespace NzbDrone.Core.Extras
|
||||||
public void Handle(MediaCoversUpdatedEvent message)
|
public void Handle(MediaCoversUpdatedEvent message)
|
||||||
{
|
{
|
||||||
var artist = message.Artist;
|
var artist = message.Artist;
|
||||||
var albums = _albumService.GetAlbumsByArtist(artist.Id);
|
|
||||||
var trackFiles = GetTrackFiles(artist.Id);
|
var trackFiles = GetTrackFiles(artist.Id);
|
||||||
|
|
||||||
foreach (var extraFileManager in _extraFileManagers)
|
foreach (var extraFileManager in _extraFileManagers)
|
||||||
{
|
{
|
||||||
extraFileManager.CreateAfterArtistScan(artist, albums, trackFiles);
|
extraFileManager.CreateAfterArtistScan(artist, trackFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(TrackFolderCreatedEvent message)
|
public void Handle(TrackFolderCreatedEvent message)
|
||||||
{
|
{
|
||||||
var artist = message.Artist;
|
var artist = message.Artist;
|
||||||
|
var album = _albumService.GetAlbum(message.TrackFile.AlbumId);
|
||||||
|
|
||||||
foreach (var extraFileManager in _extraFileManagers)
|
foreach (var extraFileManager in _extraFileManagers)
|
||||||
{
|
{
|
||||||
extraFileManager.CreateAfterTrackImport(artist, message.ArtistFolder, message.AlbumFolder);
|
extraFileManager.CreateAfterTrackImport(artist, album, message.ArtistFolder, message.AlbumFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace NzbDrone.Core.Extras.Files
|
||||||
public interface IManageExtraFiles
|
public interface IManageExtraFiles
|
||||||
{
|
{
|
||||||
int Order { get; }
|
int Order { get; }
|
||||||
IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<Album> albums, List<TrackFile> trackFiles);
|
IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<TrackFile> trackFiles);
|
||||||
IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, TrackFile trackFile);
|
IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, TrackFile trackFile);
|
||||||
IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder);
|
IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, Album album, string artistFolder, string albumFolder);
|
||||||
IEnumerable<ExtraFile> MoveFilesAfterRename(Artist artist, List<TrackFile> trackFiles);
|
IEnumerable<ExtraFile> MoveFilesAfterRename(Artist artist, List<TrackFile> trackFiles);
|
||||||
ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly);
|
ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly);
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ namespace NzbDrone.Core.Extras.Files
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract int Order { get; }
|
public abstract int Order { get; }
|
||||||
public abstract IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<Album> albums, List<TrackFile> trackFiles);
|
public abstract IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<TrackFile> trackFiles);
|
||||||
public abstract IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, TrackFile trackFile);
|
public abstract IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, TrackFile trackFile);
|
||||||
public abstract IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder);
|
public abstract IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, Album album, string artistFolder, string albumFolder);
|
||||||
public abstract IEnumerable<ExtraFile> MoveFilesAfterRename(Artist artist, List<TrackFile> trackFiles);
|
public abstract IEnumerable<ExtraFile> MoveFilesAfterRename(Artist artist, List<TrackFile> trackFiles);
|
||||||
public abstract ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly);
|
public abstract ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Extras.Lyrics
|
||||||
|
|
||||||
public override int Order => 1;
|
public override int Order => 1;
|
||||||
|
|
||||||
public override IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<Album> albums, List<TrackFile> trackFiles)
|
public override IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<TrackFile> trackFiles)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<LyricFile>();
|
return Enumerable.Empty<LyricFile>();
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ namespace NzbDrone.Core.Extras.Lyrics
|
||||||
return Enumerable.Empty<LyricFile>();
|
return Enumerable.Empty<LyricFile>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder)
|
public override IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, Album album, string artistFolder, string albumFolder)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<LyricFile>();
|
return Enumerable.Empty<LyricFile>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser
|
||||||
artistElement.Add(new XElement("LocalTitle", artist.Name));
|
artistElement.Add(new XElement("LocalTitle", artist.Name));
|
||||||
|
|
||||||
artistElement.Add(new XElement("Rating", artist.Ratings.Value));
|
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");
|
var persons = new XElement("Persons");
|
||||||
|
|
||||||
|
@ -98,7 +97,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFileResult AlbumMetadata(Artist artist, Album album)
|
public override MetadataFileResult AlbumMetadata(Artist artist, Album album, string albumPath)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +112,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser
|
||||||
return new List<ImageFileResult>();
|
return new List<ImageFileResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> AlbumImages(Artist artist, Album season)
|
public override List<ImageFileResult> AlbumImages(Artist artist, Album album, string albumFolder)
|
||||||
{
|
{
|
||||||
return new List<ImageFileResult>();
|
return new List<ImageFileResult>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.MediaBrowser
|
||||||
{
|
{
|
||||||
public class MediaBrowserSettingsValidator : AbstractValidator<MediaBrowserMetadataSettings>
|
public class MediaBrowserSettingsValidator : AbstractValidator<MediaBrowserMetadataSettings>
|
||||||
{
|
{
|
||||||
public MediaBrowserSettingsValidator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MediaBrowserMetadataSettings : IProviderConfig
|
public class MediaBrowserMetadataSettings : IProviderConfig
|
||||||
|
|
|
@ -31,7 +31,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<string> ValidCertification = new List<string> { "G", "NC-17", "PG", "PG-13", "R", "UR", "UNRATED", "NR", "TV-Y", "TV-Y7", "TV-Y7-FV", "TV-G", "TV-PG", "TV-14", "TV-MA" };
|
|
||||||
private static readonly Regex SeasonImagesRegex = new Regex(@"^(season (?<season>\d+))|(?<specials>specials)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex SeasonImagesRegex = new Regex(@"^(season (?<season>\d+))|(?<specials>specials)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
public override string Name => "Roksbox";
|
public override string Name => "Roksbox";
|
||||||
|
@ -40,11 +39,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
{
|
{
|
||||||
var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.TrackImage)
|
|
||||||
{
|
|
||||||
return GetTrackImageFilename(trackFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.TrackMetadata)
|
if (metadataFile.Type == MetadataType.TrackMetadata)
|
||||||
{
|
{
|
||||||
return GetTrackMetadataFilename(trackFilePath);
|
return GetTrackMetadataFilename(trackFilePath);
|
||||||
|
@ -104,16 +98,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
{
|
{
|
||||||
metadata.Type = MetadataType.TrackMetadata;
|
metadata.Type = MetadataType.TrackMetadata;
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extension == ".jpg")
|
|
||||||
{
|
|
||||||
if (!Path.GetFileNameWithoutExtension(filename).EndsWith("-thumb"))
|
|
||||||
{
|
|
||||||
metadata.Type = MetadataType.TrackImage;
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -125,14 +110,14 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFileResult AlbumMetadata(Artist artist, Album album)
|
public override MetadataFileResult AlbumMetadata(Artist artist, Album album, string albumPath)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile)
|
public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile)
|
||||||
{
|
{
|
||||||
if (!Settings.EpisodeMetadata)
|
if (!Settings.TrackMetadata)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -151,11 +136,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
{
|
{
|
||||||
var doc = new XDocument();
|
var doc = new XDocument();
|
||||||
|
|
||||||
var details = new XElement("video");
|
var details = new XElement("song");
|
||||||
details.Add(new XElement("title", string.Format("{0} - {1} - {2}", artist.Name, track.TrackNumber, track.Title)));
|
details.Add(new XElement("title", track.Title));
|
||||||
details.Add(new XElement("genre", string.Join(" / ", artist.Genres)));
|
details.Add(new XElement("performingartist", artist.Name));
|
||||||
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));
|
|
||||||
|
|
||||||
doc.Add(details);
|
doc.Add(details);
|
||||||
doc.Save(xw);
|
doc.Save(xw);
|
||||||
|
@ -188,34 +171,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
return new List<ImageFileResult>{ new ImageFileResult(destination, source) };
|
return new List<ImageFileResult>{ new ImageFileResult(destination, source) };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> AlbumImages(Artist artist, Album album)
|
public override List<ImageFileResult> AlbumImages(Artist artist, Album album, string albumFolder)
|
||||||
{
|
{
|
||||||
if (!Settings.AlbumImages)
|
return new List<ImageFileResult>();
|
||||||
{
|
|
||||||
return new List<ImageFileResult>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var albumFolders = GetAlbumFolders(artist);
|
|
||||||
|
|
||||||
string albumFolder;
|
|
||||||
if (!albumFolders.TryGetValue(album.ArtistId, out albumFolder))
|
|
||||||
{
|
|
||||||
_logger.Trace("Failed to find album folder for artit {0}, album {1}.", artist.Name, album.Title);
|
|
||||||
return new List<ImageFileResult>();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Roksbox only supports one season image, so first of all try for poster otherwise just use whatever is first in the collection
|
|
||||||
var image = album.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? album.Images.FirstOrDefault();
|
|
||||||
if (image == null)
|
|
||||||
{
|
|
||||||
_logger.Trace("Failed to find suitable album image for artist {0}, album {1}.", artist.Name, album.Title);
|
|
||||||
return new List<ImageFileResult>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var filename = Path.GetFileName(albumFolder) + ".jpg";
|
|
||||||
var path = artist.Path.GetRelativePath(Path.Combine(artist.Path, albumFolder, filename));
|
|
||||||
|
|
||||||
return new List<ImageFileResult> { new ImageFileResult(path, image.Url) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile)
|
public override List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile)
|
||||||
|
|
|
@ -7,9 +7,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
{
|
{
|
||||||
public class RoksboxSettingsValidator : AbstractValidator<RoksboxMetadataSettings>
|
public class RoksboxSettingsValidator : AbstractValidator<RoksboxMetadataSettings>
|
||||||
{
|
{
|
||||||
public RoksboxSettingsValidator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RoksboxMetadataSettings : IProviderConfig
|
public class RoksboxMetadataSettings : IProviderConfig
|
||||||
|
@ -18,23 +15,19 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Roksbox
|
||||||
|
|
||||||
public RoksboxMetadataSettings()
|
public RoksboxMetadataSettings()
|
||||||
{
|
{
|
||||||
EpisodeMetadata = true;
|
TrackMetadata = true;
|
||||||
ArtistImages = true;
|
ArtistImages = true;
|
||||||
AlbumImages = true;
|
AlbumImages = true;
|
||||||
EpisodeImages = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Episode Metadata", Type = FieldType.Checkbox, HelpText = "Season##\\filename.xml")]
|
[FieldDefinition(0, Label = "Track Metadata", Type = FieldType.Checkbox, HelpText = "Season##\\filename.xml")]
|
||||||
public bool EpisodeMetadata { get; set; }
|
public bool TrackMetadata { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Artist Images", Type = FieldType.Checkbox, HelpText = "Artist Title.jpg")]
|
[FieldDefinition(1, Label = "Artist Images", Type = FieldType.Checkbox, HelpText = "Artist Title.jpg")]
|
||||||
public bool ArtistImages { get; set; }
|
public bool ArtistImages { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Album Images", Type = FieldType.Checkbox, HelpText = "Album Title.jpg")]
|
[FieldDefinition(2, Label = "Album Images", Type = FieldType.Checkbox, HelpText = "Album Title.jpg")]
|
||||||
public bool AlbumImages { get; set; }
|
public bool AlbumImages { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Episode Images", Type = FieldType.Checkbox, HelpText = "Season##\\filename.jpg")]
|
|
||||||
public bool EpisodeImages { get; set; }
|
|
||||||
|
|
||||||
public bool IsValid => true;
|
public bool IsValid => true;
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
{
|
{
|
||||||
var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.TrackImage)
|
|
||||||
{
|
|
||||||
return GetTrackImageFilename(trackFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.TrackMetadata)
|
if (metadataFile.Type == MetadataType.TrackMetadata)
|
||||||
{
|
{
|
||||||
return GetTrackMetadataFilename(trackFilePath);
|
return GetTrackMetadataFilename(trackFilePath);
|
||||||
|
@ -102,9 +97,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
case ".xml":
|
case ".xml":
|
||||||
metadata.Type = MetadataType.TrackMetadata;
|
metadata.Type = MetadataType.TrackMetadata;
|
||||||
return metadata;
|
return metadata;
|
||||||
case ".metathumb":
|
|
||||||
metadata.Type = MetadataType.TrackImage;
|
|
||||||
return metadata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -118,14 +110,14 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFileResult AlbumMetadata(Artist artist, Album album)
|
public override MetadataFileResult AlbumMetadata(Artist artist, Album album, string albumPath)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile)
|
public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile)
|
||||||
{
|
{
|
||||||
if (!Settings.EpisodeMetadata)
|
if (!Settings.TrackMetadata)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +142,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
details.Add(new XElement("artist_name", artist.Name));
|
details.Add(new XElement("artist_name", artist.Name));
|
||||||
details.Add(new XElement("track_name", track.Title));
|
details.Add(new XElement("track_name", track.Title));
|
||||||
details.Add(new XElement("track_number", track.AbsoluteTrackNumber.ToString("00")));
|
details.Add(new XElement("track_number", track.AbsoluteTrackNumber.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))));
|
details.Add(new XElement("member", string.Join(" / ", artist.Members.ConvertAll(c => c.Name + " - " + c.Instrument))));
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,7 +186,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> AlbumImages(Artist artist, Album album)
|
public override List<ImageFileResult> AlbumImages(Artist artist, Album album, string albumFolder)
|
||||||
{
|
{
|
||||||
if (!Settings.AlbumImages)
|
if (!Settings.AlbumImages)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,9 +7,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
{
|
{
|
||||||
public class WdtvSettingsValidator : AbstractValidator<WdtvMetadataSettings>
|
public class WdtvSettingsValidator : AbstractValidator<WdtvMetadataSettings>
|
||||||
{
|
{
|
||||||
public WdtvSettingsValidator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WdtvMetadataSettings : IProviderConfig
|
public class WdtvMetadataSettings : IProviderConfig
|
||||||
|
@ -18,23 +15,19 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Wdtv
|
||||||
|
|
||||||
public WdtvMetadataSettings()
|
public WdtvMetadataSettings()
|
||||||
{
|
{
|
||||||
EpisodeMetadata = true;
|
TrackMetadata = true;
|
||||||
ArtistImages = true;
|
ArtistImages = true;
|
||||||
AlbumImages = true;
|
AlbumImages = true;
|
||||||
EpisodeImages = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Episode Metadata", Type = FieldType.Checkbox)]
|
[FieldDefinition(0, Label = "Track Metadata", Type = FieldType.Checkbox)]
|
||||||
public bool EpisodeMetadata { get; set; }
|
public bool TrackMetadata { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Artist Images", Type = FieldType.Checkbox)]
|
[FieldDefinition(1, Label = "Artist Images", Type = FieldType.Checkbox)]
|
||||||
public bool ArtistImages { get; set; }
|
public bool ArtistImages { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Album Images", Type = FieldType.Checkbox)]
|
[FieldDefinition(2, Label = "Album Images", Type = FieldType.Checkbox)]
|
||||||
public bool AlbumImages { get; set; }
|
public bool AlbumImages { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Episode Images", Type = FieldType.Checkbox)]
|
|
||||||
public bool EpisodeImages { get; set; }
|
|
||||||
|
|
||||||
public bool IsValid => true;
|
public bool IsValid => true;
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,8 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Regex ArtistImagesRegex = new Regex(@"^(?<type>poster|banner|fanart|logo)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex ArtistImagesRegex = new Regex(@"^(?<type>poster|banner|fanart|logo)\.(?:png|jpg|jpeg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
private static readonly Regex AlbumImagesRegex = new Regex(@"^season(?<season>\d{2,}|-all|-specials)-(?<type>poster|banner|fanart|cover)\.(?:png|jpg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex AlbumImagesRegex = new Regex(@"^(?<type>cover|disc)\.(?:png|jpg|jpeg)", 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 Name => "Kodi (XBMC) / Emby";
|
||||||
|
|
||||||
|
@ -37,14 +36,9 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
{
|
{
|
||||||
var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
var trackFilePath = Path.Combine(artist.Path, trackFile.RelativePath);
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.TrackImage)
|
|
||||||
{
|
|
||||||
return GetEpisodeImageFilename(trackFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.TrackMetadata)
|
if (metadataFile.Type == MetadataType.TrackMetadata)
|
||||||
{
|
{
|
||||||
return GetEpisodeMetadataFilename(trackFilePath);
|
return GetTrackMetadataFilename(trackFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Unknown episode file metadata: {0}", metadataFile.RelativePath);
|
_logger.Debug("Unknown episode file metadata: {0}", metadataFile.RelativePath);
|
||||||
|
@ -70,36 +64,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
var seasonMatch = AlbumImagesRegex.Match(filename);
|
var albumMatch = AlbumImagesRegex.Match(filename);
|
||||||
|
|
||||||
if (seasonMatch.Success)
|
if (albumMatch.Success)
|
||||||
{
|
{
|
||||||
metadata.Type = MetadataType.AlbumImage;
|
metadata.Type = MetadataType.AlbumImage;
|
||||||
|
|
||||||
var seasonNumberMatch = seasonMatch.Groups["season"].Value;
|
|
||||||
int seasonNumber;
|
|
||||||
|
|
||||||
if (seasonNumberMatch.Contains("specials"))
|
|
||||||
{
|
|
||||||
metadata.AlbumId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (int.TryParse(seasonNumberMatch, out seasonNumber))
|
|
||||||
{
|
|
||||||
metadata.AlbumId = seasonNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EpisodeImageRegex.IsMatch(filename))
|
|
||||||
{
|
|
||||||
metadata.Type = MetadataType.TrackImage;
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +155,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override MetadataFileResult AlbumMetadata(Artist artist, Album album)
|
public override MetadataFileResult AlbumMetadata(Artist artist, Album album, string albumPath)
|
||||||
{
|
{
|
||||||
if (!Settings.AlbumMetadata)
|
if (!Settings.AlbumMetadata)
|
||||||
{
|
{
|
||||||
|
@ -217,9 +186,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
var doc = new XDocument(albumElement);
|
var doc = new XDocument(albumElement);
|
||||||
doc.Save(xw);
|
doc.Save(xw);
|
||||||
|
|
||||||
_logger.Debug("Saving album.nfo for {0}", artist.Name);
|
_logger.Debug("Saving album.nfo for {0}", album.Title);
|
||||||
|
|
||||||
|
var fileName = Path.Combine(albumPath, "album.nfo");
|
||||||
|
|
||||||
return new MetadataFileResult("album.nfo", doc.ToString());
|
return new MetadataFileResult(fileName, doc.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +282,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MetadataFileResult(GetEpisodeMetadataFilename(trackFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
return new MetadataFileResult(GetTrackMetadataFilename(trackFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> ArtistImages(Artist artist)
|
public override List<ImageFileResult> ArtistImages(Artist artist)
|
||||||
|
@ -324,14 +295,14 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
return ProcessArtistImages(artist).ToList();
|
return ProcessArtistImages(artist).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> AlbumImages(Artist artist, Album album)
|
public override List<ImageFileResult> AlbumImages(Artist artist, Album album, string albumPath)
|
||||||
{
|
{
|
||||||
if (!Settings.AlbumImages)
|
if (!Settings.AlbumImages)
|
||||||
{
|
{
|
||||||
return new List<ImageFileResult>();
|
return new List<ImageFileResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessAlbumImages(album).ToList();
|
return ProcessAlbumImages(artist, album, albumPath).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile)
|
public override List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile)
|
||||||
|
@ -351,24 +322,21 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<ImageFileResult> ProcessAlbumImages(Album album)
|
private IEnumerable<ImageFileResult> ProcessAlbumImages(Artist artist, Album album, string albumPath)
|
||||||
{
|
{
|
||||||
foreach (var image in album.Images)
|
foreach (var image in album.Images)
|
||||||
{
|
{
|
||||||
var destination = image.CoverType.ToString().ToLowerInvariant() + Path.GetExtension(image.Url);
|
// TODO: Make Source fallback to URL if local does not exist
|
||||||
|
// var source = _mediaCoverService.GetCoverPath(album.ArtistId, image.CoverType, null, album.Id);
|
||||||
|
var destination = Path.Combine(albumPath, image.CoverType.ToString().ToLowerInvariant() + Path.GetExtension(image.Url));
|
||||||
|
|
||||||
yield return new ImageFileResult(destination, image.Url);
|
yield return new ImageFileResult(destination, image.Url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetEpisodeMetadataFilename(string episodeFilePath)
|
private string GetTrackMetadataFilename(string trackFilePath)
|
||||||
{
|
{
|
||||||
return Path.ChangeExtension(episodeFilePath, "nfo");
|
return Path.ChangeExtension(trackFilePath, "nfo");
|
||||||
}
|
|
||||||
|
|
||||||
private string GetEpisodeImageFilename(string episodeFilePath)
|
|
||||||
{
|
|
||||||
return Path.ChangeExtension(episodeFilePath, "").Trim('.') + "-thumb.jpg";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetAudioCodec(string audioCodec)
|
private string GetAudioCodec(string audioCodec)
|
||||||
|
|
|
@ -7,9 +7,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
{
|
{
|
||||||
public class XbmcSettingsValidator : AbstractValidator<XbmcMetadataSettings>
|
public class XbmcSettingsValidator : AbstractValidator<XbmcMetadataSettings>
|
||||||
{
|
{
|
||||||
public XbmcSettingsValidator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class XbmcMetadataSettings : IProviderConfig
|
public class XbmcMetadataSettings : IProviderConfig
|
||||||
|
@ -23,7 +20,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
TrackMetadata = true;
|
TrackMetadata = true;
|
||||||
ArtistImages = true;
|
ArtistImages = true;
|
||||||
AlbumImages = true;
|
AlbumImages = true;
|
||||||
EpisodeImages = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox)]
|
[FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox)]
|
||||||
|
@ -41,9 +37,6 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
|
||||||
[FieldDefinition(4, Label = "Album Images", Type = FieldType.Checkbox)]
|
[FieldDefinition(4, Label = "Album Images", Type = FieldType.Checkbox)]
|
||||||
public bool AlbumImages { get; set; }
|
public bool AlbumImages { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Episode Images", Type = FieldType.Checkbox)]
|
|
||||||
public bool EpisodeImages { get; set; }
|
|
||||||
|
|
||||||
public bool IsValid => true;
|
public bool IsValid => true;
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|
|
@ -57,8 +57,20 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata.Type == MetadataType.TrackImage ||
|
if (metadata.Type == MetadataType.AlbumImage || metadata.Type == MetadataType.AlbumMetadata)
|
||||||
metadata.Type == MetadataType.TrackMetadata)
|
{
|
||||||
|
var localAlbum = _parsingService.GetLocalAlbum(possibleMetadataFile, artist);
|
||||||
|
|
||||||
|
if (localAlbum == null)
|
||||||
|
{
|
||||||
|
_logger.Debug("Extra file folder has multiple Albums: {0}", possibleMetadataFile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata.AlbumId = localAlbum.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata.Type == MetadataType.TrackMetadata)
|
||||||
{
|
{
|
||||||
var localTrack = _parsingService.GetLocalTrack(possibleMetadataFile, artist);
|
var localTrack = _parsingService.GetLocalTrack(possibleMetadataFile, artist);
|
||||||
|
|
||||||
|
@ -70,7 +82,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
|
|
||||||
if (localTrack.Tracks.Empty())
|
if (localTrack.Tracks.Empty())
|
||||||
{
|
{
|
||||||
_logger.Debug("Cannot find related episodes for: {0}", possibleMetadataFile);
|
_logger.Debug("Cannot find related tracks for: {0}", possibleMetadataFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +91,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
_logger.Debug("Extra file: {0} does not match existing files.", possibleMetadataFile);
|
_logger.Debug("Extra file: {0} does not match existing files.", possibleMetadataFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.AlbumId = localTrack.Album.Id;
|
|
||||||
metadata.TrackFileId = localTrack.Tracks.First().TrackFileId;
|
metadata.TrackFileId = localTrack.Tracks.First().TrackFileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,13 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
public interface IMetadata : IProvider
|
public interface IMetadata : IProvider
|
||||||
{
|
{
|
||||||
string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile);
|
string GetFilenameAfterMove(Artist artist, TrackFile trackFile, MetadataFile metadataFile);
|
||||||
|
string GetFilenameAfterMove(Artist artist, string albumPath, MetadataFile metadataFile);
|
||||||
MetadataFile FindMetadataFile(Artist artist, string path);
|
MetadataFile FindMetadataFile(Artist artist, string path);
|
||||||
MetadataFileResult ArtistMetadata(Artist artist);
|
MetadataFileResult ArtistMetadata(Artist artist);
|
||||||
MetadataFileResult AlbumMetadata(Artist artist, Album album);
|
MetadataFileResult AlbumMetadata(Artist artist, Album album, string albumPath);
|
||||||
MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile);
|
MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile);
|
||||||
List<ImageFileResult> ArtistImages(Artist artist);
|
List<ImageFileResult> ArtistImages(Artist artist);
|
||||||
List<ImageFileResult> AlbumImages(Artist artist, Album album);
|
List<ImageFileResult> AlbumImages(Artist artist, Album album, string albumPath);
|
||||||
List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile);
|
List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,21 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
return newFileName;
|
return newFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual string GetFilenameAfterMove(Artist artist, string albumPath, MetadataFile metadataFile)
|
||||||
|
{
|
||||||
|
var existingFilename = Path.GetFileName(metadataFile.RelativePath);
|
||||||
|
var newFileName = Path.Combine(artist.Path, albumPath, existingFilename);
|
||||||
|
|
||||||
|
return newFileName;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract MetadataFile FindMetadataFile(Artist artist, string path);
|
public abstract MetadataFile FindMetadataFile(Artist artist, string path);
|
||||||
|
|
||||||
public abstract MetadataFileResult ArtistMetadata(Artist artist);
|
public abstract MetadataFileResult ArtistMetadata(Artist artist);
|
||||||
public abstract MetadataFileResult AlbumMetadata(Artist artist, Album album);
|
public abstract MetadataFileResult AlbumMetadata(Artist artist, Album album, string albumPath);
|
||||||
public abstract MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile);
|
public abstract MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile);
|
||||||
public abstract List<ImageFileResult> ArtistImages(Artist artist);
|
public abstract List<ImageFileResult> ArtistImages(Artist artist);
|
||||||
public abstract List<ImageFileResult> AlbumImages(Artist artist, Album album);
|
public abstract List<ImageFileResult> AlbumImages(Artist artist, Album album, string albumPath);
|
||||||
public abstract List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile);
|
public abstract List<ImageFileResult> TrackImages(Artist artist, TrackFile trackFile);
|
||||||
|
|
||||||
public virtual object RequestAction(string action, IDictionary<string, string> query) { return null; }
|
public virtual object RequestAction(string action, IDictionary<string, string> query) { return null; }
|
||||||
|
|
|
@ -12,6 +12,7 @@ using NzbDrone.Core.Extras.Files;
|
||||||
using NzbDrone.Core.Extras.Metadata.Files;
|
using NzbDrone.Core.Extras.Metadata.Files;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Extras.Metadata
|
namespace NzbDrone.Core.Extras.Metadata
|
||||||
{
|
{
|
||||||
|
@ -52,7 +53,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
|
|
||||||
public override int Order => 0;
|
public override int Order => 0;
|
||||||
|
|
||||||
public override IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<Album> albums, List<TrackFile> trackFiles)
|
public override IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<TrackFile> trackFiles)
|
||||||
{
|
{
|
||||||
var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id);
|
var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id);
|
||||||
_cleanMetadataService.Clean(artist);
|
_cleanMetadataService.Clean(artist);
|
||||||
|
@ -71,18 +72,20 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
|
|
||||||
files.AddIfNotNull(ProcessArtistMetadata(consumer, artist, consumerFiles));
|
files.AddIfNotNull(ProcessArtistMetadata(consumer, artist, consumerFiles));
|
||||||
files.AddRange(ProcessArtistImages(consumer, artist, consumerFiles));
|
files.AddRange(ProcessArtistImages(consumer, artist, consumerFiles));
|
||||||
files.AddRange(ProcessAlbumImages(consumer, artist, consumerFiles));
|
|
||||||
|
var albumGroups = trackFiles.GroupBy(s => Path.GetDirectoryName(s.RelativePath)).ToList();
|
||||||
|
|
||||||
foreach (var album in albums)
|
foreach (var group in albumGroups)
|
||||||
{
|
{
|
||||||
album.Artist = artist;
|
var album = _albumService.GetAlbum(group.First().AlbumId);
|
||||||
files.AddIfNotNull(ProcessAlbumMetadata(consumer, album, consumerFiles));
|
var albumFolder = group.Key;
|
||||||
}
|
files.AddIfNotNull(ProcessAlbumMetadata(consumer, artist, album, albumFolder, consumerFiles));
|
||||||
|
files.AddRange(ProcessAlbumImages(consumer, artist, album, albumFolder, consumerFiles));
|
||||||
|
|
||||||
foreach (var trackFile in trackFiles)
|
foreach (var trackFile in group)
|
||||||
{
|
{
|
||||||
files.AddIfNotNull(ProcessEpisodeMetadata(consumer, artist, trackFile, consumerFiles));
|
files.AddIfNotNull(ProcessTrackMetadata(consumer, artist, trackFile, consumerFiles));
|
||||||
files.AddRange(ProcessEpisodeImages(consumer, artist, trackFile, consumerFiles));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,9 +100,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
|
|
||||||
foreach (var consumer in _metadataFactory.Enabled())
|
foreach (var consumer in _metadataFactory.Enabled())
|
||||||
{
|
{
|
||||||
|
files.AddIfNotNull(ProcessTrackMetadata(consumer, artist, trackFile, new List<MetadataFile>()));
|
||||||
files.AddIfNotNull(ProcessEpisodeMetadata(consumer, artist, trackFile, new List<MetadataFile>()));
|
|
||||||
files.AddRange(ProcessEpisodeImages(consumer, artist, trackFile, new List<MetadataFile>()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_metadataFileService.Upsert(files);
|
_metadataFileService.Upsert(files);
|
||||||
|
@ -107,7 +108,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder)
|
public override IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, Album album, string artistFolder, string albumFolder)
|
||||||
{
|
{
|
||||||
var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id);
|
var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id);
|
||||||
|
|
||||||
|
@ -127,11 +128,6 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
files.AddIfNotNull(ProcessArtistMetadata(consumer, artist, consumerFiles));
|
files.AddIfNotNull(ProcessArtistMetadata(consumer, artist, consumerFiles));
|
||||||
files.AddRange(ProcessArtistImages(consumer, artist, consumerFiles));
|
files.AddRange(ProcessArtistImages(consumer, artist, consumerFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (albumFolder.IsNotNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
files.AddRange(ProcessAlbumImages(consumer, artist, consumerFiles));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_metadataFileService.Upsert(files);
|
_metadataFileService.Upsert(files);
|
||||||
|
@ -143,12 +139,42 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
{
|
{
|
||||||
var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id);
|
var metadataFiles = _metadataFileService.GetFilesByArtist(artist.Id);
|
||||||
var movedFiles = new List<MetadataFile>();
|
var movedFiles = new List<MetadataFile>();
|
||||||
|
var distinctTrackFilePaths = trackFiles.DistinctBy(s => Path.GetDirectoryName(s.RelativePath)).ToList();
|
||||||
|
|
||||||
// TODO: Move EpisodeImage and EpisodeMetadata metadata files, instead of relying on consumers to do it
|
// TODO: Move EpisodeImage and EpisodeMetadata metadata files, instead of relying on consumers to do it
|
||||||
// (Xbmc's EpisodeImage is more than just the extension)
|
// (Xbmc's EpisodeImage is more than just the extension)
|
||||||
|
|
||||||
foreach (var consumer in _metadataFactory.GetAvailableProviders())
|
foreach (var consumer in _metadataFactory.GetAvailableProviders())
|
||||||
{
|
{
|
||||||
|
foreach (var filePath in distinctTrackFilePaths)
|
||||||
|
{
|
||||||
|
var metadataFilesForConsumer = GetMetadataFilesForConsumer(consumer, metadataFiles)
|
||||||
|
.Where(m => m.AlbumId == filePath.AlbumId)
|
||||||
|
.Where(m => m.Type == MetadataType.AlbumImage || m.Type == MetadataType.AlbumMetadata)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var metadataFile in metadataFilesForConsumer)
|
||||||
|
{
|
||||||
|
var newFileName = consumer.GetFilenameAfterMove(artist, Path.GetDirectoryName(filePath.RelativePath), metadataFile);
|
||||||
|
var existingFileName = Path.Combine(artist.Path, metadataFile.RelativePath);
|
||||||
|
|
||||||
|
if (newFileName.PathNotEquals(existingFileName))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_diskProvider.MoveFile(existingFileName, newFileName);
|
||||||
|
metadataFile.RelativePath = artist.Path.GetRelativePath(newFileName);
|
||||||
|
movedFiles.Add(metadataFile);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Unable to move metadata file after rename: {0}", existingFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach (var trackFile in trackFiles)
|
foreach (var trackFile in trackFiles)
|
||||||
{
|
{
|
||||||
var metadataFilesForConsumer = GetMetadataFilesForConsumer(consumer, metadataFiles).Where(m => m.TrackFileId == trackFile.Id).ToList();
|
var metadataFilesForConsumer = GetMetadataFilesForConsumer(consumer, metadataFiles).Where(m => m.TrackFileId == trackFile.Id).ToList();
|
||||||
|
@ -233,9 +259,9 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MetadataFile ProcessAlbumMetadata(IMetadata consumer, Album album, List<MetadataFile> existingMetadataFiles)
|
private MetadataFile ProcessAlbumMetadata(IMetadata consumer, Artist artist, Album album, string albumPath, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
var albumMetadata = consumer.AlbumMetadata(album.Artist, album);
|
var albumMetadata = consumer.AlbumMetadata(artist, album, albumPath);
|
||||||
|
|
||||||
if (albumMetadata == null)
|
if (albumMetadata == null)
|
||||||
{
|
{
|
||||||
|
@ -244,10 +270,10 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
|
|
||||||
var hash = albumMetadata.Contents.SHA256Hash();
|
var hash = albumMetadata.Contents.SHA256Hash();
|
||||||
|
|
||||||
var metadata = GetMetadataFile(album.Artist, existingMetadataFiles, e => e.Type == MetadataType.AlbumMetadata && e.AlbumId == album.Id) ??
|
var metadata = GetMetadataFile(artist, existingMetadataFiles, e => e.Type == MetadataType.AlbumMetadata && e.AlbumId == album.Id) ??
|
||||||
new MetadataFile
|
new MetadataFile
|
||||||
{
|
{
|
||||||
ArtistId = album.ArtistId,
|
ArtistId = artist.Id,
|
||||||
AlbumId = album.Id,
|
AlbumId = album.Id,
|
||||||
Consumer = consumer.GetType().Name,
|
Consumer = consumer.GetType().Name,
|
||||||
Type = MetadataType.AlbumMetadata
|
Type = MetadataType.AlbumMetadata
|
||||||
|
@ -265,7 +291,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullPath = Path.Combine(album.Path, albumMetadata.RelativePath);
|
var fullPath = Path.Combine(artist.Path, albumMetadata.RelativePath);
|
||||||
|
|
||||||
_logger.Debug("Writing Album Metadata to: {0}", fullPath);
|
_logger.Debug("Writing Album Metadata to: {0}", fullPath);
|
||||||
SaveMetadataFile(fullPath, albumMetadata.Contents);
|
SaveMetadataFile(fullPath, albumMetadata.Contents);
|
||||||
|
@ -277,16 +303,16 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MetadataFile ProcessEpisodeMetadata(IMetadata consumer, Artist artist, TrackFile trackFile, List<MetadataFile> existingMetadataFiles)
|
private MetadataFile ProcessTrackMetadata(IMetadata consumer, Artist artist, TrackFile trackFile, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
var episodeMetadata = consumer.TrackMetadata(artist, trackFile);
|
var trackMetadata = consumer.TrackMetadata(artist, trackFile);
|
||||||
|
|
||||||
if (episodeMetadata == null)
|
if (trackMetadata == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullPath = Path.Combine(artist.Path, episodeMetadata.RelativePath);
|
var fullPath = Path.Combine(artist.Path, trackMetadata.RelativePath);
|
||||||
|
|
||||||
var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackMetadata &&
|
var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackMetadata &&
|
||||||
c.TrackFileId == trackFile.Id);
|
c.TrackFileId == trackFile.Id);
|
||||||
|
@ -297,11 +323,11 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
if (fullPath.PathNotEquals(existingFullPath))
|
if (fullPath.PathNotEquals(existingFullPath))
|
||||||
{
|
{
|
||||||
_diskTransferService.TransferFile(existingFullPath, fullPath, TransferMode.Move);
|
_diskTransferService.TransferFile(existingFullPath, fullPath, TransferMode.Move);
|
||||||
existingMetadata.RelativePath = episodeMetadata.RelativePath;
|
existingMetadata.RelativePath = trackMetadata.RelativePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash = episodeMetadata.Contents.SHA256Hash();
|
var hash = trackMetadata.Contents.SHA256Hash();
|
||||||
|
|
||||||
var metadata = existingMetadata ??
|
var metadata = existingMetadata ??
|
||||||
new MetadataFile
|
new MetadataFile
|
||||||
|
@ -311,7 +337,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
TrackFileId = trackFile.Id,
|
TrackFileId = trackFile.Id,
|
||||||
Consumer = consumer.GetType().Name,
|
Consumer = consumer.GetType().Name,
|
||||||
Type = MetadataType.TrackMetadata,
|
Type = MetadataType.TrackMetadata,
|
||||||
RelativePath = episodeMetadata.RelativePath,
|
RelativePath = trackMetadata.RelativePath,
|
||||||
Extension = Path.GetExtension(fullPath)
|
Extension = Path.GetExtension(fullPath)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -321,7 +347,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Writing Track Metadata to: {0}", fullPath);
|
_logger.Debug("Writing Track Metadata to: {0}", fullPath);
|
||||||
SaveMetadataFile(fullPath, episodeMetadata.Contents);
|
SaveMetadataFile(fullPath, trackMetadata.Contents);
|
||||||
|
|
||||||
metadata.Hash = hash;
|
metadata.Hash = hash;
|
||||||
|
|
||||||
|
@ -361,92 +387,39 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MetadataFile> ProcessAlbumImages(IMetadata consumer, Artist artist, List<MetadataFile> existingMetadataFiles)
|
private List<MetadataFile> ProcessAlbumImages(IMetadata consumer, Artist artist, Album album, string albumFolder, List<MetadataFile> existingMetadataFiles)
|
||||||
{
|
{
|
||||||
var result = new List<MetadataFile>();
|
var result = new List<MetadataFile>();
|
||||||
|
|
||||||
var albums = _albumService.GetAlbumsByArtist(artist.Id);
|
foreach (var image in consumer.AlbumImages(artist, album, albumFolder))
|
||||||
|
|
||||||
foreach (var album in albums)
|
|
||||||
{
|
|
||||||
foreach (var image in consumer.AlbumImages(artist, album))
|
|
||||||
{
|
|
||||||
var fullPath = Path.Combine(artist.Path, image.RelativePath);
|
|
||||||
|
|
||||||
if (_diskProvider.FileExists(fullPath))
|
|
||||||
{
|
|
||||||
_logger.Debug("Album image already exists: {0}", fullPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.AlbumImage &&
|
|
||||||
c.AlbumId == album.Id &&
|
|
||||||
c.RelativePath == image.RelativePath) ??
|
|
||||||
new MetadataFile
|
|
||||||
{
|
|
||||||
ArtistId = artist.Id,
|
|
||||||
AlbumId = album.Id,
|
|
||||||
Consumer = consumer.GetType().Name,
|
|
||||||
Type = MetadataType.AlbumImage,
|
|
||||||
RelativePath = image.RelativePath,
|
|
||||||
Extension = Path.GetExtension(fullPath)
|
|
||||||
};
|
|
||||||
|
|
||||||
DownloadImage(album, image);
|
|
||||||
|
|
||||||
result.Add(metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<MetadataFile> ProcessEpisodeImages(IMetadata consumer, Artist artist, TrackFile trackFile, List<MetadataFile> existingMetadataFiles)
|
|
||||||
{
|
|
||||||
var result = new List<MetadataFile>();
|
|
||||||
|
|
||||||
foreach (var image in consumer.TrackImages(artist, trackFile))
|
|
||||||
{
|
{
|
||||||
var fullPath = Path.Combine(artist.Path, image.RelativePath);
|
var fullPath = Path.Combine(artist.Path, image.RelativePath);
|
||||||
|
|
||||||
if (_diskProvider.FileExists(fullPath))
|
if (_diskProvider.FileExists(fullPath))
|
||||||
{
|
{
|
||||||
_logger.Debug("Track image already exists: {0}", fullPath);
|
_logger.Debug("Album image already exists: {0}", fullPath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackImage &&
|
var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.AlbumImage &&
|
||||||
c.TrackFileId == trackFile.Id);
|
c.AlbumId == album.Id &&
|
||||||
|
c.RelativePath == image.RelativePath) ??
|
||||||
if (existingMetadata != null)
|
new MetadataFile
|
||||||
{
|
{
|
||||||
var existingFullPath = Path.Combine(artist.Path, existingMetadata.RelativePath);
|
ArtistId = artist.Id,
|
||||||
if (fullPath.PathNotEquals(existingFullPath))
|
AlbumId = album.Id,
|
||||||
{
|
Consumer = consumer.GetType().Name,
|
||||||
_diskTransferService.TransferFile(existingFullPath, fullPath, TransferMode.Move);
|
Type = MetadataType.AlbumImage,
|
||||||
existingMetadata.RelativePath = image.RelativePath;
|
RelativePath = image.RelativePath,
|
||||||
|
Extension = Path.GetExtension(fullPath)
|
||||||
return new List<MetadataFile>{ existingMetadata };
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var metadata = existingMetadata ??
|
|
||||||
new MetadataFile
|
|
||||||
{
|
|
||||||
ArtistId = artist.Id,
|
|
||||||
AlbumId = trackFile.AlbumId,
|
|
||||||
TrackFileId = trackFile.Id,
|
|
||||||
Consumer = consumer.GetType().Name,
|
|
||||||
Type = MetadataType.TrackImage,
|
|
||||||
RelativePath = image.RelativePath,
|
|
||||||
Extension = Path.GetExtension(fullPath)
|
|
||||||
};
|
|
||||||
|
|
||||||
DownloadImage(artist, image);
|
DownloadImage(artist, image);
|
||||||
|
|
||||||
result.Add(metadata);
|
result.Add(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,32 +449,6 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DownloadImage(Album album, ImageFileResult image)
|
|
||||||
{
|
|
||||||
var fullPath = Path.Combine(album.Path, image.RelativePath);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (image.Url.StartsWith("http"))
|
|
||||||
{
|
|
||||||
_httpClient.DownloadFile(image.Url, fullPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_diskProvider.CopyFile(image.Url, fullPath);
|
|
||||||
}
|
|
||||||
_mediaFileAttributeService.SetFilePermissions(fullPath);
|
|
||||||
}
|
|
||||||
catch (WebException ex)
|
|
||||||
{
|
|
||||||
_logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, album, ex.Message);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, album, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveMetadataFile(string path, string contents)
|
private void SaveMetadataFile(string path, string contents)
|
||||||
{
|
{
|
||||||
_diskProvider.WriteAllText(path, contents);
|
_diskProvider.WriteAllText(path, contents);
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Extras.Others
|
||||||
|
|
||||||
public override int Order => 2;
|
public override int Order => 2;
|
||||||
|
|
||||||
public override IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<Album> albums, List<TrackFile> trackFiles)
|
public override IEnumerable<ExtraFile> CreateAfterArtistScan(Artist artist, List<TrackFile> trackFiles)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<ExtraFile>();
|
return Enumerable.Empty<ExtraFile>();
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ namespace NzbDrone.Core.Extras.Others
|
||||||
return Enumerable.Empty<ExtraFile>();
|
return Enumerable.Empty<ExtraFile>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, string artistFolder, string albumFolder)
|
public override IEnumerable<ExtraFile> CreateAfterTrackImport(Artist artist, Album album, string artistFolder, string albumFolder)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<ExtraFile>();
|
return Enumerable.Empty<ExtraFile>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
public void Clean()
|
public void Clean()
|
||||||
{
|
{
|
||||||
DeleteDuplicateArtistMetadata();
|
DeleteDuplicateArtistMetadata();
|
||||||
|
DeleteDuplicateAlbumMetadata();
|
||||||
DeleteDuplicateTrackMetadata();
|
DeleteDuplicateTrackMetadata();
|
||||||
DeleteDuplicateTrackImages();
|
DeleteDuplicateTrackImages();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
DeleteOrphanedByArtist();
|
DeleteOrphanedByArtist();
|
||||||
DeleteOrphanedByAlbum();
|
DeleteOrphanedByAlbum();
|
||||||
DeleteOrphanedByTrackFile();
|
DeleteOrphanedByTrackFile();
|
||||||
|
DeleteWhereAlbumIdIsZero();
|
||||||
DeleteWhereTrackFileIsZero();
|
DeleteWhereTrackFileIsZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +58,17 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
AND TrackFiles.Id IS NULL)");
|
AND TrackFiles.Id IS NULL)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DeleteWhereAlbumIdIsZero()
|
||||||
|
{
|
||||||
|
var mapper = _database.GetDataMapper();
|
||||||
|
|
||||||
|
mapper.ExecuteNonQuery(@"DELETE FROM MetadataFiles
|
||||||
|
WHERE Id IN (
|
||||||
|
SELECT Id FROM MetadataFiles
|
||||||
|
WHERE Type IN (4, 6)
|
||||||
|
AND AlbumId = 0)");
|
||||||
|
}
|
||||||
|
|
||||||
private void DeleteWhereTrackFileIsZero()
|
private void DeleteWhereTrackFileIsZero()
|
||||||
{
|
{
|
||||||
var mapper = _database.GetDataMapper();
|
var mapper = _database.GetDataMapper();
|
||||||
|
|
|
@ -144,9 +144,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
if (renamed.Any())
|
if (renamed.Any())
|
||||||
{
|
{
|
||||||
_diskProvider.RemoveEmptySubfolders(artist.Path);
|
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new ArtistRenamedEvent(artist));
|
_eventAggregator.PublishEvent(new ArtistRenamedEvent(artist));
|
||||||
|
|
||||||
|
_logger.Debug("Removing Empty Subfolders from: {0}", artist.Path);
|
||||||
|
_diskProvider.RemoveEmptySubfolders(artist.Path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,6 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Music
|
namespace NzbDrone.Core.Music
|
||||||
{
|
{
|
||||||
|
@ -24,12 +22,9 @@ namespace NzbDrone.Core.Music
|
||||||
public string CleanTitle { get; set; }
|
public string CleanTitle { get; set; }
|
||||||
public DateTime? ReleaseDate { get; set; }
|
public DateTime? ReleaseDate { get; set; }
|
||||||
public List<string> Label { get; set; }
|
public List<string> Label { get; set; }
|
||||||
//public int TrackCount { get; set; }
|
|
||||||
public string Path { get; set; }
|
|
||||||
public int ProfileId { get; set; }
|
public int ProfileId { get; set; }
|
||||||
public int Duration { get; set; }
|
public int Duration { get; set; }
|
||||||
public List<Track> Tracks { get; set; }
|
public List<Track> Tracks { get; set; }
|
||||||
//public int DiscCount { get; set; }
|
|
||||||
public bool Monitored { get; set; }
|
public bool Monitored { get; set; }
|
||||||
public List<MediaCover.MediaCover> Images { get; set; }
|
public List<MediaCover.MediaCover> Images { get; set; }
|
||||||
public List<string> Genres { get; set; }
|
public List<string> Genres { get; set; }
|
||||||
|
|
|
@ -8,12 +8,12 @@ using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using Marr.Data.QGen;
|
using Marr.Data.QGen;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Music
|
namespace NzbDrone.Core.Music
|
||||||
{
|
{
|
||||||
public interface IAlbumRepository : IBasicRepository<Album>
|
public interface IAlbumRepository : IBasicRepository<Album>
|
||||||
{
|
{
|
||||||
bool AlbumPathExists(string path);
|
|
||||||
List<Album> GetAlbums(int artistId);
|
List<Album> GetAlbums(int artistId);
|
||||||
Album FindByName(string cleanTitle);
|
Album FindByName(string cleanTitle);
|
||||||
Album FindByTitle(int artistId, string title);
|
Album FindByTitle(int artistId, string title);
|
||||||
|
@ -37,11 +37,6 @@ namespace NzbDrone.Core.Music
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool AlbumPathExists(string path)
|
|
||||||
{
|
|
||||||
return Query.Where(c => c.Path == path).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Album> GetAlbums(int artistId)
|
public List<Album> GetAlbums(int artistId)
|
||||||
{
|
{
|
||||||
return Query.Where(s => s.ArtistId == artistId).ToList();
|
return Query.Where(s => s.ArtistId == artistId).ToList();
|
||||||
|
|
|
@ -33,7 +33,6 @@ namespace NzbDrone.Core.Music
|
||||||
void InsertMany(List<Album> albums);
|
void InsertMany(List<Album> albums);
|
||||||
void UpdateMany(List<Album> albums);
|
void UpdateMany(List<Album> albums);
|
||||||
void DeleteMany(List<Album> albums);
|
void DeleteMany(List<Album> albums);
|
||||||
bool AlbumPathExists(string folder);
|
|
||||||
void RemoveAddOptions(Album album);
|
void RemoveAddOptions(Album album);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,11 +66,6 @@ namespace NzbDrone.Core.Music
|
||||||
return newAlbum;
|
return newAlbum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AlbumPathExists(string folder)
|
|
||||||
{
|
|
||||||
return _albumRepository.AlbumPathExists(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteAlbum(int albumId, bool deleteFiles)
|
public void DeleteAlbum(int albumId, bool deleteFiles)
|
||||||
{
|
{
|
||||||
var album = _albumRepository.Get(albumId);
|
var album = _albumRepository.Get(albumId);
|
||||||
|
@ -89,7 +83,6 @@ namespace NzbDrone.Core.Music
|
||||||
return _albumRepository.FindByTitle(artistId, title);
|
return _albumRepository.FindByTitle(artistId, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Album FindByTitleInexact(string title)
|
public Album FindByTitleInexact(string title)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -62,11 +62,6 @@ namespace NzbDrone.Core.Music
|
||||||
albumToUpdate.ProfileId = artist.ProfileId;
|
albumToUpdate.ProfileId = artist.ProfileId;
|
||||||
albumToUpdate.Added = DateTime.UtcNow;
|
albumToUpdate.Added = DateTime.UtcNow;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(albumToUpdate.Path))
|
|
||||||
{
|
|
||||||
albumToUpdate.Path = _fileNameBuilder.BuildAlbumPath(artist, album);
|
|
||||||
}
|
|
||||||
|
|
||||||
newList.Add(albumToUpdate);
|
newList.Add(albumToUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@
|
||||||
<Compile Include="Datastore\Migration\004_add_various_qualities_in_profile.cs" />
|
<Compile Include="Datastore\Migration\004_add_various_qualities_in_profile.cs" />
|
||||||
<Compile Include="Datastore\Migration\003_add_medium_support.cs" />
|
<Compile Include="Datastore\Migration\003_add_medium_support.cs" />
|
||||||
<Compile Include="Datastore\Migration\006_separate_automatic_and_interactive_search.cs" />
|
<Compile Include="Datastore\Migration\006_separate_automatic_and_interactive_search.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\007_change_album_path_to_relative.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" />
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace NzbDrone.Core.Parser
|
||||||
List<Album> GetAlbums(ParsedAlbumInfo parsedAlbumInfo, Artist artist, SearchCriteriaBase searchCriteria = null);
|
List<Album> GetAlbums(ParsedAlbumInfo parsedAlbumInfo, Artist artist, SearchCriteriaBase searchCriteria = null);
|
||||||
|
|
||||||
// Music stuff here
|
// Music stuff here
|
||||||
|
Album GetLocalAlbum(string filename, Artist artist);
|
||||||
LocalTrack GetLocalTrack(string filename, Artist artist);
|
LocalTrack GetLocalTrack(string filename, Artist artist);
|
||||||
LocalTrack GetLocalTrack(string filename, Artist artist, ParsedTrackInfo folderInfo);
|
LocalTrack GetLocalTrack(string filename, Artist artist, ParsedTrackInfo folderInfo);
|
||||||
|
|
||||||
|
@ -30,11 +31,13 @@ namespace NzbDrone.Core.Parser
|
||||||
private readonly IArtistService _artistService;
|
private readonly IArtistService _artistService;
|
||||||
private readonly IAlbumService _albumService;
|
private readonly IAlbumService _albumService;
|
||||||
private readonly ITrackService _trackService;
|
private readonly ITrackService _trackService;
|
||||||
|
private readonly IMediaFileService _mediaFileService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ParsingService(ITrackService trackService,
|
public ParsingService(ITrackService trackService,
|
||||||
IArtistService artistService,
|
IArtistService artistService,
|
||||||
IAlbumService albumService,
|
IAlbumService albumService,
|
||||||
|
IMediaFileService mediaFileService,
|
||||||
// ISceneMappingService sceneMappingService,
|
// ISceneMappingService sceneMappingService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
|
@ -42,6 +45,7 @@ namespace NzbDrone.Core.Parser
|
||||||
_artistService = artistService;
|
_artistService = artistService;
|
||||||
// _sceneMappingService = sceneMappingService;
|
// _sceneMappingService = sceneMappingService;
|
||||||
_trackService = trackService;
|
_trackService = trackService;
|
||||||
|
_mediaFileService = mediaFileService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +178,24 @@ namespace NzbDrone.Core.Parser
|
||||||
return artist;
|
return artist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Album GetLocalAlbum(string filename, Artist artist)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Path.HasExtension(filename))
|
||||||
|
{
|
||||||
|
filename = Path.GetDirectoryName(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = artist.Path.GetRelativePath(filename);
|
||||||
|
|
||||||
|
var tracksInAlbum = _mediaFileService.GetFilesByArtist(artist.Id)
|
||||||
|
.FindAll(s => Path.GetDirectoryName(s.RelativePath) == filename)
|
||||||
|
.DistinctBy(s => s.AlbumId)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return tracksInAlbum.Count == 1 ? _albumService.GetAlbum(tracksInAlbum.First().AlbumId) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public LocalTrack GetLocalTrack(string filename, Artist artist)
|
public LocalTrack GetLocalTrack(string filename, Artist artist)
|
||||||
{
|
{
|
||||||
return GetLocalTrack(filename, artist, null);
|
return GetLocalTrack(filename, artist, null);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue