jellyfin/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs

419 lines
14 KiB
C#
Raw Normal View History

2013-09-18 11:49:06 -07:00
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
2013-09-15 10:34:48 -07:00
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
2013-09-11 10:54:59 -07:00
using MediaBrowser.Controller.Localization;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
2013-09-11 10:54:59 -07:00
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Api.DefaultTheme
{
[Route("/MBT/DefaultTheme/Games", "GET")]
public class GetGamesView : IReturn<GamesView>
{
[ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid UserId { get; set; }
}
[Route("/MBT/DefaultTheme/TV", "GET")]
public class GetTvView : IReturn<TvView>
{
[ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid UserId { get; set; }
2013-09-15 10:34:48 -07:00
[ApiMember(Name = "ComedyGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string ComedyGenre { get; set; }
[ApiMember(Name = "RomanceGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string RomanceGenre { get; set; }
}
[Route("/MBT/DefaultTheme/Movies", "GET")]
public class GetMovieView : IReturn<MoviesView>
{
[ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid UserId { get; set; }
2013-09-11 10:54:59 -07:00
2013-09-15 12:33:23 -07:00
[ApiMember(Name = "FamilyGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string FamilyGenre { get; set; }
2013-09-15 10:34:48 -07:00
[ApiMember(Name = "ComedyGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string ComedyGenre { get; set; }
[ApiMember(Name = "RomanceGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string RomanceGenre { get; set; }
}
[Route("/MBT/DefaultTheme/Home", "GET")]
public class GetHomeView : IReturn<HomeView>
{
[ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public Guid UserId { get; set; }
}
2013-09-11 10:54:59 -07:00
public class DefaultThemeService : BaseApiService
{
private readonly IUserManager _userManager;
private readonly IDtoService _dtoService;
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
2013-09-18 11:49:06 -07:00
private readonly IImageProcessor _imageProcessor;
2013-09-11 18:35:18 -07:00
2013-10-04 13:08:45 -07:00
public DefaultThemeService(IUserManager userManager, IDtoService dtoService, ILogger logger, ILibraryManager libraryManager, IImageProcessor imageProcessor)
{
_userManager = userManager;
_dtoService = dtoService;
_logger = logger;
_libraryManager = libraryManager;
2013-09-18 11:49:06 -07:00
_imageProcessor = imageProcessor;
}
2013-09-15 10:34:48 -07:00
public object Get(GetHomeView request)
{
2013-09-18 11:49:06 -07:00
var result = GetHomeView(request);
2013-09-15 10:34:48 -07:00
return ToOptimizedResult(result);
}
2013-09-18 11:49:06 -07:00
private HomeView GetHomeView(GetHomeView request)
2013-09-15 10:34:48 -07:00
{
var user = _userManager.GetUserById(request.UserId);
var allItems = user.RootFolder.GetRecursiveChildren(user)
.ToList();
var itemsWithBackdrops = allItems.Where(i => i.BackdropImagePaths.Count > 0).ToList();
var view = new HomeView();
var fields = new List<ItemFields>();
var eligibleSpotlightItems = itemsWithBackdrops
.Where(i => i is Game || i is Movie || i is Series || i is MusicArtist);
2013-09-16 19:44:06 -07:00
var dtos = FilterItemsForBackdropDisplay(eligibleSpotlightItems)
2013-09-15 10:34:48 -07:00
.OrderBy(i => Guid.NewGuid())
.Take(50)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user));
view.SpotlightItems = dtos.ToList();
2013-09-15 10:34:48 -07:00
return view;
}
public object Get(GetGamesView request)
{
2013-09-18 11:49:06 -07:00
var result = GetGamesView(request);
return ToOptimizedResult(result);
}
2013-09-18 11:49:06 -07:00
private GamesView GetGamesView(GetGamesView request)
{
var user = _userManager.GetUserById(request.UserId);
var items = user.RootFolder.GetRecursiveChildren(user)
2013-09-21 14:00:04 -07:00
.Where(i => i is Game || i is GameSystem)
.ToList();
var itemsWithBackdrops = FilterItemsForBackdropDisplay(items.Where(i => i.BackdropImagePaths.Count > 0)).ToList();
var view = new GamesView();
var fields = new List<ItemFields>();
2013-09-16 19:44:06 -07:00
var dtos = itemsWithBackdrops
.OfType<Game>()
.OrderBy(i => Guid.NewGuid())
.Take(50)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user));
view.SpotlightItems = dtos.ToList();
return view;
}
public object Get(GetMovieView request)
{
2013-09-18 11:49:06 -07:00
var result = GetMovieView(request);
return ToOptimizedResult(result);
}
public object Get(GetTvView request)
{
2013-09-18 11:49:06 -07:00
var result = GetTvView(request);
return ToOptimizedResult(result);
}
2013-09-18 11:49:06 -07:00
private TvView GetTvView(GetTvView request)
{
var user = _userManager.GetUserById(request.UserId);
var series = user.RootFolder.GetRecursiveChildren(user)
.OfType<Series>()
.ToList();
var seriesWithBackdrops = series.Where(i => i.BackdropImagePaths.Count > 0).ToList();
var view = new TvView();
2013-09-11 18:35:18 -07:00
var fields = new List<ItemFields>();
2013-09-11 10:54:59 -07:00
2013-09-16 19:44:06 -07:00
var dtos = FilterItemsForBackdropDisplay(seriesWithBackdrops)
.OrderBy(i => Guid.NewGuid())
2013-09-15 10:34:48 -07:00
.Take(50)
.AsParallel()
2013-09-11 10:54:59 -07:00
.Select(i => _dtoService.GetBaseItemDto(i, fields, user));
view.SpotlightItems = dtos.ToList();
view.ShowsItems = series
2013-09-11 18:35:18 -07:00
.Where(i => i.BackdropImagePaths.Count > 0)
.OrderBy(i => Guid.NewGuid())
2013-09-11 18:35:18 -07:00
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-15 10:34:48 -07:00
var romanceGenres = request.RomanceGenre.Split(',').ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
var comedyGenres = request.ComedyGenre.Split(',').ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
view.RomanceItems = seriesWithBackdrops
.Where(i => i.Genres.Any(romanceGenres.ContainsKey))
.OrderBy(i => Guid.NewGuid())
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-15 10:34:48 -07:00
view.ComedyItems = seriesWithBackdrops
.Where(i => i.Genres.Any(comedyGenres.ContainsKey))
.OrderBy(i => Guid.NewGuid())
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-15 10:34:48 -07:00
view.ActorItems = GetActors(series);
return view;
}
2013-09-18 11:49:06 -07:00
private MoviesView GetMovieView(GetMovieView request)
{
var user = _userManager.GetUserById(request.UserId);
var items = user.RootFolder.GetRecursiveChildren(user)
.Where(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 && !(i is Trailer))
.ToList();
2013-09-11 10:54:59 -07:00
var view = new MoviesView();
var movies = items.OfType<Movie>()
.ToList();
var hdMovies = movies.Where(i => i.IsHD).ToList();
2013-09-11 10:54:59 -07:00
2013-09-15 12:33:23 -07:00
var familyGenres = request.FamilyGenre.Split(',').ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
var familyMovies = movies.Where(i => i.Genres.Any(familyGenres.ContainsKey)).ToList();
2013-09-11 10:54:59 -07:00
view.HDMoviePercentage = 100 * hdMovies.Count;
view.HDMoviePercentage /= movies.Count;
view.FamilyMoviePercentage = 100 * familyMovies.Count;
view.FamilyMoviePercentage /= movies.Count;
2013-09-11 18:35:18 -07:00
var moviesWithBackdrops = movies
.Where(i => i.BackdropImagePaths.Count > 0)
.ToList();
var fields = new List<ItemFields>();
2013-09-16 19:44:06 -07:00
var dtos = FilterItemsForBackdropDisplay(itemsWithBackdrops)
.OrderBy(i => Guid.NewGuid())
2013-09-15 10:34:48 -07:00
.Take(50)
2013-09-11 10:54:59 -07:00
.Select(i => _dtoService.GetBaseItemDto(i, fields, user));
view.SpotlightItems = dtos.ToList();
2013-09-11 18:35:18 -07:00
view.MovieItems = moviesWithBackdrops
.OrderBy(i => Guid.NewGuid())
2013-09-11 18:35:18 -07:00
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
view.TrailerItems = items
.OfType<Trailer>()
.Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath))
.OrderBy(i => Guid.NewGuid())
.Select(i => GetItemStub(i, ImageType.Primary))
.Where(i => i != null)
.Take(3)
.ToList();
view.BoxSetItems = items
.OfType<BoxSet>()
2013-09-11 18:35:18 -07:00
.Where(i => i.BackdropImagePaths.Count > 0)
.OrderBy(i => Guid.NewGuid())
2013-09-11 18:35:18 -07:00
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-11 18:35:18 -07:00
view.ThreeDItems = moviesWithBackdrops
.Where(i => i.Is3D)
.OrderBy(i => Guid.NewGuid())
2013-09-11 18:35:18 -07:00
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-15 10:34:48 -07:00
var romanceGenres = request.RomanceGenre.Split(',').ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
var comedyGenres = request.ComedyGenre.Split(',').ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
2013-09-13 18:56:03 -07:00
2013-09-15 10:34:48 -07:00
view.RomanceItems = moviesWithBackdrops
2013-09-13 18:56:03 -07:00
.Where(i => i.Genres.Any(romanceGenres.ContainsKey))
.OrderBy(i => Guid.NewGuid())
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-13 18:56:03 -07:00
2013-09-15 10:34:48 -07:00
view.ComedyItems = moviesWithBackdrops
.Where(i => i.Genres.Any(comedyGenres.ContainsKey))
.OrderBy(i => Guid.NewGuid())
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-15 10:34:48 -07:00
2013-09-11 10:54:59 -07:00
view.HDItems = hdMovies
2013-09-11 18:35:18 -07:00
.Where(i => i.BackdropImagePaths.Count > 0)
2013-09-11 10:54:59 -07:00
.OrderBy(i => Guid.NewGuid())
2013-09-11 18:35:18 -07:00
.Select(i => GetItemStub(i, ImageType.Backdrop))
2013-09-11 10:54:59 -07:00
.Where(i => i != null)
.Take(3)
.ToList();
2013-09-11 10:54:59 -07:00
view.FamilyMovies = familyMovies
2013-09-11 18:35:18 -07:00
.Where(i => i.BackdropImagePaths.Count > 0)
.OrderBy(i => Guid.NewGuid())
2013-09-11 18:35:18 -07:00
.Select(i => GetItemStub(i, ImageType.Backdrop))
.Where(i => i != null)
.Take(3)
.ToList();
view.PeopleItems = GetActors(items);
2013-09-11 10:54:59 -07:00
return view;
}
2013-09-15 10:34:48 -07:00
private IEnumerable<BaseItem> FilterItemsForBackdropDisplay(IEnumerable<BaseItem> items)
{
var tuples = items
.Select(i => new Tuple<BaseItem, double>(i, GetResolution(i, i.BackdropImagePaths[0])))
.Where(i => i.Item2 > 0)
.ToList();
var topItems = tuples
.Where(i => i.Item2 >= 1920)
.ToList();
if (topItems.Count >= 10)
{
return topItems.Select(i => i.Item1);
}
return tuples.Select(i => i.Item1);
}
2013-09-11 18:35:18 -07:00
private double GetResolution(BaseItem item, string path)
{
try
{
2013-09-18 11:49:06 -07:00
var date = item.GetImageDateModified(path);
2013-09-11 18:35:18 -07:00
2013-09-18 11:49:06 -07:00
var size = _imageProcessor.GetImageSize(path, date);
2013-09-11 18:35:18 -07:00
return size.Width;
}
catch
{
return 0;
}
}
private List<ItemStub> GetActors(IEnumerable<BaseItem> mediaItems)
{
var actors = mediaItems.SelectMany(i => i.People)
.Select(i => i.Name)
.Distinct(StringComparer.OrdinalIgnoreCase)
2013-09-11 10:54:59 -07:00
.OrderBy(i => Guid.NewGuid())
.ToList();
return 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(3)
.ToList();
}
private ItemStub GetItemStub(BaseItem item, ImageType imageType)
{
var stub = new ItemStub
{
Id = _dtoService.GetDtoId(item),
2013-09-13 18:56:03 -07:00
Name = item.Name,
ImageType = imageType
};
try
{
2013-09-18 11:49:06 -07:00
var imagePath = item.GetImagePath(imageType, 0);
2013-09-18 11:49:06 -07:00
stub.ImageTag = _imageProcessor.GetImageCacheTag(item, imageType, imagePath);
}
catch (Exception ex)
{
_logger.ErrorException("Error getting image tag for {0}", ex, item.Path);
return null;
}
return stub;
}
}
}