2024-02-21 04:12:45 +00:00
|
|
|
using System;
|
2022-01-24 05:42:41 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
2024-01-20 05:30:24 +00:00
|
|
|
using NLog;
|
2022-01-24 05:42:41 +00:00
|
|
|
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;
|
2024-01-20 05:30:24 +00:00
|
|
|
private readonly Logger _logger;
|
2022-01-24 05:42:41 +00:00
|
|
|
|
2024-01-20 05:30:24 +00:00
|
|
|
public CustomFormatCalculationService(ICustomFormatService formatService, Logger logger)
|
2022-01-24 05:42:41 +00:00
|
|
|
{
|
|
|
|
_formatService = formatService;
|
2024-01-20 05:30:24 +00:00
|
|
|
_logger = logger;
|
2022-01-24 05:42:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public List<CustomFormat> ParseCustomFormat(RemoteAlbum remoteAlbum, long size)
|
|
|
|
{
|
|
|
|
var input = new CustomFormatInput
|
|
|
|
{
|
|
|
|
AlbumInfo = remoteAlbum.ParsedAlbumInfo,
|
|
|
|
Artist = remoteAlbum.Artist,
|
2024-02-21 04:12:45 +00:00
|
|
|
Size = size,
|
|
|
|
IndexerFlags = remoteAlbum.Release?.IndexerFlags ?? 0
|
2022-01-24 05:42:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2023-02-13 06:33:45 +00:00
|
|
|
var albumInfo = new ParsedAlbumInfo
|
2022-01-24 05:42:41 +00:00
|
|
|
{
|
|
|
|
ArtistName = artist.Name,
|
|
|
|
ReleaseTitle = parsed?.ReleaseTitle ?? blocklist.SourceTitle,
|
|
|
|
Quality = blocklist.Quality,
|
|
|
|
ReleaseGroup = parsed?.ReleaseGroup
|
|
|
|
};
|
|
|
|
|
|
|
|
var input = new CustomFormatInput
|
|
|
|
{
|
2023-02-13 06:33:45 +00:00
|
|
|
AlbumInfo = albumInfo,
|
2022-01-24 05:42:41 +00:00
|
|
|
Artist = artist,
|
2024-02-21 04:12:45 +00:00
|
|
|
Size = blocklist.Size ?? 0,
|
|
|
|
IndexerFlags = blocklist.IndexerFlags
|
2022-01-24 05:42:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
2024-02-21 04:12:45 +00:00
|
|
|
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags);
|
2022-01-24 05:42:41 +00:00
|
|
|
|
|
|
|
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,
|
2024-02-21 04:12:45 +00:00
|
|
|
Size = size,
|
|
|
|
IndexerFlags = indexerFlags
|
2022-01-24 05:42:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return ParseCustomFormat(input);
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<CustomFormat> ParseCustomFormat(LocalTrack localTrack)
|
|
|
|
{
|
|
|
|
var albumInfo = new ParsedAlbumInfo
|
|
|
|
{
|
|
|
|
ArtistName = localTrack.Artist.Name,
|
2023-04-02 00:03:53 +00:00
|
|
|
ReleaseTitle = localTrack.SceneName.IsNotNullOrWhiteSpace() ? localTrack.SceneName : Path.GetFileName(localTrack.Path),
|
2022-01-24 05:42:41 +00:00
|
|
|
Quality = localTrack.Quality,
|
|
|
|
ReleaseGroup = localTrack.ReleaseGroup
|
|
|
|
};
|
|
|
|
|
|
|
|
var input = new CustomFormatInput
|
|
|
|
{
|
|
|
|
AlbumInfo = albumInfo,
|
|
|
|
Artist = localTrack.Artist,
|
2023-04-02 00:03:53 +00:00
|
|
|
Size = localTrack.Size,
|
2024-02-21 04:12:45 +00:00
|
|
|
Filename = Path.GetFileName(localTrack.Path),
|
|
|
|
IndexerFlags = localTrack.IndexerFlags,
|
2022-01-24 05:42:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-21 07:06:22 +00:00
|
|
|
return matches.OrderBy(x => x.Name).ToList();
|
2022-01-24 05:42:41 +00:00
|
|
|
}
|
|
|
|
|
2024-01-20 05:30:24 +00:00
|
|
|
private List<CustomFormat> ParseCustomFormat(TrackFile trackFile, Artist artist, List<CustomFormat> allCustomFormats)
|
2022-01-24 05:42:41 +00:00
|
|
|
{
|
2024-01-20 05:30:24 +00:00
|
|
|
var releaseTitle = string.Empty;
|
|
|
|
|
2022-01-24 05:42:41 +00:00
|
|
|
if (trackFile.SceneName.IsNotNullOrWhiteSpace())
|
|
|
|
{
|
2024-01-20 05:30:24 +00:00
|
|
|
_logger.Trace("Using scene name for release title: {0}", trackFile.SceneName);
|
|
|
|
releaseTitle = trackFile.SceneName;
|
2022-01-24 05:42:41 +00:00
|
|
|
}
|
|
|
|
else if (trackFile.OriginalFilePath.IsNotNullOrWhiteSpace())
|
|
|
|
{
|
2024-01-20 05:30:24 +00:00
|
|
|
_logger.Trace("Using original file path for release title: {0}", Path.GetFileName(trackFile.OriginalFilePath));
|
2023-02-13 06:33:45 +00:00
|
|
|
releaseTitle = Path.GetFileName(trackFile.OriginalFilePath);
|
2022-01-24 05:42:41 +00:00
|
|
|
}
|
|
|
|
else if (trackFile.Path.IsNotNullOrWhiteSpace())
|
|
|
|
{
|
2024-01-20 05:30:24 +00:00
|
|
|
_logger.Trace("Using path for release title: {0}", Path.GetFileName(trackFile.Path));
|
|
|
|
releaseTitle = Path.GetFileName(trackFile.Path);
|
2022-01-24 05:42:41 +00:00
|
|
|
}
|
|
|
|
|
2023-02-13 06:33:45 +00:00
|
|
|
var albumInfo = new ParsedAlbumInfo
|
2022-01-24 05:42:41 +00:00
|
|
|
{
|
|
|
|
ArtistName = artist.Name,
|
2024-01-20 05:30:24 +00:00
|
|
|
ReleaseTitle = releaseTitle,
|
2022-01-24 05:42:41 +00:00
|
|
|
Quality = trackFile.Quality,
|
|
|
|
ReleaseGroup = trackFile.ReleaseGroup
|
|
|
|
};
|
|
|
|
|
|
|
|
var input = new CustomFormatInput
|
|
|
|
{
|
2023-02-13 06:33:45 +00:00
|
|
|
AlbumInfo = albumInfo,
|
2022-01-24 05:42:41 +00:00
|
|
|
Artist = artist,
|
|
|
|
Size = trackFile.Size,
|
2024-02-21 04:12:45 +00:00
|
|
|
IndexerFlags = trackFile.IndexerFlags,
|
2022-01-24 05:42:41 +00:00
|
|
|
Filename = Path.GetFileName(trackFile.Path)
|
|
|
|
};
|
|
|
|
|
|
|
|
return ParseCustomFormat(input, allCustomFormats);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|