update recording scheduler

This commit is contained in:
Luke Pulverenti 2015-07-28 23:42:03 -04:00
parent a83d6322e1
commit 4d7f983618
11 changed files with 94 additions and 40 deletions

View File

@ -17,6 +17,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The series timer identifier.</value> /// <value>The series timer identifier.</value>
public string SeriesTimerId { get; set; } public string SeriesTimerId { get; set; }
/// <summary>
/// Gets or sets the timer identifier.
/// </summary>
/// <value>The timer identifier.</value>
public string TimerId { get; set; }
/// <summary> /// <summary>
/// ChannelId of the recording. /// ChannelId of the recording.
/// </summary> /// </summary>

View File

@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Channels namespace MediaBrowser.Server.Implementations.Channels
{ {
public class ChannelPostScanTask : ILibraryPostScanTask public class ChannelPostScanTask
{ {
private readonly IChannelManager _channelManager; private readonly IChannelManager _channelManager;
private readonly IUserManager _userManager; private readonly IUserManager _userManager;

View File

@ -1,6 +1,7 @@
using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Channels;
using MediaBrowser.Model.Tasks; using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,11 +10,15 @@ namespace MediaBrowser.Server.Implementations.Channels
{ {
class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
{ {
private readonly IChannelManager _manager; private readonly IChannelManager _channelManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
public RefreshChannelsScheduledTask(IChannelManager manager) public RefreshChannelsScheduledTask(IChannelManager channelManager, IUserManager userManager, ILogger logger)
{ {
_manager = manager; _channelManager = channelManager;
_userManager = userManager;
_logger = logger;
} }
public string Name public string Name
@ -31,11 +36,14 @@ namespace MediaBrowser.Server.Implementations.Channels
get { return "Channels"; } get { return "Channels"; }
} }
public Task Execute(System.Threading.CancellationToken cancellationToken, IProgress<double> progress) public async Task Execute(System.Threading.CancellationToken cancellationToken, IProgress<double> progress)
{ {
var manager = (ChannelManager)_manager; var manager = (ChannelManager)_channelManager;
return manager.RefreshChannels(progress, cancellationToken); await manager.RefreshChannels(new Progress<double>(), cancellationToken).ConfigureAwait(false);
await new ChannelPostScanTask(_channelManager, _userManager, _logger).Run(progress, cancellationToken)
.ConfigureAwait(false);
} }
public IEnumerable<ITaskTrigger> GetDefaultTriggers() public IEnumerable<ITaskTrigger> GetDefaultTriggers()
@ -48,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Channels
public bool IsHidden public bool IsHidden
{ {
get { return true; } get { return false; }
} }
public bool IsEnabled public bool IsEnabled

View File

@ -1,5 +1,4 @@
using System.ComponentModel; using MediaBrowser.Common.IO;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
@ -372,15 +371,12 @@ namespace MediaBrowser.Server.Implementations.IO
DisposeWatcher(dw); DisposeWatcher(dw);
if (ex is Win32Exception) if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto)
{ {
Logger.Info("Disabling realtime monitor to prevent future instability"); Logger.Info("Disabling realtime monitor to prevent future instability");
if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto) ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled;
{ Stop();
ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled;
Stop();
}
} }
} }

View File

@ -33,8 +33,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private readonly LiveTvManager _liveTvManager; private readonly LiveTvManager _liveTvManager;
public static EmbyTV Current;
public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager) public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager)
{ {
Current = this;
_appHpst = appHost; _appHpst = appHost;
_logger = logger; _logger = logger;
_httpClient = httpClient; _httpClient = httpClient;
@ -48,6 +52,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_timerProvider.TimerFired += _timerProvider_TimerFired; _timerProvider.TimerFired += _timerProvider_TimerFired;
} }
public void Start()
{
_timerProvider.RestartTimers();
}
public event EventHandler DataSourceChanged; public event EventHandler DataSourceChanged;
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged; public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged;
@ -147,7 +156,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken)
{ {
var remove = _seriesTimerProvider.GetAll().SingleOrDefault(r => r.Id == timerId); var remove = _seriesTimerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase));
if (remove != null) if (remove != null)
{ {
_seriesTimerProvider.Delete(remove); _seriesTimerProvider.Delete(remove);
@ -157,7 +166,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private void CancelTimerInternal(string timerId) private void CancelTimerInternal(string timerId)
{ {
var remove = _timerProvider.GetAll().SingleOrDefault(r => r.Id == timerId); var remove = _timerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase));
if (remove != null) if (remove != null)
{ {
_timerProvider.Delete(remove); _timerProvider.Delete(remove);
@ -176,11 +185,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
return Task.FromResult(true); return Task.FromResult(true);
} }
public Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken) public async Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken)
{ {
var remove = _recordingProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, recordingId, StringComparison.OrdinalIgnoreCase)); var remove = _recordingProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, recordingId, StringComparison.OrdinalIgnoreCase));
if (remove != null) if (remove != null)
{ {
if (!string.IsNullOrWhiteSpace(remove.TimerId))
{
var enableDelay = _activeRecordings.ContainsKey(remove.TimerId);
CancelTimerInternal(remove.TimerId);
if (enableDelay)
{
// A hack yes, but need to make sure the file is closed before attempting to delete it
await Task.Delay(3000).ConfigureAwait(false);
}
}
try try
{ {
File.Delete(remove.Path); File.Delete(remove.Path);
@ -195,7 +217,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
} }
_recordingProvider.Delete(remove); _recordingProvider.Delete(remove);
} }
return Task.FromResult(true);
} }
public Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken) public Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
@ -293,6 +314,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
if (list.Count > 0) if (list.Count > 0)
{ {
SaveEpgDataForChannel(channelId, list);
return list; return list;
} }
} }
@ -430,7 +453,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
} }
var mediaStreamInfo = await GetChannelStream(timer.ChannelId, null, CancellationToken.None); var mediaStreamInfo = await GetChannelStream(timer.ChannelId, null, CancellationToken.None);
var duration = (timer.EndDate - RecordingHelper.GetStartTime(timer)).TotalSeconds + timer.PrePaddingSeconds; var duration = (timer.EndDate - DateTime.UtcNow).TotalSeconds + timer.PostPaddingSeconds;
HttpRequestOptions httpRequestOptions = new HttpRequestOptions() HttpRequestOptions httpRequestOptions = new HttpRequestOptions()
{ {
@ -451,14 +474,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
recordPath = Path.Combine(recordPath, RecordingHelper.GetRecordingName(timer, info)); recordPath = Path.Combine(recordPath, RecordingHelper.GetRecordingName(timer, info));
Directory.CreateDirectory(Path.GetDirectoryName(recordPath)); Directory.CreateDirectory(Path.GetDirectoryName(recordPath));
var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.Id, info.Id, StringComparison.OrdinalIgnoreCase)); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase));
if (recording == null) if (recording == null)
{ {
recording = new RecordingInfo() recording = new RecordingInfo()
{ {
ChannelId = info.ChannelId, ChannelId = info.ChannelId,
Id = info.Id, Id = Guid.NewGuid().ToString("N"),
StartDate = info.StartDate, StartDate = info.StartDate,
EndDate = info.EndDate, EndDate = info.EndDate,
Genres = info.Genres ?? null, Genres = info.Genres ?? null,
@ -480,7 +503,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
OriginalAirDate = info.OriginalAirDate, OriginalAirDate = info.OriginalAirDate,
Status = RecordingStatus.Scheduled, Status = RecordingStatus.Scheduled,
Overview = info.Overview, Overview = info.Overview,
SeriesTimerId = info.Id.Substring(0, 10) SeriesTimerId = info.Id.Substring(0, 10),
TimerId = timer.Id
}; };
_recordingProvider.Add(recording); _recordingProvider.Add(recording);
} }

