support metabrowser special episode attributes

This commit is contained in:
Luke Pulverenti 2013-11-17 10:27:48 -05:00
parent 50fc350c1b
commit 9f9ab1ac9f
11 changed files with 119 additions and 111 deletions

View File

@ -21,6 +21,9 @@ namespace MediaBrowser.Api.DefaultTheme
{
[ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid UserId { get; set; }
[ApiMember(Name = "RecentlyPlayedGamesLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int RecentlyPlayedGamesLimit { get; set; }
}
[Route("/MBT/DefaultTheme/TV", "GET")]
@ -245,6 +248,19 @@ namespace MediaBrowser.Api.DefaultTheme
var fields = new List<ItemFields>();
view.GameSystems = items
.OfType<GameSystem>()
.OrderBy(i => i.SortName)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToList();
var currentUserId = user.Id;
view.RecentlyPlayedGames = gamesWithImages
.OrderByDescending(i => _userDataManager.GetUserData(currentUserId, i.GetUserDataKey()).LastPlayedDate ?? DateTime.MinValue)
.Take(request.RecentlyPlayedGamesLimit)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToList();
view.BackdropItems = gamesWithBackdrops
.OrderBy(i => Guid.NewGuid())
.Take(10)
@ -265,12 +281,6 @@ namespace MediaBrowser.Api.DefaultTheme
.Take(1)
.ToList();
view.MiniSpotlights = gamesWithBackdrops
.Randomize("minispotlight")
.Take(5)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToList();
return ToOptimizedResult(view);
}
@ -324,8 +334,6 @@ namespace MediaBrowser.Api.DefaultTheme
.Take(1)
.ToList();
view.ActorItems = GetActors(series, user.Id);
var spotlightSeries = seriesWithBestBackdrops
.Where(i => i.CommunityRating.HasValue && i.CommunityRating >= 8.5)
.ToList();
@ -409,10 +417,6 @@ namespace MediaBrowser.Api.DefaultTheme
var items = user.RootFolder.GetRecursiveChildren(user, i => i is Movie || i is Trailer || i is BoxSet)
.ToList();
// Exclude trailers from backdrops because they're not always 1080p
var itemsWithBackdrops = items.Where(i => i.BackdropImagePaths.Count > 0)
.ToList();
var view = new MoviesView();
var movies = items.OfType<Movie>()
@ -439,7 +443,7 @@ namespace MediaBrowser.Api.DefaultTheme
var fields = new List<ItemFields>();
var itemsWithTopBackdrops = FilterItemsForBackdropDisplay(itemsWithBackdrops).ToList();
var itemsWithTopBackdrops = FilterItemsForBackdropDisplay(moviesWithBackdrops).ToList();
view.BackdropItems = itemsWithTopBackdrops
.OrderBy(i => Guid.NewGuid())
@ -515,10 +519,10 @@ namespace MediaBrowser.Api.DefaultTheme
.Take(1)
.ToList();
view.PeopleItems = GetActors(items, user.Id);
var currentUserId = user.Id;
var spotlightItems = itemsWithTopBackdrops
.Where(i => i.CommunityRating.HasValue && i.CommunityRating >= 8)
.Where(i => !_userDataManager.GetUserData(currentUserId, i.GetUserDataKey()).Played)
.ToList();
if (spotlightItems.Count < 20)
@ -551,14 +555,13 @@ namespace MediaBrowser.Api.DefaultTheme
.ToList();
// Avoid implicitly captured closure
var currentUserId = user.Id;
miniSpotlightItems.InsertRange(2, moviesWithBackdrops
miniSpotlightItems.InsertRange(0, moviesWithBackdrops
.Where(i => _userDataManager.GetUserData(currentUserId, i.GetUserDataKey()).PlaybackPositionTicks > 0)
.OrderByDescending(i => _userDataManager.GetUserData(currentUserId, i.GetUserDataKey()).LastPlayedDate ?? DateTime.MaxValue)
.Take(3));
view.MiniSpotlights = miniSpotlightItems
.Take(5)
.Take(3)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToList();
@ -617,69 +620,6 @@ namespace MediaBrowser.Api.DefaultTheme
}
}
private List<ItemStub> GetActors(IEnumerable<BaseItem> mediaItems, Guid userId)
{
var actors = mediaItems.SelectMany(i => i.People)
.Select(i => i.Name)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Randomize()
.ToList();
var result = actors.Select(actor =>
{
try
{
var person = _libraryManager.GetPerson(actor);
if (!string.IsNullOrEmpty(person.PrimaryImagePath))
{
var userdata = _userDataManager.GetUserData(userId, person.GetUserDataKey());
if (userdata.IsFavorite || (userdata.Likes ?? false))
{
return GetItemStub(person, ImageType.Primary);
}
}
}
catch (Exception ex)
{
_logger.ErrorException("Error getting person {0}", ex, actor);
}
return null;
})
.Where(i => i != null)
.Take(1)
.ToList();
if (result.Count == 0)
{
result = actors.Select(actor =>
{
try
{
var person = _libraryManager.GetPerson(actor);
if (!string.IsNullOrEmpty(person.PrimaryImagePath))
{
return GetItemStub(person, ImageType.Primary);
}
}
catch (Exception ex)
{
_logger.ErrorException("Error getting person {0}", ex, actor);
}
return null;
})
.Where(i => i != null)
.Take(1)
.ToList();
}
return result;
}
private ItemStub GetItemStub(BaseItem item, ImageType imageType)
{
var stub = new ItemStub

View File

@ -16,7 +16,6 @@ namespace MediaBrowser.Api.DefaultTheme
public class MoviesView : BaseView
{
public List<ItemStub> MovieItems { get; set; }
public List<ItemStub> PeopleItems { get; set; }
public List<ItemStub> BoxSetItems { get; set; }
public List<ItemStub> TrailerItems { get; set; }
@ -39,7 +38,6 @@ namespace MediaBrowser.Api.DefaultTheme
public class TvView : BaseView
{
public List<ItemStub> ShowsItems { get; set; }
public List<ItemStub> ActorItems { get; set; }
public List<ItemStub> RomanceItems { get; set; }
public List<ItemStub> ComedyItems { get; set; }
@ -60,7 +58,8 @@ namespace MediaBrowser.Api.DefaultTheme
public class GamesView : BaseView
{
public List<ItemStub> MultiPlayerItems { get; set; }
public List<BaseItemDto> GameSystems { get; set; }
public List<BaseItemDto> RecentlyPlayedGames { get; set; }
}
public class BaseView

View File

@ -1013,9 +1013,9 @@ namespace MediaBrowser.Api.UserLibrary
if (episode != null)
{
var seasonNumber = episode.SpecialSeasonNumber ?? episode.ParentIndexNumber;
var seasonNumber = episode.AirsAfterSeasonNumber ?? episode.AirsBeforeEpisodeNumber ?? episode.ParentIndexNumber;
return seasonNumber.HasValue && seasonNumber.Value == val;
return episode.PremiereDate.HasValue && seasonNumber.HasValue && seasonNumber.Value == val;
}
return false;

View File

@ -1728,11 +1728,9 @@ namespace MediaBrowser.Controller.Entities
// If we didn't the metafile entry, check the Season
if (metaFileEntry == null)
{
var episode = this as Episode;
if (episode != null && episode.Season != null)
if (Parent != null)
{
episode.Season.ResolveArgs.GetMetaFileByPath(imagePath);
metaFileEntry = Parent.ResolveArgs.GetMetaFileByPath(imagePath);
}
}

View File

@ -1,7 +1,6 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Resolvers;
@ -1315,7 +1314,7 @@ namespace MediaBrowser.Controller.Entities
public override async Task MarkPlayed(User user, DateTime? datePlayed, IUserDataManager userManager)
{
// Sweep through recursively and update status
var tasks = GetRecursiveChildren(user, true).Where(i => !i.IsFolder).Select(c => c.MarkPlayed(user, datePlayed, userManager));
var tasks = GetRecursiveChildren(user, true).Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual).Select(c => c.MarkPlayed(user, datePlayed, userManager));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
@ -1329,7 +1328,7 @@ namespace MediaBrowser.Controller.Entities
public override async Task MarkUnplayed(User user, IUserDataManager userManager)
{
// Sweep through recursively and update status
var tasks = GetRecursiveChildren(user, true).Where(i => !i.IsFolder).Select(c => c.MarkUnplayed(user, userManager));
var tasks = GetRecursiveChildren(user, true).Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual).Select(c => c.MarkUnplayed(user, userManager));
await Task.WhenAll(tasks).ConfigureAwait(false);
}

View File

@ -36,7 +36,9 @@ namespace MediaBrowser.Controller.Entities.TV
/// Gets the season in which it aired.
/// </summary>
/// <value>The aired season.</value>
public int? SpecialSeasonNumber { get; set; }
public int? AirsBeforeSeasonNumber { get; set; }
public int? AirsAfterSeasonNumber { get; set; }
public int? AirsBeforeEpisodeNumber { get; set; }
/// <summary>
/// We want to group into series not show individually in an index

View File

@ -76,11 +76,19 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<EpisodeNumberEnd>" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + "</EpisodeNumberEnd>");
}
if (episode.SpecialSeasonNumber.HasValue)
if (episode.AirsAfterSeasonNumber.HasValue)
{
builder.Append("<SpecialSeasonNumber>" + SecurityElement.Escape(episode.SpecialSeasonNumber.Value.ToString(_usCulture)) + "</SpecialSeasonNumber>");
builder.Append("<airsafter_season>" + SecurityElement.Escape(episode.AirsAfterSeasonNumber.Value.ToString(_usCulture)) + "</airsafter_season>");
}
if (episode.AirsBeforeEpisodeNumber.HasValue)
{
builder.Append("<airsbefore_episode>" + SecurityElement.Escape(episode.AirsBeforeEpisodeNumber.Value.ToString(_usCulture)) + "</airsbefore_episode>");
}
if (episode.AirsBeforeSeasonNumber.HasValue)
{
builder.Append("<airsbefore_season>" + SecurityElement.Escape(episode.AirsBeforeSeasonNumber.Value.ToString(_usCulture)) + "</airsbefore_season>");
}
if (episode.ParentIndexNumber.HasValue)
{
builder.Append("<SeasonNumber>" + SecurityElement.Escape(episode.ParentIndexNumber.Value.ToString(_usCulture)) + "</SeasonNumber>");
@ -105,7 +113,9 @@ namespace MediaBrowser.Providers.Savers
"EpisodeNumber",
"EpisodeName",
"EpisodeNumberEnd",
"SpecialSeasonNumber"
"airsafter_season",
"airsbefore_episode",
"airsbefore_season"
});
// Set last refreshed so that the provider doesn't trigger after the file save

View File

@ -2,6 +2,7 @@
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@ -38,6 +39,8 @@ namespace MediaBrowser.Providers.TV
}
}
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
/// Fetches the data from XML node.
/// </summary>
@ -139,19 +142,57 @@ namespace MediaBrowser.Providers.TV
break;
}
case "SpecialSeasonNumber":
case "airsbefore_episode":
{
var number = reader.ReadElementContentAsString();
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number))
if (!string.IsNullOrWhiteSpace(val))
{
int num;
int rval;
if (int.TryParse(number, out num))
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.SpecialSeasonNumber = num;
item.AirsBeforeEpisodeNumber = rval;
}
}
break;
}
case "airsafter_season":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.AirsAfterSeasonNumber = rval;
}
}
break;
}
case "airsbefore_season":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.AirsBeforeSeasonNumber = rval;
}
}
break;
}

