diff --git a/src/NzbDrone.Api/History/HistoryModule.cs b/src/NzbDrone.Api/History/HistoryModule.cs index d85cf74d8..8a61f1d45 100644 --- a/src/NzbDrone.Api/History/HistoryModule.cs +++ b/src/NzbDrone.Api/History/HistoryModule.cs @@ -3,6 +3,7 @@ using Nancy; using NzbDrone.Api.Episodes; using NzbDrone.Api.Extensions; using NzbDrone.Api.Series; +using NzbDrone.Api.Movie; using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; @@ -34,12 +35,18 @@ namespace NzbDrone.Api.History resource.Series = model.Series.ToResource(); resource.Episode = model.Episode.ToResource(); + resource.Movie = model.Movie.ToResource(); if (model.Series != null) { resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Series.Profile.Value, model.Quality); } + if (model.Movie != null) + { + resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Movie.Profile.Value, model.Quality); + } + return resource; } @@ -47,6 +54,8 @@ namespace NzbDrone.Api.History { var episodeId = Request.Query.EpisodeId; + var movieId = Request.Query.MovieId; + var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); if (pagingResource.FilterKey == "eventType") @@ -61,6 +70,14 @@ namespace NzbDrone.Api.History pagingSpec.FilterExpression = h => h.EpisodeId == i; } + if (movieId.HasValue) + { + int i = (int)movieId; + pagingSpec.FilterExpression = h => h.MovieId == i; + } + + var pg = _historyService.Paged(pagingSpec); + return ApplyToPage(_historyService.Paged, pagingSpec, MapToResource); } diff --git a/src/NzbDrone.Api/History/HistoryResource.cs b/src/NzbDrone.Api/History/HistoryResource.cs index dba4149dd..93ec372c7 100644 --- a/src/NzbDrone.Api/History/HistoryResource.cs +++ b/src/NzbDrone.Api/History/HistoryResource.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using NzbDrone.Api.Episodes; using NzbDrone.Api.REST; using NzbDrone.Api.Series; +using NzbDrone.Api.Movie; using NzbDrone.Core.History; using NzbDrone.Core.Qualities; @@ -12,6 +13,7 @@ namespace NzbDrone.Api.History public class HistoryResource : RestResource { public int EpisodeId { get; set; } + public int MovieId { get; set; } public int SeriesId { get; set; } public string SourceTitle { get; set; } public QualityModel Quality { get; set; } @@ -22,7 +24,7 @@ namespace NzbDrone.Api.History public HistoryEventType EventType { get; set; } public Dictionary Data { get; set; } - + public MovieResource Movie { get; set; } public EpisodeResource Episode { get; set; } public SeriesResource Series { get; set; } } @@ -39,6 +41,7 @@ namespace NzbDrone.Api.History EpisodeId = model.EpisodeId, SeriesId = model.SeriesId, + MovieId = model.MovieId, SourceTitle = model.SourceTitle, Quality = model.Quality, //QualityCutoffNotMet diff --git a/src/NzbDrone.Core/Datastore/Migration/001_initial_setup.cs b/src/NzbDrone.Core/Datastore/Migration/001_initial_setup.cs index 02367724e..2fc722cb4 100644 --- a/src/NzbDrone.Core/Datastore/Migration/001_initial_setup.cs +++ b/src/NzbDrone.Core/Datastore/Migration/001_initial_setup.cs @@ -104,7 +104,8 @@ namespace NzbDrone.Core.Datastore.Migration .WithColumn("Quality").AsString() .WithColumn("Indexer").AsString() .WithColumn("NzbInfoUrl").AsString().Nullable() - .WithColumn("ReleaseGroup").AsString().Nullable(); + .WithColumn("ReleaseGroup").AsString().Nullable() + .WithColumn("MovieId").AsInt32().WithDefaultValue(0); Create.TableForModel("Notifications") .WithColumn("Name").AsString() diff --git a/src/NzbDrone.Core/History/History.cs b/src/NzbDrone.Core/History/History.cs index be35637c8..451e9b1d5 100644 --- a/src/NzbDrone.Core/History/History.cs +++ b/src/NzbDrone.Core/History/History.cs @@ -17,9 +17,11 @@ namespace NzbDrone.Core.History public int EpisodeId { get; set; } public int SeriesId { get; set; } + public int MovieId { get; set; } public string SourceTitle { get; set; } public QualityModel Quality { get; set; } public DateTime Date { get; set; } + public Movie Movie { get; set; } public Episode Episode { get; set; } public Series Series { get; set; } public HistoryEventType EventType { get; set; } diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index 35199a878..243db5f4e 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Marr.Data.QGen; using NzbDrone.Core.Datastore; @@ -16,6 +17,7 @@ namespace NzbDrone.Core.History List FindByDownloadId(string downloadId); List FindDownloadHistory(int idSeriesId, QualityModel quality); void DeleteForSeries(int seriesId); + History MostRecentForMovie(int movieId); } public class HistoryRepository : BasicRepository, IHistoryRepository @@ -76,5 +78,12 @@ namespace NzbDrone.Core.History return base.GetPagedQuery(baseQuery, pagingSpec); } + + public History MostRecentForMovie(int movieId) + { + return Query.Where(h => h.MovieId == movieId) + .OrderByDescending(h => h.Date) + .FirstOrDefault(); + } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index 32815beef..8185a1c6e 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -20,6 +20,7 @@ namespace NzbDrone.Core.History { QualityModel GetBestQualityInHistory(Profile profile, int episodeId); PagingSpec Paged(PagingSpec pagingSpec); + History MostRecentForMovie(int movieId); History MostRecentForEpisode(int episodeId); History MostRecentForDownloadId(string downloadId); History Get(int historyId); @@ -29,6 +30,7 @@ namespace NzbDrone.Core.History public class HistoryService : IHistoryService, IHandle, + IHandle, IHandle, IHandle, IHandle, @@ -53,6 +55,11 @@ namespace NzbDrone.Core.History return _historyRepository.MostRecentForEpisode(episodeId); } + public History MostRecentForMovie(int movieId) + { + return _historyRepository.MostRecentForMovie(movieId); + } + public History MostRecentForDownloadId(string downloadId) { return _historyRepository.MostRecentForDownloadId(downloadId); @@ -138,7 +145,8 @@ namespace NzbDrone.Core.History SourceTitle = message.Episode.Release.Title, SeriesId = episode.SeriesId, EpisodeId = episode.Id, - DownloadId = message.DownloadId + DownloadId = message.DownloadId, + MovieId = 0 }; history.Data.Add("Indexer", message.Episode.Release.Indexer); @@ -172,6 +180,50 @@ namespace NzbDrone.Core.History } } + public void Handle(MovieGrabbedEvent message) + { + var history = new History + { + EventType = HistoryEventType.Grabbed, + Date = DateTime.UtcNow, + Quality = message.Movie.ParsedEpisodeInfo.Quality, + SourceTitle = message.Movie.Release.Title, + SeriesId = 0, + EpisodeId = 0, + DownloadId = message.DownloadId, + MovieId = message.Movie.Movie.Id + }; + + history.Data.Add("Indexer", message.Movie.Release.Indexer); + history.Data.Add("NzbInfoUrl", message.Movie.Release.InfoUrl); + history.Data.Add("ReleaseGroup", message.Movie.ParsedEpisodeInfo.ReleaseGroup); + history.Data.Add("Age", message.Movie.Release.Age.ToString()); + history.Data.Add("AgeHours", message.Movie.Release.AgeHours.ToString()); + history.Data.Add("AgeMinutes", message.Movie.Release.AgeMinutes.ToString()); + history.Data.Add("PublishedDate", message.Movie.Release.PublishDate.ToString("s") + "Z"); + history.Data.Add("DownloadClient", message.DownloadClient); + history.Data.Add("Size", message.Movie.Release.Size.ToString()); + history.Data.Add("DownloadUrl", message.Movie.Release.DownloadUrl); + history.Data.Add("Guid", message.Movie.Release.Guid); + history.Data.Add("TvdbId", message.Movie.Release.TvdbId.ToString()); + history.Data.Add("TvRageId", message.Movie.Release.TvRageId.ToString()); + history.Data.Add("Protocol", ((int)message.Movie.Release.DownloadProtocol).ToString()); + + if (!message.Movie.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace()) + { + history.Data.Add("ReleaseHash", message.Movie.ParsedEpisodeInfo.ReleaseHash); + } + + var torrentRelease = message.Movie.Release as TorrentInfo; + + if (torrentRelease != null) + { + history.Data.Add("TorrentInfoHash", torrentRelease.InfoHash); + } + + _historyRepository.Insert(history); + } + public void Handle(EpisodeImportedEvent message) { if (!message.NewDownload) @@ -189,15 +241,18 @@ namespace NzbDrone.Core.History foreach (var episode in message.EpisodeInfo.Episodes) { var history = new History - { - EventType = HistoryEventType.DownloadFolderImported, - Date = DateTime.UtcNow, - Quality = message.EpisodeInfo.Quality, - SourceTitle = message.ImportedEpisode.SceneName ?? Path.GetFileNameWithoutExtension(message.EpisodeInfo.Path), - SeriesId = message.ImportedEpisode.SeriesId, - EpisodeId = episode.Id, - DownloadId = downloadId - }; + { + EventType = HistoryEventType.DownloadFolderImported, + Date = DateTime.UtcNow, + Quality = message.EpisodeInfo.Quality, + SourceTitle = message.ImportedEpisode.SceneName ?? Path.GetFileNameWithoutExtension(message.EpisodeInfo.Path), + SeriesId = message.ImportedEpisode.SeriesId, + EpisodeId = episode.Id, + DownloadId = downloadId, + MovieId = 0, + + + }; //Won't have a value since we publish this event before saving to DB. //history.Data.Add("FileId", message.ImportedEpisode.Id.ToString()); @@ -249,6 +304,7 @@ namespace NzbDrone.Core.History SourceTitle = message.EpisodeFile.Path, SeriesId = message.EpisodeFile.SeriesId, EpisodeId = episode.Id, + MovieId = 0 }; history.Data.Add("Reason", message.Reason.ToString()); diff --git a/src/UI/Activity/History/HistoryCollection.js b/src/UI/Activity/History/HistoryCollection.js index 3bd564309..8adb6e96b 100644 --- a/src/UI/Activity/History/HistoryCollection.js +++ b/src/UI/Activity/History/HistoryCollection.js @@ -55,11 +55,15 @@ var Collection = PageableCollection.extend({ initialize : function(options) { delete this.queryParams.episodeId; + delete this.queryParams.movieId; if (options) { if (options.episodeId) { this.queryParams.episodeId = options.episodeId; } + if (options.movieId) { + this.queryParams.movieId = options.movieId; + } } }, @@ -80,4 +84,4 @@ Collection = AsFilteredCollection.call(Collection); Collection = AsSortedCollection.call(Collection); Collection = AsPersistedStateCollection.call(Collection); -module.exports = Collection; \ No newline at end of file +module.exports = Collection; diff --git a/src/UI/Activity/History/HistoryModel.js b/src/UI/Activity/History/HistoryModel.js index f8ec8c538..967b7ba22 100644 --- a/src/UI/Activity/History/HistoryModel.js +++ b/src/UI/Activity/History/HistoryModel.js @@ -1,12 +1,20 @@ var Backbone = require('backbone'); var SeriesModel = require('../../Series/SeriesModel'); var EpisodeModel = require('../../Series/EpisodeModel'); +var MovieModel = require('../../Movies/MovieModel'); module.exports = Backbone.Model.extend({ parse : function(model) { - model.series = new SeriesModel(model.series); - model.episode = new EpisodeModel(model.episode); - model.episode.set('series', model.series); + if (model.series) { + model.series = new SeriesModel(model.series); + model.episode = new EpisodeModel(model.episode); + model.episode.set('series', model.series); + } + + if (model.movie) { + model.movie = new MovieModel(model.movie); + } + return model; } -}); \ No newline at end of file +}); diff --git a/src/UI/Activity/History/HistoryQualityCell.js b/src/UI/Activity/History/HistoryQualityCell.js index c65aa042b..f779c714e 100644 --- a/src/UI/Activity/History/HistoryQualityCell.js +++ b/src/UI/Activity/History/HistoryQualityCell.js @@ -27,4 +27,4 @@ module.exports = NzbDroneCell.extend({ return this; } -}); \ No newline at end of file +}); diff --git a/src/UI/Movies/History/MovieHistoryLayout.js b/src/UI/Movies/History/MovieHistoryLayout.js index cb8b4f54b..3cbe20c24 100644 --- a/src/UI/Movies/History/MovieHistoryLayout.js +++ b/src/UI/Movies/History/MovieHistoryLayout.js @@ -56,7 +56,7 @@ module.exports = Marionette.Layout.extend({ this.model = options.model; this.collection = new HistoryCollection({ - episodeId : this.model.id, + movieId : this.model.id, tableName : 'episodeHistory' }); this.collection.fetch();