diff --git a/NzbDrone.Api/History/HistoryModule.cs b/NzbDrone.Api/History/HistoryModule.cs index b4fefdfcf..e46f253ba 100644 --- a/NzbDrone.Api/History/HistoryModule.cs +++ b/NzbDrone.Api/History/HistoryModule.cs @@ -13,48 +13,27 @@ namespace NzbDrone.Api.History { - public class HistoryModule : NzbDroneApiModule + public class HistoryModule : NzbDroneRestModule { private readonly IHistoryService _historyService; public HistoryModule(IHistoryService historyService) - : base("/history") { _historyService = historyService; - Get["/"] = x => GetHistory(); + GetResourcePaged = GetHistory; } - private Response GetHistory() + private PagingResource GetHistory(PagingResource pagingResource) { - //TODO: common page parsing logic should be done somewhere else - - int pageSize; - Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.PageSize), out pageSize); - if (pageSize == 0) pageSize = 20; - - int page; - Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.Page), out page); - if (page == 0) page = 1; - - var sortKey = PrimitiveExtensions.ToNullSafeString(Request.Query.SortKey); - if (String.IsNullOrEmpty(sortKey)) sortKey = "AirDate"; - - var sortDirection = PrimitiveExtensions.ToNullSafeString(Request.Query.SortDir) - .Equals("Asc", StringComparison.InvariantCultureIgnoreCase) - ? SortDirection.Ascending - : SortDirection.Descending; - var pagingSpec = new PagingSpec { - Page = page, - PageSize = pageSize, - SortKey = sortKey, - SortDirection = sortDirection + Page = pagingResource.Page, + PageSize = pagingResource.PageSize, + SortKey = pagingResource.SortKey, + SortDirection = pagingResource.SortDirection }; - var result = _historyService.Paged(pagingSpec); - - return Mapper.Map, PagingResource>(result).AsResponse(); + return ApplyToPage(_historyService.Paged, pagingSpec); } } } \ No newline at end of file diff --git a/NzbDrone.Api/Missing/MissingModule.cs b/NzbDrone.Api/Missing/MissingModule.cs index a316601a8..22673c2ab 100644 --- a/NzbDrone.Api/Missing/MissingModule.cs +++ b/NzbDrone.Api/Missing/MissingModule.cs @@ -1,59 +1,29 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using AutoMapper; -using Nancy; -using NzbDrone.Api.Episodes; -using NzbDrone.Api.Extensions; -using NzbDrone.Core.Datastore; +using NzbDrone.Core.Datastore; using NzbDrone.Core.Tv; namespace NzbDrone.Api.Missing { - public class MissingModule : NzbDroneApiModule + public class MissingModule : NzbDroneRestModule { private readonly IEpisodeService _episodeService; public MissingModule(IEpisodeService episodeService) - : base("/missing") { _episodeService = episodeService; - Get["/"] = x => GetMissingEpisodes(); + GetResourcePaged = GetMissingEpisodes; } - private Response GetMissingEpisodes() + private PagingResource GetMissingEpisodes(PagingResource pagingResource) { - bool includeSpecials; - Boolean.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.IncludeSpecials), out includeSpecials); - - int pageSize; - Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.PageSize), out pageSize); - if (pageSize == 0) pageSize = 20; - - int page; - Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.Page), out page); - if (page == 0) page = 1; - - var sortKey = PrimitiveExtensions.ToNullSafeString(Request.Query.SortKey); - if (String.IsNullOrEmpty(sortKey)) sortKey = "AirDate"; - - var sortDirection = PrimitiveExtensions.ToNullSafeString(Request.Query.SortDir) - .Equals("Asc", StringComparison.InvariantCultureIgnoreCase) - ? SortDirection.Ascending - : SortDirection.Descending; - var pagingSpec = new PagingSpec - { - Page = page, - PageSize = pageSize, - SortKey = sortKey, - SortDirection = sortDirection - }; + { + Page = pagingResource.Page, + PageSize = pagingResource.PageSize, + SortKey = pagingResource.SortKey, + SortDirection = pagingResource.SortDirection + }; - var result = _episodeService.EpisodesWithoutFiles(pagingSpec, includeSpecials); - - return Mapper.Map, PagingResource>(result).AsResponse(); + return ApplyToPage(_episodeService.EpisodesWithoutFiles, pagingSpec); } } } \ No newline at end of file diff --git a/NzbDrone.Api/Missing/MissingResource.cs b/NzbDrone.Api/Missing/MissingResource.cs new file mode 100644 index 000000000..11bd7704b --- /dev/null +++ b/NzbDrone.Api/Missing/MissingResource.cs @@ -0,0 +1,34 @@ +using System; +using NzbDrone.Api.REST; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Model; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Api.Missing +{ + public class MissingResource : RestResource + { + public Int32 Id { get; set; } + public Int32 SeriesId { get; set; } + public Int32 EpisodeFileId { get; set; } + public Int32 SeasonNumber { get; set; } + public Int32 EpisodeNumber { get; set; } + public String Title { get; set; } + public DateTime? AirDate { get; set; } + public EpisodeStatuses Status { get; set; } + public String Overview { get; set; } + public EpisodeFile EpisodeFile { get; set; } + + public Boolean HasFile { get; set; } + public Boolean Ignored { get; set; } + public Int32 SceneEpisodeNumber { get; set; } + public Int32 SceneSeasonNumber { get; set; } + public Int32 TvDbEpisodeId { get; set; } + public Int32? AbsoluteEpisodeNumber { get; set; } + public DateTime? EndTime { get; set; } + public DateTime? GrabDate { get; set; } + public PostDownloadStatusType PostDownloadStatus { get; set; } + public Core.Tv.Series Series { get; set; } + public String SeriesTitle { get; set; } + } +} diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index 7694cf32b..1e08e4fc1 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -109,6 +109,7 @@ + diff --git a/NzbDrone.Api/NzbDroneRestModule.cs b/NzbDrone.Api/NzbDroneRestModule.cs index 0b026eea3..87507b234 100644 --- a/NzbDrone.Api/NzbDroneRestModule.cs +++ b/NzbDrone.Api/NzbDroneRestModule.cs @@ -48,5 +48,19 @@ protected NzbDroneRestModule(string resource) return model.InjectTo(); } + protected PagingResource ApplyToPage(Func, PagingSpec> function, PagingSpec pagingSpec) where TModel : ModelBase, new() + { + pagingSpec = function(pagingSpec); + + return new PagingResource + { + Page = pagingSpec.Page, + PageSize = pagingSpec.PageSize, + SortDirection = pagingSpec.SortDirection, + SortKey = pagingSpec.SortKey, + TotalRecords = pagingSpec.TotalRecords, + Records = pagingSpec.Records.InjectTo>() + }; + } } } \ No newline at end of file diff --git a/NzbDrone.Api/PagingResource.cs b/NzbDrone.Api/PagingResource.cs index 389552c5b..7452c9bff 100644 --- a/NzbDrone.Api/PagingResource.cs +++ b/NzbDrone.Api/PagingResource.cs @@ -2,13 +2,16 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using NzbDrone.Core.Datastore; namespace NzbDrone.Api { public class PagingResource { public int Page { get; set; } + public int PageSize { get; set; } public string SortKey { get; set; } + public SortDirection SortDirection { get; set; } public int TotalRecords { get; set; } public List Records { get; set; } } diff --git a/NzbDrone.Api/REST/RestModule.cs b/NzbDrone.Api/REST/RestModule.cs index 79e0f4b8c..9e57625ab 100644 --- a/NzbDrone.Api/REST/RestModule.cs +++ b/NzbDrone.Api/REST/RestModule.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using AutoMapper; using FluentValidation; using Nancy; using NzbDrone.Api.Extensions; using System.Linq; +using NzbDrone.Core.Datastore; namespace NzbDrone.Api.REST { @@ -16,6 +18,7 @@ public abstract class RestModule : NancyModule private Action _deleteResource; private Func _getResourceById; private Func> _getResourceAll; + private Func, PagingResource> _getResourcePaged; private Func _getResourceSingle; private Func _createResource; private Func _updateResource; @@ -24,7 +27,6 @@ public abstract class RestModule : NancyModule protected ResourceValidator PutValidator { get; private set; } protected ResourceValidator SharedValidator { get; private set; } - protected void ValidateId(int id) { if (id <= 0) @@ -33,7 +35,6 @@ protected void ValidateId(int id) } } - protected RestModule(string modulePath) : base(modulePath) { @@ -88,6 +89,21 @@ protected Func> GetResourceAll } } + protected Func, PagingResource> GetResourcePaged + { + private get { return _getResourcePaged; } + set + { + _getResourcePaged = value; + + Get[ROOT_ROUTE] = options => + { + var resource = GetResourcePaged(ReadPagingResourceFromRequest()); + return resource.AsResponse(); + }; + } + } + protected Func GetResourceSingle { private get { return _getResourceSingle; } @@ -132,7 +148,6 @@ protected Func UpdateResource } } - private TResource ReadFromRequest() { //TODO: handle when request is null @@ -140,7 +155,6 @@ private TResource ReadFromRequest() var errors = SharedValidator.Validate(resource).Errors.ToList(); - if (Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase)) { errors.AddRange(PostValidator.Validate(resource).Errors); @@ -157,5 +171,34 @@ private TResource ReadFromRequest() return resource; } + + private PagingResource ReadPagingResourceFromRequest() + { + int pageSize; + Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.PageSize), out pageSize); + if (pageSize == 0) pageSize = 10; + + int page; + Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.Page), out page); + if (page == 0) page = 1; + + var sortKey = PrimitiveExtensions.ToNullSafeString(Request.Query.SortKey); + if (String.IsNullOrEmpty(sortKey)) sortKey = "AirDate"; + + var sortDirection = PrimitiveExtensions.ToNullSafeString(Request.Query.SortDir) + .Equals("Asc", StringComparison.InvariantCultureIgnoreCase) + ? SortDirection.Ascending + : SortDirection.Descending; + + var pagingResource = new PagingResource + { + PageSize = pageSize, + Page = page, + SortKey = sortKey, + SortDirection = sortDirection + }; + + return pagingResource; + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Tv/EpisodeService.cs b/NzbDrone.Core/Tv/EpisodeService.cs index 12d68ab8a..28e19f7c9 100644 --- a/NzbDrone.Core/Tv/EpisodeService.cs +++ b/NzbDrone.Core/Tv/EpisodeService.cs @@ -21,7 +21,7 @@ public interface IEpisodeService Episode GetEpisode(int seriesId, DateTime date); List GetEpisodeBySeries(int seriesId); List GetEpisodesBySeason(int seriesId, int seasonNumber); - PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec, bool includeSpecials); + PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec); List GetEpisodesByFileId(int episodeFileId); List EpisodesWithFiles(); void RefreshEpisodeInfo(Series series); @@ -93,9 +93,9 @@ public List GetEpisodesBySeason(int seriesId, int seasonNumber) return _episodeRepository.GetEpisodes(seriesId, seasonNumber); } - public PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec, bool includeSpecials) + public PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec) { - var episodeResult = _episodeRepository.EpisodesWithoutFiles(pagingSpec, includeSpecials); + var episodeResult = _episodeRepository.EpisodesWithoutFiles(pagingSpec, false); return episodeResult; } diff --git a/NzbDrone.ncrunchsolution b/NzbDrone.ncrunchsolution index 444b34b1d..6cb47a29a 100644 --- a/NzbDrone.ncrunchsolution +++ b/NzbDrone.ncrunchsolution @@ -2,7 +2,6 @@ 1 False true - true UseDynamicAnalysis Disabled Disabled diff --git a/UI/AddSeries/New/AddNewSeriesView.js b/UI/AddSeries/New/AddNewSeriesView.js index 95c0b6d09..e1f973fdf 100644 --- a/UI/AddSeries/New/AddNewSeriesView.js +++ b/UI/AddSeries/New/AddNewSeriesView.js @@ -16,8 +16,6 @@ define(['app', 'AddSeries/RootFolders/RootFolderCollection', 'AddSeries/New/Sear initialize: function () { this.collection = new NzbDrone.AddSeries.Collection(); - - model.id = undefined; NzbDrone.AddSeries.New.AddNewSeriesContext = this; NzbDrone.vent.on(NzbDrone.Events.SeriesAdded, function (options) {