@ -63,16 +63,8 @@ namespace MediaBrowser.Server.Implementations.Intros
? null
: _localization . GetRatingLevel ( item . OfficialRating ) ;
var random = new Random ( Environment . TickCount + Guid . NewGuid ( ) . GetHashCode ( ) ) ;
var candidates = new List < ItemWithTrailer > ( ) ;
var itemPeople = _libraryManager . GetPeople ( item ) ;
var allPeople = _libraryManager . GetPeople ( new InternalPeopleQuery
{
AppearsInItemId = item . Id
} ) ;
var trailerTypes = new List < TrailerType > ( ) ;
if ( config . EnableIntrosFromMoviesInLibrary )
@ -105,26 +97,25 @@ namespace MediaBrowser.Server.Implementations.Intros
var trailerResult = _libraryManager . GetItemList ( new InternalItemsQuery
{
IncludeItemTypes = new [ ] { typeof ( Trailer ) . Name } ,
TrailerTypes = trailerTypes . ToArray ( )
TrailerTypes = trailerTypes . ToArray ( ) ,
SimilarTo = item ,
IsPlayed = config . EnableIntrosForWatchedContent ? ( bool? ) null : false ,
MaxParentalRating = config . EnableIntrosParentalControl ? ratingLevel : null ,
Limit = config . TrailerLimit
} ) ;
candidates . AddRange ( trailerResult . Select ( i = > new ItemWithTrailer
{
Item = i ,
Type = i . SourceType = = SourceType . Channel ? ItemWithTrailerType . ChannelTrailer : ItemWithTrailerType . ItemWithTrailer ,
User = user ,
WatchingItem = item ,
WatchingItemPeople = itemPeople ,
AllPeople = allPeople ,
Random = random ,
LibraryManager = _libraryManager
} ) ) ;
}
return GetResult ( item , candidates , config , ratingLevel );
return GetResult ( item , candidates , config ) ;
}
private IEnumerable < IntroInfo > GetResult ( BaseItem item , IEnumerable < ItemWithTrailer > candidates , CinemaModeConfiguration config , int? ratingLevel )
private IEnumerable < IntroInfo > GetResult ( BaseItem item , IEnumerable < ItemWithTrailer > candidates , CinemaModeConfiguration config )
{
var customIntros = ! string . IsNullOrWhiteSpace ( config . CustomIntroPath ) ?
GetCustomIntros ( config ) :
@ -134,48 +125,12 @@ namespace MediaBrowser.Server.Implementations.Intros
GetMediaInfoIntros ( config , item ) :
new List < IntroInfo > ( ) ;
var trailerLimit = config . TrailerLimit ;
// Avoid implicitly captured closure
return candidates . Where ( i = >
{
if ( config . EnableIntrosParentalControl & & ! FilterByParentalRating ( ratingLevel , i . Item ) )
{
return false ;
}
if ( ! config . EnableIntrosForWatchedContent & & i . IsPlayed )
{
return false ;
}
return ! IsDuplicate ( item , i . Item ) ;
} )
. OrderByDescending ( i = > i . Score )
. ThenBy ( i = > Guid . NewGuid ( ) )
. ThenByDescending ( i = > i . IsPlayed ? 0 : 1 )
. Select ( i = > i . IntroInfo )
. Take ( trailerLimit )
return candidates . Select ( i = > i . IntroInfo )
. Concat ( customIntros . Take ( 1 ) )
. Concat ( mediaInfoIntros ) ;
}
private bool IsDuplicate ( BaseItem playingContent , BaseItem test )
{
var id = playingContent . GetProviderId ( MetadataProviders . Imdb ) ;
if ( ! string . IsNullOrWhiteSpace ( id ) & & string . Equals ( id , test . GetProviderId ( MetadataProviders . Imdb ) , StringComparison . OrdinalIgnoreCase ) )
{
return true ;
}
id = playingContent . GetProviderId ( MetadataProviders . Tmdb ) ;
if ( ! string . IsNullOrWhiteSpace ( id ) & & string . Equals ( id , test . GetProviderId ( MetadataProviders . Tmdb ) , StringComparison . OrdinalIgnoreCase ) )
{
return true ;
}
return false ;
}
private CinemaModeConfiguration GetOptions ( )
{
return _serverConfig . GetConfiguration < CinemaModeConfiguration > ( "cinemamode" ) ;
@ -346,96 +301,6 @@ namespace MediaBrowser.Server.Implementations.Intros
return list . Distinct ( StringComparer . OrdinalIgnoreCase ) ;
}
private bool FilterByParentalRating ( int? ratingLevel , BaseItem item )
{
// Only content rated same or lower
if ( ratingLevel . HasValue )
{
var level = string . IsNullOrWhiteSpace ( item . OfficialRating )
? ( int? ) null
: _localization . GetRatingLevel ( item . OfficialRating ) ;
return level . HasValue & & level . Value < = ratingLevel . Value ;
}
return true ;
}
internal static int GetSimiliarityScore ( BaseItem item1 , List < PersonInfo > item1People , List < PersonInfo > allPeople , BaseItem item2 , Random random , ILibraryManager libraryManager )
{
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 keywords
points + = GetKeywords ( item1 ) . Where ( i = > GetKeywords ( item2 ) . Contains ( i , StringComparer . OrdinalIgnoreCase ) ) . Sum ( i = > 10 ) ;
// Find common studios
points + = item1 . Studios . Where ( i = > item2 . Studios . Contains ( i , StringComparer . OrdinalIgnoreCase ) ) . Sum ( i = > 5 ) ;
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 ;
} ) ;
// Add some randomization so that you're not always seeing the same ones for a given movie
points + = random . Next ( 0 , 50 ) ;
return points ;
}
private static IEnumerable < string > GetTags ( BaseItem item )
{
var hasTags = item as IHasTags ;
if ( hasTags ! = null )
{
return hasTags . Tags ;
}
return new List < string > ( ) ;
}
private static IEnumerable < string > GetKeywords ( BaseItem item )
{
return item . Keywords ;
}
public IEnumerable < string > GetAllIntroFiles ( )
{
return GetCustomIntroFiles ( GetOptions ( ) , true , true ) ;
@ -455,39 +320,8 @@ namespace MediaBrowser.Server.Implementations.Intros
{
internal BaseItem Item ;
internal ItemWithTrailerType Type ;
internal User User ;
internal BaseItem WatchingItem ;
internal List < PersonInfo > WatchingItemPeople ;
internal List < PersonInfo > AllPeople ;
internal Random Random ;
internal ILibraryManager LibraryManager ;
private bool? _isPlayed ;
public bool IsPlayed
{
get
{
if ( ! _isPlayed . HasValue )
{
_isPlayed = Item . IsPlayed ( User ) ;
}
return _isPlayed . Value ;
}
}
private int? _score ;
public int Score
{
get
{
if ( ! _score . HasValue )
{
_score = GetSimiliarityScore ( WatchingItem , WatchingItemPeople , AllPeople , Item , Random , LibraryManager ) ;
}
return _score . Value ;
}
}
public IntroInfo IntroInfo
{
get