diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 34368d61f1..9d35c86d25 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public string SeriesName { get; set; } + [IgnoreDataMember] public Guid? SeriesId { get; set; } public string FindSeriesName() diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index b13c291d11..78c35ad484 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -249,6 +249,7 @@ namespace MediaBrowser.Controller.Entities.TV [IgnoreDataMember] public Guid? SeasonId { get; set; } + [IgnoreDataMember] public Guid? SeriesId { get; set; } public Guid? FindSeriesId() diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 218d0fef83..865cadeb90 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -237,6 +237,7 @@ namespace MediaBrowser.Controller.Entities.TV [IgnoreDataMember] public string SeriesName { get; set; } + [IgnoreDataMember] public Guid? SeriesId { get; set; } public string FindSeriesName() diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 859452362a..0866bd255a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -86,20 +86,28 @@ namespace MediaBrowser.MediaEncoding.Encoder "libvorbis", "srt", "h264_nvenc", - "h264_qsv" + "h264_qsv", + "ac3" }; output = output ?? string.Empty; + var index = 0; + foreach (var codec in required) { var srch = " " + codec + " "; if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1) { - _logger.Info("Encoder available: " + codec); + if (index < required.Length - 1) + { + _logger.Info("Encoder available: " + codec); + } + found.Add(codec); } + index++; } return found; diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 3e009d210a..de6c23cac6 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -671,17 +671,6 @@ namespace MediaBrowser.Server.Implementations.Dto .ToList(); } - private IEnumerable GetCacheTags(BaseItem item, ImageType type, int limit) - { - return item.GetImages(type) - // Convert to a list now in case GetImageCacheTag is slow - .ToList() - .Select(p => GetImageCacheTag(item, p)) - .Where(i => i != null) - .Take(limit) - .ToList(); - } - private string GetImageCacheTag(BaseItem item, ImageType type) { try @@ -1458,9 +1447,16 @@ namespace MediaBrowser.Server.Implementations.Dto while (((!dto.HasLogo && logoLimit > 0) || (!dto.HasArtImage && artLimit > 0) || (!dto.HasThumb && thumbLimit > 0) || parent is Series) && (parent = parent ?? (isFirst ? item.GetParent() ?? owner : parent)) != null) { + if (parent == null) + { + break; + } + + var allImages = parent.ImageInfos; + if (logoLimit > 0 && !dto.HasLogo && dto.ParentLogoItemId == null) { - var image = parent.GetImageInfo(ImageType.Logo, 0); + var image = allImages.FirstOrDefault(i => i.Type == ImageType.Logo); if (image != null) { @@ -1470,7 +1466,7 @@ namespace MediaBrowser.Server.Implementations.Dto } if (artLimit > 0 && !dto.HasArtImage && dto.ParentArtItemId == null) { - var image = parent.GetImageInfo(ImageType.Art, 0); + var image = allImages.FirstOrDefault(i => i.Type == ImageType.Art); if (image != null) { @@ -1480,7 +1476,7 @@ namespace MediaBrowser.Server.Implementations.Dto } if (thumbLimit > 0 && !dto.HasThumb && (dto.ParentThumbItemId == null || parent is Series)) { - var image = parent.GetImageInfo(ImageType.Thumb, 0); + var image = allImages.FirstOrDefault(i => i.Type == ImageType.Thumb); if (image != null) { @@ -1490,7 +1486,7 @@ namespace MediaBrowser.Server.Implementations.Dto } if (backdropLimit > 0 && !dto.HasBackdrop) { - var images = parent.GetImages(ImageType.Backdrop).Take(backdropLimit).ToList(); + var images = allImages.Where(i => i.Type == ImageType.Backdrop).Take(backdropLimit).ToList(); if (images.Count > 0) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index a3e5589e88..69b6fb5a94 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -17,6 +17,7 @@ using System.Threading.Tasks; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Net; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { @@ -106,18 +107,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private async Task GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken) { - using (var stream = await _httpClient.Get(new HttpRequestOptions() + try { - Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), - CancellationToken = cancellationToken, - CacheLength = TimeSpan.FromDays(1), - CacheMode = CacheMode.Unconditional, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds) - })) + using (var stream = await _httpClient.Get(new HttpRequestOptions() + { + Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), + CancellationToken = cancellationToken, + CacheLength = TimeSpan.FromDays(1), + CacheMode = CacheMode.Unconditional, + TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds) + })) + { + var response = JsonSerializer.DeserializeFromStream(stream); + + return response.ModelNumber; + } + } + catch (HttpException ex) { - var response = JsonSerializer.DeserializeFromStream(stream); + if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound) + { + // HDHR4 doesn't have this api + return "HDHR"; + } - return response.ModelNumber; + throw; } } @@ -455,16 +469,29 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return; } - // Test it by pulling down the lineup - using (var stream = await _httpClient.Get(new HttpRequestOptions + try { - Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), - CancellationToken = CancellationToken.None - })) + // Test it by pulling down the lineup + using (var stream = await _httpClient.Get(new HttpRequestOptions + { + Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), + CancellationToken = CancellationToken.None + })) + { + var response = JsonSerializer.DeserializeFromStream(stream); + + info.DeviceId = response.DeviceID; + } + } + catch (HttpException ex) { - var response = JsonSerializer.DeserializeFromStream(stream); + if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound) + { + // HDHR4 doesn't have this api + return; + } - info.DeviceId = response.DeviceID; + throw; } } diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index b11a3e4968..bf2afb5ace 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -155,6 +155,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _logger.Debug("Upgrading schema for {0} items", numItems); + var list = new List(); + foreach (var itemId in itemIds) { cancellationToken.ThrowIfCancellationRequested(); @@ -166,19 +168,26 @@ namespace MediaBrowser.Server.Implementations.Persistence if (item != null) { - try - { - await _itemRepo.SaveItem(item, cancellationToken).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - throw; - } - catch (Exception ex) - { - _logger.ErrorException("Error saving item", ex); - } + list.Add(item); + } + } + + if (list.Count >= 1000) + { + try + { + await _itemRepo.SaveItems(list, cancellationToken).ConfigureAwait(false); } + catch (OperationCanceledException) + { + throw; + } + catch (Exception ex) + { + _logger.ErrorException("Error saving item", ex); + } + + list.Clear(); } numComplete++; @@ -187,6 +196,22 @@ namespace MediaBrowser.Server.Implementations.Persistence progress.Report(percent * 100); } + if (list.Count > 0) + { + try + { + await _itemRepo.SaveItems(list, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception ex) + { + _logger.ErrorException("Error saving item", ex); + } + } + progress.Report(100); } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 93f58b3994..a3217e3ed3 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -156,8 +156,6 @@ namespace MediaBrowser.Server.Implementations.Persistence string[] queries = { "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID, Path TEXT)", - "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", - "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))", "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)", @@ -303,6 +301,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "drop index if exists idx_ItemValues4", "drop index if exists idx_ItemValues5", + "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", + "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", + "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", "create index if not exists idx_GuidTypeIsFolderIsVirtualItem on TypedBaseItems(Guid,Type,IsFolder,IsVirtualItem)", //"create index if not exists idx_GuidMediaTypeIsFolderIsVirtualItem on TypedBaseItems(Guid,MediaType,IsFolder,IsVirtualItem)",