aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-24 11:29:23 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-24 11:29:23 -0500
commit9606a2a710614404b4dda96cceff688314a1ec89 (patch)
tree024ecd23b21be91f752c73ed7a6278e922c6276b
parent8bc4d49c8967f850d0b76ee8896bbc8ce3e50424 (diff)
filter duplicate recordings based on showId
-rw-r--r--Emby.Common.Implementations/Net/UdpSocket.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs3
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs50
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs1
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs7
-rw-r--r--MediaBrowser.Controller/LiveTv/TimerInfo.cs2
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs2
-rw-r--r--MediaBrowser.Model/Querying/ItemFields.cs2
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs16
-rw-r--r--MediaBrowser.WebDashboard/Api/PackageCreator.cs32
10 files changed, 79 insertions, 38 deletions
diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs
index b9b7d8a2d..367d2242c 100644
--- a/Emby.Common.Implementations/Net/UdpSocket.cs
+++ b/Emby.Common.Implementations/Net/UdpSocket.cs
@@ -33,8 +33,6 @@ namespace Emby.Common.Implementations.Net
_LocalPort = localPort;
_Socket.Bind(new IPEndPoint(ip, _LocalPort));
- if (_LocalPort == 0)
- _LocalPort = (_Socket.LocalEndPoint as IPEndPoint).Port;
}
#endregion
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index f65331ec7..313db6a75 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -100,7 +100,8 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- if (addCachePrevention)
+ string expires;
+ if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out expires))
{
responseHeaders["Expires"] = "-1";
}
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index b7d2d1748..1fe5d87ce 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -645,6 +645,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
existingTimer.SeasonNumber = updatedTimer.SeasonNumber;
existingTimer.ShortOverview = updatedTimer.ShortOverview;
existingTimer.StartDate = updatedTimer.StartDate;
+ existingTimer.ShowId = updatedTimer.ShowId;
}
public Task<ImageStream> GetChannelImageAsync(string channelId, CancellationToken cancellationToken)
@@ -1836,6 +1837,39 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return seriesTimer.SkipEpisodesInLibrary && IsProgramAlreadyInLibrary(timer);
}
+ private void HandleDuplicateShowIds(List<TimerInfo> timers)
+ {
+ foreach (var timer in timers.Skip(1))
+ {
+ // TODO: Get smarter, prefer HD, etc
+
+ timer.Status = RecordingStatus.Cancelled;
+ _timerProvider.Update(timer);
+ }
+ }
+
+ private void SearchForDuplicateShowIds(List<TimerInfo> timers)
+ {
+ var groups = timers.ToLookup(i => i.ShowId ?? string.Empty).ToList();
+
+ foreach (var group in groups)
+ {
+ if (string.IsNullOrWhiteSpace(group.Key))
+ {
+ continue;
+ }
+
+ var groupTimers = group.ToList();
+
+ if (groupTimers.Count < 2)
+ {
+ continue;
+ }
+
+ HandleDuplicateShowIds(groupTimers);
+ }
+ }
+
private async Task UpdateTimersForSeriesTimer(List<ProgramInfo> epgData, SeriesTimerInfo seriesTimer, bool deleteInvalidTimers)
{
var allTimers = GetTimersForSeries(seriesTimer, epgData)
@@ -1843,6 +1877,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var registration = await _liveTvManager.GetRegistrationInfo("seriesrecordings").ConfigureAwait(false);
+ var enabledTimersForSeries = new List<TimerInfo>();
+
if (registration.IsValid)
{
foreach (var timer in allTimers)
@@ -1855,6 +1891,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
timer.Status = RecordingStatus.Cancelled;
}
+ else
+ {
+ enabledTimersForSeries.Add(timer);
+ }
_timerProvider.Add(timer);
}
else
@@ -1870,6 +1910,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
existingTimer.Status = RecordingStatus.Cancelled;
}
+ if (existingTimer.Status != RecordingStatus.Cancelled)
+ {
+ enabledTimersForSeries.Add(existingTimer);
+ }
+
existingTimer.SeriesTimerId = seriesTimer.Id;
_timerProvider.Update(existingTimer);
}
@@ -1877,6 +1922,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
+ SearchForDuplicateShowIds(enabledTimersForSeries);
+
if (deleteInvalidTimers)
{
var allTimerIds = allTimers
@@ -1901,8 +1948,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
- private IEnumerable<TimerInfo> GetTimersForSeries(SeriesTimerInfo seriesTimer,
- IEnumerable<ProgramInfo> allPrograms)
+ private IEnumerable<TimerInfo> GetTimersForSeries(SeriesTimerInfo seriesTimer, IEnumerable<ProgramInfo> allPrograms)
{
if (seriesTimer == null)
{
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
index 0ae5971bc..1b6ddc73f 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
@@ -31,6 +31,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
timer.Name = parent.Name;
timer.Overview = parent.Overview;
timer.SeriesTimerId = seriesTimer.Id;
+ timer.ShowId = parent.ShowId;
CopyProgramInfoToTimerInfo(parent, timer);
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 33db69ee2..45158b3c2 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -124,12 +124,14 @@ namespace Emby.Server.Implementations.LiveTv.Listings
private ProgramInfo GetProgramInfo(XmlTvProgram p, ListingsProviderInfo info)
{
+ var episodeTitle = p.Episode == null ? null : p.Episode.Title;
+
var programInfo = new ProgramInfo
{
ChannelId = p.ChannelId,
EndDate = GetDate(p.EndDate),
EpisodeNumber = p.Episode == null ? null : p.Episode.Episode,
- EpisodeTitle = p.Episode == null ? null : p.Episode.Title,
+ EpisodeTitle = episodeTitle,
Genres = p.Categories,
Id = String.Format("{0}_{1:O}", p.ChannelId, p.StartDate), // Construct an id from the channel and start date,
StartDate = GetDate(p.StartDate),
@@ -149,7 +151,8 @@ namespace Emby.Server.Implementations.LiveTv.Listings
HasImage = p.Icon != null && !String.IsNullOrEmpty(p.Icon.Source),
OfficialRating = p.Rating != null && !String.IsNullOrEmpty(p.Rating.Value) ? p.Rating.Value : null,
CommunityRating = p.StarRating.HasValue ? p.StarRating.Value : (float?)null,
- SeriesId = p.Episode != null ? p.Title.GetMD5().ToString("N") : null
+ SeriesId = p.Episode != null ? p.Title.GetMD5().ToString("N") : null,
+ ShowId = ((p.Title ?? string.Empty) + (episodeTitle ?? string.Empty)).GetMD5().ToString("N")
};
if (programInfo.IsMovie)
diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs
index fd614253a..ee8dd5d3a 100644
--- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs
@@ -34,6 +34,8 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The program identifier.</value>
public string ProgramId { get; set; }
+ public string ShowId { get; set; }
+
/// <summary>
/// Name of the recording.
/// </summary>
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index cdda858b7..64225ae76 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -154,7 +154,6 @@ namespace MediaBrowser.Model.Configuration
/// </summary>
/// <value><c>true</c> if [enable dashboard response caching]; otherwise, <c>false</c>.</value>
public bool EnableDashboardResponseCaching { get; set; }
- public bool EnableDashboardResourceMinification { get; set; }
/// <summary>
/// Allows the dashboard to be served from a custom path.
@@ -230,7 +229,6 @@ namespace MediaBrowser.Model.Configuration
HttpsPortNumber = DefaultHttpsPort;
EnableHttps = false;
EnableDashboardResponseCaching = true;
- EnableDashboardResourceMinification = true;
EnableAnonymousUsageReporting = true;
EnableAutomaticRestart = true;
diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs
index dfca9e771..bf1d4991c 100644
--- a/MediaBrowser.Model/Querying/ItemFields.cs
+++ b/MediaBrowser.Model/Querying/ItemFields.cs
@@ -45,6 +45,8 @@
/// </summary>
Chapters,
+ ChildCount,
+
/// <summary>
/// The critic rating summary
/// </summary>
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index ebd11ca9a..7fcfbfb13 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -113,6 +113,7 @@ namespace MediaBrowser.WebDashboard.Api
private readonly ILocalizationManager _localization;
private readonly IJsonSerializer _jsonSerializer;
private readonly IAssemblyInfo _assemblyInfo;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
/// <summary>
/// Initializes a new instance of the <see cref="DashboardService" /> class.
@@ -120,7 +121,7 @@ namespace MediaBrowser.WebDashboard.Api
/// <param name="appHost">The app host.</param>
/// <param name="serverConfigurationManager">The server configuration manager.</param>
/// <param name="fileSystem">The file system.</param>
- public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization, IJsonSerializer jsonSerializer, IAssemblyInfo assemblyInfo, ILogger logger, IHttpResultFactory resultFactory)
+ public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization, IJsonSerializer jsonSerializer, IAssemblyInfo assemblyInfo, ILogger logger, IHttpResultFactory resultFactory, IMemoryStreamFactory memoryStreamFactory)
{
_appHost = appHost;
_serverConfigurationManager = serverConfigurationManager;
@@ -130,6 +131,7 @@ namespace MediaBrowser.WebDashboard.Api
_assemblyInfo = assemblyInfo;
_logger = logger;
_resultFactory = resultFactory;
+ _memoryStreamFactory = memoryStreamFactory;
}
/// <summary>
@@ -161,7 +163,7 @@ namespace MediaBrowser.WebDashboard.Api
if (plugin != null && stream != null)
{
- return _resultFactory.GetStaticResult(Request, plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", stream, null, _appHost.ApplicationVersion.ToString(), null, false));
+ return _resultFactory.GetStaticResult(Request, plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", stream, null, _appHost.ApplicationVersion.ToString(), null));
}
throw new ResourceNotFoundException();
@@ -294,7 +296,7 @@ namespace MediaBrowser.WebDashboard.Api
cacheDuration = TimeSpan.FromDays(365);
}
- var cacheKey = (_appHost.ApplicationVersion.ToString() + (localizationCulture ?? string.Empty) + path).GetMD5();
+ var cacheKey = (_appHost.ApplicationVersion + (localizationCulture ?? string.Empty) + path).GetMD5();
return await _resultFactory.GetStaticResult(Request, cacheKey, null, cacheDuration, contentType, () => GetResourceStream(path, localizationCulture)).ConfigureAwait(false);
}
@@ -312,15 +314,13 @@ namespace MediaBrowser.WebDashboard.Api
/// <returns>Task{Stream}.</returns>
private Task<Stream> GetResourceStream(string path, string localizationCulture)
{
- var minify = _serverConfigurationManager.Configuration.EnableDashboardResourceMinification;
-
return GetPackageCreator()
- .GetResource(path, null, localizationCulture, _appHost.ApplicationVersion.ToString(), minify);
+ .GetResource(path, null, localizationCulture, _appHost.ApplicationVersion.ToString());
}
private PackageCreator GetPackageCreator()
{
- return new PackageCreator(_fileSystem, _localization, _logger, _serverConfigurationManager, _jsonSerializer);
+ return new PackageCreator(_fileSystem, _logger, _serverConfigurationManager, _memoryStreamFactory);
}
private List<string> GetDeployIgnoreExtensions()
@@ -507,7 +507,7 @@ namespace MediaBrowser.WebDashboard.Api
private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string mode, string culture, string appVersion)
{
- using (var stream = await GetPackageCreator().GetResource(resourceVirtualPath, mode, culture, appVersion, false).ConfigureAwait(false))
+ using (var stream = await GetPackageCreator().GetResource(resourceVirtualPath, mode, culture, appVersion).ConfigureAwait(false))
{
using (var fs = _fileSystem.GetFileStream(destinationFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index 260352c7e..f2df01976 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -16,32 +16,28 @@ namespace MediaBrowser.WebDashboard.Api
public class PackageCreator
{
private readonly IFileSystem _fileSystem;
- private readonly ILocalizationManager _localization;
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
- private readonly IJsonSerializer _jsonSerializer;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
- public PackageCreator(IFileSystem fileSystem, ILocalizationManager localization, ILogger logger, IServerConfigurationManager config, IJsonSerializer jsonSerializer)
+ public PackageCreator(IFileSystem fileSystem, ILogger logger, IServerConfigurationManager config, IMemoryStreamFactory memoryStreamFactory)
{
_fileSystem = fileSystem;
- _localization = localization;
_logger = logger;
_config = config;
- _jsonSerializer = jsonSerializer;
+ _memoryStreamFactory = memoryStreamFactory;
}
public async Task<Stream> GetResource(string path,
string mode,
string localizationCulture,
- string appVersion,
- bool enableMinification)
+ string appVersion)
{
Stream resourceStream;
if (path.Equals("css/all.css", StringComparison.OrdinalIgnoreCase))
{
- resourceStream = await GetAllCss(enableMinification).ConfigureAwait(false);
- enableMinification = false;
+ resourceStream = await GetAllCss().ConfigureAwait(false);
}
else
{
@@ -56,7 +52,7 @@ namespace MediaBrowser.WebDashboard.Api
{
if (IsCoreHtml(path))
{
- resourceStream = await ModifyHtml(path, resourceStream, mode, appVersion, localizationCulture, enableMinification).ConfigureAwait(false);
+ resourceStream = await ModifyHtml(path, resourceStream, mode, appVersion, localizationCulture).ConfigureAwait(false);
}
}
}
@@ -140,20 +136,14 @@ namespace MediaBrowser.WebDashboard.Api
/// <summary>
/// Modifies the HTML by adding common meta tags, css and js.
/// </summary>
- /// <param name="path">The path.</param>
- /// <param name="sourceStream">The source stream.</param>
- /// <param name="mode">The mode.</param>
- /// <param name="appVersion">The application version.</param>
- /// <param name="localizationCulture">The localization culture.</param>
- /// <param name="enableMinification">if set to <c>true</c> [enable minification].</param>
/// <returns>Task{Stream}.</returns>
- public async Task<Stream> ModifyHtml(string path, Stream sourceStream, string mode, string appVersion, string localizationCulture, bool enableMinification)
+ public async Task<Stream> ModifyHtml(string path, Stream sourceStream, string mode, string appVersion, string localizationCulture)
{
using (sourceStream)
{
string html;
- using (var memoryStream = new MemoryStream())
+ using (var memoryStream = _memoryStreamFactory.CreateNew())
{
await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false);
@@ -202,7 +192,7 @@ namespace MediaBrowser.WebDashboard.Api
var bytes = Encoding.UTF8.GetBytes(html);
- return new MemoryStream(bytes);
+ return _memoryStreamFactory.CreateNew(bytes);
}
}
@@ -332,9 +322,9 @@ namespace MediaBrowser.WebDashboard.Api
/// Gets all CSS.
/// </summary>
/// <returns>Task{Stream}.</returns>
- private async Task<Stream> GetAllCss(bool enableMinification)
+ private async Task<Stream> GetAllCss()
{
- var memoryStream = new MemoryStream();
+ var memoryStream = _memoryStreamFactory.CreateNew();
var files = new[]
{