View File

@ -113,7 +113,7 @@ namespace MediaBrowser.Providers.TV
{
get
{
return "3";
return "5";
}
}
@ -404,6 +404,24 @@ namespace MediaBrowser.Providers.TV
break;
}
case "airsbefore_episode":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
{
item.AirsBeforeEpisodeNumber = rval;
}
}
break;
}
case "airsafter_season":
{
var val = reader.ReadElementContentAsString();
@ -415,9 +433,10 @@ namespace MediaBrowser.Providers.TV
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
{
item.SpecialSeasonNumber = rval;
item.AirsAfterSeasonNumber = rval;
}
}
break;
}
@ -432,9 +451,10 @@ namespace MediaBrowser.Providers.TV
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
{
item.SpecialSeasonNumber = rval;
item.AirsBeforeSeasonNumber = rval;
}
}
break;
}

View File

@ -1029,7 +1029,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (episode != null)
{
dto.IndexNumberEnd = episode.IndexNumberEnd;
dto.SpecialSeasonNumber = episode.SpecialSeasonNumber;
dto.SpecialSeasonNumber = episode.AirsAfterSeasonNumber ?? episode.AirsBeforeSeasonNumber;
}
// Add SeriesInfo

View File

@ -1,7 +1,6 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
@ -48,12 +47,12 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// <summary>
/// The audio image resource pool
/// </summary>
private readonly SemaphoreSlim _audioImageResourcePool = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim _audioImageResourcePool = new SemaphoreSlim(2, 2);
/// <summary>
/// The FF probe resource pool
/// </summary>
private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2);
private readonly IFileSystem _fileSystem;
public string FFMpegPath { get; private set; }