From b9699fde05f33070c373d25d1ca72a13130ad149 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 20 Nov 2015 22:13:43 -0500 Subject: [PATCH 1/4] update schedules direct --- .../LiveTv/Listings/SchedulesDirect.cs | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 86815ae41e..85d3ffdbaa 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings UserAgent = UserAgent, CancellationToken = cancellationToken, // The data can be large so give it some extra time - TimeoutMs = 120000, + TimeoutMs = 60000, LogErrorResponseBody = true }; @@ -114,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestString = _jsonSerializer.SerializeToString(requestList); _logger.Debug("Request string for schedules is: " + requestString); httpOptions.RequestContent = requestString; - using (var response = await _httpClient.Post(httpOptions)) + using (var response = await Post(httpOptions).ConfigureAwait(false)) { StreamReader reader = new StreamReader(response.Content); string responseString = reader.ReadToEnd(); @@ -138,7 +138,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]"; httpOptions.RequestContent = requestBody; - using (var innerResponse = await _httpClient.Post(httpOptions)) + using (var innerResponse = await Post(httpOptions).ConfigureAwait(false)) { StreamReader innerReader = new StreamReader(innerResponse.Content); responseString = innerReader.ReadToEnd(); @@ -222,12 +222,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings Url = ApiUrl + "/lineups/" + info.ListingsId, UserAgent = UserAgent, CancellationToken = cancellationToken, - LogErrorResponseBody = true + LogErrorResponseBody = true, + // The data can be large so give it some extra time + TimeoutMs = 60000 }; httpOptions.RequestHeaders["token"] = token; - using (var response = await _httpClient.Get(httpOptions)) + using (var response = await Get(httpOptions).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(response); _logger.Info("Found " + root.map.Count() + " channels on the lineup on ScheduleDirect"); @@ -470,7 +472,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings TimeoutMs = 60000 }; List images; - using (var innerResponse2 = await _httpClient.Post(httpOptions)) + using (var innerResponse2 = await Post(httpOptions).ConfigureAwait(false)) { images = _jsonSerializer.DeserializeFromStream>( innerResponse2.Content); @@ -502,7 +504,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (Stream responce = await _httpClient.Get(options).ConfigureAwait(false)) + using (Stream responce = await Get(options).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream>(responce); @@ -571,7 +573,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out ticks)) { // If it's under 24 hours old we can still use it - if ((DateTime.UtcNow.Ticks - ticks) < TimeSpan.FromHours(24).Ticks) + if ((DateTime.UtcNow.Ticks - ticks) < TimeSpan.FromHours(20).Ticks) { return savedToken.Name; } @@ -604,6 +606,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } + private async Task Post(HttpRequestOptions options) + { + try + { + return await _httpClient.Post(options).ConfigureAwait(false); + } + catch + { + _tokens.Clear(); + throw; + } + } + + private async Task Get(HttpRequestOptions options) + { + try + { + return await _httpClient.Get(options).ConfigureAwait(false); + } + catch + { + _tokens.Clear(); + throw; + } + } + private async Task GetTokenInternal(string username, string password, CancellationToken cancellationToken) { @@ -618,7 +646,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings //_logger.Info("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " + // httpOptions.RequestContent); - using (var responce = await _httpClient.Post(httpOptions)) + using (var responce = await Post(httpOptions).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(responce.Content); if (root.message == "OK") @@ -700,7 +728,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (var response = await _httpClient.Get(options).ConfigureAwait(false)) + using (var response = await Get(options).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(response); From fe5537f779b08570f9a1c99ff2c5df50b6dd7f1f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 20 Nov 2015 23:34:55 -0500 Subject: [PATCH 2/4] update EmbyTV --- .../LiveTv/EmbyTV/EmbyTV.cs | 24 +++++++++++++------ .../LiveTv/EmbyTV/ItemDataProvider.cs | 16 ++++++++++++- .../LiveTv/EmbyTV/TimerManager.cs | 16 +------------ 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2ac06cda82..b529e91347 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -134,11 +134,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress progress) { - var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); + var seriesTimers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); List channels = null; - foreach (var timer in timers) + foreach (var timer in seriesTimers) { List epgData; @@ -157,6 +157,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } await UpdateTimersForSeriesTimer(epgData, timer).ConfigureAwait(false); } + + var timers = await GetTimersAsync(cancellationToken).ConfigureAwait(false); + + foreach (var timer in timers.ToList()) + { + if (DateTime.UtcNow > timer.EndDate && !_activeRecordings.ContainsKey(timer.Id)) + { + _timerProvider.Delete(timer); + } + } } private List _channelCache = null; @@ -684,7 +694,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV TimerId = timer.Id, ShowId = info.ShowId }; - _recordingProvider.Add(recording); + _recordingProvider.AddOrUpdate(recording); } try @@ -709,7 +719,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recording.Path = recordPath; recording.Status = RecordingStatus.InProgress; recording.DateLastUpdated = DateTime.UtcNow; - _recordingProvider.Update(recording); + _recordingProvider.AddOrUpdate(recording); _logger.Info("Beginning recording."); @@ -757,7 +767,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } recording.DateLastUpdated = DateTime.UtcNow; - _recordingProvider.Update(recording); + _recordingProvider.AddOrUpdate(recording); if (recording.Status == RecordingStatus.Completed) { @@ -828,12 +838,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private async Task UpdateTimersForSeriesTimer(List epgData, SeriesTimerInfo seriesTimer) { + var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); + var registration = await GetRegistrationInfo("seriesrecordings").ConfigureAwait(false); if (registration.IsValid) { - var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); - foreach (var timer in newTimers) { _timerProvider.AddOrUpdate(timer); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index d89c1c0cb6..f46daa6d50 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -73,7 +73,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void UpdateList(List newList) { var file = _dataPath + ".json"; - _fileSystem.CreateDirectory(Path.GetDirectoryName(file)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(file)); lock (_fileDataLock) { @@ -112,6 +112,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV UpdateList(list); } + public void AddOrUpdate(T item) + { + var list = GetAll().ToList(); + + if (!list.Any(i => EqualityComparer(i, item))) + { + Add(item); + } + else + { + Update(item); + } + } + public virtual void Delete(T item) { var list = GetAll().Where(i => !EqualityComparer(i, item)).ToList(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 94ad5e5cec..80bb671fa7 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -76,20 +76,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV AddTimer(item); } - public void AddOrUpdate(TimerInfo item) - { - var list = GetAll().ToList(); - - if (!list.Any(i => EqualityComparer(i, item))) - { - Add(item); - } - else - { - Update(item); - } - } - private void AddTimer(TimerInfo item) { var startDate = RecordingHelper.GetStartTime(item); @@ -108,7 +94,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public void StartTimer(TimerInfo item, TimeSpan length) { StopTimer(item); - + var timer = new Timer(TimerCallback, item.Id, length, TimeSpan.Zero); if (!_timers.TryAdd(item.Id, timer)) From 057c4b54943c13c123c060d5f7bd7086239aab66 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 20 Nov 2015 23:44:22 -0500 Subject: [PATCH 3/4] support image placeholders --- MediaBrowser.Controller/Entities/BaseItem.cs | 1 + .../Entities/ItemImageInfo.cs | 6 +++++ .../Manager/ItemImageProvider.cs | 16 +++++++++--- .../LiveTv/LiveTvManager.cs | 25 ++++++++++++++----- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index ec688bd9f4..7086ac7437 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1479,6 +1479,7 @@ namespace MediaBrowser.Controller.Entities image.Path = file.FullName; image.DateModified = imageInfo.DateModified; + image.IsPlaceholder = false; } } diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs index bb113e596d..aa3917c15f 100644 --- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs +++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs @@ -24,6 +24,12 @@ namespace MediaBrowser.Controller.Entities /// The date modified. public DateTime DateModified { get; set; } + /// + /// Gets or sets a value indicating whether this instance is placeholder. + /// + /// true if this instance is placeholder; otherwise, false. + public bool IsPlaceholder { get; set; } + [IgnoreDataMember] public bool IsLocalFile { diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index a4710bec47..9932df2bc6 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -130,7 +130,7 @@ namespace MediaBrowser.Providers.Manager { if (!IsEnabled(savedOptions, imageType, item)) continue; - if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) + if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); @@ -199,6 +199,14 @@ namespace MediaBrowser.Providers.Manager ImageType.Thumb }; + private bool HasImage(IHasImages item, ImageType type) + { + var image = item.GetImageInfo(type, 0); + + // if it's a placeholder image then pretend like it's not there so that we can replace it + return image != null && !image.IsPlaceholder; + } + /// /// Determines if an item already contains the given images /// @@ -210,7 +218,7 @@ namespace MediaBrowser.Providers.Manager /// true if the specified item contains images; otherwise, false. private bool ContainsImages(IHasImages item, List images, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit) { - if (_singularImages.Any(i => images.Contains(i) && !item.HasImage(i) && savedOptions.GetLimit(i) > 0)) + if (_singularImages.Any(i => images.Contains(i) && !HasImage(item, i) && savedOptions.GetLimit(i) > 0)) { return false; } @@ -282,7 +290,7 @@ namespace MediaBrowser.Providers.Manager { if (!IsEnabled(savedOptions, imageType, item)) continue; - if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) + if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { minWidth = savedOptions.GetMinWidth(imageType); var downloaded = await DownloadImage(item, provider, result, list, minWidth, imageType, cancellationToken).ConfigureAwait(false); @@ -613,4 +621,4 @@ namespace MediaBrowser.Providers.Manager } } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index e4a7683d69..7a0397a2d3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -653,13 +653,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.IndexNumber = info.EpisodeNumber; item.ParentIndexNumber = info.SeasonNumber; - if (!string.IsNullOrWhiteSpace(info.ImagePath)) + if (!item.HasImage(ImageType.Primary)) { - item.SetImagePath(ImageType.Primary, info.ImagePath); - } - else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) - { - item.SetImagePath(ImageType.Primary, info.ImageUrl); + if (!string.IsNullOrWhiteSpace(info.ImagePath)) + { + item.SetImage(new ItemImageInfo + { + Path = info.ImagePath, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); + } + else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) + { + item.SetImage(new ItemImageInfo + { + Path = info.ImageUrl, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); + } } if (isNew) From 60cd72b97409822af37ad23459aedf6684e38ab6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 20 Nov 2015 23:53:40 -0500 Subject: [PATCH 4/4] update channel item images --- MediaBrowser.Server.Implementations/Channels/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index ba759dcb9a..b115c3bfdc 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1286,7 +1286,7 @@ namespace MediaBrowser.Server.Implementations.Channels item.Path = mediaSource == null ? null : mediaSource.Path; } - if (!string.IsNullOrWhiteSpace(info.ImageUrl)) + if (!string.IsNullOrWhiteSpace(info.ImageUrl) && !item.HasImage(ImageType.Primary)) { item.SetImagePath(ImageType.Primary, info.ImageUrl); }