View File

@ -0,0 +1,16 @@
using MediaBrowser.Controller.Plugins;
namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
public class EntryPoint : IServerEntryPoint
{
public void Run()
{
EmbyTV.Current.Start();
}
public void Dispose()
{
}
}
}

View File

@ -1,11 +1,10 @@
using System.Text; using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{ {
@ -49,10 +48,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public static DateTime GetStartTime(TimerInfo timer) public static DateTime GetStartTime(TimerInfo timer)
{ {
if (timer.StartDate.AddSeconds(-timer.PrePaddingSeconds + 1) < DateTime.UtcNow)
{
return DateTime.UtcNow.AddSeconds(1);
}
return timer.StartDate.AddSeconds(-timer.PrePaddingSeconds); return timer.StartDate.AddSeconds(-timer.PrePaddingSeconds);
} }

View File

@ -24,6 +24,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public void RestartTimers() public void RestartTimers()
{ {
StopTimers(); StopTimers();
foreach (var item in GetAll().ToList())
{
AddTimer(item);
}
} }
public void StopTimers() public void StopTimers()
@ -90,7 +95,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private void AddTimer(TimerInfo item) private void AddTimer(TimerInfo item)
{ {
var timespan = RecordingHelper.GetStartTime(item) - DateTime.UtcNow; var startDate = RecordingHelper.GetStartTime(item);
var now = DateTime.UtcNow;
if (startDate < now)
{
EventHelper.FireEventIfNotNull(TimerFired, this, new GenericEventArgs<TimerInfo> { Argument = item }, Logger);
return;
}
var timespan = startDate - now;
var timer = new Timer(TimerCallback, item.Id, timespan, TimeSpan.Zero); var timer = new Timer(TimerCallback, item.Id, timespan, TimeSpan.Zero);

View File

@ -217,6 +217,7 @@
<Compile Include="Library\Validators\YearsPostScanTask.cs" /> <Compile Include="Library\Validators\YearsPostScanTask.cs" />
<Compile Include="LiveTv\ChannelImageProvider.cs" /> <Compile Include="LiveTv\ChannelImageProvider.cs" />
<Compile Include="LiveTv\EmbyTV\EmbyTV.cs" /> <Compile Include="LiveTv\EmbyTV\EmbyTV.cs" />
<Compile Include="LiveTv\EmbyTV\EntryPoint.cs" />
<Compile Include="LiveTv\EmbyTV\ItemDataProvider.cs" /> <Compile Include="LiveTv\EmbyTV\ItemDataProvider.cs" />
<Compile Include="LiveTv\EmbyTV\RecordingHelper.cs" /> <Compile Include="LiveTv\EmbyTV\RecordingHelper.cs" />
<Compile Include="LiveTv\EmbyTV\SeriesTimerManager.cs" /> <Compile Include="LiveTv\EmbyTV\SeriesTimerManager.cs" />

View File

@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
new StartupTrigger(), new StartupTrigger(),
new IntervalTrigger{ Interval = TimeSpan.FromHours(6)} new IntervalTrigger{ Interval = TimeSpan.FromHours(8)}
}; };
} }

View File

@ -742,9 +742,6 @@
<Content Include="dashboard-ui\livetvnewrecording.html"> <Content Include="dashboard-ui\livetvnewrecording.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="dashboard-ui\livetvprogram.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\livetvrecording.html"> <Content Include="dashboard-ui\livetvrecording.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -1006,9 +1003,6 @@
<Content Include="dashboard-ui\scripts\livetvnewrecording.js"> <Content Include="dashboard-ui\scripts\livetvnewrecording.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="dashboard-ui\scripts\livetvprogram.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\livetvrecording.js"> <Content Include="dashboard-ui\scripts\livetvrecording.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>