Remove duplicate /Similar endpoints and add poor matching for artists and albums
This commit is contained in:
parent
96dcd9c87e
commit
b99519898d
|
@ -2403,11 +2403,11 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
if (string.IsNullOrEmpty(item.OfficialRating))
|
||||
{
|
||||
builder.Append("((OfficialRating is null) * 10)");
|
||||
builder.Append("(OfficialRating is null * 10)");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("((OfficialRating=@ItemOfficialRating) * 10)");
|
||||
builder.Append("(OfficialRating=@ItemOfficialRating * 10)");
|
||||
}
|
||||
|
||||
if (item.ProductionYear.HasValue)
|
||||
|
@ -2416,8 +2416,26 @@ namespace Emby.Server.Implementations.Data
|
|||
builder.Append("+(Select Case When Abs(COALESCE(ProductionYear, 0) - @ItemProductionYear) < 5 Then 5 Else 0 End )");
|
||||
}
|
||||
|
||||
//// genres, tags
|
||||
builder.Append("+ ((Select count(CleanValue) from ItemValues where ItemId=Guid and CleanValue in (select CleanValue from itemvalues where ItemId=@SimilarItemId)) * 10)");
|
||||
// genres, tags, studios, person, year?
|
||||
builder.Append("+ (Select count(1) * 10 from ItemValues where ItemId=Guid and CleanValue in (select CleanValue from itemvalues where ItemId=@SimilarItemId))");
|
||||
|
||||
if (item is MusicArtist)
|
||||
{
|
||||
// Match albums where the artist is AlbumArtist against other albums.
|
||||
// It is assumed that similar albums => similar artists.
|
||||
builder.Append(
|
||||
@"+ (WITH artistValues AS (
|
||||
SELECT DISTINCT albumValues.CleanValue
|
||||
FROM ItemValues albumValues
|
||||
INNER JOIN ItemValues artistAlbums ON albumValues.ItemId = artistAlbums.ItemId
|
||||
INNER JOIN TypedBaseItems artistItem ON artistAlbums.CleanValue = artistItem.CleanName AND artistAlbums.TYPE = 1 AND artistItem.Guid = @SimilarItemId
|
||||
), similarArtist AS (
|
||||
SELECT albumValues.ItemId
|
||||
FROM ItemValues albumValues
|
||||
INNER JOIN ItemValues artistAlbums ON albumValues.ItemId = artistAlbums.ItemId
|
||||
INNER JOIN TypedBaseItems artistItem ON artistAlbums.CleanValue = artistItem.CleanName AND artistAlbums.TYPE = 1 AND artistItem.Guid = A.Guid
|
||||
) SELECT COUNT(DISTINCT(CleanValue)) * 10 FROM ItemValues WHERE ItemId IN (SELECT ItemId FROM similarArtist) AND CleanValue IN (SELECT CleanValue FROM artistValues))");
|
||||
}
|
||||
|
||||
builder.Append(") as SimilarityScore");
|
||||
|
||||
|
@ -5052,7 +5070,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
|||
|
||||
CheckDisposed();
|
||||
|
||||
var commandText = "select ItemId, Name, Role, PersonType, SortOrder from People";
|
||||
var commandText = "select ItemId, Name, Role, PersonType, SortOrder from People p";
|
||||
|
||||
var whereClauses = GetPeopleWhereClauses(query, null);
|
||||
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Jellyfin.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// The albums controller.
|
||||
/// </summary>
|
||||
[Route("")]
|
||||
public class AlbumsController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IDtoService _dtoService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AlbumsController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
||||
public AlbumsController(
|
||||
IUserManager userManager,
|
||||
ILibraryManager libraryManager,
|
||||
IDtoService dtoService)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_libraryManager = libraryManager;
|
||||
_dtoService = dtoService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds albums similar to a given album.
|
||||
/// </summary>
|
||||
/// <param name="albumId">The album id.</param>
|
||||
/// <param name="userId">Optional. Filter by user id, and attach user data.</param>
|
||||
/// <param name="excludeArtistIds">Optional. Ids of artists to exclude.</param>
|
||||
/// <param name="limit">Optional. The maximum number of records to return.</param>
|
||||
/// <response code="200">Similar albums returned.</response>
|
||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with similar albums.</returns>
|
||||
[HttpGet("Albums/{albumId}/Similar")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetSimilarAlbums(
|
||||
[FromRoute, Required] string albumId,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] string? excludeArtistIds,
|
||||
[FromQuery] int? limit)
|
||||
{
|
||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
||||
|
||||
return SimilarItemsHelper.GetSimilarItemsResult(
|
||||
dtoOptions,
|
||||
_userManager,
|
||||
_libraryManager,
|
||||
_dtoService,
|
||||
userId,
|
||||
albumId,
|
||||
excludeArtistIds,
|
||||
limit,
|
||||
new[] { typeof(MusicAlbum) },
|
||||
GetAlbumSimilarityScore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds artists similar to a given artist.
|
||||
/// </summary>
|
||||
/// <param name="artistId">The artist id.</param>
|
||||
/// <param name="userId">Optional. Filter by user id, and attach user data.</param>
|
||||
/// <param name="excludeArtistIds">Optional. Ids of artists to exclude.</param>
|
||||
/// <param name="limit">Optional. The maximum number of records to return.</param>
|
||||
/// <response code="200">Similar artists returned.</response>
|
||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with similar artists.</returns>
|
||||
[HttpGet("Artists/{artistId}/Similar")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetSimilarArtists(
|
||||
[FromRoute, Required] string artistId,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] string? excludeArtistIds,
|
||||
[FromQuery] int? limit)
|
||||
{
|
||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
||||
|
||||
return SimilarItemsHelper.GetSimilarItemsResult(
|
||||
dtoOptions,
|
||||
_userManager,
|
||||
_libraryManager,
|
||||
_dtoService,
|
||||
userId,
|
||||
artistId,
|
||||
excludeArtistIds,
|
||||
limit,
|
||||
new[] { typeof(MusicArtist) },
|
||||
SimilarItemsHelper.GetSimiliarityScore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a similairty score of two albums.
|
||||
/// </summary>
|
||||
/// <param name="item1">The first item.</param>
|
||||
/// <param name="item1People">The item1 people.</param>
|
||||
/// <param name="allPeople">All people.</param>
|
||||
/// <param name="item2">The second item.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
private int GetAlbumSimilarityScore(BaseItem item1, List<PersonInfo> item1People, List<PersonInfo> allPeople, BaseItem item2)
|
||||
{
|
||||
var points = SimilarItemsHelper.GetSimiliarityScore(item1, item1People, allPeople, item2);
|
||||
|
||||
var album1 = (MusicAlbum)item1;
|
||||
var album2 = (MusicAlbum)item2;
|
||||
|
||||
var artists1 = album1
|
||||
.GetAllArtists()
|
||||
.DistinctNames()
|
||||
.ToList();
|
||||
|
||||
var artists2 = new HashSet<string>(
|
||||
album2.GetAllArtists().DistinctNames(),
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
return points + artists1.Where(artists2.Contains).Sum(i => 5);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -680,12 +680,12 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <param name="fields">Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimited. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls.</param>
|
||||
/// <response code="200">Similar items returned.</response>
|
||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> containing the similar items.</returns>
|
||||
[HttpGet("Artists/{itemId}/Similar", Name = "GetSimilarArtists2")]
|
||||
[HttpGet("Artists/{itemId}/Similar")]
|
||||
[HttpGet("Items/{itemId}/Similar")]
|
||||
[HttpGet("Albums/{itemId}/Similar", Name = "GetSimilarAlbums2")]
|
||||
[HttpGet("Shows/{itemId}/Similar", Name = "GetSimilarShows2")]
|
||||
[HttpGet("Movies/{itemId}/Similar", Name = "GetSimilarMovies2")]
|
||||
[HttpGet("Trailers/{itemId}/Similar", Name = "GetSimilarTrailers2")]
|
||||
[HttpGet("Albums/{itemId}/Similar")]
|
||||
[HttpGet("Shows/{itemId}/Similar")]
|
||||
[HttpGet("Movies/{itemId}/Similar")]
|
||||
[HttpGet("Trailers/{itemId}/Similar")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetSimilarItems(
|
||||
|
@ -701,33 +701,72 @@ namespace Jellyfin.Api.Controllers
|
|||
: _libraryManager.RootFolder)
|
||||
: _libraryManager.GetItemById(itemId);
|
||||
|
||||
var program = item as IHasProgramAttributes;
|
||||
var isMovie = item is MediaBrowser.Controller.Entities.Movies.Movie || (program != null && program.IsMovie) || item is Trailer;
|
||||
if (program != null && program.IsSeries)
|
||||
{
|
||||
return GetSimilarItemsResult(
|
||||
item,
|
||||
excludeArtistIds,
|
||||
userId,
|
||||
limit,
|
||||
fields,
|
||||
new[] { nameof(Series) },
|
||||
false);
|
||||
}
|
||||
|
||||
if (item is MediaBrowser.Controller.Entities.TV.Episode || (item is IItemByName && !(item is MusicArtist)))
|
||||
if (item is Episode || (item is IItemByName && !(item is MusicArtist)))
|
||||
{
|
||||
return new QueryResult<BaseItemDto>();
|
||||
}
|
||||
|
||||
return GetSimilarItemsResult(
|
||||
item,
|
||||
excludeArtistIds,
|
||||
userId,
|
||||
limit,
|
||||
fields,
|
||||
new[] { item.GetType().Name },
|
||||
isMovie);
|
||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||
? _userManager.GetUserById(userId.Value)
|
||||
: null;
|
||||
var dtoOptions = new DtoOptions()
|
||||
.AddItemFields(fields)
|
||||
.AddClientFields(Request);
|
||||
|
||||
var program = item as IHasProgramAttributes;
|
||||
bool? isMovie = item is Movie || (program != null && program.IsMovie) || item is Trailer;
|
||||
bool? isSeries = item is Series || (program != null && program.IsSeries);
|
||||
|
||||
var includeItemTypes = new List<string>();
|
||||
if (isMovie.Value)
|
||||
{
|
||||
includeItemTypes.Add(nameof(Movie));
|
||||
if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
|
||||
{
|
||||
includeItemTypes.Add(nameof(Trailer));
|
||||
includeItemTypes.Add(nameof(LiveTvProgram));
|
||||
}
|
||||
}
|
||||
else if (isSeries.Value)
|
||||
{
|
||||
includeItemTypes.Add(nameof(Series));
|
||||
}
|
||||
else
|
||||
{
|
||||
// For non series and movie types these columns are typically null
|
||||
isSeries = null;
|
||||
isMovie = null;
|
||||
includeItemTypes.Add(item.GetType().Name);
|
||||
}
|
||||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
Limit = limit,
|
||||
IncludeItemTypes = includeItemTypes.ToArray(),
|
||||
IsMovie = isMovie,
|
||||
IsSeries = isSeries,
|
||||
SimilarTo = item,
|
||||
DtoOptions = dtoOptions,
|
||||
EnableTotalRecordCount = !isMovie ?? true,
|
||||
EnableGroupByMetadataKey = isMovie ?? false,
|
||||
MinSimilarityScore = 2 // A remnant from album/artist scoring
|
||||
};
|
||||
|
||||
// ExcludeArtistIds
|
||||
if (!string.IsNullOrEmpty(excludeArtistIds))
|
||||
{
|
||||
query.ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds);
|
||||
}
|
||||
|
||||
List<BaseItem> itemsResult = _libraryManager.GetItemList(query);
|
||||
|
||||
var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
|
||||
|
||||
return new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = returnList,
|
||||
TotalRecordCount = itemsResult.Count
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -880,75 +919,6 @@ namespace Jellyfin.Api.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
private QueryResult<BaseItemDto> GetSimilarItemsResult(
|
||||
BaseItem item,
|
||||
string? excludeArtistIds,
|
||||
Guid? userId,
|
||||
int? limit,
|
||||
string? fields,
|
||||
string[] includeItemTypes,
|
||||
bool isMovie)
|
||||
{
|
||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||
? _userManager.GetUserById(userId.Value)
|
||||
: null;
|
||||
var dtoOptions = new DtoOptions()
|
||||
.AddItemFields(fields)
|
||||
.AddClientFields(Request);
|
||||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
Limit = limit,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
IsMovie = isMovie,
|
||||
SimilarTo = item,
|
||||
DtoOptions = dtoOptions,
|
||||
EnableTotalRecordCount = !isMovie,
|
||||
EnableGroupByMetadataKey = isMovie
|
||||
};
|
||||
|
||||
// ExcludeArtistIds
|
||||
if (!string.IsNullOrEmpty(excludeArtistIds))
|
||||
{
|
||||
query.ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds);
|
||||
}
|
||||
|
||||
List<BaseItem> itemsResult;
|
||||
|
||||
if (isMovie)
|
||||
{
|
||||
var itemTypes = new List<string> { nameof(MediaBrowser.Controller.Entities.Movies.Movie) };
|
||||
if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
|
||||
{
|
||||
itemTypes.Add(nameof(Trailer));
|
||||
itemTypes.Add(nameof(LiveTvProgram));
|
||||
}
|
||||
|
||||
query.IncludeItemTypes = itemTypes.ToArray();
|
||||
itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
|
||||
}
|
||||
else if (item is MusicArtist)
|
||||
{
|
||||
query.IncludeItemTypes = Array.Empty<string>();
|
||||
|
||||
itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
itemsResult = _libraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
|
||||
|
||||
var result = new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = returnList,
|
||||
TotalRecordCount = itemsResult.Count
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string[] GetRepresentativeItemTypes(string? contentType)
|
||||
{
|
||||
return contentType switch
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace Jellyfin.Api.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// The similar items helper class.
|
||||
/// </summary>
|
||||
public static class SimilarItemsHelper
|
||||
{
|
||||
internal static QueryResult<BaseItemDto> GetSimilarItemsResult(
|
||||
DtoOptions dtoOptions,
|
||||
IUserManager userManager,
|
||||
ILibraryManager libraryManager,
|
||||
IDtoService dtoService,
|
||||
Guid? userId,
|
||||
string id,
|
||||
string? excludeArtistIds,
|
||||
int? limit,
|
||||
Type[] includeTypes,
|
||||
Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
|
||||
{
|
||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||
? userManager.GetUserById(userId.Value)
|
||||
: null;
|
||||
|
||||
var item = string.IsNullOrEmpty(id) ?
|
||||
(!userId.Equals(Guid.Empty) ? libraryManager.GetUserRootFolder() :
|
||||
libraryManager.RootFolder) : libraryManager.GetItemById(id);
|
||||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = includeTypes.Select(i => i.Name).ToArray(),
|
||||
Recursive = true,
|
||||
DtoOptions = dtoOptions,
|
||||
ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds)
|
||||
};
|
||||
|
||||
var inputItems = libraryManager.GetItemList(query);
|
||||
|
||||
var items = GetSimilaritems(item, libraryManager, inputItems, getSimilarityScore)
|
||||
.ToList();
|
||||
|
||||
var returnItems = items;
|
||||
|
||||
if (limit.HasValue && limit < returnItems.Count)
|
||||
{
|
||||
returnItems = returnItems.GetRange(0, limit.Value);
|
||||
}
|
||||
|
||||
var dtos = dtoService.GetBaseItemDtos(returnItems, dtoOptions, user);
|
||||
|
||||
return new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = dtos,
|
||||
TotalRecordCount = items.Count
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the similaritems.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="inputItems">The input items.</param>
|
||||
/// <param name="getSimilarityScore">The get similarity score.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private static IEnumerable<BaseItem> GetSimilaritems(
|
||||
BaseItem item,
|
||||
ILibraryManager libraryManager,
|
||||
IEnumerable<BaseItem> inputItems,
|
||||
Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
|
||||
{
|
||||
var itemId = item.Id;
|
||||
inputItems = inputItems.Where(i => i.Id != itemId);
|
||||
var itemPeople = libraryManager.GetPeople(item);
|
||||
var allPeople = libraryManager.GetPeople(new InternalPeopleQuery
|
||||
{
|
||||
AppearsInItemId = item.Id
|
||||
});
|
||||
|
||||
return inputItems.Select(i => new Tuple<BaseItem, int>(i, getSimilarityScore(item, itemPeople, allPeople, i)))
|
||||
.Where(i => i.Item2 > 2)
|
||||
.OrderByDescending(i => i.Item2)
|
||||
.Select(i => i.Item1);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetTags(BaseItem item)
|
||||
{
|
||||
return item.Tags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the similiarity score.
|
||||
/// </summary>
|
||||
/// <param name="item1">The item1.</param>
|
||||
/// <param name="item1People">The item1 people.</param>
|
||||
/// <param name="allPeople">All people.</param>
|
||||
/// <param name="item2">The item2.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
internal static int GetSimiliarityScore(BaseItem item1, List<PersonInfo> item1People, List<PersonInfo> allPeople, BaseItem item2)
|
||||
{
|
||||
var points = 0;
|
||||
|
||||
if (!string.IsNullOrEmpty(item1.OfficialRating) && string.Equals(item1.OfficialRating, item2.OfficialRating, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
points += 10;
|
||||
}
|
||||
|
||||
// Find common genres
|
||||
points += item1.Genres.Where(i => item2.Genres.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
|
||||
|
||||
// Find common tags
|
||||
points += GetTags(item1).Where(i => GetTags(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
|
||||
|
||||
// Find common studios
|
||||
points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 3);
|
||||
|
||||
var item2PeopleNames = allPeople.Where(i => i.ItemId == item2.Id)
|
||||
.Select(i => i.Name)
|
||||
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||
.DistinctNames()
|
||||
.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
points += item1People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i =>
|
||||
{
|
||||
if (string.Equals(i.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
});
|
||||
|
||||
if (item1.ProductionYear.HasValue && item2.ProductionYear.HasValue)
|
||||
{
|
||||
var diff = Math.Abs(item1.ProductionYear.Value - item2.ProductionYear.Value);
|
||||
|
||||
// Add if they came out within the same decade
|
||||
if (diff < 10)
|
||||
{
|
||||
points += 2;
|
||||
}
|
||||
|
||||
// And more if within five years
|
||||
if (diff < 5)
|
||||
{
|
||||
points += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user