implement keep up to
This commit is contained in:
parent
adb39f4090
commit
64d63c1b4b
|
@ -9,6 +9,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
public TimerInfo()
|
||||
{
|
||||
Genres = new List<string>();
|
||||
KeepUntil = KeepUntil.UntilDeleted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -109,5 +110,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
public string ShortOverview { get; set; }
|
||||
public string OfficialRating { get; set; }
|
||||
public List<string> Genres { get; set; }
|
||||
public string RecordingPath { get; set; }
|
||||
public KeepUntil KeepUntil { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,5 +105,6 @@ namespace MediaBrowser.Model.LiveTv
|
|||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value>
|
||||
public bool IsPostPaddingRequired { get; set; }
|
||||
public KeepUntil KeepUntil { get; set; }
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ namespace MediaBrowser.Model.LiveTv
|
|||
public bool RecordAnyChannel { get; set; }
|
||||
|
||||
public int KeepUpTo { get; set; }
|
||||
public KeepUntil KeepUntil { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [record new only].
|
||||
|
|
|
@ -442,7 +442,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
|
||||
private void CancelTimerInternal(string timerId, bool isSeriesCancelled)
|
||||
{
|
||||
var timer = _timerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase));
|
||||
var timer = _timerProvider.GetTimer(timerId);
|
||||
if (timer != null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(timer.SeriesTimerId) || isSeriesCancelled)
|
||||
|
@ -474,10 +474,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> CreateTimer(TimerInfo timer, CancellationToken cancellationToken)
|
||||
{
|
||||
var existingTimer = _timerProvider.GetAll()
|
||||
.FirstOrDefault(i => string.Equals(info.ProgramId, i.ProgramId, StringComparison.OrdinalIgnoreCase));
|
||||
.FirstOrDefault(i => string.Equals(timer.ProgramId, i.ProgramId, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (existingTimer != null)
|
||||
{
|
||||
|
@ -485,6 +495,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
{
|
||||
existingTimer.Status = RecordingStatus.New;
|
||||
_timerProvider.Update(existingTimer);
|
||||
return Task.FromResult(existingTimer.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -492,16 +503,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
}
|
||||
|
||||
return CreateTimer(info, cancellationToken);
|
||||
}
|
||||
|
||||
public Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
return CreateSeriesTimer(info, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<string> CreateTimer(TimerInfo timer, CancellationToken cancellationToken)
|
||||
{
|
||||
timer.Id = Guid.NewGuid().ToString("N");
|
||||
|
||||
ProgramInfo programInfo = null;
|
||||
|
@ -601,9 +602,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
|
||||
public Task UpdateTimerAsync(TimerInfo updatedTimer, CancellationToken cancellationToken)
|
||||
{
|
||||
var existingTimer = _timerProvider
|
||||
.GetAll()
|
||||
.FirstOrDefault(i => string.Equals(i.Id, updatedTimer.Id, StringComparison.OrdinalIgnoreCase));
|
||||
var existingTimer = _timerProvider.GetTimer(updatedTimer.Id);
|
||||
|
||||
if (existingTimer == null)
|
||||
{
|
||||
|
@ -1137,6 +1136,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
_timerProvider.AddOrUpdate(timer, false);
|
||||
|
||||
SaveNfo(timer, recordPath, seriesPath);
|
||||
EnforceKeepUpTo(timer);
|
||||
};
|
||||
|
||||
var pathWithDuration = tunerHost.ApplyDuration(mediaStreamInfo.Path, duration);
|
||||
|
@ -1148,8 +1148,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
mediaStreamInfo.RunTimeTicks = duration.Ticks;
|
||||
}
|
||||
|
||||
await
|
||||
recorder.Record(mediaStreamInfo, recordPath, duration, onStarted, cancellationToken)
|
||||
await recorder.Record(mediaStreamInfo, recordPath, duration, onStarted, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
recordingStatus = RecordingStatus.Completed;
|
||||
|
@ -1195,6 +1194,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
else if (File.Exists(recordPath))
|
||||
{
|
||||
timer.RecordingPath = recordPath;
|
||||
timer.Status = RecordingStatus.Completed;
|
||||
_timerProvider.AddOrUpdate(timer, false);
|
||||
OnSuccessfulRecording(timer, recordPath);
|
||||
|
@ -1205,6 +1205,102 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
}
|
||||
|
||||
private async void EnforceKeepUpTo(TimerInfo timer)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(timer.SeriesTimerId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var seriesTimerId = timer.SeriesTimerId;
|
||||
var seriesTimer = _seriesTimerProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, seriesTimerId, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (seriesTimer == null || seriesTimer.KeepUpTo <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await _recordingDeleteSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var timersToDelete = _timerProvider.GetAll()
|
||||
.Where(i => i.Status == RecordingStatus.Completed && !string.IsNullOrWhiteSpace(i.RecordingPath))
|
||||
.Where(i => string.Equals(i.SeriesTimerId, seriesTimerId, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderByDescending(i => i.EndDate)
|
||||
.Where(i => File.Exists(i.RecordingPath))
|
||||
.Skip(seriesTimer.KeepUpTo - 1)
|
||||
.ToList();
|
||||
|
||||
await DeleteLibraryItemsForTimers(timersToDelete).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_recordingDeleteSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly SemaphoreSlim _recordingDeleteSemaphore = new SemaphoreSlim(1,1);
|
||||
private async Task DeleteLibraryItemsForTimers(List<TimerInfo> timers)
|
||||
{
|
||||
foreach (var timer in timers)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await DeleteLibraryItemForTimer(timer).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error deleting recording", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteLibraryItemForTimer(TimerInfo timer)
|
||||
{
|
||||
var libraryItem = _libraryManager.FindByPath(timer.RecordingPath, false);
|
||||
|
||||
if (libraryItem != null)
|
||||
{
|
||||
await _libraryManager.DeleteItem(libraryItem, new DeleteOptions
|
||||
{
|
||||
DeleteFileLocation = true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(timer.RecordingPath);
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_timerProvider.Delete(timer);
|
||||
}
|
||||
|
||||
private string EnsureFileUnique(string path, string timerId)
|
||||
{
|
||||
var originalPath = path;
|
||||
|
@ -1460,9 +1556,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
{
|
||||
foreach (var timer in allTimers)
|
||||
{
|
||||
var existingTimer = _timerProvider
|
||||
.GetAll()
|
||||
.FirstOrDefault(i => string.Equals(i.Id, timer.Id, StringComparison.OrdinalIgnoreCase));
|
||||
var existingTimer = _timerProvider.GetTimer(timer.Id);
|
||||
|
||||
if (existingTimer == null)
|
||||
{
|
||||
|
@ -1484,6 +1578,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
{
|
||||
existingTimer.Status = RecordingStatus.Cancelled;
|
||||
}
|
||||
|
||||
existingTimer.SeriesTimerId = seriesTimer.Id;
|
||||
_timerProvider.Update(existingTimer);
|
||||
}
|
||||
}
|
||||
|
@ -1649,8 +1745,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
return channelIds.SelectMany(GetEpgDataForChannel).ToList();
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
foreach (var pair in _activeRecordings.ToList())
|
||||
{
|
||||
pair.Value.CancellationTokenSource.Cancel();
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
timer.PostPaddingSeconds = series.PostPaddingSeconds;
|
||||
timer.IsPostPaddingRequired = series.IsPostPaddingRequired;
|
||||
timer.IsPrePaddingRequired = series.IsPrePaddingRequired;
|
||||
timer.KeepUntil = series.KeepUntil;
|
||||
timer.Priority = series.Priority;
|
||||
timer.Name = parent.Name;
|
||||
timer.Overview = parent.Overview;
|
||||
|
|
|
@ -156,5 +156,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
EventHelper.FireEventIfNotNull(TimerFired, this, new GenericEventArgs<TimerInfo> { Argument = timer }, Logger);
|
||||
}
|
||||
}
|
||||
|
||||
public TimerInfo GetTimer(string id)
|
||||
{
|
||||
return GetAll().FirstOrDefault(r => string.Equals(r.Id, id, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
PostPaddingSeconds = info.PostPaddingSeconds,
|
||||
IsPostPaddingRequired = info.IsPostPaddingRequired,
|
||||
IsPrePaddingRequired = info.IsPrePaddingRequired,
|
||||
KeepUntil = info.KeepUntil,
|
||||
ExternalChannelId = info.ChannelId,
|
||||
ExternalSeriesTimerId = info.SeriesTimerId,
|
||||
ServiceName = service.Name,
|
||||
|
@ -247,6 +248,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
PostPaddingSeconds = dto.PostPaddingSeconds,
|
||||
IsPostPaddingRequired = dto.IsPostPaddingRequired,
|
||||
IsPrePaddingRequired = dto.IsPrePaddingRequired,
|
||||
KeepUntil = dto.KeepUntil,
|
||||
Priority = dto.Priority,
|
||||
SeriesTimerId = dto.ExternalSeriesTimerId,
|
||||
ProgramId = dto.ExternalProgramId,
|
||||
|
|
Loading…
Reference in New Issue
Block a user