diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 737d4ceea0..1d3d4f1e5f 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -725,12 +725,13 @@ namespace Emby.Server.Implementations.HttpServer Summary = route.Summary }); - //routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs) - //{ - // Notes = route.Notes, - // Priority = route.Priority, - // Summary = route.Summary - //}); + // needed because apps add /emby, and some users also add /emby, thereby double prefixing + routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs) + { + Notes = route.Notes, + Priority = route.Priority, + Summary = route.Summary + }); } return routes.ToArray(routes.Count); diff --git a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs index 4852c3c6ae..7aa4c299ff 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs @@ -12,7 +12,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books /// public class BookResolver : MediaBrowser.Controller.Resolvers.ItemResolver { - private readonly string[] _validExtensions = {".pdf", ".epub", ".mobi", ".cbr", ".cbz"}; + private readonly string[] _validExtensions = { ".pdf", ".epub", ".mobi", ".cbr", ".cbz", ".azw3" }; /// /// @@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books // Only process items that are in a collection folder containing books if (!string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) return null; - + if (args.IsDirectory) { return GetBook(args); @@ -69,9 +69,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books return null; return new Book - { - Path = bookFiles[0].FullName - }; + { + Path = bookFiles[0].FullName + }; } } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 149f69e5b3..d6f5e0d9fe 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -272,11 +272,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private bool EncodeVideo(MediaSourceInfo mediaSource) { - if (string.Equals(_liveTvOptions.RecordedVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - var mediaStreams = mediaSource.MediaStreams ?? new List(); return !mediaStreams.Any(i => i.Type == MediaStreamType.Video && string.Equals(i.Codec, "h264", StringComparison.OrdinalIgnoreCase) && !i.IsInterlaced); } diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 8ea98879a6..95ec1dee0d 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -110,7 +110,15 @@ namespace Emby.Server.Implementations.LiveTv.Listings var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString()); _fileSystem.CreateDirectory(tempFolder); - _zipClient.ExtractAllFromGz(stream, tempFolder, true); + try + { + _zipClient.ExtractAllFromGz(stream, tempFolder, true); + } + catch + { + // If the extraction fails just return the original file, it could be a gz + return file; + } return _fileSystem.GetFiles(tempFolder, true) .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index bb11dac5f1..cfdaaed101 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -299,6 +299,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun int? videoBitrate = null; int? audioBitrate = null; + var isHd = channelInfo.IsHD ?? true; + if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase)) { width = 1280; @@ -350,7 +352,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun else { // This is for android tv's 1200 condition. Remove once not needed anymore so that we can avoid possible side effects of dummying up this data - if ((channelInfo.IsHD ?? true)) + if (isHd) { width = 1920; height = 1080; @@ -367,9 +369,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun if (!videoBitrate.HasValue) { - videoBitrate = (channelInfo.IsHD ?? true) ? 15000000 : 2000000; + videoBitrate = isHd ? 15000000 : 2000000; } - audioBitrate = (channelInfo.IsHD ?? true) ? 448000 : 192000; + audioBitrate = isHd ? 448000 : 192000; } // normalize diff --git a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs index d2b4569baf..1b717b900a 100644 --- a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs +++ b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs @@ -1,8 +1,9 @@ -using MediaBrowser.Model.Serialization; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities.Audio { - public class AudioPodcast : Audio + public class AudioPodcast : Audio, IHasLookupInfo { [IgnoreDataMember] public override bool SupportsPositionTicksResume @@ -13,6 +14,15 @@ namespace MediaBrowser.Controller.Entities.Audio } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return true; + } + } + public override double? GetDefaultPrimaryImageAspectRatio() { return 1; diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs index 1bdcfb881e..78fb102536 100644 --- a/MediaBrowser.Controller/Entities/AudioBook.cs +++ b/MediaBrowser.Controller/Entities/AudioBook.cs @@ -1,11 +1,12 @@ using System; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Entities { - public class AudioBook : Audio.Audio, IHasSeries + public class AudioBook : Audio.Audio, IHasSeries, IHasLookupInfo { [IgnoreDataMember] public override bool SupportsPositionTicksResume diff --git a/MediaBrowser.Controller/Providers/IMetadataService.cs b/MediaBrowser.Controller/Providers/IMetadataService.cs index 2d4873f7ed..7b7bf166b5 100644 --- a/MediaBrowser.Controller/Providers/IMetadataService.cs +++ b/MediaBrowser.Controller/Providers/IMetadataService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using System; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using System.Threading; using System.Threading.Tasks; @@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Providers /// The item. /// true if this instance can refresh the specified item; otherwise, false. bool CanRefresh(IHasMetadata item); + bool CanRefreshPrimary(Type type); /// /// Refreshes the metadata. diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 910d697ec0..0bf4b914f1 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -91,8 +91,6 @@ namespace MediaBrowser.Controller.Sync /// List GetSyncTargets(string userId); - List GetSyncTargets(string userId, bool? supportsRemoteSync); - /// /// Supportses the synchronize. /// diff --git a/MediaBrowser.Controller/Sync/ISyncProvider.cs b/MediaBrowser.Controller/Sync/ISyncProvider.cs index 2f60e124ec..baee1a52f3 100644 --- a/MediaBrowser.Controller/Sync/ISyncProvider.cs +++ b/MediaBrowser.Controller/Sync/ISyncProvider.cs @@ -11,8 +11,6 @@ namespace MediaBrowser.Controller.Sync /// The name. string Name { get; } - bool SupportsRemoteSync { get; } - /// /// Gets the synchronize targets. /// diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index a70a1066d7..caf1bb2a89 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -13,7 +13,6 @@ namespace MediaBrowser.Model.LiveTv public string RecordingEncodingFormat { get; set; } public bool EnableRecordingSubfolders { get; set; } public bool EnableOriginalAudioWithEncodedRecordings { get; set; } - public string RecordedVideoCodec { get; set; } public TunerHostInfo[] TunerHosts { get; set; } public ListingsProviderInfo[] ListingProviders { get; set; } diff --git a/MediaBrowser.Providers/Books/GoogleBooksProvider.cs b/MediaBrowser.Providers/Books/GoogleBooksProvider.cs new file mode 100644 index 0000000000..7330b8c43e --- /dev/null +++ b/MediaBrowser.Providers/Books/GoogleBooksProvider.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Providers; + +namespace MediaBrowser.Providers.Books +{ + public class GoogleBooksProvider : IRemoteMetadataProvider + { + public string Name => "Google Books"; + private readonly IHttpClient _httpClient; + + public GoogleBooksProvider(IHttpClient httpClient) + { + _httpClient = httpClient; + } + + public Task GetImageResponse(string url, CancellationToken cancellationToken) + { + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + BufferContent = false + }); + } + + public async Task> GetMetadata(SongInfo info, CancellationToken cancellationToken) + { + return new MetadataResult(); + } + + public async Task> GetSearchResults(SongInfo searchInfo, CancellationToken cancellationToken) + { + return new List(); + } + } +} diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 23c6b3efd6..c37e05d957 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -453,6 +453,11 @@ namespace MediaBrowser.Providers.Manager return item is TItemType; } + public bool CanRefreshPrimary(Type type) + { + return type == typeof(TItemType); + } + protected virtual async Task RefreshWithProviders(MetadataResult metadata, TIdType id, MetadataRefreshOptions options, diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 9f46d41dfe..28367662bc 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -118,7 +118,29 @@ namespace MediaBrowser.Providers.Manager public Task RefreshSingleItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken) { - var service = _metadataServices.FirstOrDefault(i => i.CanRefresh(item)); + IMetadataService service = null; + var type = item.GetType(); + + foreach (var current in _metadataServices) + { + if (current.CanRefreshPrimary(type)) + { + service = current; + break; + } + } + + if (service == null) + { + foreach (var current in _metadataServices) + { + if (current.CanRefresh(item)) + { + service = current; + break; + } + } + } if (service != null) { @@ -452,6 +474,8 @@ namespace MediaBrowser.Providers.Manager GetPluginSummary(), GetPluginSummary(), GetPluginSummary