From b9aa38b5ab326aeb61921116fe6a27c62b8bf63c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 28 Feb 2014 23:12:56 -0500 Subject: added unidentified indicators --- MediaBrowser.Controller/Entities/BaseItem.cs | 2 ++ MediaBrowser.Controller/Entities/IHasMetadata.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 9d520cf6f..923673bd8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -229,6 +229,8 @@ namespace MediaBrowser.Controller.Entities } } + public bool IsUnidentified { get; set; } + /// /// Gets or sets the locked fields. /// diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 7182d086a..91f37135f 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -36,12 +36,6 @@ namespace MediaBrowser.Controller.Entities /// The date last saved. DateTime DateLastSaved { get; set; } - /// - /// Gets a value indicating whether this instance is in mixed folder. - /// - /// true if this instance is in mixed folder; otherwise, false. - bool IsInMixedFolder { get; } - /// /// Updates to repository. /// @@ -55,5 +49,11 @@ namespace MediaBrowser.Controller.Entities /// /// true if XXXX, false otherwise. bool BeforeMetadataRefresh(); + + /// + /// Gets or sets a value indicating whether this instance is unidentified. + /// + /// true if this instance is unidentified; otherwise, false. + bool IsUnidentified { get; set; } } } -- cgit v1.2.3 From c2e51df31df8b112fe2750ce02a4dd210fccf937 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 28 Feb 2014 23:13:22 -0500 Subject: add custom providers that can run before refresh chain --- .../Providers/ICustomMetadataProvider.cs | 5 +++++ MediaBrowser.Providers/Manager/MetadataService.cs | 24 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs index c98810cbc..9aed4d921 100644 --- a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs @@ -14,4 +14,9 @@ namespace MediaBrowser.Controller.Providers { Task FetchAsync(TItemType item, IDirectoryService directoryService, CancellationToken cancellationToken); } + + public interface IPreRefreshProvider : ICustomMetadataProvider + { + + } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index eb2d7d747..e9dec7f6d 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -269,6 +269,13 @@ namespace MediaBrowser.Providers.Manager Providers = providers.Select(i => i.GetType().FullName.GetMD5()).ToList() }; + var customProviders = providers.OfType>().ToList(); + + foreach (var provider in customProviders.Where(i => i is IPreRefreshProvider)) + { + await RunCustomProvider(provider, item, options.DirectoryService, refreshResult, cancellationToken).ConfigureAwait(false); + } + var temp = CreateNew(); temp.Path = item.Path; @@ -342,7 +349,7 @@ namespace MediaBrowser.Providers.Manager MergeData(temp, item, item.LockedFields, true, true); } - foreach (var provider in providers.OfType>()) + foreach (var provider in customProviders.Where(i => !(i is IPreRefreshProvider))) { await RunCustomProvider(provider, item, options.DirectoryService, refreshResult, cancellationToken).ConfigureAwait(false); } @@ -379,6 +386,9 @@ namespace MediaBrowser.Providers.Manager { TIdType id = null; + var unidentifiedCount = 0; + var identifiedCount = 0; + foreach (var provider in providers) { var providerName = provider.GetType().Name; @@ -402,9 +412,12 @@ namespace MediaBrowser.Providers.Manager MergeData(result.Item, temp, new List(), false, false); refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload; + + identifiedCount++; } else { + unidentifiedCount++; Logger.Debug("{0} returned no metadata for {1}", providerName, item.Path ?? item.Name); } } @@ -414,11 +427,20 @@ namespace MediaBrowser.Providers.Manager } catch (Exception ex) { + unidentifiedCount++; refreshResult.Status = ProviderRefreshStatus.CompletedWithErrors; refreshResult.ErrorMessage = ex.Message; Logger.ErrorException("Error in {0}", ex, provider.Name); } } + + var isUnidentified = unidentifiedCount > 0 && identifiedCount == 0; + + if (item.IsUnidentified != isUnidentified) + { + item.IsUnidentified = isUnidentified; + refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; + } } private void MergeNewData(TItemType source, TIdType lookupInfo) -- cgit v1.2.3 From 6c5cf81752c4189e9a7a8c79ea84d802cc979eea Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 1 Mar 2014 17:34:27 -0500 Subject: a start to the lookup feature --- MediaBrowser.Api/ItemLookupService.cs | 252 +++++++++++++++++++++ MediaBrowser.Api/Library/LibraryService.cs | 27 +-- MediaBrowser.Api/MediaBrowser.Api.csproj | 1 + .../Providers/IProviderManager.cs | 12 +- .../Providers/IRemoteMetadataProvider.cs | 11 +- .../BoxSets/MovieDbBoxSetProvider.cs | 73 +++++- MediaBrowser.Providers/Manager/ProviderManager.cs | 23 +- .../Movies/GenericMovieDbInfo.cs | 4 +- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 7 +- MediaBrowser.Providers/Movies/MovieDbSearch.cs | 96 +++++--- .../Movies/MovieDbTrailerProvider.cs | 14 +- .../People/MovieDbPersonProvider.cs | 15 +- MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs | 15 +- .../EntryPoints/ExternalPortForwarding.cs | 28 +-- 14 files changed, 484 insertions(+), 94 deletions(-) create mode 100644 MediaBrowser.Api/ItemLookupService.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs new file mode 100644 index 000000000..25782f8c1 --- /dev/null +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -0,0 +1,252 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Providers; +using ServiceStack; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Api +{ + [Route("/Items/{Id}/ExternalIdInfos", "GET")] + [Api(Description = "Gets external id infos for an item")] + public class GetExternalIdInfos : IReturn> + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + [Route("/Items/RemoteSearch/Movie", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetMovieRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/Trailer", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetTrailerRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/AdultVideo", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetAdultVideoRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/Series", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetSeriesRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/Game", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetGameRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/BoxSet", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetBoxSetRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/Person", "POST")] + [Api(Description = "Gets external id infos for an item")] + public class GetPersonRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + + [Route("/Items/RemoteSearch/Image", "GET")] + [Api(Description = "Gets a remote image")] + public class GetRemoteSearchImage + { + [ApiMember(Name = "ImageUrl", Description = "The image url", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ImageUrl { get; set; } + + [ApiMember(Name = "ProviderName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ProviderName { get; set; } + } + + public class ItemLookupService : BaseApiService + { + private readonly IDtoService _dtoService; + private readonly IProviderManager _providerManager; + private readonly IServerApplicationPaths _appPaths; + private readonly IFileSystem _fileSystem; + + public ItemLookupService(IDtoService dtoService, IProviderManager providerManager, IServerApplicationPaths appPaths, IFileSystem fileSystem) + { + _dtoService = dtoService; + _providerManager = providerManager; + _appPaths = appPaths; + _fileSystem = fileSystem; + } + + public object Get(GetExternalIdInfos request) + { + var item = _dtoService.GetItemByDtoId(request.Id); + + var infos = _providerManager.GetExternalIdInfos(item).ToList(); + + return ToOptimizedResult(infos); + } + + public object Post(GetMovieRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Post(GetAdultVideoRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Post(GetSeriesRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Post(GetGameRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Post(GetBoxSetRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Post(GetPersonRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Post(GetTrailerRemoteSearchResults request) + { + var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Get(GetRemoteSearchImage request) + { + var result = GetRemoteImage(request).Result; + + return result; + } + + /// + /// Gets the remote image. + /// + /// The request. + /// Task{System.Object}. + private async Task GetRemoteImage(GetRemoteSearchImage request) + { + var urlHash = request.ImageUrl.GetMD5(); + var pointerCachePath = GetFullCachePath(urlHash.ToString()); + + string contentPath; + + try + { + using (var reader = new StreamReader(pointerCachePath)) + { + contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); + } + + if (File.Exists(contentPath)) + { + return ToStaticFileResult(contentPath); + } + } + catch (DirectoryNotFoundException) + { + // Means the file isn't cached yet + } + catch (FileNotFoundException) + { + // Means the file isn't cached yet + } + + await DownloadImage(request.ProviderName, request.ImageUrl, urlHash, pointerCachePath).ConfigureAwait(false); + + // Read the pointer file again + using (var reader = new StreamReader(pointerCachePath)) + { + contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); + } + + return ToStaticFileResult(contentPath); + } + + /// + /// Downloads the image. + /// + /// Name of the provider. + /// The URL. + /// The URL hash. + /// The pointer cache path. + /// Task. + private async Task DownloadImage(string providerName, string url, Guid urlHash, string pointerCachePath) + { + var result = await _providerManager.GetSearchImage(providerName, url, CancellationToken.None).ConfigureAwait(false); + + var ext = result.ContentType.Split('/').Last(); + + var fullCachePath = GetFullCachePath(urlHash + "." + ext); + + Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); + using (var stream = result.Content) + { + using (var filestream = _fileSystem.GetFileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, true)) + { + await stream.CopyToAsync(filestream).ConfigureAwait(false); + } + } + + Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); + using (var writer = new StreamWriter(pointerCachePath)) + { + await writer.WriteAsync(fullCachePath).ConfigureAwait(false); + } + } + + /// + /// Gets the full cache path. + /// + /// The filename. + /// System.String. + private string GetFullCachePath(string filename) + { + return Path.Combine(_appPaths.CachePath, "remote-images", filename.Substring(0, 1), filename); + } + + } +} diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 4cb20273f..c3fdbb9a0 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -6,10 +6,8 @@ using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Providers; using MediaBrowser.Model.Querying; using ServiceStack; using System; @@ -50,18 +48,6 @@ namespace MediaBrowser.Api.Library public int Index { get; set; } } - [Route("/Items/{Id}/ExternalIdInfos", "GET")] - [Api(Description = "Gets external id infos for an item")] - public class GetExternalIdInfos : IReturn> - { - /// - /// Gets or sets the id. - /// - /// The id. - [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string Id { get; set; } - } - /// /// Class GetCriticReviews /// @@ -256,29 +242,18 @@ namespace MediaBrowser.Api.Library private readonly IUserDataManager _userDataManager; private readonly IDtoService _dtoService; - private readonly IProviderManager _providerManager; /// /// Initializes a new instance of the class. /// public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, - IDtoService dtoService, IUserDataManager userDataManager, IProviderManager providerManager) + IDtoService dtoService, IUserDataManager userDataManager) { _itemRepo = itemRepo; _libraryManager = libraryManager; _userManager = userManager; _dtoService = dtoService; _userDataManager = userDataManager; - _providerManager = providerManager; - } - - public object Get(GetExternalIdInfos request) - { - var item = _dtoService.GetItemByDtoId(request.Id); - - var infos = _providerManager.GetExternalIdInfos(item).ToList(); - - return ToOptimizedResult(infos); } public object Get(GetMediaFolders request) diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index ee2a7eafc..bcc487a5d 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -82,6 +82,7 @@ + diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 83ee6ae83..94b19498a 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; @@ -126,5 +127,14 @@ namespace MediaBrowser.Controller.Providers CancellationToken cancellationToken) where TItemType : BaseItem, new() where TLookupType : ItemLookupInfo; + + /// + /// Gets the search image. + /// + /// Name of the provider. + /// The URL. + /// The cancellation token. + /// Task{HttpResponseInfo}. + Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs index f00a22a3a..0ff7ee5a9 100644 --- a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs @@ -18,11 +18,8 @@ namespace MediaBrowser.Controller.Providers Task> GetMetadata(TLookupInfoType info, CancellationToken cancellationToken); } - public interface IRemoteSearchProvider : IMetadataProvider - where TLookupInfoType : ItemLookupInfo + public interface IRemoteSearchProvider : IMetadataProvider { - Task> GetSearchResults(TLookupInfoType searchInfo, CancellationToken cancellationToken); - /// /// Gets the image response. /// @@ -31,6 +28,12 @@ namespace MediaBrowser.Controller.Providers /// Task{HttpResponseInfo}. Task GetImageResponse(string url, CancellationToken cancellationToken); } + + public interface IRemoteSearchProvider : IRemoteSearchProvider + where TLookupInfoType : ItemLookupInfo + { + Task> GetSearchResults(TLookupInfoType searchInfo, CancellationToken cancellationToken); + } public class RemoteSearchQuery where T : ItemLookupInfo diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs index 09939f2d6..d698b4ce0 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs @@ -32,20 +32,71 @@ namespace MediaBrowser.Providers.BoxSets private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly ILocalizationManager _localization; + private readonly IHttpClient _httpClient; - public MovieDbBoxSetProvider(ILogger logger, IJsonSerializer json, IServerConfigurationManager config, IFileSystem fileSystem, ILocalizationManager localization) + public MovieDbBoxSetProvider(ILogger logger, IJsonSerializer json, IServerConfigurationManager config, IFileSystem fileSystem, ILocalizationManager localization, IHttpClient httpClient) { _logger = logger; _json = json; _config = config; _fileSystem = fileSystem; _localization = localization; + _httpClient = httpClient; Current = this; } + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + public async Task> GetSearchResults(BoxSetInfo searchInfo, CancellationToken cancellationToken) { - return new List(); + var tmdbId = searchInfo.GetProviderId(MetadataProviders.Tmdb); + + var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); + + var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + + if (!string.IsNullOrEmpty(tmdbId)) + { + await EnsureInfo(tmdbId, searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false); + + var dataFilePath = GetDataFilePath(_config.ApplicationPaths, tmdbId, searchInfo.MetadataLanguage); + var info = _json.DeserializeFromFile(dataFilePath); + + var images = (info.images ?? new Images()).posters ?? new List(); + + var result = new RemoteSearchResult + { + Name = info.name, + + SearchProviderName = Name, + + ImageUrl = images.Count == 0 ? null : (tmdbImageUrl + images[0].file_path) + }; + + result.SetProviderId(MetadataProviders.Tmdb, info.id.ToString(_usCulture)); + + return new[] { result }; + } + + var results = await new MovieDbSearch(_logger, _json).GetSearchResults(searchInfo, cancellationToken).ConfigureAwait(false); + + return results.Select(i => GetRemoteSearchResult(i, tmdbImageUrl)); + } + + private RemoteSearchResult GetRemoteSearchResult(MovieDbSearch.TmdbMovieSearchResult tmdbResult, string baseImageUrl) + { + var result = new RemoteSearchResult + { + Name = tmdbResult.name, + + SearchProviderName = Name, + + ImageUrl = string.IsNullOrEmpty(tmdbResult.poster_path) ? null : (baseImageUrl + tmdbResult.poster_path) + }; + + result.SetProviderId(MetadataProviders.Tmdb, tmdbResult.id.ToString(_usCulture)); + + return result; } public async Task> GetMetadata(BoxSetInfo id, CancellationToken cancellationToken) @@ -55,7 +106,9 @@ namespace MediaBrowser.Providers.BoxSets // We don't already have an Id, need to fetch it if (string.IsNullOrEmpty(tmdbId)) { - var searchResult = await new MovieDbSearch(_logger, _json).FindCollectionId(id, cancellationToken).ConfigureAwait(false); + var searchResults = await new MovieDbSearch(_logger, _json).GetSearchResults(id, cancellationToken).ConfigureAwait(false); + + var searchResult = searchResults.FirstOrDefault(); if (searchResult != null) { @@ -219,10 +272,15 @@ namespace MediaBrowser.Providers.BoxSets private static string GetDataFilePath(IApplicationPaths appPaths, string tmdbId, string preferredLanguage) { + if (string.IsNullOrWhiteSpace(preferredLanguage)) + { + throw new ArgumentNullException("preferredLanguage"); + } + var path = GetDataPath(appPaths, tmdbId); var filename = string.Format("all-{0}.json", - preferredLanguage ?? string.Empty); + preferredLanguage); return Path.Combine(path, filename); } @@ -291,7 +349,12 @@ namespace MediaBrowser.Providers.BoxSets public Task GetImageResponse(string url, CancellationToken cancellationToken) { - throw new NotImplementedException(); + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + ResourcePool = MovieDbProvider.Current.MovieDbResourcePool + }); } } } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 942f414b6..b35c4887c 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -657,6 +657,15 @@ namespace MediaBrowser.Providers.Manager providers = providers.Where(i => string.Equals(i.Name, searchInfo.SearchProviderName, StringComparison.OrdinalIgnoreCase)); } + if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage)) + { + searchInfo.SearchInfo.MetadataLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage; + } + if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode)) + { + searchInfo.SearchInfo.MetadataCountryCode = ConfigurationManager.Configuration.MetadataCountryCode; + } + foreach (var provider in providers) { var results = await provider.GetSearchResults(searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false); @@ -665,7 +674,7 @@ namespace MediaBrowser.Providers.Manager if (list.Count > 0) { - return list; + return list.Take(10); } } @@ -673,6 +682,18 @@ namespace MediaBrowser.Providers.Manager return new List(); } + public Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken) + { + var provider = _metadataProviders.OfType().FirstOrDefault(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase)); + + if (provider == null) + { + throw new ArgumentException("Search provider not found."); + } + + return provider.GetImageResponse(url, cancellationToken); + } + public IEnumerable GetExternalIds(IHasProviderIds item) { return _externalIds.Where(i => diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index abd48e37c..b6dca5b7d 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -39,7 +39,9 @@ namespace MediaBrowser.Providers.Movies // Don't search for music video id's because it is very easy to misidentify. if (string.IsNullOrEmpty(tmdbId) && string.IsNullOrEmpty(imdbId) && typeof(T) != typeof(MusicVideo)) { - var searchResult = await new MovieDbSearch(_logger, _jsonSerializer).FindMovieId(itemId, cancellationToken).ConfigureAwait(false); + var searchResults = await new MovieDbSearch(_logger, _jsonSerializer).GetMovieSearchResults(itemId, cancellationToken).ConfigureAwait(false); + + var searchResult = searchResults.FirstOrDefault(); if (searchResult != null) { diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 32a77a8a6..2c47dbc2f 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -558,7 +558,12 @@ namespace MediaBrowser.Providers.Movies public Task GetImageResponse(string url, CancellationToken cancellationToken) { - throw new NotImplementedException(); + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + ResourcePool = MovieDbResourcePool + }); } } } diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index 383705e0a..ad7335009 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -29,22 +29,22 @@ namespace MediaBrowser.Providers.Movies _json = json; } - public Task FindSeriesId(ItemLookupInfo idInfo, CancellationToken cancellationToken) + public Task> GetSearchResults(SeriesInfo idInfo, CancellationToken cancellationToken) { - return FindId(idInfo, "tv", cancellationToken); + return GetSearchResults(idInfo, "tv", cancellationToken); } - public Task FindMovieId(ItemLookupInfo idInfo, CancellationToken cancellationToken) + public Task> GetMovieSearchResults(ItemLookupInfo idInfo, CancellationToken cancellationToken) { - return FindId(idInfo, "movie", cancellationToken); + return GetSearchResults(idInfo, "movie", cancellationToken); } - public Task FindCollectionId(ItemLookupInfo idInfo, CancellationToken cancellationToken) + public Task> GetSearchResults(BoxSetInfo idInfo, CancellationToken cancellationToken) { - return FindId(idInfo, "collection", cancellationToken); + return GetSearchResults(idInfo, "collection", cancellationToken); } - private async Task FindId(ItemLookupInfo idInfo, string searchType, CancellationToken cancellationToken) + private async Task> GetSearchResults(ItemLookupInfo idInfo, string searchType, CancellationToken cancellationToken) { var name = idInfo.Name; var year = idInfo.Year; @@ -60,48 +60,49 @@ namespace MediaBrowser.Providers.Movies //nope - search for it //var searchType = item is BoxSet ? "collection" : "movie"; - var id = await AttemptFindId(name, searchType, year, language, cancellationToken).ConfigureAwait(false); + var results = await GetSearchResults(name, searchType, year, language, cancellationToken).ConfigureAwait(false); - if (id == null) + if (results.Count == 0) { //try in english if wasn't before - if (language != "en") + if (!string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) { - id = await AttemptFindId(name, searchType, year, "en", cancellationToken).ConfigureAwait(false); + results = await GetSearchResults(name, searchType, year, "en", cancellationToken).ConfigureAwait(false); } - else - { - // try with dot and _ turned to space - var originalName = name; + } - name = name.Replace(",", " "); - name = name.Replace(".", " "); - name = name.Replace("_", " "); - name = name.Replace("-", " "); - name = name.Replace("!", " "); - name = name.Replace("?", " "); + if (results.Count == 0) + { + // try with dot and _ turned to space + var originalName = name; - name = name.Trim(); + name = name.Replace(",", " "); + name = name.Replace(".", " "); + name = name.Replace("_", " "); + name = name.Replace("-", " "); + name = name.Replace("!", " "); + name = name.Replace("?", " "); - // Search again if the new name is different - if (!string.Equals(name, originalName)) - { - id = await AttemptFindId(name, searchType, year, language, cancellationToken).ConfigureAwait(false); + name = name.Trim(); - if (id == null && language != "en") - { - //one more time, in english - id = await AttemptFindId(name, searchType, year, "en", cancellationToken).ConfigureAwait(false); + // Search again if the new name is different + if (!string.Equals(name, originalName)) + { + results = await GetSearchResults(name, searchType, year, language, cancellationToken).ConfigureAwait(false); + + if (results.Count == 0 && !string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) + { + //one more time, in english + results = await GetSearchResults(name, searchType, year, "en", cancellationToken).ConfigureAwait(false); - } } } } - return id; + return results; } - private async Task AttemptFindId(string name, string type, int? year, string language, CancellationToken cancellationToken) + private async Task> GetSearchResults(string name, string type, int? year, string language, CancellationToken cancellationToken) { var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, type); @@ -113,9 +114,34 @@ namespace MediaBrowser.Providers.Movies }).ConfigureAwait(false)) { - var searchResult = _json.DeserializeFromStream(json); - return FindBestResult(searchResult.results, name, year); + var searchResults = _json.DeserializeFromStream(json); + + var results = searchResults.results ?? new List(); + + var index = 0; + var resultTuples = results.Select(result => new Tuple(result, index++)).ToList(); + + return resultTuples.OrderBy(i => GetSearchResultOrder(i.Item1, year)) + .ThenBy(i => i.Item2) + .Select(i => i.Item1) + .ToList(); + } + } + + private int GetSearchResultOrder(TmdbMovieSearchResult result, int? year) + { + if (year.HasValue) + { + DateTime r; + + // These dates are always in this exact format + if (DateTime.TryParseExact(result.release_date, "yyyy-MM-dd", EnUs, DateTimeStyles.None, out r)) + { + return Math.Abs(r.Year - year.Value); + } } + + return 0; } private TmdbMovieSearchResult FindBestResult(List results, string name, int? year) diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs index 8c981e2d8..512fee8f8 100644 --- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs @@ -11,6 +11,13 @@ namespace MediaBrowser.Providers.Movies { public class MovieDbTrailerProvider : IRemoteMetadataProvider, IHasOrder { + private readonly IHttpClient _httpClient; + + public MovieDbTrailerProvider(IHttpClient httpClient) + { + _httpClient = httpClient; + } + public Task> GetMetadata(TrailerInfo info, CancellationToken cancellationToken) { return MovieDbProvider.Current.GetItemMetadata(info, cancellationToken); @@ -42,7 +49,12 @@ namespace MediaBrowser.Providers.Movies public Task GetImageResponse(string url, CancellationToken cancellationToken) { - throw new NotImplementedException(); + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + ResourcePool = MovieDbProvider.Current.MovieDbResourcePool + }); } } } diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 01be6bf91..b5bf445bf 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -29,12 +29,14 @@ namespace MediaBrowser.Providers.People private readonly IJsonSerializer _jsonSerializer; private readonly IFileSystem _fileSystem; private readonly IServerConfigurationManager _configurationManager; + private readonly IHttpClient _httpClient; - public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer) + public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient) { _fileSystem = fileSystem; _configurationManager = configurationManager; _jsonSerializer = jsonSerializer; + _httpClient = httpClient; Current = this; } @@ -64,6 +66,8 @@ namespace MediaBrowser.Providers.People { Name = info.name, + SearchProviderName = Name, + ImageUrl = images.Count == 0 ? null : (tmdbImageUrl + images[0].file_path) }; @@ -94,6 +98,8 @@ namespace MediaBrowser.Providers.People { var result = new RemoteSearchResult { + SearchProviderName = Name, + Name = i.Name, ImageUrl = string.IsNullOrEmpty(i.Profile_Path) ? null : (baseImageUrl + i.Profile_Path) @@ -349,7 +355,12 @@ namespace MediaBrowser.Providers.People public Task GetImageResponse(string url, CancellationToken cancellationToken) { - throw new NotImplementedException(); + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + ResourcePool = MovieDbProvider.Current.MovieDbResourcePool + }); } } } diff --git a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs index b46336e90..9f1d5f021 100644 --- a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs @@ -33,14 +33,16 @@ namespace MediaBrowser.Providers.TV private readonly IServerConfigurationManager _configurationManager; private readonly ILogger _logger; private readonly ILocalizationManager _localization; + private readonly IHttpClient _httpClient; - public MovieDbSeriesProvider(IJsonSerializer jsonSerializer, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILogger logger, ILocalizationManager localization) + public MovieDbSeriesProvider(IJsonSerializer jsonSerializer, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILogger logger, ILocalizationManager localization, IHttpClient httpClient) { _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; _configurationManager = configurationManager; _logger = logger; _localization = localization; + _httpClient = httpClient; Current = this; } @@ -82,7 +84,9 @@ namespace MediaBrowser.Providers.TV if (string.IsNullOrEmpty(tmdbId)) { - var searchResult = await new MovieDbSearch(_logger, _jsonSerializer).FindSeriesId(info, cancellationToken).ConfigureAwait(false); + var searchResults = await new MovieDbSearch(_logger, _jsonSerializer).GetSearchResults(info, cancellationToken).ConfigureAwait(false); + + var searchResult = searchResults.FirstOrDefault(); if (searchResult != null) { @@ -462,7 +466,12 @@ namespace MediaBrowser.Providers.TV public Task GetImageResponse(string url, CancellationToken cancellationToken) { - throw new NotImplementedException(); + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + ResourcePool = MovieDbProvider.Current.MovieDbResourcePool + }); } } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 43037d6ce..c0d784fcc 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints public void Run() { - NatUtility.Logger = new LogWriter(_logger); + //NatUtility.Logger = new LogWriter(_logger); Reload(); } @@ -64,17 +64,17 @@ namespace MediaBrowser.Server.Implementations.EntryPoints void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e) { - var ex = e.ExceptionObject as Exception; - - if (ex == null) - { - _logger.Error("Unidentified error reported by Mono.Nat"); - } - else - { - // Seeing some blank exceptions coming through here - _logger.ErrorException("Error reported by Mono.Nat: ", ex); - } + //var ex = e.ExceptionObject as Exception; + + //if (ex == null) + //{ + // _logger.Error("Unidentified error reported by Mono.Nat"); + //} + //else + //{ + // // Seeing some blank exceptions coming through here + // _logger.ErrorException("Error reported by Mono.Nat: ", ex); + //} } void NatUtility_DeviceFound(object sender, DeviceEventArgs e) @@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints } catch (Exception ex) { - _logger.ErrorException("Error creating port forwarding rules", ex); + //_logger.ErrorException("Error creating port forwarding rules", ex); } } @@ -106,7 +106,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private void CreatePortMap(INatDevice device, int port) { - _logger.Info("Creating port map on port {0}", port); + _logger.Debug("Creating port map on port {0}", port); device.CreatePortMap(new Mapping(Protocol.Tcp, port, port) { -- cgit v1.2.3 From 6987f2794aa0bb547072924c0a44aba7baf95350 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Mar 2014 13:01:46 -0500 Subject: search refinements --- .../Entities/CollectionFolder.cs | 4 +- .../Movies/GenericMovieDbInfo.cs | 13 ++++-- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 14 ++++++- MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs | 49 ++++++++++------------ .../Library/LibraryManager.cs | 18 ++++++++ 5 files changed, 63 insertions(+), 35 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 2d47cf632..6628ffc23 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -149,7 +149,7 @@ namespace MediaBrowser.Controller.Entities try { - locationsDicionary = PhysicalLocations.Distinct().ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + locationsDicionary = PhysicalLocations.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); } catch (IOException ex) { @@ -181,7 +181,7 @@ namespace MediaBrowser.Controller.Entities try { - locationsDicionary = PhysicalLocations.Distinct().ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + locationsDicionary = PhysicalLocations.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); } catch (IOException ex) { diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index c6d5d1502..bf2be654b 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -176,11 +176,16 @@ namespace MediaBrowser.Providers.Movies : null; } - if (movieData.release_date.Year != 1) + if (!string.IsNullOrWhiteSpace(movieData.release_date)) { - //no specific country release info at all - movie.PremiereDate = movieData.release_date.ToUniversalTime(); - movie.ProductionYear = movieData.release_date.Year; + DateTime r; + + // These dates are always in this exact format + if (DateTime.TryParse(movieData.release_date, _usCulture, DateTimeStyles.None, out r)) + { + movie.PremiereDate = r.ToUniversalTime(); + movie.ProductionYear = movie.PremiereDate.Value.Year; + } } //studios diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index b40158dd7..05f2d485e 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -79,6 +79,18 @@ namespace MediaBrowser.Providers.Movies ImageUrl = string.IsNullOrWhiteSpace(obj.poster_path) ? null : tmdbImageUrl + obj.poster_path }; + if (!string.IsNullOrWhiteSpace(obj.release_date)) + { + DateTime r; + + // These dates are always in this exact format + if (DateTime.TryParse(obj.release_date, _usCulture, DateTimeStyles.None, out r)) + { + remoteResult.PremiereDate = r.ToUniversalTime(); + remoteResult.ProductionYear = remoteResult.PremiereDate.Value.Year; + } + } + remoteResult.SetProviderId(MetadataProviders.Tmdb, obj.id.ToString(_usCulture)); if (!string.IsNullOrWhiteSpace(obj.imdb_id)) @@ -571,7 +583,7 @@ namespace MediaBrowser.Providers.Movies public string poster_path { get; set; } public List production_companies { get; set; } public List production_countries { get; set; } - public DateTime release_date { get; set; } + public string release_date { get; set; } public int revenue { get; set; } public int runtime { get; set; } public List spoken_languages { get; set; } diff --git a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs index b149f709a..fc53d4c15 100644 --- a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs @@ -53,10 +53,6 @@ namespace MediaBrowser.Providers.TV public async Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) { - var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; - var tmdbId = searchInfo.GetProviderId(MetadataProviders.Tmdb); if (!string.IsNullOrEmpty(tmdbId)) @@ -69,6 +65,9 @@ namespace MediaBrowser.Providers.TV var obj = _jsonSerializer.DeserializeFromFile(dataFilePath); + var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); + var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var remoteResult = new RemoteSearchResult { Name = obj.name, @@ -95,16 +94,7 @@ namespace MediaBrowser.Providers.TV if (searchResult != null) { - var remoteResult = new RemoteSearchResult - { - Name = searchResult.name, - SearchProviderName = Name, - ImageUrl = string.IsNullOrWhiteSpace(searchResult.poster_path) ? null : tmdbImageUrl + searchResult.poster_path - }; - - remoteResult.SetProviderId(MetadataProviders.Tmdb, searchResult.id.ToString(_usCulture)); - - return new[] { remoteResult }; + return new[] { searchResult }; } } @@ -116,16 +106,7 @@ namespace MediaBrowser.Providers.TV if (searchResult != null) { - var remoteResult = new RemoteSearchResult - { - Name = searchResult.name, - SearchProviderName = Name, - ImageUrl = string.IsNullOrWhiteSpace(searchResult.poster_path) ? null : tmdbImageUrl + searchResult.poster_path - }; - - remoteResult.SetProviderId(MetadataProviders.Tmdb, searchResult.id.ToString(_usCulture)); - - return new[] { remoteResult }; + return new[] { searchResult }; } } @@ -148,7 +129,7 @@ namespace MediaBrowser.Providers.TV if (searchResult != null) { - tmdbId = searchResult.id.ToString(_usCulture); + tmdbId = searchResult.GetProviderId(MetadataProviders.Tmdb); } } } @@ -163,7 +144,7 @@ namespace MediaBrowser.Providers.TV if (searchResult != null) { - tmdbId = searchResult.id.ToString(_usCulture); + tmdbId = searchResult.GetProviderId(MetadataProviders.Tmdb); } } } @@ -418,7 +399,7 @@ namespace MediaBrowser.Providers.TV return false; } - private async Task FindByExternalId(string id, string externalSource, CancellationToken cancellationToken) + private async Task FindByExternalId(string id, string externalSource, CancellationToken cancellationToken) { var url = string.Format("http://api.themoviedb.org/3/tv/find/{0}?api_key={1}&external_source={2}", id, @@ -441,7 +422,19 @@ namespace MediaBrowser.Providers.TV if (tv != null) { - return tv; + var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); + var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + + var remoteResult = new RemoteSearchResult + { + Name = tv.name, + SearchProviderName = Name, + ImageUrl = string.IsNullOrWhiteSpace(tv.poster_path) ? null : tmdbImageUrl + tv.poster_path + }; + + remoteResult.SetProviderId(MetadataProviders.Tmdb, tv.id.ToString(_usCulture)); + + return remoteResult; } } } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 66e9e4fa1..c5cddf40a 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -922,6 +922,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task ValidatePeople(CancellationToken cancellationToken, IProgress progress) { + // Ensure the location is unavailable. + Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath); + return new PeopleValidator(this, _logger).ValidatePeople(cancellationToken, progress); } @@ -933,6 +936,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task ValidateArtists(CancellationToken cancellationToken, IProgress progress) { + // Ensure the location is unavailable. + Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.ArtistsPath); + return new ArtistsValidator(this, _userManager, _logger).Run(progress, cancellationToken); } @@ -944,6 +950,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task ValidateMusicGenres(CancellationToken cancellationToken, IProgress progress) { + // Ensure the location is unavailable. + Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.MusicGenrePath); + return new MusicGenresValidator(this, _userManager, _logger).Run(progress, cancellationToken); } @@ -955,6 +964,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task ValidateGameGenres(CancellationToken cancellationToken, IProgress progress) { + // Ensure the location is unavailable. + Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.GameGenrePath); + return new GameGenresValidator(this, _userManager, _logger).Run(progress, cancellationToken); } @@ -966,6 +978,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task ValidateStudios(CancellationToken cancellationToken, IProgress progress) { + // Ensure the location is unavailable. + Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.StudioPath); + return new StudiosValidator(this, _userManager, _logger).Run(progress, cancellationToken); } @@ -977,6 +992,9 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task ValidateGenres(CancellationToken cancellationToken, IProgress progress) { + // Ensure the location is unavailable. + Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.GenrePath); + return new GenresValidator(this, _userManager, _logger).Run(progress, cancellationToken); } -- cgit v1.2.3 From 2db452f68f64fe4182e8ef3e83cc236c61fa8d82 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Mar 2014 21:17:12 -0500 Subject: add more data to media report --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 14 +++++++++++++- MediaBrowser.Controller/Entities/IHasMetadata.cs | 6 ------ MediaBrowser.Providers/Manager/MetadataService.cs | 15 --------------- MediaBrowser.ServerApplication/LibraryViewer.cs | 13 ++++++++----- 5 files changed, 22 insertions(+), 28 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 39cccf28a..9075bdfc6 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -332,7 +332,7 @@ namespace MediaBrowser.Api.UserLibrary var userId = user == null ? (Guid?)null : user.Id; var item = string.IsNullOrEmpty(request.ParentId) ? - user == null ? (BaseItem)_libraryManager.RootFolder : user.RootFolder : + user == null ? _libraryManager.RootFolder : user.RootFolder : _dtoService.GetItemByDtoId(request.ParentId, userId); // Default list type = children diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 923673bd8..f7f2346a8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -229,7 +229,19 @@ namespace MediaBrowser.Controller.Entities } } - public bool IsUnidentified { get; set; } + [IgnoreDataMember] + public bool IsUnidentified + { + get + { + if (ProviderIds.Any()) + { + return false; + } + + return false; + } + } /// /// Gets or sets the locked fields. diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 91f37135f..095db0815 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -49,11 +49,5 @@ namespace MediaBrowser.Controller.Entities /// /// true if XXXX, false otherwise. bool BeforeMetadataRefresh(); - - /// - /// Gets or sets a value indicating whether this instance is unidentified. - /// - /// true if this instance is unidentified; otherwise, false. - bool IsUnidentified { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 9b42820e8..24f4b3b2f 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -312,7 +312,6 @@ namespace MediaBrowser.Providers.Manager // Only one local provider allowed per item hasLocalMetadata = true; - item.IsUnidentified = false; break; } @@ -387,9 +386,6 @@ namespace MediaBrowser.Providers.Manager { TIdType id = null; - var unidentifiedCount = 0; - var identifiedCount = 0; - foreach (var provider in providers) { var providerName = provider.GetType().Name; @@ -414,11 +410,9 @@ namespace MediaBrowser.Providers.Manager refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload; - identifiedCount++; } else { - unidentifiedCount++; Logger.Debug("{0} returned no metadata for {1}", providerName, item.Path ?? item.Name); } } @@ -428,20 +422,11 @@ namespace MediaBrowser.Providers.Manager } catch (Exception ex) { - unidentifiedCount++; refreshResult.Status = ProviderRefreshStatus.CompletedWithErrors; refreshResult.ErrorMessage = ex.Message; Logger.ErrorException("Error in {0}", ex, provider.Name); } } - - var isUnidentified = unidentifiedCount > 0 && identifiedCount == 0; - - if (item.IsUnidentified != isUnidentified) - { - item.IsUnidentified = isUnidentified; - refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; - } } private void MergeNewData(TItemType source, TIdType lookupInfo) diff --git a/MediaBrowser.ServerApplication/LibraryViewer.cs b/MediaBrowser.ServerApplication/LibraryViewer.cs index 2bf51be4a..a8eda801b 100644 --- a/MediaBrowser.ServerApplication/LibraryViewer.cs +++ b/MediaBrowser.ServerApplication/LibraryViewer.cs @@ -84,7 +84,8 @@ namespace MediaBrowser.ServerApplication { treeView1.Nodes.Clear(); - IEnumerable children = _currentUser.Name == "Physical" ? new[] { _libraryManager.RootFolder } : _libraryManager.RootFolder.GetChildren(_currentUser, true); + var isPhysical = _currentUser.Name == "Physical"; + IEnumerable children = isPhysical ? new[] { _libraryManager.RootFolder } : _libraryManager.RootFolder.GetChildren(_currentUser, true); children = OrderByName(children, _currentUser); foreach (Folder folder in children) @@ -94,9 +95,9 @@ namespace MediaBrowser.ServerApplication var node = new TreeNode { Tag = currentFolder }; - var subChildren = currentFolder.GetChildren(_currentUser, true); + var subChildren = isPhysical ? currentFolder.Children : currentFolder.GetChildren(_currentUser, true); subChildren = OrderByName(subChildren, _currentUser); - AddChildren(node, subChildren, _currentUser); + AddChildren(node, subChildren, _currentUser, isPhysical); node.Text = currentFolder.Name + " (" + node.Nodes.Count + ")"; @@ -110,7 +111,7 @@ namespace MediaBrowser.ServerApplication /// The parent. /// The children. /// The user. - private void AddChildren(TreeNode parent, IEnumerable children, User user) + private void AddChildren(TreeNode parent, IEnumerable children, User user, bool isPhysical) { foreach (var item in children) { @@ -120,7 +121,9 @@ namespace MediaBrowser.ServerApplication { var prefs = _displayPreferencesManager.GetDisplayPreferences(subFolder.DisplayPreferencesId, user.Id, "LibraryExplorer"); - AddChildren(node, OrderBy(subFolder.GetChildren(user, true), user, prefs.SortBy), user); + var subChildren = isPhysical ? subFolder.Children : subFolder.GetChildren(_currentUser, true); + + AddChildren(node, OrderBy(subChildren, user, prefs.SortBy), user, isPhysical); node.Text = item.Name + " (" + node.Nodes.Count + ")"; } else -- cgit v1.2.3 From 6efb78b8b2c023369d18097ba8d17c396faabce1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 3 Mar 2014 00:11:03 -0500 Subject: fixes #697 - Support xbmc offline discs --- MediaBrowser.Api/GamesService.cs | 4 ++-- MediaBrowser.Api/UserLibrary/ItemsService.cs | 18 ++++++++++++++++++ .../MediaBrowser.Common.Implementations.csproj | 8 ++++---- .../packages.config | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 14 +------------- MediaBrowser.Controller/Entities/Folder.cs | 22 +++++++++++++++++++++- MediaBrowser.Controller/Entities/Game.cs | 8 ++++---- MediaBrowser.Controller/Entities/IHasMetadata.cs | 6 ++++++ .../Entities/ISupportsPlaceHolders.cs | 12 ++++++++++++ MediaBrowser.Controller/Entities/Video.cs | 4 +++- MediaBrowser.Controller/Library/TVUtils.cs | 7 +++++-- .../MediaBrowser.Controller.csproj | 1 + .../Resolvers/BaseVideoResolver.cs | 7 +++++-- .../Resolvers/EntityResolutionHelper.cs | 18 ++++++++++++++++++ MediaBrowser.Model/Dto/BaseItemDto.cs | 6 ++++++ MediaBrowser.Model/Providers/RemoteSearchResult.cs | 2 ++ .../Games/GameMetadataService.cs | 13 ++++++------- MediaBrowser.Providers/Manager/MetadataService.cs | 14 ++++++++++++++ .../MediaInfo/FFProbeProvider.cs | 7 ++++++- .../MediaInfo/VideoImageProvider.cs | 2 +- .../Dto/DtoService.cs | 6 ++++++ .../Library/LibraryManager.cs | 2 +- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 1 + .../MediaEncoder/EncodingManager.cs | 5 +++++ Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 27 files changed, 154 insertions(+), 45 deletions(-) create mode 100644 MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index d3b7cbe41..eabda673a 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -155,11 +155,11 @@ namespace MediaBrowser.Api var games = items.OfType().ToList(); - summary.ClientInstalledGameCount = games.Count(i => !i.IsInstalledOnClient); + summary.ClientInstalledGameCount = games.Count(i => !i.IsPlaceHolder); summary.GameCount = games.Count; - summary.GameFileExtensions = games.Where(i => !i.IsInstalledOnClient).Select(i => Path.GetExtension(i.Path)) + summary.GameFileExtensions = games.Where(i => !i.IsPlaceHolder).Select(i => Path.GetExtension(i.Path)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 9075bdfc6..4a5b69704 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -220,6 +220,12 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsInBoxSet { get; set; } + + [ApiMember(Name = "IsLocked", Description = "Optional filter by items that are locked.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public bool? IsLocked { get; set; } + + [ApiMember(Name = "HasSubtitles", Description = "Optional filter by items that are unidentified by internet metadata providers.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public bool? IsUnidentified { get; set; } } /// @@ -1019,6 +1025,18 @@ namespace MediaBrowser.Api.UserLibrary items = items.Where(i => i.IsPlayed(user) == val); } + if (request.IsUnidentified.HasValue) + { + var val = request.IsUnidentified.Value; + items = items.Where(i => i.IsUnidentified == val); + } + + if (request.IsLocked.HasValue) + { + var val = request.IsLocked.Value; + items = items.Where(i => i.IsLocked == val); + } + if (request.ParentIndexNumber.HasValue) { var filterValue = request.ParentIndexNumber.Value; diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 1688fac8b..04b8865c1 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -48,13 +48,13 @@ Always - + False - ..\packages\SimpleInjector.2.4.1\lib\net45\SimpleInjector.dll + ..\packages\SimpleInjector.2.5.0\lib\net45\SimpleInjector.dll - + False - ..\packages\SimpleInjector.2.4.1\lib\net45\SimpleInjector.Diagnostics.dll + ..\packages\SimpleInjector.2.5.0\lib\net45\SimpleInjector.Diagnostics.dll diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index e04fecc1d..38d6be2ef 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f7f2346a8..923673bd8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -229,19 +229,7 @@ namespace MediaBrowser.Controller.Entities } } - [IgnoreDataMember] - public bool IsUnidentified - { - get - { - if (ProviderIds.Any()) - { - return false; - } - - return false; - } - } + public bool IsUnidentified { get; set; } /// /// Gets or sets the locked fields. diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 522bc3a2d..627f657ab 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -352,6 +352,26 @@ namespace MediaBrowser.Controller.Entities return dictionary; } + private bool IsValidFromResolver(BaseItem current, BaseItem newItem) + { + var currentAsPlaceHolder = current as ISupportsPlaceHolders; + + if (currentAsPlaceHolder != null) + { + var newHasPlaceHolder = newItem as ISupportsPlaceHolders; + + if (newHasPlaceHolder != null) + { + if (currentAsPlaceHolder.IsPlaceHolder != newHasPlaceHolder.IsPlaceHolder) + { + return false; + } + } + } + + return current.IsInMixedFolder == newItem.IsInMixedFolder; + } + /// /// Validates the children internal. /// @@ -401,7 +421,7 @@ namespace MediaBrowser.Controller.Entities { BaseItem currentChild; - if (currentChildren.TryGetValue(child.Id, out currentChild) && child.IsInMixedFolder == currentChild.IsInMixedFolder) + if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child)) { var currentChildLocationType = currentChild.LocationType; if (currentChildLocationType != LocationType.Remote && diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index e490a59cd..062bdfa88 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -7,7 +7,7 @@ using System.Linq; namespace MediaBrowser.Controller.Entities { - public class Game : BaseItem, IHasSoundtracks, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, IHasPreferredMetadataLanguage, IHasLookupInfo + public class Game : BaseItem, IHasSoundtracks, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasPreferredMetadataLanguage, IHasLookupInfo { public List SoundtrackIds { get; set; } @@ -63,10 +63,10 @@ namespace MediaBrowser.Controller.Entities public int? PlayersSupported { get; set; } /// - /// Gets or sets a value indicating whether this instance is installed on client. + /// Gets a value indicating whether this instance is place holder. /// - /// true if this instance is installed on client; otherwise, false. - public bool IsInstalledOnClient { get; set; } + /// true if this instance is place holder; otherwise, false. + public bool IsPlaceHolder { get; set; } /// /// Gets or sets the game system. diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 095db0815..91f37135f 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -49,5 +49,11 @@ namespace MediaBrowser.Controller.Entities /// /// true if XXXX, false otherwise. bool BeforeMetadataRefresh(); + + /// + /// Gets or sets a value indicating whether this instance is unidentified. + /// + /// true if this instance is unidentified; otherwise, false. + bool IsUnidentified { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs b/MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs new file mode 100644 index 000000000..2507c8ee6 --- /dev/null +++ b/MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs @@ -0,0 +1,12 @@ + +namespace MediaBrowser.Controller.Entities +{ + public interface ISupportsPlaceHolders + { + /// + /// Gets a value indicating whether this instance is place holder. + /// + /// true if this instance is place holder; otherwise, false. + bool IsPlaceHolder { get; } + } +} diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index fa85f0edc..e61e958f5 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.Entities /// /// Class Video /// - public class Video : BaseItem, IHasMediaStreams, IHasAspectRatio, IHasTags + public class Video : BaseItem, IHasMediaStreams, IHasAspectRatio, IHasTags, ISupportsPlaceHolders { public bool IsMultiPart { get; set; } @@ -42,6 +42,8 @@ namespace MediaBrowser.Controller.Entities /// true if this instance has subtitles; otherwise, false. public bool HasSubtitles { get; set; } + public bool IsPlaceHolder { get; set; } + /// /// Gets or sets the tags. /// diff --git a/MediaBrowser.Controller/Library/TVUtils.cs b/MediaBrowser.Controller/Library/TVUtils.cs index 82911117f..c64e4fa0c 100644 --- a/MediaBrowser.Controller/Library/TVUtils.cs +++ b/MediaBrowser.Controller/Library/TVUtils.cs @@ -234,9 +234,12 @@ namespace MediaBrowser.Controller.Library { var fullName = child.FullName; - if (EntityResolutionHelper.IsVideoFile(fullName) && GetEpisodeNumberFromFile(fullName, false).HasValue) + if (EntityResolutionHelper.IsVideoFile(fullName) || EntityResolutionHelper.IsVideoPlaceHolder(fullName)) { - return true; + if (GetEpisodeNumberFromFile(fullName, false).HasValue) + { + return true; + } } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index c07693b36..ff446f2ef 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -105,6 +105,7 @@ + diff --git a/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs index aadaf5423..9e5d68c48 100644 --- a/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs +++ b/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs @@ -35,7 +35,9 @@ namespace MediaBrowser.Controller.Resolvers // If the path is a file check for a matching extensions if (!args.IsDirectory) { - if (EntityResolutionHelper.IsVideoFile(args.Path)) + var isPlaceHolder = EntityResolutionHelper.IsVideoPlaceHolder(args.Path); + + if (EntityResolutionHelper.IsVideoFile(args.Path) || isPlaceHolder) { var extension = Path.GetExtension(args.Path); @@ -46,7 +48,8 @@ namespace MediaBrowser.Controller.Resolvers { VideoType = type, Path = args.Path, - IsInMixedFolder = true + IsInMixedFolder = true, + IsPlaceHolder = isPlaceHolder }; } } diff --git a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs index 42b637140..0f93e8e8a 100644 --- a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs +++ b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs @@ -139,6 +139,24 @@ namespace MediaBrowser.Controller.Resolvers return VideoFileExtensionsDictionary.ContainsKey(extension); } + /// + /// Determines whether [is place holder] [the specified path]. + /// + /// The path. + /// true if [is place holder] [the specified path]; otherwise, false. + /// path + public static bool IsVideoPlaceHolder(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var extension = Path.GetExtension(path); + + return string.Equals(extension, ".disc", StringComparison.OrdinalIgnoreCase); + } + /// /// Ensures DateCreated and DateModified have values /// diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 661dc62bb..9e57f045a 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -208,6 +208,12 @@ namespace MediaBrowser.Model.Dto /// The players. public int? Players { get; set; } + /// + /// Gets or sets a value indicating whether this instance is place holder. + /// + /// null if [is place holder] contains no value, true if [is place holder]; otherwise, false. + public bool? IsPlaceHolder { get; set; } + /// /// Gets or sets the index number. /// diff --git a/MediaBrowser.Model/Providers/RemoteSearchResult.cs b/MediaBrowser.Model/Providers/RemoteSearchResult.cs index 122266614..8c9e116d6 100644 --- a/MediaBrowser.Model/Providers/RemoteSearchResult.cs +++ b/MediaBrowser.Model/Providers/RemoteSearchResult.cs @@ -31,6 +31,8 @@ namespace MediaBrowser.Model.Providers public string SearchProviderName { get; set; } + public string GameSystem { get; set; } + public RemoteSearchResult() { ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Providers/Games/GameMetadataService.cs b/MediaBrowser.Providers/Games/GameMetadataService.cs index 1586414ea..1e184bb06 100644 --- a/MediaBrowser.Providers/Games/GameMetadataService.cs +++ b/MediaBrowser.Providers/Games/GameMetadataService.cs @@ -1,25 +1,19 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Providers.Games { public class GameMetadataService : MetadataService { - private readonly ILibraryManager _libraryManager; - - public GameMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager) + public GameMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem) { - _libraryManager = libraryManager; } /// @@ -38,6 +32,11 @@ namespace MediaBrowser.Providers.Games { target.GameSystem = source.GameSystem; } + + if (replaceData || !target.PlayersSupported.HasValue) + { + target.PlayersSupported = source.PlayersSupported; + } } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 24f4b3b2f..2ecc6c9dd 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -386,6 +386,9 @@ namespace MediaBrowser.Providers.Manager { TIdType id = null; + var unidentifiedCount = 0; + var identifiedCount = 0; + foreach (var provider in providers) { var providerName = provider.GetType().Name; @@ -410,9 +413,11 @@ namespace MediaBrowser.Providers.Manager refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload; + identifiedCount++; } else { + unidentifiedCount++; Logger.Debug("{0} returned no metadata for {1}", providerName, item.Path ?? item.Name); } } @@ -422,11 +427,20 @@ namespace MediaBrowser.Providers.Manager } catch (Exception ex) { + unidentifiedCount++; refreshResult.Status = ProviderRefreshStatus.CompletedWithErrors; refreshResult.ErrorMessage = ex.Message; Logger.ErrorException("Error in {0}", ex, provider.Name); } } + + var isUnidentified = unidentifiedCount > 0 && identifiedCount == 0; + + if (item.IsUnidentified != isUnidentified) + { + item.IsUnidentified = isUnidentified; + refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; + } } private void MergeNewData(TItemType source, TIdType lookupInfo) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index bb417536a..55d09b68b 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -126,6 +126,11 @@ namespace MediaBrowser.Providers.MediaInfo return _cachedTask; } + if (item.IsPlaceHolder) + { + return _cachedTask; + } + var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager); return prober.ProbeVideo(item, directoryService, cancellationToken); @@ -155,7 +160,7 @@ namespace MediaBrowser.Providers.MediaInfo { var video = item as Video; - if (video != null) + if (video != null && !video.IsPlaceHolder) { var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager); diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 68216c6e1..354758497 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -56,7 +56,7 @@ namespace MediaBrowser.Providers.MediaInfo var video = (Video)item; // No support for this - if (video.VideoType == VideoType.HdDvd) + if (video.VideoType == VideoType.HdDvd || video.IsPlaceHolder) { return Task.FromResult(new DynamicImageResponse { HasImage = false }); } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 1174f16ae..7bf87875e 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -970,6 +970,12 @@ namespace MediaBrowser.Server.Implementations.Dto } } + var supportsPlaceHolders = item as ISupportsPlaceHolders; + if (supportsPlaceHolders != null) + { + dto.IsPlaceHolder = supportsPlaceHolders.IsPlaceHolder; + } + // Add audio info var audio = item as Audio; if (audio != null) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index c5cddf40a..6e9d803bf 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -451,7 +451,7 @@ namespace MediaBrowser.Server.Implementations.Library } } - if (options.DeleteFileLocation && (locationType == LocationType.FileSystem || locationType == LocationType.Offline)) + if (options.DeleteFileLocation && locationType != LocationType.Remote && locationType != LocationType.Virtual) { foreach (var path in item.GetDeletePaths().ToList()) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 7e643cd99..871171541 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -132,6 +132,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return true; } if (EntityResolutionHelper.IsVideoFile(fullName)) return false; + if (EntityResolutionHelper.IsVideoPlaceHolder(fullName)) return false; } // or a single audio file and no video files diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index 6f4b7a8a7..f74865d2c 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -84,6 +84,11 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// true if [is eligible for chapter image extraction] [the specified video]; otherwise, false. private bool IsEligibleForChapterImageExtraction(Video video) { + if (video.IsPlaceHolder) + { + return false; + } + if (video is Movie) { if (!_config.Configuration.EnableMovieChapterImageExtraction) diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index b9e4fc39c..e570f18d8 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.334 + 3.0.335 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 0db7f2139..75b695584 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.334 + 3.0.335 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 7bcee1e78..581a82106 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.334 + 3.0.335 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + -- cgit v1.2.3 From a72a297c88a50e48c1dc4a6b58c7213be786e1a0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 3 Mar 2014 23:53:48 -0500 Subject: add more report data --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 39 +++++++++++++++++++++- MediaBrowser.Controller/Entities/TV/Episode.cs | 2 +- .../Providers/BaseItemXmlParser.cs | 1 - .../ScheduledTasks/PeopleValidationTask.cs | 4 +-- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 2 +- .../FFMpeg/FFMpegDownloadInfo.cs | 4 +-- MediaBrowser.WebDashboard/Api/DashboardService.cs | 3 +- .../MediaBrowser.WebDashboard.csproj | 4 ++- 8 files changed, 47 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 4a5b69704..871c9aecb 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -224,8 +224,14 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "IsLocked", Description = "Optional filter by items that are locked.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public bool? IsLocked { get; set; } - [ApiMember(Name = "HasSubtitles", Description = "Optional filter by items that are unidentified by internet metadata providers.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "IsUnidentified", Description = "Optional filter by items that are unidentified by internet metadata providers.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public bool? IsUnidentified { get; set; } + + [ApiMember(Name = "IsPlaceHolder", Description = "Optional filter by items that are placeholders", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public bool? IsPlaceHolder { get; set; } + + [ApiMember(Name = "HasOfficialRating", Description = "Optional filter by items that have official ratings", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public bool? HasOfficialRating { get; set; } } /// @@ -1135,6 +1141,37 @@ namespace MediaBrowser.Api.UserLibrary items = items.Where(i => IsYearMismatched(i) == filterValue); } + if (request.HasOfficialRating.HasValue) + { + var filterValue = request.HasOfficialRating.Value; + + items = items.Where(i => + { + var hasValue = !string.IsNullOrEmpty(i.OfficialRating); + + return hasValue == filterValue; + }); + } + + if (request.IsPlaceHolder.HasValue) + { + var filterValue = request.IsPlaceHolder.Value; + + items = items.Where(i => + { + var isPlaceHolder = false; + + var hasPlaceHolder = i as ISupportsPlaceHolders; + + if (hasPlaceHolder != null) + { + isPlaceHolder = hasPlaceHolder.IsPlaceHolder; + } + + return isPlaceHolder == filterValue; + }); + } + return items; } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 4a3c82b46..503d1513c 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -185,7 +185,7 @@ namespace MediaBrowser.Controller.Entities.TV { get { - return LocationType == LocationType.Virtual && PremiereDate.HasValue && PremiereDate.Value < DateTime.UtcNow; + return LocationType == LocationType.Virtual && !IsUnaired; } } diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 0163dec20..d71c7af32 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -779,7 +779,6 @@ namespace MediaBrowser.Controller.Providers break; case "TMDbCollectionId": - case "CollectionNumber": var tmdbCollection = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(tmdbCollection)) { diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs index 7d0593c5f..bfa4fe944 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs @@ -34,9 +34,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks { return new ITaskTrigger[] { - new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }, - - new IntervalTrigger{ Interval = TimeSpan.FromHours(24)} + new DailyTrigger { TimeOfDay = TimeSpan.FromHours(3) }, }; } diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index 462dc1e78..97dfb2c5d 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -40,7 +40,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - new IntervalTrigger{ Interval = TimeSpan.FromHours(4)} + new IntervalTrigger{ Interval = TimeSpan.FromHours(6)} }; } diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs index c560a5b91..2588c3d5c 100644 --- a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs @@ -121,7 +121,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg { return new[] { - "https://copy.com/IB0W4efS6t9A/ffall-2.1.1.tar.gz?download=1" + "https://www.dropbox.com/s/n188rxbulqem8ry/ffmpeg-osx-20131121.gz?dl=1" }; } @@ -148,7 +148,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg //No Unix version available return new string[] {}; - #endif +#endif } return new string[] {}; } diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 0e6010fd0..c10b17d67 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -456,8 +456,6 @@ namespace MediaBrowser.WebDashboard.Api /// Task{Stream}. private async Task GetAllJavascript() { - var assembly = GetType().Assembly; - var scriptFiles = new[] { "extensions.js", @@ -581,6 +579,7 @@ namespace MediaBrowser.WebDashboard.Api await AppendResource(memoryStream, "thirdparty/autonumeric/autoNumeric.min.js", newLineBytes).ConfigureAwait(false); + var assembly = GetType().Assembly; await AppendResource(assembly, memoryStream, "MediaBrowser.WebDashboard.ApiClient.js", newLineBytes).ConfigureAwait(false); foreach (var file in scriptFiles) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 55f97e1da..4895d203f 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -84,7 +84,9 @@ - + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 040c36dbf22a4175686bbf0a7824f698a764ab8b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 4 Mar 2014 21:59:23 -0500 Subject: removed use of libbluray --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Controller/Entities/Video.cs | 14 +++++++------- .../MediaEncoding/MediaEncoderHelpers.cs | 17 ++++++++++------- .../MediaEncoder/MediaEncoder.cs | 4 +--- 4 files changed, 19 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index fea44c9a8..b97afc217 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -618,7 +618,7 @@ namespace MediaBrowser.Api.Playback // Don't re-encode ass/ssa to ass because ffmpeg ass encoder fails if there's more than one ass rectangle. Affect Anime mostly. // See https://lists.ffmpeg.org/pipermail/ffmpeg-cvslog/2013-April/063616.html - bool isAssSubtitle = string.Equals(state.SubtitleStream.Codec, "ass", StringComparison.OrdinalIgnoreCase) || string.Equals(state.SubtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase); + var isAssSubtitle = string.Equals(state.SubtitleStream.Codec, "ass", StringComparison.OrdinalIgnoreCase) || string.Equals(state.SubtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase); var task = MediaEncoder.ExtractTextSubtitle(inputPath, type, state.SubtitleStream.Index, isAssSubtitle, path, CancellationToken.None); diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index e61e958f5..10034d7e5 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -110,10 +110,13 @@ namespace MediaBrowser.Controller.Entities return System.IO.Path.GetDirectoryName(Path); } - if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd || - VideoType == VideoType.HdDvd) + if (!IsPlaceHolder) { - return Path; + if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd || + VideoType == VideoType.HdDvd) + { + return Path; + } } return base.ContainingFolderPath; @@ -259,10 +262,7 @@ namespace MediaBrowser.Controller.Entities { if (!IsInMixedFolder) { - if (VideoType == VideoType.VideoFile || VideoType == VideoType.Iso) - { - return new[] { System.IO.Path.GetDirectoryName(Path) }; - } + return new[] { ContainingFolderPath }; } return base.GetDeletePaths(); diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs index b2b9e2af3..184033177 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs @@ -34,6 +34,7 @@ namespace MediaBrowser.Controller.MediaEncoding { case VideoType.BluRay: type = InputType.Bluray; + inputPath = GetPlayableStreamFiles(inputPath[0], playableStreamFileNames).ToArray(); break; case VideoType.Dvd: type = InputType.Dvd; @@ -46,6 +47,7 @@ namespace MediaBrowser.Controller.MediaEncoding { case IsoType.BluRay: type = InputType.Bluray; + inputPath = GetPlayableStreamFiles(inputPath[0], playableStreamFileNames).ToArray(); break; case IsoType.Dvd: type = InputType.Dvd; @@ -118,15 +120,16 @@ namespace MediaBrowser.Controller.MediaEncoding return type; } - public static Model.Entities.MediaInfo GetMediaInfo(InternalMediaInfoResult data) + public static MediaInfo GetMediaInfo(InternalMediaInfoResult data) { var internalStreams = data.streams ?? new MediaStreamInfo[] { }; - var info = new Model.Entities.MediaInfo(); - - info.MediaStreams = internalStreams.Select(s => GetMediaStream(s, data.format)) - .Where(i => i != null) - .ToList(); + var info = new MediaInfo + { + MediaStreams = internalStreams.Select(s => GetMediaStream(s, data.format)) + .Where(i => i != null) + .ToList() + }; if (data.format != null) { @@ -137,7 +140,7 @@ namespace MediaBrowser.Controller.MediaEncoding } private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - + /// /// Converts ffprobe stream info to our MediaStream class /// diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs index e71867b05..25b9c687c 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs @@ -125,13 +125,11 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder switch (type) { + case InputType.Bluray: case InputType.Dvd: case InputType.File: inputPath = GetConcatInputArgument(inputFiles); break; - case InputType.Bluray: - inputPath = GetBlurayInputArgument(inputFiles[0]); - break; case InputType.Url: inputPath = GetHttpInputArgument(inputFiles); break; -- cgit v1.2.3 From 9396f16aed2f304789324afc83e0c9f385c5f00a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 4 Mar 2014 21:59:59 -0500 Subject: add more reporting data --- .../Resolvers/BaseVideoResolver.cs | 24 +++++- .../Configuration/ServerConfiguration.cs | 1 + .../MediaInfo/FFProbeVideoInfo.cs | 92 ++++++++++++---------- MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs | 3 + MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 2 +- MediaBrowser.ServerApplication/ApplicationHost.cs | 24 +++++- 6 files changed, 101 insertions(+), 45 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs index 9e5d68c48..06bee2ad1 100644 --- a/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs +++ b/MediaBrowser.Controller/Resolvers/BaseVideoResolver.cs @@ -35,6 +35,7 @@ namespace MediaBrowser.Controller.Resolvers // If the path is a file check for a matching extensions if (!args.IsDirectory) { + // http://wiki.xbmc.org/index.php?title=Media_stubs var isPlaceHolder = EntityResolutionHelper.IsVideoPlaceHolder(args.Path); if (EntityResolutionHelper.IsVideoFile(args.Path) || isPlaceHolder) @@ -44,13 +45,34 @@ namespace MediaBrowser.Controller.Resolvers var type = string.Equals(extension, ".iso", StringComparison.OrdinalIgnoreCase) || string.Equals(extension, ".img", StringComparison.OrdinalIgnoreCase) ? VideoType.Iso : VideoType.VideoFile; - return new TVideoType + var video = new TVideoType { VideoType = type, Path = args.Path, IsInMixedFolder = true, IsPlaceHolder = isPlaceHolder }; + + if (isPlaceHolder) + { + if (args.Path.EndsWith("dvd.disc", StringComparison.OrdinalIgnoreCase)) + { + video.VideoType = VideoType.Dvd; + } + else if (args.Path.EndsWith("hddvd.disc", StringComparison.OrdinalIgnoreCase)) + { + video.VideoType = VideoType.HdDvd; + } + else if (args.Path.EndsWith("bluray.disc", StringComparison.OrdinalIgnoreCase) || + args.Path.EndsWith("brrip.disc", StringComparison.OrdinalIgnoreCase) || + args.Path.EndsWith("bd25.disc", StringComparison.OrdinalIgnoreCase) || + args.Path.EndsWith("bd50.disc", StringComparison.OrdinalIgnoreCase)) + { + video.VideoType = VideoType.BluRay; + } + } + + return video; } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index fc232edb3..0bff8a1bd 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -210,6 +210,7 @@ namespace MediaBrowser.Model.Configuration public PathSubstitution[] PathSubstitutions { get; set; } public string ServerName { get; set; } + public string WanDdns { get; set; } /// /// Initializes a new instance of the class. diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 620a7a6f6..c2279fb50 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -53,9 +53,18 @@ namespace MediaBrowser.Providers.MediaInfo { var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false); + BlurayDiscInfo blurayDiscInfo = null; + try { - OnPreFetch(item, isoMount); + if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay)) + { + var inputPath = isoMount != null ? isoMount.MountedPath : item.Path; + + blurayDiscInfo = GetBDInfo(inputPath); + } + + OnPreFetch(item, isoMount, blurayDiscInfo); // If we didn't find any satisfying the min length, just take them all if (item.VideoType == VideoType.Dvd || (item.IsoType.HasValue && item.IsoType == IsoType.Dvd)) @@ -67,6 +76,15 @@ namespace MediaBrowser.Providers.MediaInfo } } + if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType == IsoType.BluRay)) + { + if (item.PlayableStreamFileNames.Count == 0) + { + _logger.Error("No playable vobs found in bluray structure, skipping ffprobe."); + return ItemUpdateType.MetadataImport; + } + } + var result = await GetMediaInfo(item, isoMount, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); @@ -75,7 +93,7 @@ namespace MediaBrowser.Providers.MediaInfo cancellationToken.ThrowIfCancellationRequested(); - await Fetch(item, cancellationToken, result, isoMount, directoryService).ConfigureAwait(false); + await Fetch(item, cancellationToken, result, isoMount, blurayDiscInfo, directoryService).ConfigureAwait(false); } finally @@ -128,7 +146,7 @@ namespace MediaBrowser.Providers.MediaInfo return result; } - protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, IDirectoryService directoryService) + protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, BlurayDiscInfo blurayInfo, IDirectoryService directoryService) { if (data.format != null) { @@ -147,8 +165,7 @@ namespace MediaBrowser.Providers.MediaInfo if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay)) { - var inputPath = isoMount != null ? isoMount.MountedPath : video.Path; - FetchBdInfo(video, chapters, mediaStreams, inputPath, cancellationToken); + FetchBdInfo(video, chapters, mediaStreams, blurayInfo); } AddExternalSubtitles(video, mediaStreams, directoryService); @@ -183,14 +200,10 @@ namespace MediaBrowser.Providers.MediaInfo await _itemRepo.SaveChapters(video.Id, chapters, cancellationToken).ConfigureAwait(false); } - private void FetchBdInfo(BaseItem item, List chapters, List mediaStreams, string inputPath, CancellationToken cancellationToken) + private void FetchBdInfo(BaseItem item, List chapters, List mediaStreams, BlurayDiscInfo blurayInfo) { var video = (Video)item; - var result = GetBDInfo(inputPath); - - cancellationToken.ThrowIfCancellationRequested(); - int? currentHeight = null; int? currentWidth = null; int? currentBitRate = null; @@ -206,51 +219,43 @@ namespace MediaBrowser.Providers.MediaInfo } // Fill video properties from the BDInfo result - Fetch(video, mediaStreams, result, chapters); - - videoStream = mediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video); - - // Use the ffprobe values if these are empty - if (videoStream != null) - { - videoStream.BitRate = IsEmpty(videoStream.BitRate) ? currentBitRate : videoStream.BitRate; - videoStream.Width = IsEmpty(videoStream.Width) ? currentWidth : videoStream.Width; - videoStream.Height = IsEmpty(videoStream.Height) ? currentHeight : videoStream.Height; - } - } - - private bool IsEmpty(int? num) - { - return !num.HasValue || num.Value == 0; - } - - /// The chapters. - private void Fetch(Video video, List mediaStreams, BlurayDiscInfo stream, List chapters) - { - // Check all input for null/empty/zero - mediaStreams.Clear(); - mediaStreams.AddRange(stream.MediaStreams); + mediaStreams.AddRange(blurayInfo.MediaStreams); - video.MainFeaturePlaylistName = stream.PlaylistName; + video.MainFeaturePlaylistName = blurayInfo.PlaylistName; - if (stream.RunTimeTicks.HasValue && stream.RunTimeTicks.Value > 0) + if (blurayInfo.RunTimeTicks.HasValue && blurayInfo.RunTimeTicks.Value > 0) { - video.RunTimeTicks = stream.RunTimeTicks; + video.RunTimeTicks = blurayInfo.RunTimeTicks; } - video.PlayableStreamFileNames = stream.Files.ToList(); + video.PlayableStreamFileNames = blurayInfo.Files.ToList(); - if (stream.Chapters != null) + if (blurayInfo.Chapters != null) { chapters.Clear(); - chapters.AddRange(stream.Chapters.Select(c => new ChapterInfo + chapters.AddRange(blurayInfo.Chapters.Select(c => new ChapterInfo { StartPositionTicks = TimeSpan.FromSeconds(c).Ticks })); } + + videoStream = mediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video); + + // Use the ffprobe values if these are empty + if (videoStream != null) + { + videoStream.BitRate = IsEmpty(videoStream.BitRate) ? currentBitRate : videoStream.BitRate; + videoStream.Width = IsEmpty(videoStream.Width) ? currentWidth : videoStream.Width; + videoStream.Height = IsEmpty(videoStream.Height) ? currentHeight : videoStream.Height; + } + } + + private bool IsEmpty(int? num) + { + return !num.HasValue || num.Value == 0; } /// @@ -498,7 +503,7 @@ namespace MediaBrowser.Providers.MediaInfo /// /// The item. /// The mount. - private void OnPreFetch(Video item, IIsoMount mount) + private void OnPreFetch(Video item, IIsoMount mount, BlurayDiscInfo blurayDiscInfo) { if (item.VideoType == VideoType.Iso) { @@ -509,6 +514,11 @@ namespace MediaBrowser.Providers.MediaInfo { FetchFromDvdLib(item, mount); } + + if (item.VideoType == VideoType.BluRay || (item.IsoType.HasValue && item.IsoType.Value == IsoType.BluRay)) + { + item.PlayableStreamFileNames = blurayDiscInfo.Files.ToList(); + } } private void FetchFromDvdLib(Video item, IIsoMount mount) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 08d21ab39..5f6bdfa04 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -45,6 +45,9 @@ namespace MediaBrowser.Providers.TV if (!string.IsNullOrEmpty(seriesTvdbId)) { + await TvdbSeriesProvider.Current.EnsureSeriesInfo(seriesTvdbId, searchInfo.MetadataLanguage, + cancellationToken).ConfigureAwait(false); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesTvdbId); try diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 4bd22107c..4b78c1a96 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -1005,7 +1005,7 @@ namespace MediaBrowser.Providers.TV /// System.String. internal static string GetSeriesDataPath(IApplicationPaths appPaths) { - var dataPath = Path.Combine(appPaths.DataPath, "tvdb-v3"); + var dataPath = Path.Combine(appPaths.CachePath, "tvdb"); return dataPath; } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 1907344a1..479e07ee6 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -372,6 +372,15 @@ namespace MediaBrowser.ServerApplication { // Not there, no big deal } + + try + { + Directory.Delete(Path.Combine(ApplicationPaths.DataPath, "tvdb-v3"), true); + } + catch (IOException) + { + // Not there, no big deal + } }); } @@ -856,11 +865,22 @@ namespace MediaBrowser.ServerApplication private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private string GetWanAddress() { - var ip = WanAddressEntryPoint.WanAddress; + var ip = ServerConfigurationManager.Configuration.WanDdns; + + if (string.IsNullOrWhiteSpace(ip)) + { + ip = WanAddressEntryPoint.WanAddress; + } if (!string.IsNullOrEmpty(ip)) { - return "http://" + ip + ":" + ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(_usCulture); + if (!ip.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && + !ip.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) + { + ip = "http://" + ip; + } + + return ip + ":" + ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(_usCulture); } return null; -- cgit v1.2.3