2017-09-24 19:44:25 +00:00
|
|
|
using NLog;
|
2017-05-07 16:58:24 +00:00
|
|
|
using NzbDrone.Common.Extensions;
|
2019-03-15 12:10:45 +00:00
|
|
|
using NzbDrone.Core.MediaFiles;
|
2017-05-07 16:58:24 +00:00
|
|
|
using NzbDrone.Core.Messaging.Events;
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Music
|
|
|
|
{
|
|
|
|
public interface IRefreshTrackService
|
|
|
|
{
|
2019-03-15 12:10:45 +00:00
|
|
|
void RefreshTrackInfo(Album rg, bool forceUpdateFileTags);
|
2017-05-07 16:58:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public class RefreshTrackService : IRefreshTrackService
|
|
|
|
{
|
|
|
|
private readonly ITrackService _trackService;
|
2017-07-03 18:39:06 +00:00
|
|
|
private readonly IAlbumService _albumService;
|
2019-03-15 12:10:45 +00:00
|
|
|
private readonly IMediaFileService _mediaFileService;
|
|
|
|
private readonly IAudioTagService _audioTagService;
|
2017-05-07 16:58:24 +00:00
|
|
|
private readonly IEventAggregator _eventAggregator;
|
|
|
|
private readonly Logger _logger;
|
|
|
|
|
2019-03-15 12:10:45 +00:00
|
|
|
public RefreshTrackService(ITrackService trackService,
|
|
|
|
IAlbumService albumService,
|
|
|
|
IMediaFileService mediaFileService,
|
|
|
|
IAudioTagService audioTagService,
|
|
|
|
IEventAggregator eventAggregator,
|
|
|
|
Logger logger)
|
2017-05-07 16:58:24 +00:00
|
|
|
{
|
|
|
|
_trackService = trackService;
|
2017-07-03 18:39:06 +00:00
|
|
|
_albumService = albumService;
|
2019-03-15 12:10:45 +00:00
|
|
|
_mediaFileService = mediaFileService;
|
|
|
|
_audioTagService = audioTagService;
|
2017-05-07 16:58:24 +00:00
|
|
|
_eventAggregator = eventAggregator;
|
|
|
|
_logger = logger;
|
|
|
|
}
|
|
|
|
|
2019-03-15 12:10:45 +00:00
|
|
|
public void RefreshTrackInfo(Album album, bool forceUpdateFileTags)
|
2017-05-07 16:58:24 +00:00
|
|
|
{
|
2017-06-18 02:27:01 +00:00
|
|
|
_logger.Info("Starting track info refresh for: {0}", album);
|
2017-05-07 16:58:24 +00:00
|
|
|
var successCount = 0;
|
|
|
|
var failCount = 0;
|
|
|
|
|
2018-12-15 00:02:43 +00:00
|
|
|
foreach (var release in album.AlbumReleases.Value)
|
|
|
|
{
|
2019-03-15 12:10:45 +00:00
|
|
|
var remoteTracks = release.Tracks.Value.DistinctBy(m => m.ForeignTrackId).ToList();
|
|
|
|
var existingTracks = _trackService.GetTracksForRefresh(release.Id, remoteTracks.Select(x => x.ForeignTrackId));
|
2017-05-07 16:58:24 +00:00
|
|
|
|
2018-12-15 00:02:43 +00:00
|
|
|
var updateList = new List<Track>();
|
|
|
|
var newList = new List<Track>();
|
2019-03-15 12:10:45 +00:00
|
|
|
var upToDateList = new List<Track>();
|
2017-05-07 16:58:24 +00:00
|
|
|
|
2019-03-15 12:10:45 +00:00
|
|
|
foreach (var track in remoteTracks)
|
2017-05-07 16:58:24 +00:00
|
|
|
{
|
2019-03-15 12:10:45 +00:00
|
|
|
track.AlbumRelease = release;
|
|
|
|
track.AlbumReleaseId = release.Id;
|
|
|
|
// the artist metadata will have been inserted by RefreshAlbumInfo so the Id will now be populated
|
|
|
|
track.ArtistMetadataId = track.ArtistMetadata.Value.Id;
|
|
|
|
|
2018-12-15 00:02:43 +00:00
|
|
|
try
|
2017-05-07 16:58:24 +00:00
|
|
|
{
|
2019-03-15 12:10:45 +00:00
|
|
|
var trackToUpdate = existingTracks.SingleOrDefault(e => e.ForeignTrackId == track.ForeignTrackId);
|
2018-12-15 00:02:43 +00:00
|
|
|
if (trackToUpdate != null)
|
|
|
|
{
|
|
|
|
existingTracks.Remove(trackToUpdate);
|
2019-03-15 12:10:45 +00:00
|
|
|
|
|
|
|
// populate albumrelease for later
|
|
|
|
trackToUpdate.AlbumRelease = release;
|
|
|
|
|
|
|
|
// copy across the db keys to the remote track and check if we need to update
|
|
|
|
track.Id = trackToUpdate.Id;
|
|
|
|
track.TrackFileId = trackToUpdate.TrackFileId;
|
|
|
|
// make sure title is not null
|
|
|
|
track.Title = track.Title ?? "Unknown";
|
|
|
|
|
|
|
|
if (!trackToUpdate.Equals(track))
|
|
|
|
{
|
|
|
|
updateList.Add(track);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
upToDateList.Add(track);
|
|
|
|
}
|
2018-12-15 00:02:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-15 12:10:45 +00:00
|
|
|
newList.Add(track);
|
2018-12-15 00:02:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
successCount++;
|
2017-05-07 16:58:24 +00:00
|
|
|
}
|
2018-12-15 00:02:43 +00:00
|
|
|
catch (Exception e)
|
2017-05-07 16:58:24 +00:00
|
|
|
{
|
2018-12-15 00:02:43 +00:00
|
|
|
_logger.Fatal(e, "An error has occurred while updating track info for album {0}. {1}", album, track);
|
|
|
|
failCount++;
|
2017-05-07 16:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-15 12:10:45 +00:00
|
|
|
// if any tracks with files are deleted, strip out the MB tags from the metadata
|
|
|
|
// so that we stand a chance of matching next time
|
|
|
|
_audioTagService.RemoveMusicBrainzTags(existingTracks);
|
|
|
|
|
|
|
|
var tagsToUpdate = updateList;
|
|
|
|
if (forceUpdateFileTags)
|
|
|
|
{
|
|
|
|
_logger.Debug("Forcing tag update due to Artist/Album/Release updates");
|
|
|
|
tagsToUpdate = updateList.Concat(upToDateList).ToList();
|
|
|
|
}
|
|
|
|
_audioTagService.SyncTags(tagsToUpdate);
|
|
|
|
|
|
|
|
_logger.Debug($"{release}: {upToDateList.Count} tracks up to date; Deleting {existingTracks.Count}, Updating {updateList.Count}, Adding {newList.Count} tracks.");
|
2019-01-12 16:56:13 +00:00
|
|
|
|
2018-12-15 00:02:43 +00:00
|
|
|
_trackService.DeleteMany(existingTracks);
|
|
|
|
_trackService.UpdateMany(updateList);
|
|
|
|
_trackService.InsertMany(newList);
|
|
|
|
}
|
2017-05-07 16:58:24 +00:00
|
|
|
|
|
|
|
if (failCount != 0)
|
|
|
|
{
|
2017-06-18 02:27:01 +00:00
|
|
|
_logger.Info("Finished track refresh for album: {0}. Successful: {1} - Failed: {2} ",
|
|
|
|
album.Title, successCount, failCount);
|
2017-05-07 16:58:24 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-18 02:27:01 +00:00
|
|
|
_logger.Info("Finished track refresh for album: {0}.", album);
|
2017-05-07 16:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|