You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationServ...

199 lines
7.0 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Blocklisting;
using NzbDrone.Core.History;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Music;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
{
public interface ICustomFormatCalculationService
{
List<CustomFormat> ParseCustomFormat(RemoteAlbum remoteAlbum, long size);
List<CustomFormat> ParseCustomFormat(TrackFile trackFile, Artist artist);
List<CustomFormat> ParseCustomFormat(TrackFile trackFile);
List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Artist artist);
List<CustomFormat> ParseCustomFormat(EntityHistory history, Artist artist);
List<CustomFormat> ParseCustomFormat(LocalTrack localTrack);
}
public class CustomFormatCalculationService : ICustomFormatCalculationService
{
private readonly ICustomFormatService _formatService;
private readonly Logger _logger;
public CustomFormatCalculationService(ICustomFormatService formatService, Logger logger)
{
_formatService = formatService;
_logger = logger;
}
public List<CustomFormat> ParseCustomFormat(RemoteAlbum remoteAlbum, long size)
{
var input = new CustomFormatInput
{
AlbumInfo = remoteAlbum.ParsedAlbumInfo,
Artist = remoteAlbum.Artist,
Size = size,
IndexerFlags = remoteAlbum.Release?.IndexerFlags ?? 0
};
return ParseCustomFormat(input);
}
public List<CustomFormat> ParseCustomFormat(TrackFile trackFile, Artist artist)
{
return ParseCustomFormat(trackFile, artist, _formatService.All());
}
public List<CustomFormat> ParseCustomFormat(TrackFile trackFile)
{
return ParseCustomFormat(trackFile, trackFile.Artist.Value, _formatService.All());
}
public List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Artist artist)
{
var parsed = Parser.Parser.ParseAlbumTitle(blocklist.SourceTitle);
var albumInfo = new ParsedAlbumInfo
{
ArtistName = artist.Name,
ReleaseTitle = parsed?.ReleaseTitle ?? blocklist.SourceTitle,
Quality = blocklist.Quality,
ReleaseGroup = parsed?.ReleaseGroup
};
var input = new CustomFormatInput
{
AlbumInfo = albumInfo,
Artist = artist,
Size = blocklist.Size ?? 0,
IndexerFlags = blocklist.IndexerFlags
};
return ParseCustomFormat(input);
}
public List<CustomFormat> ParseCustomFormat(EntityHistory history, Artist artist)
{
var parsed = Parser.Parser.ParseAlbumTitle(history.SourceTitle);
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags);
var albumInfo = new ParsedAlbumInfo
{
ArtistName = artist.Name,
ReleaseTitle = parsed?.ReleaseTitle ?? history.SourceTitle,
Quality = history.Quality,
ReleaseGroup = parsed?.ReleaseGroup,
};
var input = new CustomFormatInput
{
AlbumInfo = albumInfo,
Artist = artist,
Size = size,
IndexerFlags = indexerFlags
};
return ParseCustomFormat(input);
}
public List<CustomFormat> ParseCustomFormat(LocalTrack localTrack)
{
var albumInfo = new ParsedAlbumInfo
{
ArtistName = localTrack.Artist.Name,
ReleaseTitle = localTrack.SceneName.IsNotNullOrWhiteSpace() ? localTrack.SceneName : Path.GetFileName(localTrack.Path),
Quality = localTrack.Quality,
ReleaseGroup = localTrack.ReleaseGroup
};
var input = new CustomFormatInput
{
AlbumInfo = albumInfo,
Artist = localTrack.Artist,
Size = localTrack.Size,
Filename = Path.GetFileName(localTrack.Path),
IndexerFlags = localTrack.IndexerFlags,
};
return ParseCustomFormat(input);
}
private List<CustomFormat> ParseCustomFormat(CustomFormatInput input)
{
return ParseCustomFormat(input, _formatService.All());
}
private static List<CustomFormat> ParseCustomFormat(CustomFormatInput input, List<CustomFormat> allCustomFormats)
{
var matches = new List<CustomFormat>();
foreach (var customFormat in allCustomFormats)
{
var specificationMatches = customFormat.Specifications
.GroupBy(t => t.GetType())
.Select(g => new SpecificationMatchesGroup
{
Matches = g.ToDictionary(t => t, t => t.IsSatisfiedBy(input))
})
.ToList();
if (specificationMatches.All(x => x.DidMatch))
{
matches.Add(customFormat);
}
}
return matches.OrderBy(x => x.Name).ToList();
}
private List<CustomFormat> ParseCustomFormat(TrackFile trackFile, Artist artist, List<CustomFormat> allCustomFormats)
{
var releaseTitle = string.Empty;
if (trackFile.SceneName.IsNotNullOrWhiteSpace())
{
_logger.Trace("Using scene name for release title: {0}", trackFile.SceneName);
releaseTitle = trackFile.SceneName;
}
else if (trackFile.OriginalFilePath.IsNotNullOrWhiteSpace())
{
_logger.Trace("Using original file path for release title: {0}", Path.GetFileName(trackFile.OriginalFilePath));
releaseTitle = Path.GetFileName(trackFile.OriginalFilePath);
}
else if (trackFile.Path.IsNotNullOrWhiteSpace())
{
_logger.Trace("Using path for release title: {0}", Path.GetFileName(trackFile.Path));
releaseTitle = Path.GetFileName(trackFile.Path);
}
var albumInfo = new ParsedAlbumInfo
{
ArtistName = artist.Name,
ReleaseTitle = releaseTitle,
Quality = trackFile.Quality,
ReleaseGroup = trackFile.ReleaseGroup
};
var input = new CustomFormatInput
{
AlbumInfo = albumInfo,
Artist = artist,
Size = trackFile.Size,
IndexerFlags = trackFile.IndexerFlags,
Filename = Path.GetFileName(trackFile.Path)
};
return ParseCustomFormat(input, allCustomFormats);
}
}
}