diff options
Diffstat (limited to 'MediaBrowser.Api')
25 files changed, 358 insertions, 881 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 55f191f1a3..117ff2305d 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -63,6 +63,15 @@ namespace MediaBrowser.Api _mediaSourceManager = mediaSourceManager; Instance = this; + _sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress; + } + + void _sessionManager_PlaybackProgress(object sender, PlaybackProgressEventArgs e) + { + if (!string.IsNullOrWhiteSpace(e.PlaySessionId)) + { + PingTranscodingJob(e.PlaySessionId, e.IsPaused); + } } /// <summary> @@ -300,26 +309,31 @@ namespace MediaBrowser.Api PingTimer(job, false); } } - internal void PingTranscodingJob(string playSessionId) + internal void PingTranscodingJob(string playSessionId, bool? isUserPaused) { if (string.IsNullOrEmpty(playSessionId)) { throw new ArgumentNullException("playSessionId"); } - //Logger.Debug("PingTranscodingJob PlaySessionId={0}", playSessionId); + //Logger.Debug("PingTranscodingJob PlaySessionId={0} isUsedPaused: {1}", playSessionId, isUserPaused); - var jobs = new List<TranscodingJob>(); + List<TranscodingJob> jobs; lock (_activeTranscodingJobs) { // This is really only needed for HLS. // Progressive streams can stop on their own reliably - jobs = jobs.Where(j => string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase)).ToList(); + jobs = _activeTranscodingJobs.Where(j => string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase)).ToList(); } foreach (var job in jobs) { + if (isUserPaused.HasValue) + { + //Logger.Debug("Setting job.IsUserPaused to {0}. jobId: {1}", isUserPaused, job.Id); + job.IsUserPaused = isUserPaused.Value; + } PingTimer(job, true); } } @@ -655,6 +669,7 @@ namespace MediaBrowser.Api public object ProcessLock = new object(); public bool HasExited { get; set; } + public bool IsUserPaused { get; set; } public string Id { get; set; } diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index c3b0314480..4f3e3fb283 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -196,9 +196,13 @@ namespace MediaBrowser.Api return name; } - return libraryManager.RootFolder - .GetRecursiveChildren(i => i is IHasArtist) - .Cast<IHasArtist>() + var items = libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name } + }); + + return items + .OfType<IHasArtist>() .SelectMany(i => i.AllArtists) .DistinctNames() .FirstOrDefault(i => @@ -239,8 +243,12 @@ namespace MediaBrowser.Api return name; } - return libraryManager.RootFolder - .GetRecursiveChildren(i => i is Game) + var items = libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Game).Name } + }); + + return items .SelectMany(i => i.Genres) .DistinctNames() .FirstOrDefault(i => diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index a27c872f15..040872fcc8 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Api IncludeItemTypes = new[] { typeof(GameSystem).Name } }; var parentIds = new string[] { } ; - var gameSystems = _libraryManager.GetItems(query, parentIds) + var gameSystems = _libraryManager.GetItemList(query, parentIds) .Cast<GameSystem>() .ToList(); @@ -129,7 +129,7 @@ namespace MediaBrowser.Api IncludeItemTypes = new[] { typeof(Game).Name } }; var parentIds = new string[] { }; - var games = _libraryManager.GetItems(query, parentIds) + var games = _libraryManager.GetItemList(query, parentIds) .Cast<Game>() .ToList(); @@ -192,7 +192,7 @@ namespace MediaBrowser.Api _userDataRepository, _dtoService, Logger, - request, item => item is Game, + request, new[] { typeof(Game) }, SimilarItemsHelper.GetSimiliarityScore); return ToOptimizedSerializedResultUsingCache(result); diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 8d58070fdf..e5fe5bd684 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -699,6 +699,7 @@ namespace MediaBrowser.Api.Images private ImageFormat[] GetClientSupportedFormats() { + //Logger.Debug("Request types: {0}", string.Join(",", Request.AcceptTypes ?? new string[] { })); var supportsWebP = (Request.AcceptTypes ?? new string[] { }).Contains("image/webp", StringComparer.OrdinalIgnoreCase); var userAgent = Request.UserAgent ?? string.Empty; diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 896f8c9908..097546af6d 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -289,7 +289,6 @@ namespace MediaBrowser.Api.Library private readonly IActivityManager _activityManager; private readonly ILocalizationManager _localization; private readonly ILiveTvManager _liveTv; - private readonly IChannelManager _channelManager; private readonly ITVSeriesManager _tvManager; private readonly ILibraryMonitor _libraryMonitor; private readonly IFileSystem _fileSystem; @@ -298,7 +297,7 @@ namespace MediaBrowser.Api.Library /// Initializes a new instance of the <see cref="LibraryService" /> class. /// </summary> public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, - IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv, IChannelManager channelManager, ITVSeriesManager tvManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem) + IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv, ITVSeriesManager tvManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem) { _itemRepo = itemRepo; _libraryManager = libraryManager; @@ -309,7 +308,6 @@ namespace MediaBrowser.Api.Library _activityManager = activityManager; _localization = localization; _liveTv = liveTv; - _channelManager = channelManager; _tvManager = tvManager; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; @@ -379,11 +377,10 @@ namespace MediaBrowser.Api.Library } var program = item as IHasProgramAttributes; - var channelItem = item as ChannelVideoItem; - if (item is Movie || (program != null && program.IsMovie) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Movie) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.MovieExtra)) + if (item is Movie || (program != null && program.IsMovie) || item is Trailer) { - return new MoviesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _channelManager) + return new MoviesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) { AuthorizationContext = AuthorizationContext, Logger = Logger, @@ -400,7 +397,7 @@ namespace MediaBrowser.Api.Library }); } - if (item is Series || (program != null && program.IsSeries) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Episode)) + if (item is Series || (program != null && program.IsSeries)) { return new TvShowsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _tvManager) { @@ -447,13 +444,11 @@ namespace MediaBrowser.Api.Library public void Post(PostUpdatedSeries request) { - var series = _libraryManager.GetItems(new InternalItemsQuery + var series = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Series).Name } - }).Items; - - series = series.Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray(); + }).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray(); if (series.Length > 0) { @@ -470,11 +465,11 @@ namespace MediaBrowser.Api.Library public void Post(PostUpdatedMovies request) { - var movies = _libraryManager.GetItems(new InternalItemsQuery + var movies = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Movie).Name } - }).Items; + }).ToArray(); if (!string.IsNullOrWhiteSpace(request.ImdbId)) { @@ -664,87 +659,38 @@ namespace MediaBrowser.Api.Library /// <returns>System.Object.</returns> public object Get(GetItemCounts request) { - var filteredItems = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, i => i.LocationType != LocationType.Virtual && FilterItem(i, request, request.UserId)); + var user = string.IsNullOrWhiteSpace(request.UserId) ? null : _userManager.GetUserById(request.UserId); var counts = new ItemCounts { - AlbumCount = filteredItems.Count(i => i is MusicAlbum), - EpisodeCount = filteredItems.Count(i => i is Episode), - GameCount = filteredItems.Count(i => i is Game), - GameSystemCount = filteredItems.Count(i => i is GameSystem), - MovieCount = filteredItems.Count(i => i is Movie), - SeriesCount = filteredItems.Count(i => i is Series), - SongCount = filteredItems.Count(i => i is Audio), - MusicVideoCount = filteredItems.Count(i => i is MusicVideo), - BoxSetCount = filteredItems.Count(i => i is BoxSet), - BookCount = filteredItems.Count(i => i is Book), - - UniqueTypes = filteredItems.Select(i => i.GetClientTypeName()).Distinct().ToList() + AlbumCount = GetCount(typeof(MusicAlbum), user, request), + EpisodeCount = GetCount(typeof(Episode), user, request), + GameCount = GetCount(typeof(Game), user, request), + GameSystemCount = GetCount(typeof(GameSystem), user, request), + MovieCount = GetCount(typeof(Movie), user, request), + SeriesCount = GetCount(typeof(Series), user, request), + SongCount = GetCount(typeof(Audio), user, request), + MusicVideoCount = GetCount(typeof(MusicVideo), user, request), + BoxSetCount = GetCount(typeof(BoxSet), user, request), + BookCount = GetCount(typeof(Book), user, request) }; return ToOptimizedSerializedResultUsingCache(counts); } - private IList<BaseItem> GetAllLibraryItems(string userId, IUserManager userManager, ILibraryManager libraryManager, string parentId, Func<BaseItem, bool> filter) - { - if (!string.IsNullOrEmpty(parentId)) - { - var folder = (Folder)libraryManager.GetItemById(new Guid(parentId)); - - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return folder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return folder - .GetRecursiveChildren(filter); - } - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return userManager - .GetUserById(userId) - .RootFolder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return libraryManager - .RootFolder - .GetRecursiveChildren(filter); - } - - private bool FilterItem(BaseItem item, GetItemCounts request, string userId) + private int GetCount(Type type, User user, GetItemCounts request) { - if (!string.IsNullOrWhiteSpace(userId)) - { - if (request.IsFavorite.HasValue) - { - var val = request.IsFavorite.Value; - - if (_userDataManager.GetUserData(userId, item.GetUserDataKey()).IsFavorite != val) - { - return false; - } - } - } + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { type.Name }, + Limit = 0, + Recursive = true, + ExcludeLocationTypes = new[] { LocationType.Virtual }, + SourceTypes = new[] { SourceType.Library }, + IsFavorite = request.IsFavorite + }; - return true; + return _libraryManager.GetItemsResult(query).TotalRecordCount; } /// <summary> @@ -985,20 +931,15 @@ namespace MediaBrowser.Api.Library ? new string[] { } : request.IncludeItemTypes.Split(','); - Func<BaseItem, bool> filter = i => + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var query = new InternalItemsQuery(user) { - if (includeTypes.Length > 0) - { - if (!includeTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - return true; + IncludeItemTypes = includeTypes, + Recursive = true }; - IEnumerable<BaseItem> items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, filter); + var items = _libraryManager.GetItemList(query); var lookup = items .ToLookup(i => i.ProductionYear ?? -1) diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index decd19602c..82931e11ec 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -201,10 +201,10 @@ namespace MediaBrowser.Api.Library var rootFolderPath = _appPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, name); - - if (_fileSystem.DirectoryExists(virtualFolderPath)) + while (_fileSystem.DirectoryExists(virtualFolderPath)) { - throw new ArgumentException("There is already a media library with the name " + name + "."); + name += "1"; + virtualFolderPath = Path.Combine(rootFolderPath, name); } if (request.Paths != null) @@ -236,7 +236,7 @@ namespace MediaBrowser.Api.Library { foreach (var path in request.Paths) { - LibraryHelpers.AddMediaPath(_fileSystem, request.Name, path, _appPaths); + LibraryHelpers.AddMediaPath(_fileSystem, name, path, _appPaths); } } } diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 344d6ab3d3..5b7bc78a8b 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -478,19 +478,30 @@ namespace MediaBrowser.Api.LiveTv public string Feature { get; set; } } + [Route("/LiveTv/TunerHosts/Satip/IniMappings", "GET", Summary = "Gets available mappings")] + [Authenticated(AllowBeforeStartupWizard = true)] + public class GetSatIniMappings : IReturn<List<NameValuePair>> + { + + } + public class LiveTvService : BaseApiService { private readonly ILiveTvManager _liveTvManager; private readonly IUserManager _userManager; private readonly IConfigurationManager _config; private readonly IHttpClient _httpClient; + private readonly ILibraryManager _libraryManager; + private readonly IDtoService _dtoService; - public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IConfigurationManager config, IHttpClient httpClient) + public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService) { _liveTvManager = liveTvManager; _userManager = userManager; _config = config; _httpClient = httpClient; + _libraryManager = libraryManager; + _dtoService = dtoService; } public async Task<object> Get(GetLiveTvRegistrationInfo request) @@ -500,6 +511,11 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedResult(result); } + public object Get(GetSatIniMappings request) + { + return ToOptimizedResult(_liveTvManager.GetSatIniMappings()); + } + public async Task<object> Get(GetSchedulesDirectCountries request) { // https://json.schedulesdirect.org/20141201/available/countries @@ -581,7 +597,7 @@ namespace MediaBrowser.Api.LiveTv public async Task<object> Get(GetChannels request) { - var result = await _liveTvManager.GetChannels(new LiveTvChannelQuery + var channelResult = await _liveTvManager.GetInternalChannels(new LiveTvChannelQuery { ChannelType = request.Type, UserId = request.UserId, @@ -593,16 +609,30 @@ namespace MediaBrowser.Api.LiveTv EnableFavoriteSorting = request.EnableFavoriteSorting, AddCurrentProgram = request.AddCurrentProgram - }, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); + }, CancellationToken.None).ConfigureAwait(false); + + var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); + + var returnArray = _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ToArray(); + var result = new QueryResult<BaseItemDto> + { + Items = returnArray, + TotalRecordCount = channelResult.TotalRecordCount + }; + return ToOptimizedSerializedResultUsingCache(result); } - public async Task<object> Get(GetChannel request) + public object Get(GetChannel request) { - var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); + var user = string.IsNullOrWhiteSpace(request.UserId) ? null : _userManager.GetUserById(request.UserId); + + var item = _libraryManager.GetItemById(request.Id); + + var dtoOptions = GetDtoOptions(request); - var result = await _liveTvManager.GetChannel(request.Id, CancellationToken.None, user).ConfigureAwait(false); + var result = _dtoService.GetBaseItemDto(item, dtoOptions, user); return ToOptimizedSerializedResultUsingCache(result); } diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index be79f4d74f..cdc0cd6aea 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -47,7 +47,7 @@ <ItemGroup> <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath> + <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath> </Reference> <Reference Include="MoreLinq"> <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 36cbc6ffa6..b3d485dc70 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -91,22 +91,21 @@ namespace MediaBrowser.Api.Movies private readonly IItemRepository _itemRepo; private readonly IDtoService _dtoService; - private readonly IChannelManager _channelManager; - /// <summary> - /// Initializes a new instance of the <see cref="MoviesService"/> class. + /// Initializes a new instance of the <see cref="MoviesService" /> class. /// </summary> /// <param name="userManager">The user manager.</param> /// <param name="userDataRepository">The user data repository.</param> /// <param name="libraryManager">The library manager.</param> - public MoviesService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService, IChannelManager channelManager) + /// <param name="itemRepo">The item repo.</param> + /// <param name="dtoService">The dto service.</param> + public MoviesService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService) { _userManager = userManager; _userDataRepository = userDataRepository; _libraryManager = libraryManager; _itemRepo = itemRepo; _dtoService = dtoService; - _channelManager = channelManager; } /// <summary> @@ -138,8 +137,16 @@ namespace MediaBrowser.Api.Movies { IncludeItemTypes = new[] { typeof(Movie).Name } }; + + if (user.Configuration.IncludeTrailersInSuggestions) + { + var includeList = query.IncludeItemTypes.ToList(); + includeList.Add(typeof(Trailer).Name); + query.IncludeItemTypes = includeList.ToArray(); + } + var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; - var movies = _libraryManager.GetItems(query, parentIds); + var movies = _libraryManager.GetItemList(query, parentIds); movies = _libraryManager.ReplaceVideosWithPrimaryVersions(movies); var listEligibleForCategories = new List<BaseItem>(); @@ -150,19 +157,6 @@ namespace MediaBrowser.Api.Movies listEligibleForCategories.AddRange(list); listEligibleForSuggestion.AddRange(list); - if (user.Configuration.IncludeTrailersInSuggestions) - { - var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery - { - ContentTypes = new[] { ChannelMediaContentType.MovieExtra }, - ExtraTypes = new[] { ExtraType.Trailer }, - UserId = user.Id.ToString("N") - - }, CancellationToken.None).ConfigureAwait(false); - - listEligibleForSuggestion.AddRange(trailerResult.Items); - } - listEligibleForCategories = listEligibleForCategories .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) @@ -194,36 +188,25 @@ namespace MediaBrowser.Api.Movies { IncludeItemTypes = new[] { typeof(Movie).Name } }; + + if (user == null || user.Configuration.IncludeTrailersInSuggestions) + { + var includeList = query.IncludeItemTypes.ToList(); + includeList.Add(typeof(Trailer).Name); + query.IncludeItemTypes = includeList.ToArray(); + } + var parentIds = new string[] { }; - var list = _libraryManager.GetItems(query, parentIds) + var list = _libraryManager.GetItemList(query, parentIds) .Where(i => { // Strip out secondary versions var v = i as Video; return v != null && !v.PrimaryVersionId.HasValue; }) + .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) .ToList(); - if (user != null && user.Configuration.IncludeTrailersInSuggestions) - { - var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery - { - ContentTypes = new[] { ChannelMediaContentType.MovieExtra }, - ExtraTypes = new[] { ExtraType.Trailer }, - UserId = user.Id.ToString("N") - - }, CancellationToken.None).ConfigureAwait(false); - - var newTrailers = trailerResult.Items; - - list.AddRange(newTrailers); - - list = list - .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) - .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) - .ToList(); - } - if (item is Video) { var imdbId = item.GetProviderId(MetadataProviders.Imdb); diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs index ed197911a0..4883b38fb0 100644 --- a/MediaBrowser.Api/Movies/TrailersService.cs +++ b/MediaBrowser.Api/Movies/TrailersService.cs @@ -12,6 +12,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Collections; +using MediaBrowser.Controller.Localization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Api.Movies { @@ -41,87 +44,37 @@ namespace MediaBrowser.Api.Movies private readonly ILibraryManager _libraryManager; private readonly IDtoService _dtoService; - private readonly IChannelManager _channelManager; + private readonly ICollectionManager _collectionManager; + private readonly ILocalizationManager _localizationManager; + private readonly IJsonSerializer _json; - /// <summary> - /// Initializes a new instance of the <see cref="TrailersService"/> class. - /// </summary> - /// <param name="userManager">The user manager.</param> - /// <param name="userDataRepository">The user data repository.</param> - /// <param name="libraryManager">The library manager.</param> - public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IDtoService dtoService, IChannelManager channelManager) + public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IDtoService dtoService, ICollectionManager collectionManager, ILocalizationManager localizationManager, IJsonSerializer json) { _userManager = userManager; _userDataRepository = userDataRepository; _libraryManager = libraryManager; _dtoService = dtoService; - _channelManager = channelManager; + _collectionManager = collectionManager; + _localizationManager = localizationManager; + _json = json; } - public async Task<object> Get(Getrailers request) + public object Get(Getrailers request) { - var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; - var result = await GetAllTrailers(user).ConfigureAwait(false); - - IEnumerable<BaseItem> items = result.Items; - - // Apply filters - // Run them starting with the ones that are likely to reduce the list the most - foreach (var filter in request.GetFilters().OrderByDescending(f => (int)f)) - { - items = ItemsService.ApplyFilter(items, filter, user, _userDataRepository); - } - - items = _libraryManager.Sort(items, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending); + var json = _json.SerializeToString(request); + var getItems = _json.DeserializeFromString<GetItems>(json); - var itemsArray = items.ToList(); + getItems.IncludeItemTypes = "Trailer"; - var pagedItems = ApplyPaging(request, itemsArray); - - var dtoOptions = GetDtoOptions(request); - - var returnItems = _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user).ToArray(); - - return new ItemsResult + return new ItemsService(_userManager, _libraryManager, _userDataRepository, _localizationManager, _dtoService, _collectionManager) { - TotalRecordCount = itemsArray.Count, - Items = returnItems - }; - } + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + ResultFactory = ResultFactory, + SessionContext = SessionContext - private IEnumerable<BaseItem> ApplyPaging(Getrailers request, IEnumerable<BaseItem> items) - { - // Start at - if (request.StartIndex.HasValue) - { - items = items.Skip(request.StartIndex.Value); - } - - // Return limit - if (request.Limit.HasValue) - { - items = items.Take(request.Limit.Value); - } - - return items; - } - - private async Task<QueryResult<BaseItem>> GetAllTrailers(User user) - { - var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery - { - ContentTypes = new[] { ChannelMediaContentType.MovieExtra }, - ExtraTypes = new[] { ExtraType.Trailer }, - UserId = user.Id.ToString("N") - - }, CancellationToken.None).ConfigureAwait(false); - - - return new QueryResult<BaseItem> - { - Items = trailerResult.Items, - TotalRecordCount = trailerResult.TotalRecordCount - }; + }.Get(getItems); } } } diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index 548598d429..9628ab2319 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -52,10 +52,15 @@ namespace MediaBrowser.Api.Music public object Get(GetSimilarArtists request) { - var result = GetSimilarItemsResult( - - request, + var dtoOptions = GetDtoOptions(request); + var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + _itemRepo, + _libraryManager, + _userDataRepository, + _dtoService, + Logger, + request, new[] { typeof(MusicArtist) }, SimilarItemsHelper.GetSimiliarityScore); return ToOptimizedSerializedResultUsingCache(result); @@ -76,44 +81,11 @@ namespace MediaBrowser.Api.Music _userDataRepository, _dtoService, Logger, - request, item => item is MusicAlbum, + request, new[] { typeof(MusicAlbum) }, GetAlbumSimilarityScore); return ToOptimizedSerializedResultUsingCache(result); } - - private ItemsResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore) - { - var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; - - var item = string.IsNullOrEmpty(request.Id) ? - (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : - _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - - var inputItems = _libraryManager.GetArtists(user.RootFolder.GetRecursiveChildren(user, i => i is IHasArtist).OfType<IHasArtist>()); - - var list = inputItems.ToList(); - - var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList(); - - IEnumerable<BaseItem> returnItems = items; - - if (request.Limit.HasValue) - { - returnItems = returnItems.Take(request.Limit.Value); - } - - var dtoOptions = GetDtoOptions(request); - - var result = new ItemsResult - { - Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), - - TotalRecordCount = items.Count - }; - - return result; - } /// <summary> /// Gets the album similarity score. diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index f66363da67..9d2c8c4448 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -214,7 +214,7 @@ namespace MediaBrowser.Api.Playback args += " -map -0:a"; } - if (state.SubtitleStream == null) + if (state.SubtitleStream == null || state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Hls) { args += " -map -0:s"; } @@ -477,7 +477,7 @@ namespace MediaBrowser.Api.Playback var pts = string.Empty; - if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && !state.VideoRequest.CopyTimestamps) + if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode && !state.VideoRequest.CopyTimestamps) { var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds; @@ -575,7 +575,7 @@ namespace MediaBrowser.Api.Playback var output = string.Empty; - if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream) + if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode) { var subParam = GetTextSubtitleParam(state); @@ -865,7 +865,7 @@ namespace MediaBrowser.Api.Playback { var arg = string.Format("-i {0}", GetInputPathArgument(state)); - if (state.SubtitleStream != null) + if (state.SubtitleStream != null && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode) { if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) { @@ -1482,6 +1482,17 @@ namespace MediaBrowser.Api.Playback videoRequest.CopyTimestamps = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); } } + else if (i == 25) + { + if (!string.IsNullOrWhiteSpace(val) && videoRequest != null) + { + SubtitleDeliveryMethod method; + if (Enum.TryParse(val, out method)) + { + videoRequest.SubtitleMethod = method; + } + } + } } } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 4a83615b4d..000c022567 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -529,7 +529,12 @@ namespace MediaBrowser.Api.Playback.Hls "subs" : null; - AppendPlaylist(builder, playlistUrl, totalBitrate, subtitleGroup); + if (!string.IsNullOrWhiteSpace(subtitleGroup)) + { + AddSubtitles(state, subtitleStreams, builder); + } + + AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup); if (EnableAdaptiveBitrateStreaming(state, isLiveStream)) { @@ -540,17 +545,12 @@ namespace MediaBrowser.Api.Playback.Hls var newBitrate = totalBitrate - variation; var variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, (requestedVideoBitrate - variation)); - AppendPlaylist(builder, variantUrl, newBitrate, subtitleGroup); + AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup); variation *= 2; newBitrate = totalBitrate - variation; variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, (requestedVideoBitrate - variation)); - AppendPlaylist(builder, variantUrl, newBitrate, subtitleGroup); - } - - if (!string.IsNullOrWhiteSpace(subtitleGroup)) - { - AddSubtitles(state, subtitleStreams, builder); + AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup); } return builder.ToString(); @@ -566,11 +566,11 @@ namespace MediaBrowser.Api.Playback.Hls private void AddSubtitles(StreamState state, IEnumerable<MediaStream> subtitles, StringBuilder builder) { - var selectedIndex = state.SubtitleStream == null ? (int?)null : state.SubtitleStream.Index; + var selectedIndex = state.SubtitleStream == null || state.VideoRequest.SubtitleMethod != SubtitleDeliveryMethod.Hls ? (int?)null : state.SubtitleStream.Index; foreach (var stream in subtitles) { - const string format = "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"{0}\",DEFAULT={1},FORCED={2},URI=\"{3}\",LANGUAGE=\"{4}\""; + const string format = "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"{0}\",DEFAULT={1},FORCED={2},AUTOSELECT=YES,URI=\"{3}\",LANGUAGE=\"{4}\""; var name = stream.Language; @@ -579,10 +579,11 @@ namespace MediaBrowser.Api.Playback.Hls if (string.IsNullOrWhiteSpace(name)) name = stream.Codec ?? "Unknown"; - var url = string.Format("{0}/Subtitles/{1}/subtitles.m3u8?SegmentLength={2}", + var url = string.Format("{0}/Subtitles/{1}/subtitles.m3u8?SegmentLength={2}&api_key={3}", state.Request.MediaSourceId, stream.Index.ToString(UsCulture), - 30.ToString(UsCulture)); + 30.ToString(UsCulture), + AuthorizationContext.GetAuthorizationInfo(Request).Token); var line = string.Format(format, name, @@ -635,9 +636,15 @@ namespace MediaBrowser.Api.Playback.Hls //return state.VideoRequest.VideoBitRate.HasValue; } - private void AppendPlaylist(StringBuilder builder, string url, int bitrate, string subtitleGroup) + private void AppendPlaylist(StringBuilder builder, StreamState state, string url, int bitrate, string subtitleGroup) { - var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(UsCulture); + var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(UsCulture) + ",AVERAGE-BANDWIDTH=" + bitrate.ToString(UsCulture); + + // tvos wants resolution, codecs, framerate + //if (state.TargetFramerate.HasValue) + //{ + // header += string.Format(",FRAME-RATE=\"{0}\"", state.TargetFramerate.Value.ToString(CultureInfo.InvariantCulture)); + //} if (!string.IsNullOrWhiteSpace(subtitleGroup)) { @@ -694,6 +701,7 @@ namespace MediaBrowser.Api.Playback.Hls var builder = new StringBuilder(); builder.AppendLine("#EXTM3U"); + builder.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD"); builder.AppendLine("#EXT-X-VERSION:3"); builder.AppendLine("#EXT-X-TARGETDURATION:" + Math.Ceiling((segmentLengths.Length > 0 ? segmentLengths.Max() : state.SegmentLength)).ToString(UsCulture)); builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); @@ -820,7 +828,7 @@ namespace MediaBrowser.Api.Playback.Hls var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", state.SegmentLength.ToString(UsCulture)); - var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; + var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode; args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg; @@ -846,7 +854,7 @@ namespace MediaBrowser.Api.Playback.Hls private bool EnableCopyTs(StreamState state) { - return state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream; + return state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode; } protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding) diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index 22c38009a6..f8adbdc227 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -9,6 +9,7 @@ using MediaBrowser.Model.Serialization; using ServiceStack; using System; using CommonIO; +using MediaBrowser.Model.Dlna; namespace MediaBrowser.Api.Playback.Hls { @@ -104,7 +105,7 @@ namespace MediaBrowser.Api.Playback.Hls var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", state.SegmentLength.ToString(UsCulture)); - var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; + var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode; args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg; diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index ada4761c75..1d8f5003f1 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -73,9 +73,13 @@ namespace MediaBrowser.Api.Playback.Progressive audioTranscodeParams.Add("-ac " + state.OutputAudioChannels.Value.ToString(UsCulture)); } - if (state.OutputAudioSampleRate.HasValue) + // opus will fail on 44100 + if (!string.Equals(state.OutputAudioCodec, "opus", global::System.StringComparison.OrdinalIgnoreCase)) { - audioTranscodeParams.Add("-ar " + state.OutputAudioSampleRate.Value.ToString(UsCulture)); + if (state.OutputAudioSampleRate.HasValue) + { + audioTranscodeParams.Add("-ar " + state.OutputAudioSampleRate.Value.ToString(UsCulture)); + } } const string vn = " -vn"; diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 2719b1faf5..f766f46b1f 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -61,8 +61,9 @@ namespace MediaBrowser.Api.Playback.Progressive { try { - new ProgressiveFileCopier(_fileSystem, _job) - .StreamFile(Path, responseStream); + var task = new ProgressiveFileCopier(_fileSystem, _job, Logger).StreamFile(Path, responseStream); + + Task.WaitAll(task); } catch (IOException) { @@ -91,19 +92,21 @@ namespace MediaBrowser.Api.Playback.Progressive { private readonly IFileSystem _fileSystem; private readonly TranscodingJob _job; + private readonly ILogger _logger; // 256k private const int BufferSize = 262144; - + private long _bytesWritten = 0; - public ProgressiveFileCopier(IFileSystem fileSystem, TranscodingJob job) + public ProgressiveFileCopier(IFileSystem fileSystem, TranscodingJob job, ILogger logger) { _fileSystem = fileSystem; _job = job; + _logger = logger; } - public void StreamFile(string path, Stream outputStream) + public async Task StreamFile(string path, Stream outputStream) { var eofCount = 0; long position = 0; @@ -126,8 +129,7 @@ namespace MediaBrowser.Api.Playback.Progressive { eofCount++; } - var task = Task.Delay(100); - Task.WaitAll(task); + await Task.Delay(100).ConfigureAwait(false); } else { @@ -145,6 +147,30 @@ namespace MediaBrowser.Api.Playback.Progressive int count; while ((count = source.Read(array, 0, array.Length)) != 0) { + //if (_job != null) + //{ + // var didPause = false; + // var totalPauseTime = 0; + + // if (_job.IsUserPaused) + // { + // _logger.Debug("Pausing writing to network stream while user has paused playback."); + + // while (_job.IsUserPaused && totalPauseTime < 30000) + // { + // didPause = true; + // var pauseTime = 500; + // totalPauseTime += pauseTime; + // await Task.Delay(pauseTime).ConfigureAwait(false); + // } + // } + + // if (didPause) + // { + // _logger.Debug("Resuming writing to network stream due to user unpausing playback."); + // } + //} + destination.Write(array, 0, count); _bytesWritten += count; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index b7e180eca0..1353d8fe73 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -13,6 +13,7 @@ using System; using System.Globalization; using System.IO; using CommonIO; +using MediaBrowser.Model.Dlna; namespace MediaBrowser.Api.Playback.Progressive { @@ -161,7 +162,7 @@ namespace MediaBrowser.Api.Playback.Progressive args += keyFrameArg; - var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; + var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode; var hasCopyTs = false; // Add resolution params, if specified diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs index 6cbe2fd892..ae6fbc9e24 100644 --- a/MediaBrowser.Api/Reports/ReportsService.cs +++ b/MediaBrowser.Api/Reports/ReportsService.cs @@ -213,8 +213,6 @@ namespace MediaBrowser.Api.Reports SortBy = request.GetOrderBy(), SortOrder = request.SortOrder ?? SortOrder.Ascending, - Filter = i => ApplyAdditionalFilters(request, i, user, _libraryManager), - IsFavorite = request.IsFavorite, Limit = request.Limit, StartIndex = request.StartIndex, @@ -258,7 +256,10 @@ namespace MediaBrowser.Api.Reports MinPlayers = request.MinPlayers, MaxPlayers = request.MaxPlayers, MinCommunityRating = request.MinCommunityRating, - MinCriticRating = request.MinCriticRating + MinCriticRating = request.MinCriticRating, + ParentIndexNumber = request.ParentIndexNumber, + AiredDuringSeason = request.AiredDuringSeason, + AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater }; if (!string.IsNullOrWhiteSpace(request.Ids)) @@ -302,285 +303,79 @@ namespace MediaBrowser.Api.Reports } } - if (request.HasQueryLimit == false) - { - query.StartIndex = null; - query.Limit = null; - } - - return query; - } - - private bool ApplyAdditionalFilters(BaseReportRequest request, BaseItem i, User user, ILibraryManager libraryManager) - { - // Artists - if (!string.IsNullOrEmpty(request.ArtistIds)) - { - var artistIds = request.ArtistIds.Split(new[] { '|', ',' }); - - var audio = i as IHasArtist; - - if (!(audio != null && artistIds.Any(id => - { - var artistItem = libraryManager.GetItemById(id); - return artistItem != null && audio.HasAnyArtist(artistItem.Name); - }))) - { - return false; - } - } - - // Artists - if (!string.IsNullOrEmpty(request.Artists)) - { - var artists = request.Artists.Split('|'); - - var audio = i as IHasArtist; - - if (!(audio != null && artists.Any(audio.HasAnyArtist))) - { - return false; - } - } - - // Albums - if (!string.IsNullOrEmpty(request.Albums)) - { - var albums = request.Albums.Split('|'); - - var audio = i as Audio; - - if (audio != null) - { - if (!albums.Any(a => string.Equals(a, audio.Album, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - var album = i as MusicAlbum; - - if (album != null) - { - if (!albums.Any(a => string.Equals(a, album.Name, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - var musicVideo = i as MusicVideo; - - if (musicVideo != null) - { - if (!albums.Any(a => string.Equals(a, musicVideo.Album, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - return false; - } - - // Min index number - if (request.MinIndexNumber.HasValue) + if (!string.IsNullOrEmpty(request.MinPremiereDate)) { - if (!(i.IndexNumber.HasValue && i.IndexNumber.Value >= request.MinIndexNumber.Value)) - { - return false; - } + query.MinPremiereDate = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); } - // Min official rating - if (!string.IsNullOrEmpty(request.MinOfficialRating)) + if (!string.IsNullOrEmpty(request.MaxPremiereDate)) { - var level = _localization.GetRatingLevel(request.MinOfficialRating); - - if (level.HasValue) - { - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (!string.IsNullOrEmpty(rating)) - { - var itemLevel = _localization.GetRatingLevel(rating); - - if (!(!itemLevel.HasValue || itemLevel.Value >= level.Value)) - { - return false; - } - } - } + query.MaxPremiereDate = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); } - // Max official rating - if (!string.IsNullOrEmpty(request.MaxOfficialRating)) + // Filter by Series Status + if (!string.IsNullOrEmpty(request.SeriesStatus)) { - var level = _localization.GetRatingLevel(request.MaxOfficialRating); - - if (level.HasValue) - { - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (!string.IsNullOrEmpty(rating)) - { - var itemLevel = _localization.GetRatingLevel(rating); - - if (!(!itemLevel.HasValue || itemLevel.Value <= level.Value)) - { - return false; - } - } - } + query.SeriesStatuses = request.SeriesStatus.Split(',').Select(d => (SeriesStatus)Enum.Parse(typeof(SeriesStatus), d, true)).ToArray(); } - // LocationTypes - if (!string.IsNullOrEmpty(request.LocationTypes)) + // Filter by Series AirDays + if (!string.IsNullOrEmpty(request.AirDays)) { - var vals = request.LocationTypes.Split(','); - if (!vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } + query.AirDays = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)).ToArray(); } // ExcludeLocationTypes if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) { - var vals = request.ExcludeLocationTypes.Split(','); - if (vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } + query.ExcludeLocationTypes = request.ExcludeLocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); } - if (!string.IsNullOrEmpty(request.AlbumArtistStartsWithOrGreater)) - { - var ok = new[] { i }.OfType<IHasAlbumArtist>() - .Any(p => string.Compare(request.AlbumArtistStartsWithOrGreater, p.AlbumArtists.FirstOrDefault(), StringComparison.CurrentCultureIgnoreCase) < 1); - - if (!ok) - { - return false; - } - } - - // Filter by Series Status - if (!string.IsNullOrEmpty(request.SeriesStatus)) + if (!string.IsNullOrEmpty(request.LocationTypes)) { - var vals = request.SeriesStatus.Split(','); - - var ok = new[] { i }.OfType<Series>().Any(p => p.Status.HasValue && vals.Contains(p.Status.Value.ToString(), StringComparer.OrdinalIgnoreCase)); - - if (!ok) - { - return false; - } + query.LocationTypes = request.LocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); } - // Filter by Series AirDays - if (!string.IsNullOrEmpty(request.AirDays)) + // Min official rating + if (!string.IsNullOrEmpty(request.MinOfficialRating)) { - var days = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)); - - var ok = new[] { i }.OfType<Series>().Any(p => p.AirDays != null && days.Any(d => p.AirDays.Contains(d))); - - if (!ok) - { - return false; - } + query.MinParentalRating = _localization.GetRatingLevel(request.MinOfficialRating); } - if (request.ParentIndexNumber.HasValue) - { - var filterValue = request.ParentIndexNumber.Value; - - var episode = i as Episode; - - if (episode != null) - { - if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - - var song = i as Audio; - - if (song != null) - { - if (song.ParentIndexNumber.HasValue && song.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - } - - if (request.AiredDuringSeason.HasValue) + // Max official rating + if (!string.IsNullOrEmpty(request.MaxOfficialRating)) { - var episode = i as Episode; - - if (episode == null) - { - return false; - } - - if (!Series.FilterEpisodesBySeason(new[] { episode }, request.AiredDuringSeason.Value, true).Any()) - { - return false; - } + query.MaxParentalRating = _localization.GetRatingLevel(request.MinOfficialRating); } - if (!string.IsNullOrEmpty(request.MinPremiereDate)) + // Artists + if (!string.IsNullOrEmpty(request.ArtistIds)) { - var date = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); + var artistIds = request.ArtistIds.Split(new[] { '|', ',' }); - if (!(i.PremiereDate.HasValue && i.PremiereDate.Value >= date)) - { - return false; - } + var artistItems = artistIds.Select(_libraryManager.GetItemById).Where(i => i != null).ToList(); + query.ArtistNames = artistItems.Select(i => i.Name).ToArray(); } - if (!string.IsNullOrEmpty(request.MaxPremiereDate)) + // Artists + if (!string.IsNullOrEmpty(request.Artists)) { - var date = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); - - if (!(i.PremiereDate.HasValue && i.PremiereDate.Value <= date)) - { - return false; - } + query.ArtistNames = request.Artists.Split('|'); } - return true; - } - - /// <summary> Applies the paging. </summary> - /// <param name="request"> The request. </param> - /// <param name="items"> The items. </param> - /// <returns> IEnumerable{BaseItem}. </returns> - private IEnumerable<BaseItem> ApplyPaging(BaseReportRequest request, IEnumerable<BaseItem> items) - { - // Start at - if (request.StartIndex.HasValue) + // Albums + if (!string.IsNullOrEmpty(request.Albums)) { - items = items.Skip(request.StartIndex.Value); + query.AlbumNames = request.Albums.Split('|'); } - // Return limit - if (request.Limit.HasValue) + if (request.HasQueryLimit == false) { - items = items.Take(request.Limit.Value); + query.StartIndex = null; + query.Limit = null; } - return items; + return query; } /// <summary> Gets query result. </summary> diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index d114446eeb..277bba1dd1 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -54,21 +54,7 @@ namespace MediaBrowser.Api /// </summary> public static class SimilarItemsHelper { - /// <summary> - /// Gets the similar items. - /// </summary> - /// <param name="dtoOptions">The dto options.</param> - /// <param name="userManager">The user manager.</param> - /// <param name="itemRepository">The item repository.</param> - /// <param name="libraryManager">The library manager.</param> - /// <param name="userDataRepository">The user data repository.</param> - /// <param name="dtoService">The dto service.</param> - /// <param name="logger">The logger.</param> - /// <param name="request">The request.</param> - /// <param name="includeInSearch">The include in search.</param> - /// <param name="getSimilarityScore">The get similarity score.</param> - /// <returns>ItemsResult.</returns> - internal static ItemsResult GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Func<BaseItem, bool> includeInSearch, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore) + internal static ItemsResult GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? userManager.GetUserById(request.UserId) : null; @@ -76,11 +62,13 @@ namespace MediaBrowser.Api (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : libraryManager.RootFolder) : libraryManager.GetItemById(request.Id); - Func<BaseItem, bool> filter = i => i.Id != item.Id && includeInSearch(i); + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = includeTypes.Select(i => i.Name).ToArray(), + Recursive = true + }; - var inputItems = user == null - ? libraryManager.RootFolder.GetRecursiveChildren(filter) - : user.RootFolder.GetRecursiveChildren(user, filter); + var inputItems = libraryManager.GetItemList(query); var items = GetSimilaritems(item, libraryManager, inputItems, getSimilarityScore) .ToList(); diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 06db1de745..14bd6b61f6 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -68,6 +68,8 @@ namespace MediaBrowser.Api _config.Configuration.EnableLocalizedGuids = true; _config.Configuration.EnableCustomPathSubFolders = true; _config.Configuration.EnableDateLastRefresh = true; + _config.Configuration.EnableStandaloneMusicKeys = true; + _config.Configuration.EnableCaseSensitiveItemIds = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index 37034751d8..ff17e988ea 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -164,6 +164,8 @@ namespace MediaBrowser.Api.Subtitles long positionTicks = 0; var segmentLengthTicks = TimeSpan.FromSeconds(request.SegmentLength).Ticks; + var accessToken = AuthorizationContext.GetAuthorizationInfo(Request).Token; + while (positionTicks < runtime) { var remaining = runtime - positionTicks; @@ -173,9 +175,10 @@ namespace MediaBrowser.Api.Subtitles var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); - var url = string.Format("stream.srt?StartPositionTicks={0}&EndPositionTicks={1}", + var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", positionTicks.ToString(CultureInfo.InvariantCulture), - endPositionTicks.ToString(CultureInfo.InvariantCulture)); + endPositionTicks.ToString(CultureInfo.InvariantCulture), + accessToken); builder.AppendLine(url); diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 2dad9533fe..5b5b0a9024 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -263,7 +263,7 @@ namespace MediaBrowser.Api _userDataManager, _dtoService, Logger, - request, item => item is Series, + request, new[] { typeof(Series) }, SimilarItemsHelper.GetSimiliarityScore); return ToOptimizedSerializedResultUsingCache(result); @@ -273,11 +273,11 @@ namespace MediaBrowser.Api { var user = _userManager.GetUserById(request.UserId); - var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime(); + var minPremiereDate = DateTime.Now.Date.ToUniversalTime(); var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; - var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user) + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { "PremiereDate", "AirTime", "SortName" }, @@ -286,15 +286,15 @@ namespace MediaBrowser.Api StartIndex = request.StartIndex, Limit = request.Limit - }, parentIds); + }, parentIds).ToList(); var options = GetDtoOptions(request); - var returnItems = _dtoService.GetBaseItemDtos(itemsResult.Items, options, user).ToArray(); + var returnItems = _dtoService.GetBaseItemDtos(itemsResult, options, user).ToArray(); var result = new ItemsResult { - TotalRecordCount = itemsResult.TotalRecordCount, + TotalRecordCount = itemsResult.Count, Items = returnItems }; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 761d107603..ea7e16e8d6 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -85,17 +85,16 @@ namespace MediaBrowser.Api.UserLibrary /// <returns>Task{ItemsResult}.</returns> private async Task<ItemsResult> GetItems(GetItems request) { - var parentItem = string.IsNullOrEmpty(request.ParentId) ? null : _libraryManager.GetItemById(request.ParentId); var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; - var result = await GetItemsToSerialize(request, user, parentItem).ConfigureAwait(false); + var result = await GetItemsToSerialize(request, user).ConfigureAwait(false); var dtoOptions = GetDtoOptions(request); return new ItemsResult { - TotalRecordCount = result.Item1.TotalRecordCount, - Items = _dtoService.GetBaseItemDtos(result.Item1.Items, dtoOptions, user).ToArray() + TotalRecordCount = result.TotalRecordCount, + Items = _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ToArray() }; } @@ -104,17 +103,16 @@ namespace MediaBrowser.Api.UserLibrary /// </summary> /// <param name="request">The request.</param> /// <param name="user">The user.</param> - /// <param name="parentItem">The parent item.</param> /// <returns>IEnumerable{BaseItem}.</returns> - private async Task<Tuple<QueryResult<BaseItem>, bool>> GetItemsToSerialize(GetItems request, User user, BaseItem parentItem) + private async Task<QueryResult<BaseItem>> GetItemsToSerialize(GetItems request, User user) { var item = string.IsNullOrEmpty(request.ParentId) ? user == null ? _libraryManager.RootFolder : user.RootFolder : - parentItem; + _libraryManager.GetItemById(request.ParentId); if (string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase)) { - item = user == null ? _libraryManager.RootFolder : user.RootFolder; + //item = user == null ? _libraryManager.RootFolder : user.RootFolder; } else if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase)) { @@ -137,21 +135,21 @@ namespace MediaBrowser.Api.UserLibrary result.Items = result.Items.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); } - return new Tuple<QueryResult<BaseItem>, bool>(result, true); + return result; } if (request.Recursive) { var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); - return new Tuple<QueryResult<BaseItem>, bool>(result, true); + return result; } if (user == null) { var result = await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); - return new Tuple<QueryResult<BaseItem>, bool>(result, true); + return result; } var userRoot = item as UserRootFolder; @@ -160,26 +158,24 @@ namespace MediaBrowser.Api.UserLibrary { var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); - return new Tuple<QueryResult<BaseItem>, bool>(result, true); + return result; } IEnumerable<BaseItem> items = ((Folder)item).GetChildren(user, true); var itemsArray = items.ToArray(); - return new Tuple<QueryResult<BaseItem>, bool>(new QueryResult<BaseItem> + return new QueryResult<BaseItem> { Items = itemsArray, TotalRecordCount = itemsArray.Length - - }, false); + }; } private InternalItemsQuery GetItemsQuery(GetItems request, User user) { - var query = new InternalItemsQuery + var query = new InternalItemsQuery(user) { - User = user, IsPlayed = request.IsPlayed, MediaTypes = request.GetMediaTypes(), IncludeItemTypes = request.GetIncludeItemTypes(), @@ -188,8 +184,6 @@ namespace MediaBrowser.Api.UserLibrary SortBy = request.GetOrderBy(), SortOrder = request.SortOrder ?? SortOrder.Ascending, - Filter = i => ApplyAdditionalFilters(request, i, user, _libraryManager), - IsFavorite = request.IsFavorite, Limit = request.Limit, StartIndex = request.StartIndex, @@ -234,7 +228,11 @@ namespace MediaBrowser.Api.UserLibrary MinPlayers = request.MinPlayers, MaxPlayers = request.MaxPlayers, MinCommunityRating = request.MinCommunityRating, - MinCriticRating = request.MinCriticRating + MinCriticRating = request.MinCriticRating, + ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId), + ParentIndexNumber = request.ParentIndexNumber, + AiredDuringSeason = request.AiredDuringSeason, + AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater }; if (!string.IsNullOrWhiteSpace(request.Ids)) @@ -278,331 +276,73 @@ namespace MediaBrowser.Api.UserLibrary } } - return query; - } - - /// <summary> - /// Applies filtering - /// </summary> - /// <param name="items">The items.</param> - /// <param name="filter">The filter.</param> - /// <param name="user">The user.</param> - /// <param name="repository">The repository.</param> - /// <returns>IEnumerable{BaseItem}.</returns> - internal static IEnumerable<BaseItem> ApplyFilter(IEnumerable<BaseItem> items, ItemFilter filter, User user, IUserDataManager repository) - { - // Avoid implicitly captured closure - var currentUser = user; - - switch (filter) - { - case ItemFilter.IsFavoriteOrLikes: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - if (userdata == null) - { - return false; - } - - var likes = userdata.Likes ?? false; - var favorite = userdata.IsFavorite; - - return likes || favorite; - }); - - case ItemFilter.Likes: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value; - }); - - case ItemFilter.Dislikes: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value; - }); - - case ItemFilter.IsFavorite: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.IsFavorite; - }); - - case ItemFilter.IsResumable: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.PlaybackPositionTicks > 0; - }); - - case ItemFilter.IsPlayed: - return items.Where(item => item.IsPlayed(currentUser)); - - case ItemFilter.IsUnplayed: - return items.Where(item => item.IsUnplayed(currentUser)); - - case ItemFilter.IsFolder: - return items.Where(item => item.IsFolder); - - case ItemFilter.IsNotFolder: - return items.Where(item => !item.IsFolder); - - case ItemFilter.IsRecentlyAdded: - return items.Where(item => (DateTime.UtcNow - item.DateCreated).TotalDays <= 10); - } - - return items; - } - - private bool ApplyAdditionalFilters(GetItems request, BaseItem i, User user, ILibraryManager libraryManager) - { - // Artists - if (!string.IsNullOrEmpty(request.ArtistIds)) - { - var artistIds = request.ArtistIds.Split(new[] { '|', ',' }); - - var audio = i as IHasArtist; - - if (!(audio != null && artistIds.Any(id => - { - var artistItem = libraryManager.GetItemById(id); - return artistItem != null && audio.HasAnyArtist(artistItem.Name); - }))) - { - return false; - } - } - - // Artists - if (!string.IsNullOrEmpty(request.Artists)) - { - var artists = request.Artists.Split('|'); - - var audio = i as IHasArtist; - - if (!(audio != null && artists.Any(audio.HasAnyArtist))) - { - return false; - } - } - - // Albums - if (!string.IsNullOrEmpty(request.Albums)) + if (!string.IsNullOrEmpty(request.MinPremiereDate)) { - var albums = request.Albums.Split('|'); - - var audio = i as Audio; - - if (audio != null) - { - if (!albums.Any(a => string.Equals(a, audio.Album, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - var album = i as MusicAlbum; - - if (album != null) - { - if (!albums.Any(a => string.Equals(a, album.Name, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - var musicVideo = i as MusicVideo; - - if (musicVideo != null) - { - if (!albums.Any(a => string.Equals(a, musicVideo.Album, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - return false; + query.MinPremiereDate = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); } - // Min official rating - if (!string.IsNullOrEmpty(request.MinOfficialRating)) + if (!string.IsNullOrEmpty(request.MaxPremiereDate)) { - var level = _localization.GetRatingLevel(request.MinOfficialRating); - - if (level.HasValue) - { - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (!string.IsNullOrEmpty(rating)) - { - var itemLevel = _localization.GetRatingLevel(rating); - - if (!(!itemLevel.HasValue || itemLevel.Value >= level.Value)) - { - return false; - } - } - } + query.MaxPremiereDate = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); } - // Max official rating - if (!string.IsNullOrEmpty(request.MaxOfficialRating)) + // Filter by Series Status + if (!string.IsNullOrEmpty(request.SeriesStatus)) { - var level = _localization.GetRatingLevel(request.MaxOfficialRating); - - if (level.HasValue) - { - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (!string.IsNullOrEmpty(rating)) - { - var itemLevel = _localization.GetRatingLevel(rating); - - if (!(!itemLevel.HasValue || itemLevel.Value <= level.Value)) - { - return false; - } - } - } + query.SeriesStatuses = request.SeriesStatus.Split(',').Select(d => (SeriesStatus)Enum.Parse(typeof(SeriesStatus), d, true)).ToArray(); } - // LocationTypes - if (!string.IsNullOrEmpty(request.LocationTypes)) + // Filter by Series AirDays + if (!string.IsNullOrEmpty(request.AirDays)) { - var vals = request.LocationTypes.Split(','); - if (!vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } + query.AirDays = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)).ToArray(); } // ExcludeLocationTypes if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) { - var vals = request.ExcludeLocationTypes.Split(','); - if (vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(request.AlbumArtistStartsWithOrGreater)) - { - var ok = new[] { i }.OfType<IHasAlbumArtist>() - .Any(p => string.Compare(request.AlbumArtistStartsWithOrGreater, p.AlbumArtists.FirstOrDefault(), StringComparison.CurrentCultureIgnoreCase) < 1); - - if (!ok) - { - return false; - } + query.ExcludeLocationTypes = request.ExcludeLocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); } - // Filter by Series Status - if (!string.IsNullOrEmpty(request.SeriesStatus)) + if (!string.IsNullOrEmpty(request.LocationTypes)) { - var vals = request.SeriesStatus.Split(','); - - var ok = new[] { i }.OfType<Series>().Any(p => p.Status.HasValue && vals.Contains(p.Status.Value.ToString(), StringComparer.OrdinalIgnoreCase)); - - if (!ok) - { - return false; - } + query.LocationTypes = request.LocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); } - - // Filter by Series AirDays - if (!string.IsNullOrEmpty(request.AirDays)) + + // Min official rating + if (!string.IsNullOrEmpty(request.MinOfficialRating)) { - var days = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)); - - var ok = new[] { i }.OfType<Series>().Any(p => p.AirDays != null && days.Any(d => p.AirDays.Contains(d))); - - if (!ok) - { - return false; - } + query.MinParentalRating = _localization.GetRatingLevel(request.MinOfficialRating); } - if (request.ParentIndexNumber.HasValue) + // Max official rating + if (!string.IsNullOrEmpty(request.MaxOfficialRating)) { - var filterValue = request.ParentIndexNumber.Value; - - var episode = i as Episode; - - if (episode != null) - { - if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - - var song = i as Audio; - - if (song != null) - { - if (song.ParentIndexNumber.HasValue && song.ParentIndexNumber.Value != filterValue) - { - return false; - } - } + query.MaxParentalRating = _localization.GetRatingLevel(request.MinOfficialRating); } - if (request.AiredDuringSeason.HasValue) + // Artists + if (!string.IsNullOrEmpty(request.ArtistIds)) { - var episode = i as Episode; - - if (episode == null) - { - return false; - } + var artistIds = request.ArtistIds.Split(new[] { '|', ',' }); - if (!Series.FilterEpisodesBySeason(new[] { episode }, request.AiredDuringSeason.Value, true).Any()) - { - return false; - } + var artistItems = artistIds.Select(_libraryManager.GetItemById).Where(i => i != null).ToList(); + query.ArtistNames = artistItems.Select(i => i.Name).ToArray(); } - if (!string.IsNullOrEmpty(request.MinPremiereDate)) + // Artists + if (!string.IsNullOrEmpty(request.Artists)) { - var date = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); - - if (!(i.PremiereDate.HasValue && i.PremiereDate.Value >= date)) - { - return false; - } + query.ArtistNames = request.Artists.Split('|'); } - if (!string.IsNullOrEmpty(request.MaxPremiereDate)) + // Albums + if (!string.IsNullOrEmpty(request.Albums)) { - var date = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); - - if (!(i.PremiereDate.HasValue && i.PremiereDate.Value <= date)) - { - return false; - } + query.AlbumNames = request.Albums.Split('|'); } - return true; + return query; } } diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs index 08c6b0ba47..0a96a5b06c 100644 --- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs +++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs @@ -335,11 +335,6 @@ namespace MediaBrowser.Api.UserLibrary public void Post(ReportPlaybackProgress request) { - if (!string.IsNullOrWhiteSpace(request.PlaySessionId)) - { - ApiEntryPoint.Instance.PingTranscodingJob(request.PlaySessionId); - } - request.SessionId = GetSession().Result.Id; var task = _sessionManager.OnPlaybackProgress(request); @@ -349,7 +344,7 @@ namespace MediaBrowser.Api.UserLibrary public void Post(PingPlaybackSession request) { - ApiEntryPoint.Instance.PingTranscodingJob(request.PlaySessionId); + ApiEntryPoint.Instance.PingTranscodingJob(request.PlaySessionId, null); } /// <summary> diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index ecb1109cad..4f2cbae7cb 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="CommonIO" version="1.0.0.8" targetFramework="net45" /> + <package id="CommonIO" version="1.0.0.9" targetFramework="net45" /> <package id="morelinq" version="1.4.0" targetFramework="net45" /> <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file |
