Send signalr message for episode monitored flag changes
This commit is contained in:
parent
dab1834960
commit
9e81d41f26
|
@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeServiceTests
|
|||
Subject.Handle(new EpisodeFileDeletedEvent(_episodeFile, DeleteMediaFileReason.MissingFromDisk));
|
||||
|
||||
Mocker.GetMock<IEpisodeRepository>()
|
||||
.Verify(v => v.Update(It.Is<Episode>(e => e.EpisodeFileId == 0)), Times.Once());
|
||||
.Verify(v => v.ClearFileId(It.IsAny<Episode>(), It.IsAny<bool>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeServiceTests
|
|||
Subject.Handle(new EpisodeFileDeletedEvent(_episodeFile, DeleteMediaFileReason.MissingFromDisk));
|
||||
|
||||
Mocker.GetMock<IEpisodeRepository>()
|
||||
.Verify(v => v.Update(It.Is<Episode>(e => e.EpisodeFileId == 0)), Times.Exactly(2));
|
||||
.Verify(v => v.ClearFileId(It.IsAny<Episode>(), It.IsAny<bool>()), Times.Exactly(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeServiceTests
|
|||
Subject.Handle(new EpisodeFileDeletedEvent(_episodeFile, DeleteMediaFileReason.MissingFromDisk));
|
||||
|
||||
Mocker.GetMock<IEpisodeRepository>()
|
||||
.Verify(v => v.Update(It.Is<Episode>(e => e.Monitored == false)), Times.Once());
|
||||
.Verify(v => v.ClearFileId(It.IsAny<Episode>(), true), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -102,7 +102,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeServiceTests
|
|||
Subject.Handle(new EpisodeFileDeletedEvent(_episodeFile, DeleteMediaFileReason.Upgrade));
|
||||
|
||||
Mocker.GetMock<IEpisodeRepository>()
|
||||
.Verify(v => v.Update(It.Is<Episode>(e => e.Monitored == true)), Times.Once());
|
||||
.Verify(v => v.ClearFileId(It.IsAny<Episode>(), false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -117,7 +117,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeServiceTests
|
|||
Subject.Handle(new EpisodeFileDeletedEvent(_episodeFile, DeleteMediaFileReason.Upgrade));
|
||||
|
||||
Mocker.GetMock<IEpisodeRepository>()
|
||||
.Verify(v => v.Update(It.Is<Episode>(e => e.Monitored == true)), Times.Once());
|
||||
.Verify(v => v.ClearFileId(It.IsAny<Episode>(), false), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,24 +279,24 @@ namespace NzbDrone.Core.Datastore
|
|||
.Take(pagingSpec.PageSize);
|
||||
}
|
||||
|
||||
protected void ModelCreated(TModel model)
|
||||
protected void ModelCreated(TModel model, bool forcePublish = false)
|
||||
{
|
||||
PublishModelEvent(model, ModelAction.Created);
|
||||
PublishModelEvent(model, ModelAction.Created, forcePublish);
|
||||
}
|
||||
|
||||
protected void ModelUpdated(TModel model)
|
||||
protected void ModelUpdated(TModel model, bool forcePublish = false)
|
||||
{
|
||||
PublishModelEvent(model, ModelAction.Updated);
|
||||
PublishModelEvent(model, ModelAction.Updated, forcePublish);
|
||||
}
|
||||
|
||||
protected void ModelDeleted(TModel model)
|
||||
protected void ModelDeleted(TModel model, bool forcePublish = false)
|
||||
{
|
||||
PublishModelEvent(model, ModelAction.Deleted);
|
||||
PublishModelEvent(model, ModelAction.Deleted, forcePublish);
|
||||
}
|
||||
|
||||
private void PublishModelEvent(TModel model, ModelAction action)
|
||||
private void PublishModelEvent(TModel model, ModelAction action, bool forcePublish)
|
||||
{
|
||||
if (PublishModelEvents)
|
||||
if (PublishModelEvents || forcePublish)
|
||||
{
|
||||
_eventAggregator.PublishEvent(new ModelEvent<TModel>(model, action));
|
||||
}
|
||||
|
|
|
@ -3,12 +3,21 @@
|
|||
namespace NzbDrone.Core.Datastore.Events
|
||||
{
|
||||
public class ModelEvent<TModel> : IEvent
|
||||
where TModel : ModelBase
|
||||
{
|
||||
public int ModelId { get; set; }
|
||||
public TModel Model { get; set; }
|
||||
public ModelAction Action { get; set; }
|
||||
|
||||
public ModelEvent(int modelId, ModelAction action)
|
||||
{
|
||||
ModelId = modelId;
|
||||
Action = action;
|
||||
}
|
||||
|
||||
public ModelEvent(TModel model, ModelAction action)
|
||||
{
|
||||
ModelId = model.Id;
|
||||
Model = model;
|
||||
Action = action;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
using System.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Marr.Data;
|
||||
using Marr.Data.Mapping;
|
||||
using NzbDrone.Common.Reflection;
|
||||
|
@ -59,5 +62,10 @@ namespace NzbDrone.Core.Datastore.Extensions
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<TModel> QueryScalar<TModel>(this IDataMapper dataMapper, string sql)
|
||||
{
|
||||
return dataMapper.ExecuteReader(sql, reader => (TModel)Convert.ChangeType(reader.GetValue(0), typeof(TModel))).ToList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,8 @@ namespace NzbDrone.Core.Tv
|
|||
void SetMonitoredFlat(Episode episode, bool monitored);
|
||||
void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored);
|
||||
void SetMonitored(IEnumerable<int> ids, bool monitored);
|
||||
void SetFileId(int episodeId, int fileId);
|
||||
void SetFileId(Episode episode, int fileId);
|
||||
void ClearFileId(Episode episode, bool unmonitor);
|
||||
}
|
||||
|
||||
public class EpisodeRepository : BasicRepository<Episode>, IEpisodeRepository
|
||||
|
@ -163,6 +164,8 @@ namespace NzbDrone.Core.Tv
|
|||
{
|
||||
episode.Monitored = monitored;
|
||||
SetFields(episode, p => p.Monitored);
|
||||
|
||||
ModelUpdated(episode, true);
|
||||
}
|
||||
|
||||
public void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored)
|
||||
|
@ -173,30 +176,39 @@ namespace NzbDrone.Core.Tv
|
|||
mapper.AddParameter("seasonNumber", seasonNumber);
|
||||
mapper.AddParameter("monitored", monitored);
|
||||
|
||||
const string sql = "UPDATE Episodes " +
|
||||
"SET Monitored = @monitored " +
|
||||
"WHERE SeriesId = @seriesId " +
|
||||
"AND SeasonNumber = @seasonNumber";
|
||||
var sqlUpdate = $"UPDATE Episodes SET Monitored = @monitored WHERE SeriesId = @seriesId AND SeasonNumber = @seasonNumber AND Monitored != @monitored";
|
||||
|
||||
mapper.ExecuteNonQuery(sql);
|
||||
mapper.ExecuteNonQuery(sqlUpdate);
|
||||
}
|
||||
|
||||
public void SetMonitored(IEnumerable<int> ids, bool monitored)
|
||||
{
|
||||
var mapper = _database.GetDataMapper();
|
||||
var mapper = DataMapper;
|
||||
|
||||
mapper.AddParameter("monitored", monitored);
|
||||
|
||||
var sql = "UPDATE Episodes " +
|
||||
"SET Monitored = @monitored " +
|
||||
$"WHERE Id IN ({string.Join(", ", ids)})";
|
||||
var sqlUpdate = $"UPDATE Episodes SET Monitored = @monitored WHERE Id IN ({string.Join(", ", ids)}) AND Monitored != @monitored";
|
||||
|
||||
mapper.ExecuteNonQuery(sql);
|
||||
mapper.ExecuteNonQuery(sqlUpdate);
|
||||
}
|
||||
|
||||
public void SetFileId(int episodeId, int fileId)
|
||||
public void SetFileId(Episode episode, int fileId)
|
||||
{
|
||||
SetFields(new Episode { Id = episodeId, EpisodeFileId = fileId }, episode => episode.EpisodeFileId);
|
||||
episode.EpisodeFileId = fileId;
|
||||
|
||||
SetFields(episode, ep => ep.EpisodeFileId);
|
||||
|
||||
ModelUpdated(episode, true);
|
||||
}
|
||||
|
||||
public void ClearFileId(Episode episode, bool unmonitor)
|
||||
{
|
||||
episode.EpisodeFileId = 0;
|
||||
episode.Monitored &= !unmonitor;
|
||||
|
||||
SetFields(episode, ep => ep.EpisodeFileId, ep => ep.Monitored);
|
||||
|
||||
ModelUpdated(episode, true);
|
||||
}
|
||||
|
||||
private SortBuilder<Episode> GetMissingEpisodesQuery(PagingSpec<Episode> pagingSpec, DateTime currentTime, int startingSeasonNumber)
|
||||
|
|
|
@ -220,14 +220,7 @@ namespace NzbDrone.Core.Tv
|
|||
foreach (var episode in GetEpisodesByFileId(message.EpisodeFile.Id))
|
||||
{
|
||||
_logger.Debug("Detaching episode {0} from file.", episode.Id);
|
||||
episode.EpisodeFileId = 0;
|
||||
|
||||
if (message.Reason != DeleteMediaFileReason.Upgrade && _configService.AutoUnmonitorPreviouslyDownloadedEpisodes)
|
||||
{
|
||||
episode.Monitored = false;
|
||||
}
|
||||
|
||||
UpdateEpisode(episode);
|
||||
_episodeRepository.ClearFileId(episode, message.Reason != DeleteMediaFileReason.Upgrade && _configService.AutoUnmonitorPreviouslyDownloadedEpisodes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +228,7 @@ namespace NzbDrone.Core.Tv
|
|||
{
|
||||
foreach (var episode in message.EpisodeFile.Episodes.Value)
|
||||
{
|
||||
_episodeRepository.SetFileId(episode.Id, message.EpisodeFile.Id);
|
||||
_episodeRepository.SetFileId(episode, message.EpisodeFile.Id);
|
||||
_logger.Debug("Linking [{0}] > [{1}]", message.EpisodeFile.RelativePath, episode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,9 @@ namespace Sonarr.Api.V3.Episodes
|
|||
var resource = Request.Body.FromJson<EpisodeResource>();
|
||||
_episodeService.SetEpisodeMonitored(id, resource.Monitored);
|
||||
|
||||
return ResponseWithCode(MapToResource(_episodeService.GetEpisode(id), false, false, false), HttpStatusCode.Accepted);
|
||||
resource = MapToResource(_episodeService.GetEpisode(id), false, false, false);
|
||||
|
||||
return ResponseWithCode(resource, HttpStatusCode.Accepted);
|
||||
}
|
||||
|
||||
private object SetEpisodesMonitored()
|
||||
|
@ -77,10 +79,18 @@ namespace Sonarr.Api.V3.Episodes
|
|||
var includeImages = Request.GetBooleanQueryParameter("includeImages", false);
|
||||
var resource = Request.Body.FromJson<EpisodesMonitoredResource>();
|
||||
|
||||
if (resource.EpisodeIds.Count == 1)
|
||||
{
|
||||
_episodeService.SetEpisodeMonitored(resource.EpisodeIds.First(), resource.Monitored);
|
||||
}
|
||||
else
|
||||
{
|
||||
_episodeService.SetMonitored(resource.EpisodeIds, resource.Monitored);
|
||||
}
|
||||
|
||||
return ResponseWithCode(MapToResource(_episodeService.GetEpisodes(resource.EpisodeIds), false, false, includeImages)
|
||||
, HttpStatusCode.Accepted);
|
||||
var resources = MapToResource(_episodeService.GetEpisodes(resource.EpisodeIds), false, false, includeImages);
|
||||
|
||||
return ResponseWithCode(resources, HttpStatusCode.Accepted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,13 @@ namespace Sonarr.Api.V3.Episodes
|
|||
return resource;
|
||||
}
|
||||
|
||||
protected override EpisodeResource GetResourceByIdForBroadcast(int id)
|
||||
{
|
||||
var episode = _episodeService.GetEpisode(id);
|
||||
var resource = MapToResource(episode, false, false, false);
|
||||
return resource;
|
||||
}
|
||||
|
||||
protected EpisodeResource MapToResource(Episode episode, bool includeSeries, bool includeEpisodeFile, bool includeImages)
|
||||
{
|
||||
var resource = episode.ToResource();
|
||||
|
|
|
@ -23,6 +23,11 @@ namespace Sonarr.Http
|
|||
_signalRBroadcaster = signalRBroadcaster;
|
||||
}
|
||||
|
||||
protected virtual TResource GetResourceByIdForBroadcast(int id)
|
||||
{
|
||||
return GetResourceById(id);
|
||||
}
|
||||
|
||||
public void Handle(ModelEvent<TModel> message)
|
||||
{
|
||||
if (!_signalRBroadcaster.IsConnected) return;
|
||||
|
@ -32,7 +37,7 @@ namespace Sonarr.Http
|
|||
BroadcastResourceChange(message.Action);
|
||||
}
|
||||
|
||||
BroadcastResourceChange(message.Action, message.Model.Id);
|
||||
BroadcastResourceChange(message.Action, message.ModelId);
|
||||
}
|
||||
|
||||
protected void BroadcastResourceChange(ModelAction action, int id)
|
||||
|
@ -45,7 +50,7 @@ namespace Sonarr.Http
|
|||
}
|
||||
else
|
||||
{
|
||||
var resource = GetResourceById(id);
|
||||
var resource = GetResourceByIdForBroadcast(id);
|
||||
BroadcastResourceChange(action, resource);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue