diff options
18 files changed, 275 insertions, 148 deletions
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 0a8d39ee5..dbb6478a1 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -113,7 +113,8 @@ namespace MediaBrowser.Api config.EnableCustomPathSubFolders = true; config.EnableStandaloneMusicKeys = true; config.EnableCaseSensitiveItemIds = true; - config.SchemaVersion = 87; + config.EnableFolderView = true; + config.SchemaVersion = 89; } public void Post(UpdateStartupConfiguration request) diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index bbb9b3019..a24148360 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -107,9 +107,11 @@ namespace MediaBrowser.Controller.Entities.TV { get { - if (EnablePooling()) + var userdatakeys = GetUserDataKeys(); + + if (userdatakeys.Count > 1) { - return GetUserDataKeys().First(); + return userdatakeys[0]; } return base.PresentationUniqueKey; } @@ -207,33 +209,13 @@ namespace MediaBrowser.Controller.Entities.TV { IEnumerable<Season> seasons; - if (EnablePooling()) + seasons = LibraryManager.GetItemList(new InternalItemsQuery(user) { - var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user) - { - PresentationUniqueKey = PresentationUniqueKey, - IncludeItemTypes = new[] { typeof(Series).Name } - }); + AncestorWithPresentationUniqueKey = PresentationUniqueKey, + IncludeItemTypes = new[] { typeof(Season).Name }, + SortBy = new[] { ItemSortBy.SortName } - if (seriesIds.Count > 1) - { - seasons = LibraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(), - IncludeItemTypes = new[] { typeof(Season).Name }, - SortBy = new[] { ItemSortBy.SortName } - - }).Cast<Season>(); - } - else - { - seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>(); - } - } - else - { - seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>(); - } + }).Cast<Season>(); if (!includeMissingSeasons) { @@ -256,9 +238,16 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable<Episode> GetEpisodes(User user, bool includeMissing, bool includeVirtualUnaired) { - var allSeriesEpisodes = GetAllEpisodes(user).ToList(); + var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user) + { + AncestorWithPresentationUniqueKey = PresentationUniqueKey, + IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name }, + SortBy = new[] { ItemSortBy.SortName } + }).ToList(); + + var allSeriesEpisodes = allItems.OfType<Episode>().ToList(); - var allEpisodes = GetSeasons(user, true, true) + var allEpisodes = allItems.OfType<Season>() .SelectMany(i => i.GetEpisodes(this, user, includeMissing, includeVirtualUnaired, allSeriesEpisodes)) .Reverse() .ToList(); @@ -343,50 +332,15 @@ namespace MediaBrowser.Controller.Entities.TV return GetEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); } - private bool EnablePooling() - { - return false; - } - private IEnumerable<Episode> GetAllEpisodes(User user) { - IEnumerable<Episode> episodes; - - if (EnablePooling()) + return LibraryManager.GetItemList(new InternalItemsQuery(user) { - var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user) - { - PresentationUniqueKey = PresentationUniqueKey, - IncludeItemTypes = new[] { typeof(Series).Name } - }); - - if (seriesIds.Count > 1) - { - episodes = LibraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(), - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName } - - }).Cast<Episode>(); - } - else - { - episodes = GetRecursiveChildren(user, new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Episode).Name } - }).Cast<Episode>(); - } - } - else - { - episodes = GetRecursiveChildren(user, new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Episode).Name } - }).Cast<Episode>(); - } + AncestorWithPresentationUniqueKey = PresentationUniqueKey, + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { ItemSortBy.SortName } - return episodes; + }).Cast<Episode>(); } public IEnumerable<Episode> GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index df0e42869..e89aafaca 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -198,6 +198,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableAnonymousUsageReporting { get; set; } public bool EnableStandaloneMusicKeys { get; set; } public bool EnableLocalizedGuids { get; set; } + public bool EnableFolderView { get; set; } /// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs index a1e038374..563118940 100644 --- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Common.Net; +using CommonIO; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -6,7 +8,10 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; using System.Collections.Generic; +using System.IO; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -15,10 +20,16 @@ namespace MediaBrowser.Providers.Omdb public class OmdbImageProvider : IRemoteImageProvider, IHasOrder { private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + private readonly IFileSystem _fileSystem; + private readonly IServerConfigurationManager _configurationManager; - public OmdbImageProvider(IHttpClient httpClient) + public OmdbImageProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { + _jsonSerializer = jsonSerializer; _httpClient = httpClient; + _fileSystem = fileSystem; + _configurationManager = configurationManager; } public IEnumerable<ImageType> GetSupportedImages(IHasImages item) @@ -29,22 +40,29 @@ namespace MediaBrowser.Providers.Omdb }; } - public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken) + public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken) { var imdbId = item.GetProviderId(MetadataProviders.Imdb); var list = new List<RemoteImageInfo>(); + var provider = new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _configurationManager); + if (!string.IsNullOrWhiteSpace(imdbId)) { - list.Add(new RemoteImageInfo + OmdbProvider.RootObject rootObject = await provider.GetRootObject(imdbId, cancellationToken).ConfigureAwait(false); + + if (!string.IsNullOrEmpty(rootObject.Poster)) { - ProviderName = Name, - Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=82e83907", imdbId) - }); + list.Add(new RemoteImageInfo + { + ProviderName = Name, + Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=82e83907", imdbId) + }); + } } - return Task.FromResult<IEnumerable<RemoteImageInfo>>(list); + return list; } public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) @@ -65,18 +83,6 @@ namespace MediaBrowser.Providers.Omdb public bool Supports(IHasImages item) { - // We'll hammer Omdb if we enable this - if (item is Person) - { - return false; - } - - // Save the http requests since we know it's not currently supported - if (item is Season || item is Episode) - { - return false; - } - // Supports images for tv movies var tvProgram = item as LiveTvProgram; if (tvProgram != null && tvProgram.IsMovie) @@ -84,7 +90,7 @@ namespace MediaBrowser.Providers.Omdb return true; } - return item is Movie || item is Trailer; + return item is Movie || item is Trailer || item is Episode; } public int Order diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index a0d60c166..7a803eb6f 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Common.Net; +using CommonIO; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -26,13 +28,17 @@ namespace MediaBrowser.Providers.Omdb private readonly IHttpClient _httpClient; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; + private readonly IFileSystem _fileSystem; + private readonly IServerConfigurationManager _configurationManager; - public OmdbItemProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager) + public OmdbItemProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; _logger = logger; _libraryManager = libraryManager; + _fileSystem = fileSystem; + _configurationManager = configurationManager; } public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) @@ -220,7 +226,7 @@ namespace MediaBrowser.Providers.Omdb result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _configurationManager).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); } return result; @@ -259,7 +265,7 @@ namespace MediaBrowser.Providers.Omdb result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _configurationManager).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); } return result; diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index 39da70210..4056073f2 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -1,4 +1,7 @@ -using MediaBrowser.Common.Net; +using CommonIO; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Serialization; @@ -17,17 +20,17 @@ namespace MediaBrowser.Providers.Omdb { internal static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1); private readonly IJsonSerializer _jsonSerializer; + private readonly IFileSystem _fileSystem; + private readonly IServerConfigurationManager _configurationManager; private readonly IHttpClient _httpClient; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public static OmdbProvider Current; - - public OmdbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient) + public OmdbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; - - Current = this; + _fileSystem = fileSystem; + _configurationManager = configurationManager; } public async Task Fetch(BaseItem item, string imdbId, string language, string country, CancellationToken cancellationToken) @@ -37,28 +40,7 @@ namespace MediaBrowser.Providers.Omdb throw new ArgumentNullException("imdbId"); } - var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId; - - var url = string.Format("https://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam); - - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = url, - ResourcePool = ResourcePool, - CancellationToken = cancellationToken - - }).ConfigureAwait(false)) - { - string resultString; - - using (var reader = new StreamReader(stream, new UTF8Encoding(false))) - { - resultString = reader.ReadToEnd(); - } - - resultString = resultString.Replace("\"N/A\"", "\"\""); - - var result = _jsonSerializer.DeserializeFromString<RootObject>(resultString); + var result = await GetRootObject(imdbId, cancellationToken); // Only take the name and rating if the user's language is set to english, since Omdb has no localization if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) @@ -130,7 +112,79 @@ namespace MediaBrowser.Providers.Omdb } ParseAdditionalMetadata(item, result); + } + + internal async Task<RootObject> GetRootObject(string imdbId, CancellationToken cancellationToken) + { + var path = await EnsureItemInfo(imdbId, cancellationToken); + + string resultString; + + using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 131072)) + { + using (var reader = new StreamReader(stream, new UTF8Encoding(false))) + { + resultString = reader.ReadToEnd(); + resultString = resultString.Replace("\"N/A\"", "\"\""); + } + } + + var result = _jsonSerializer.DeserializeFromString<RootObject>(resultString); + return result; + } + + private async Task<string> EnsureItemInfo(string imdbId, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(imdbId)) + { + throw new ArgumentNullException("imdbId"); + } + + var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId; + + var path = GetDataFilePath(imdbParam); + + var fileInfo = _fileSystem.GetFileSystemInfo(path); + + if (fileInfo.Exists) + { + // If it's recent or automatic updates are enabled, don't re-download + if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 3) + { + return path; + } } + + var url = string.Format("https://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam); + + using (var stream = await _httpClient.Get(new HttpRequestOptions + { + Url = url, + ResourcePool = ResourcePool, + CancellationToken = cancellationToken + + }).ConfigureAwait(false)) + { + var rootObject = _jsonSerializer.DeserializeFromStream<RootObject>(stream); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _jsonSerializer.SerializeToFile(rootObject, path); + } + + return path; + } + + internal string GetDataFilePath(string imdbId) + { + if (string.IsNullOrEmpty(imdbId)) + { + throw new ArgumentNullException("imdbId"); + } + + var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb"); + + var filename = string.Format("{0}.json", imdbId); + + return Path.Combine(dataPath, filename); } private void ParseAdditionalMetadata(BaseItem item, RootObject result) @@ -184,7 +238,7 @@ namespace MediaBrowser.Providers.Omdb return string.Equals(lang, "en", StringComparison.OrdinalIgnoreCase); } - private class RootObject + internal class RootObject { public string Title { get; set; } public string Year { get; set; } diff --git a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs index 5da1fcf27..ebbefbeb1 100644 --- a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Common.Net; +using CommonIO; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -21,12 +23,16 @@ namespace MediaBrowser.Providers.TV private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; private readonly OmdbItemProvider _itemProvider; + private readonly IFileSystem _fileSystem; + private readonly IServerConfigurationManager _configurationManager; - public OmdbEpisodeProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager) + public OmdbEpisodeProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; - _itemProvider = new OmdbItemProvider(jsonSerializer, httpClient, logger, libraryManager); + _fileSystem = fileSystem; + _configurationManager = configurationManager; + _itemProvider = new OmdbItemProvider(jsonSerializer, httpClient, logger, libraryManager, fileSystem, configurationManager); } public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) @@ -58,7 +64,7 @@ namespace MediaBrowser.Providers.TV result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _configurationManager).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); } return result; diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs index 9bab3d380..bc9842b73 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs @@ -114,6 +114,22 @@ namespace MediaBrowser.Providers.TV item.CommunityRating = (float)response.vote_average; item.VoteCount = response.vote_count; + if (response.videos != null && response.videos.results != null) + { + foreach (var video in response.videos.results) + { + if (video.type.Equals("trailer", System.StringComparison.OrdinalIgnoreCase) + || video.type.Equals("clip", System.StringComparison.OrdinalIgnoreCase)) + { + if (video.site.Equals("youtube", System.StringComparison.OrdinalIgnoreCase)) + { + var videoUrl = string.Format("http://www.youtube.com/watch?v={0}", video.key); + item.AddTrailerUrl(videoUrl, true); + } + } + } + } + result.ResetPeople(); var credits = response.credits; diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs index 36800202f..a6df245b0 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs @@ -210,7 +210,19 @@ namespace MediaBrowser.Providers.TV public class Videos { - public List<object> results { get; set; } + public List<Video> results { get; set; } + } + + public class Video + { + public string id { get; set; } + public string iso_639_1 { get; set; } + public string iso_3166_1 { get; set; } + public string key { get; set; } + public string name { get; set; } + public string site { get; set; } + public string size { get; set; } + public string type { get; set; } } public class RootObject diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs index 2e51393e3..194af5b99 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Providers.TV result.HasMetadata = true; result.Item = new Season(); - result.Item.Name = info.Name; + result.Item.Name = seasonInfo.name; result.Item.IndexNumber = seasonNumber; result.Item.Overview = seasonInfo.overview; diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs index 4a20418bb..3245a2c85 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs @@ -168,7 +168,7 @@ namespace MediaBrowser.Providers.TV { cancellationToken.ThrowIfCancellationRequested(); - result.Item = await FetchMovieData(tmdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + result.Item = await FetchSeriesData(tmdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); result.HasMetadata = result.Item != null; } @@ -176,7 +176,7 @@ namespace MediaBrowser.Providers.TV return result; } - private async Task<Series> FetchMovieData(string tmdbId, string language, string preferredCountryCode, CancellationToken cancellationToken) + private async Task<Series> FetchSeriesData(string tmdbId, string language, string preferredCountryCode, CancellationToken cancellationToken) { string dataFilePath = null; RootObject seriesInfo = null; @@ -285,6 +285,21 @@ namespace MediaBrowser.Providers.TV series.OfficialRating = minimumRelease.rating; } + if (seriesInfo.videos != null && seriesInfo.videos.results != null) + { + foreach (var video in seriesInfo.videos.results) + { + if (video.type.Equals("trailer", System.StringComparison.OrdinalIgnoreCase) + || video.type.Equals("clip", System.StringComparison.OrdinalIgnoreCase)) + { + if (video.site.Equals("youtube", System.StringComparison.OrdinalIgnoreCase)) + { + var videoUrl = string.Format("http://www.youtube.com/watch?v={0}", video.key); + series.AddTrailerUrl(videoUrl, true); + } + } + } + } } internal static string GetSeriesDataPath(IApplicationPaths appPaths, string tmdbId) @@ -555,7 +570,19 @@ namespace MediaBrowser.Providers.TV public class Videos { - public List<object> results { get; set; } + public List<Video> results { get; set; } + } + + public class Video + { + public string id { get; set; } + public string iso_639_1 { get; set; } + public string iso_3166_1 { get; set; } + public string key { get; set; } + public string name { get; set; } + public string site { get; set; } + public string size { get; set; } + public string type { get; set; } } public class ContentRating diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 6c88f506b..e6a571f07 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -105,6 +105,12 @@ namespace MediaBrowser.Server.Implementations.Library } } + if (_config.Configuration.EnableFolderView) + { + var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Folders); + list.Add(await _libraryManager.GetNamedView(name, CollectionType.Folders, string.Empty, cancellationToken).ConfigureAwait(false)); + } + if (query.IncludeExternalContent) { var channelResult = await _channelManager.GetChannelsInternal(new ChannelQuery diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9f827c553..c790e829a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -94,7 +94,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 87; + public const int LatestSchemaVersion = 89; /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. @@ -137,6 +137,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID, Path TEXT)", "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", + "create index if not exists idx_TypedBaseItems2 on TypedBaseItems(Type,Guid)", "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))", "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)", diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 6019d64b4..d57aea08e 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -125,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.TV private Tuple<Episode, DateTime, bool> GetNextUp(Series series, User user) { // Get them in display order, then reverse - var allEpisodes = series.GetEpisodes(user, true, true) + var allEpisodes = series.GetEpisodes(user, false, false) .Where(i => !i.ParentIndexNumber.HasValue || i.ParentIndexNumber.Value != 0) .Reverse() .ToList(); @@ -134,8 +134,6 @@ namespace MediaBrowser.Server.Implementations.TV var lastWatchedDate = DateTime.MinValue; Episode nextUp = null; - var includeMissing = user.Configuration.DisplayMissingEpisodes; - var unplayedEpisodes = new List<Episode>(); // Go back starting with the most recent episodes @@ -157,10 +155,7 @@ namespace MediaBrowser.Server.Implementations.TV { unplayedEpisodes.Add(episode); - if (!episode.IsVirtualUnaired && (includeMissing || !episode.IsMissingEpisode)) - { - nextUp = episode; - } + nextUp = episode; } } @@ -175,11 +170,8 @@ namespace MediaBrowser.Server.Implementations.TV { var unplayedEpisode = unplayedEpisodes[i]; - if (!unplayedEpisode.IsVirtualUnaired && (includeMissing || !unplayedEpisode.IsMissingEpisode)) - { - firstEpisode = unplayedEpisode; - break; - } + firstEpisode = unplayedEpisode; + break; } // Return the first episode diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 59a8a4f78..75e3bb7f5 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -380,7 +380,8 @@ namespace MediaBrowser.Server.Startup.Common { new OmdbEpisodeProviderMigration(ServerConfigurationManager), new MovieDbEpisodeProviderMigration(ServerConfigurationManager), - new DbMigration(ServerConfigurationManager, TaskManager) + new DbMigration(ServerConfigurationManager, TaskManager), + new FolderViewSettingMigration(ServerConfigurationManager, UserManager) }; foreach (var task in migrations) @@ -568,7 +569,7 @@ namespace MediaBrowser.Server.Startup.Common SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager); RegisterSingleInstance(SubtitleEncoder); - + await displayPreferencesRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); await ConfigureUserDataRepositories().ConfigureAwait(false); await itemRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index d0769f488..a6d09d343 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -71,6 +71,7 @@ <Compile Include="FFMpeg\FFmpegValidator.cs" /> <Compile Include="INativeApp.cs" /> <Compile Include="MbLinkShortcutHandler.cs" /> + <Compile Include="Migrations\FolderViewSettingMigration.cs" /> <Compile Include="Migrations\IVersionMigration.cs" /> <Compile Include="Migrations\DbMigration.cs" /> <Compile Include="Migrations\MovieDbEpisodeProviderMigration.cs" /> diff --git a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs new file mode 100644 index 000000000..4049d1754 --- /dev/null +++ b/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs @@ -0,0 +1,37 @@ +using System.Linq; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Library; + +namespace MediaBrowser.Server.Startup.Common.Migrations +{ + public class FolderViewSettingMigration : IVersionMigration + { + private readonly IServerConfigurationManager _config; + private readonly IUserManager _userManager; + + public FolderViewSettingMigration(IServerConfigurationManager config, IUserManager userManager) + { + _config = config; + _userManager = userManager; + } + + public void Run() + { + var migrationKey = this.GetType().Name; + var migrationKeyList = _config.Configuration.Migrations.ToList(); + + if (!migrationKeyList.Contains(migrationKey)) + { + if (_config.Configuration.IsStartupWizardCompleted) + { + _config.Configuration.EnableFolderView = _userManager.Users.Any(i => i.Configuration.DisplayFoldersView); + } + + migrationKeyList.Add(migrationKey); + _config.Configuration.Migrations = migrationKeyList.ToArray(); + _config.SaveConfiguration(); + } + + } + } +} diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1d860ed29..36693ad8e 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -272,6 +272,9 @@ <Content Include="dashboard-ui\legacy\selectmenu.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\librarydisplay.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\livetvguideprovider.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -308,6 +311,9 @@ <Content Include="dashboard-ui\scripts\homeupcoming.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\librarydisplay.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\livetvguideprovider.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
|
