diff --git a/NzbDrone.Core/Model/HistoryQueryModel.cs b/NzbDrone.Core/Model/HistoryQueryModel.cs new file mode 100644 index 000000000..00a018c2b --- /dev/null +++ b/NzbDrone.Core/Model/HistoryQueryModel.cs @@ -0,0 +1,26 @@ +using System; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using PetaPoco; + +namespace NzbDrone.Core.Model +{ + public class HistoryQueryModel + { + public int HistoryId { get; set; } + public int EpisodeId { get; set; } + public int SeriesId { get; set; } + public string NzbTitle { get; set; } + public QualityTypes Quality { get; set; } + public DateTime Date { get; set; } + public bool IsProper { get; set; } + public string Indexer { get; set; } + public string NzbInfoUrl { get; set; } + + public string EpisodeTitle { get; set; } + public int SeasonNumber { get; set; } + public int EpisodeNumber { get; set; } + public string EpisodeOverview { get; set; } + public string SeriesTitle { get; set; }public int Id { get; set; } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 7dedf5250..3f7acc5fd 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -123,6 +123,10 @@ + + False + ..\packages\DataTables.Mvc.Core.0.1.0.85\lib\DataTables.Mvc.Core.dll + ..\Libraries\DeskMetrics\DeskMetrics.NET.dll @@ -251,6 +255,7 @@ + diff --git a/NzbDrone.Core/Providers/HistoryProvider.cs b/NzbDrone.Core/Providers/HistoryProvider.cs index 94a3c8479..807c39fb6 100644 --- a/NzbDrone.Core/Providers/HistoryProvider.cs +++ b/NzbDrone.Core/Providers/HistoryProvider.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using DataTables.Mvc.Core.Helpers; +using DataTables.Mvc.Core.Models; using Ninject; using NLog; using NzbDrone.Core.Model; @@ -77,5 +79,42 @@ public virtual void Delete(int historyId) { _database.Delete(historyId); } + + public virtual Page GetPagedItems(DataTablesPageRequest pageRequest) + { + var query = Sql.Builder + .Select(@"History.*, Series.Title as SeriesTitle, Episodes.Title as EpisodeTitle, + Episodes.SeasonNumber as SeasonNumber, Episodes.EpisodeNumber as EpisodeNumber, + Episodes.Overview as EpisodeOverview") + .From("History") + .InnerJoin("Series") + .On("History.SeriesId = Series.SeriesId") + .InnerJoin("Episodes") + .On("History.EpisodeId = Episodes.EpisodeId"); + + var startPage = (pageRequest.DisplayLength == 0) ? 1 : pageRequest.DisplayStart / pageRequest.DisplayLength + 1; + + if (!string.IsNullOrEmpty(pageRequest.Search)) + { + var whereClause = string.Join(" OR ", SqlBuilderHelper.GetSearchClause(pageRequest)); + + if (!string.IsNullOrEmpty(whereClause)) + query.Append("WHERE " + whereClause, "%" + pageRequest.Search + "%"); + } + + var orderBy = string.Join(",", SqlBuilderHelper.GetOrderByClause(pageRequest)); + + if (!string.IsNullOrEmpty(orderBy)) + { + query.Append("ORDER BY " + orderBy); + } + + return _database.Page(startPage, pageRequest.DisplayLength, query); + } + + public virtual long Count() + { + return _database.Single(@"SELECT COUNT(*) from History"); + } } } \ No newline at end of file diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config index 28e5af301..f24ef5601 100644 --- a/NzbDrone.Core/packages.config +++ b/NzbDrone.Core/packages.config @@ -1,5 +1,6 @@  + diff --git a/NzbDrone.Web/App_Start/DataTablesMvc.cs b/NzbDrone.Web/App_Start/DataTablesMvc.cs index 6ac4a3b4f..8375e53ab 100644 --- a/NzbDrone.Web/App_Start/DataTablesMvc.cs +++ b/NzbDrone.Web/App_Start/DataTablesMvc.cs @@ -10,8 +10,8 @@ public static class DataTablesModelBinderActivator { public static void Start() { - if (!ModelBinders.Binders.ContainsKey(typeof(DataTablesParams))) - ModelBinders.Binders.Add(typeof(DataTablesParams), new DataTablesModelBinder()); + if (!ModelBinders.Binders.ContainsKey(typeof(DataTablesPageRequest))) + ModelBinders.Binders.Add(typeof(DataTablesPageRequest), new DataTablesModelBinder()); } } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/HistoryController.cs b/NzbDrone.Web/Controllers/HistoryController.cs index 06e50b185..4aee08267 100644 --- a/NzbDrone.Web/Controllers/HistoryController.cs +++ b/NzbDrone.Web/Controllers/HistoryController.cs @@ -1,6 +1,9 @@ -using System.Linq; +using System; +using System.Linq; +using System.Linq.Dynamic; using System.Web.Mvc; using System.Web.Script.Serialization; +using DataTables.Mvc.Core.Models; using NzbDrone.Core.Helpers; using NzbDrone.Core.Jobs; using NzbDrone.Core.Providers; @@ -24,15 +27,46 @@ public ActionResult Index() return View(); } - public JsonResult AjaxBinding() + //public JsonResult AjaxBinding() + //{ + // var history = _historyProvider.AllItemsWithRelationships().Select(h => new HistoryModel + // { + // HistoryId = h.HistoryId, + // SeriesId = h.SeriesId, + // EpisodeNumbering = string.Format("{0}x{1:00}", h.Episode.SeasonNumber, h.Episode.EpisodeNumber), + // EpisodeTitle = h.Episode.Title, + // EpisodeOverview = h.Episode.Overview, + // SeriesTitle = h.SeriesTitle, + // SeriesTitleSorter = SortHelper.SkipArticles(h.SeriesTitle), + // NzbTitle = h.NzbTitle, + // Quality = h.Quality.ToString(), + // IsProper = h.IsProper, + // Date = h.Date.ToString(), + // DateSorter = h.Date.ToString("MM/dd/yyyy h:mm:ss tt"), + // Indexer = h.Indexer, + // EpisodeId = h.EpisodeId, + // NzbInfoUrl = h.NzbInfoUrl + // }).OrderByDescending(h => h.Date).ToList(); + + // return Json(new + // { + // aaData = history + // }, + // JsonRequestBehavior.AllowGet); + //} + + public ActionResult AjaxBinding(DataTablesPageRequest pageRequest) { - var history = _historyProvider.AllItemsWithRelationships().Select(h => new HistoryModel + var pageResult = _historyProvider.GetPagedItems(pageRequest); + var totalItems = _historyProvider.Count(); + + var items = pageResult.Items.Select(h => new HistoryModel { HistoryId = h.HistoryId, SeriesId = h.SeriesId, - EpisodeNumbering = string.Format("{0}x{1:00}", h.Episode.SeasonNumber, h.Episode.EpisodeNumber), - EpisodeTitle = h.Episode.Title, - EpisodeOverview = h.Episode.Overview, + EpisodeNumbering = string.Format("{0}x{1:00}", h.SeasonNumber, h.EpisodeNumber), + EpisodeTitle = h.EpisodeTitle, + EpisodeOverview = h.EpisodeOverview, SeriesTitle = h.SeriesTitle, SeriesTitleSorter = SortHelper.SkipArticles(h.SeriesTitle), NzbTitle = h.NzbTitle, @@ -43,11 +77,14 @@ public JsonResult AjaxBinding() Indexer = h.Indexer, EpisodeId = h.EpisodeId, NzbInfoUrl = h.NzbInfoUrl - }).OrderByDescending(h => h.Date).ToList(); + }); return Json(new { - aaData = history + sEcho = pageRequest.Echo, + iTotalRecords = totalItems, + iTotalDisplayRecords = pageResult.TotalItems, + aaData = items }, JsonRequestBehavior.AllowGet); } diff --git a/NzbDrone.Web/Controllers/LogController.cs b/NzbDrone.Web/Controllers/LogController.cs index 6df8bd2ad..bc31e062a 100644 --- a/NzbDrone.Web/Controllers/LogController.cs +++ b/NzbDrone.Web/Controllers/LogController.cs @@ -52,36 +52,36 @@ public JsonResult Clear() return JsonNotificationResult.Info("Logs Cleared"); } - public ActionResult AjaxBinding(DataTablesParams dataTablesParams) + public ActionResult AjaxBinding(DataTablesPageRequest pageRequest) { var logs = _logProvider.GetAllLogs(); var totalCount = logs.Count(); IQueryable q = logs; - if (!string.IsNullOrEmpty(dataTablesParams.sSearch)) + if (!string.IsNullOrEmpty(pageRequest.Search)) { - q = q.Where(b => b.Logger.Contains(dataTablesParams.sSearch) - || b.Exception.Contains(dataTablesParams.sSearch) - || b.Message.Contains(dataTablesParams.sSearch)); + q = q.Where(b => b.Logger.Contains(pageRequest.Search) + || b.Exception.Contains(pageRequest.Search) + || b.Message.Contains(pageRequest.Search)); } int filteredCount = q.Count(); IQueryable sorted = q; - for (int i = 0; i < dataTablesParams.iSortingCols; i++) + for (int i = 0; i < pageRequest.SortingCols; i++) { - int sortCol = dataTablesParams.iSortCol[i]; + int sortCol = pageRequest.SortCol[i]; var sortColName = sortCol == 0 ? "Time" : sortCol == 1 ? "Level" : "Logger"; - var sortExpression = String.Format("{0} {1}", sortColName, dataTablesParams.sSortDir[i]); + var sortExpression = String.Format("{0} {1}", sortColName, pageRequest.SortDir[i]); sorted = sorted.OrderBy(sortExpression); } IQueryable filteredAndSorted = sorted; - if (filteredCount > dataTablesParams.iDisplayLength) + if (filteredCount > pageRequest.DisplayLength) { - filteredAndSorted = sorted.Skip(dataTablesParams.iDisplayStart).Take(dataTablesParams.iDisplayLength); + filteredAndSorted = sorted.Skip(pageRequest.DisplayStart).Take(pageRequest.DisplayLength); } var logModels = filteredAndSorted.ToList().Select(s => new LogModel @@ -97,7 +97,7 @@ public ActionResult AjaxBinding(DataTablesParams dataTablesParams) return Json(new { - sEcho = dataTablesParams.sEcho, + sEcho = pageRequest.Echo, iTotalRecords = totalCount, iTotalDisplayRecords = filteredCount, aaData = logModels diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 74005fcb6..060760cef 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -53,9 +53,9 @@ x86 - - ..\packages\DataTables.Mvc.0.1.0.79\lib\DataTables.Mvc.Core.dll - True + + False + ..\packages\DataTables.Mvc.Core.0.1.0.85\lib\DataTables.Mvc.Core.dll ..\packages\DynamicQuery.1.0\lib\35\Dynamic.dll @@ -142,9 +142,9 @@ False ..\Libraries\TvdbLib.dll - + False - ..\packages\WebActivator.1.5\lib\net40\WebActivator.dll + ..\packages\WebActivator.1.5.1\lib\net40\WebActivator.dll @@ -363,6 +363,7 @@ + diff --git a/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js b/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js new file mode 100644 index 000000000..f020aca48 --- /dev/null +++ b/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js @@ -0,0 +1,33 @@ +$.fn.dataTableExt.oApi.fnSetFilteringDelay = function (oSettings, iDelay) { + /* + * Inputs: object:oSettings - dataTables settings object - automatically given + * integer:iDelay - delay in milliseconds + * Usage: $('#example').dataTable().fnSetFilteringDelay(250); + * Author: Zygimantas Berziunas (www.zygimantas.com) and Allan Jardine + * License: GPL v2 or BSD 3 point style + * Contact: zygimantas.berziunas /AT\ hotmail.com + */ + var _that = this, + iDelay = (typeof iDelay == 'undefined') ? 250 : iDelay; + + this.each(function (i) { + $.fn.dataTableExt.iApiIndex = i; + var oTimerId = null, + sPreviousSearch = null, + anControl = $('input', _that.fnSettings().aanFeatures.f); + + anControl.unbind('keyup').bind('keyup', function () { + if (sPreviousSearch === null || sPreviousSearch != anControl.val()) { + window.clearTimeout(oTimerId); + sPreviousSearch = anControl.val(); + oTimerId = window.setTimeout(function () { + $.fn.dataTableExt.iApiIndex = i; + _that.fnFilter(anControl.val()); + }, iDelay); + } + }); + + return this; + }); + return this; +}; \ No newline at end of file diff --git a/NzbDrone.Web/Views/History/Index.cshtml b/NzbDrone.Web/Views/History/Index.cshtml index efbddff65..216969c13 100644 --- a/NzbDrone.Web/Views/History/Index.cshtml +++ b/NzbDrone.Web/Views/History/Index.cshtml @@ -46,7 +46,7 @@ oTable = $('#historyGrid').dataTable({ "sAjaxSource": "History/AjaxBinding", - "bServerSide": false, + "bServerSide": true, "bProcessing": true, "bShowAll": false, "bPaginate": true, @@ -59,7 +59,7 @@ "sPaginationType": "four_button", "aoColumns": [ { - sWidth: '20px', "bSortable": false, "mDataProp": function (source, type, val) { + sName: 'Icon', sWidth: '20px', "bSortable": false, "bSearchable": false, "mDataProp": function (source, type, val) { // 'display' and 'filter' use the image if (type === 'display' || type === 'filter') { if (source['Indexer'].indexOf("Newznab") === 0) @@ -71,7 +71,8 @@ return source["Indexer"]; } }, //Image - { sWidth: 'auto', "mDataProp": function (source, type, val) { + { + sName: 'Series.Title', sWidth: 'auto', "mDataProp": function (source, type, val) { // 'display' and 'filter' use our fancy naming if (type === 'display' || type === 'filter') { return "" + source["SeriesTitle"] + ""; @@ -80,10 +81,10 @@ return source["SeriesTitleSorter"]; } }, //Series Title - { sWidth: '80px', "mDataProp": "EpisodeNumbering", "bSortable": false }, //EpisodeNumbering - { sWidth: 'auto', "mDataProp": "EpisodeTitle", "bSortable": false }, //Episode Title - { sWidth: '70px', "mDataProp": "Quality", "bSortable": false }, //Quality - { sWidth: '150px', "mDataProp": function (source, type, val) { + { sName: 'EpisodeNumbering', sWidth: '80px', "mDataProp": "EpisodeNumbering", "bSortable": false, "bSearchable": false }, //EpisodeNumbering + { sName: 'Episodes.Title', sWidth: 'auto', "mDataProp": "EpisodeTitle", "bSortable": false }, //Episode Title + { sName: 'Quality', sWidth: '70px', "mDataProp": "Quality", "bSortable": false, "bSearchable": false }, //Quality + { sName: 'Date', sWidth: '150px', "bSearchable": false, "mDataProp": function (source, type, val) { // 'display' and 'filter' use our fancy naming if (type === 'display' || type === 'filter') { return source["Date"]; @@ -92,7 +93,7 @@ return source["DateSorter"]; } }, //Date - { sWidth: '40px', "mDataProp": "HistoryId", "bSortable": false, "fnRender": function (row) { + { sName: 'Actions', sWidth: '40px', "mDataProp": "HistoryId", "bSortable": false, "bSearchable": false, "fnRender": function (row) { var deleteImage = "\"Delete\""; var redownloadImage = "\"Redownload\""; @@ -100,9 +101,10 @@ } }, //Actions { - sWidth: 'auto', + sName: 'Details', sWidth: 'auto', "mDataProp": "Details", "bSortable": false, + "bSearchable": false, "bVisible": false, "fnRender": function(row) { var result = "Overview: " + row.aData["EpisodeOverview"] + "
" + @@ -118,7 +120,7 @@ } //Details ], "aaSorting": [[5, 'desc']] - }); + }).fnSetFilteringDelay(500); }); function deleteHistory(row, historyId) { diff --git a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml index 598fdf8c7..e4207762c 100644 --- a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml +++ b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml @@ -44,7 +44,8 @@ @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.min.js") @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.reloadAjax.js") @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.editable.js") - @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.jeditable.js") + @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.jeditable.js")s + @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js") @Html.IncludeScript("jquery.dataTables.4button.pagination.js") @RenderSection("Scripts", required: false) diff --git a/NzbDrone.Web/packages.config b/NzbDrone.Web/packages.config index 325a983b0..62a0524c4 100644 --- a/NzbDrone.Web/packages.config +++ b/NzbDrone.Web/packages.config @@ -1,6 +1,7 @@  - + + @@ -27,5 +28,5 @@ - + \ No newline at end of file diff --git a/ServiceHelpers/ServiceInstall/ServiceInstall.ncrunchproject b/ServiceHelpers/ServiceInstall/ServiceInstall.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/ServiceHelpers/ServiceInstall/ServiceInstall.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/ServiceHelpers/ServiceUninstall/ServiceUninstall.ncrunchproject b/ServiceHelpers/ServiceUninstall/ServiceUninstall.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/ServiceHelpers/ServiceUninstall/ServiceUninstall.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/packages/DataTables.Mvc.0.1.0.79/DataTables.Mvc.0.1.0.79.nupkg b/packages/DataTables.Mvc.0.1.0.79/DataTables.Mvc.0.1.0.79.nupkg deleted file mode 100644 index ae278e47f..000000000 Binary files a/packages/DataTables.Mvc.0.1.0.79/DataTables.Mvc.0.1.0.79.nupkg and /dev/null differ diff --git a/packages/DataTables.Mvc.0.1.0.79/lib/DataTables.Mvc.Core.dll b/packages/DataTables.Mvc.0.1.0.79/lib/DataTables.Mvc.Core.dll deleted file mode 100644 index 5e9769930..000000000 Binary files a/packages/DataTables.Mvc.0.1.0.79/lib/DataTables.Mvc.Core.dll and /dev/null differ diff --git a/packages/DataTables.Mvc.0.1.0.85/Content/App_Start/DataTablesMvc.cs.pp b/packages/DataTables.Mvc.0.1.0.85/Content/App_Start/DataTablesMvc.cs.pp new file mode 100644 index 000000000..7f045638d --- /dev/null +++ b/packages/DataTables.Mvc.0.1.0.85/Content/App_Start/DataTablesMvc.cs.pp @@ -0,0 +1,17 @@ +using DataTables.Mvc.Core.Helpers; +using DataTables.Mvc.Core.Models; +using System.Web.Mvc; + +[assembly: WebActivator.PreApplicationStartMethod(typeof($rootnamespace$.App_Start.DataTablesModelBinderActivator), "Start")] + +namespace $rootnamespace$.App_Start +{ + public static class DataTablesModelBinderActivator + { + public static void Start() + { + if (!ModelBinders.Binders.ContainsKey(typeof(DataTablesPageRequest))) + ModelBinders.Binders.Add(typeof(DataTablesPageRequest), new DataTablesModelBinder()); + } + } +} \ No newline at end of file diff --git a/packages/DataTables.Mvc.0.1.0.85/DataTables.Mvc.0.1.0.85.nupkg b/packages/DataTables.Mvc.0.1.0.85/DataTables.Mvc.0.1.0.85.nupkg new file mode 100644 index 000000000..d98c4938f Binary files /dev/null and b/packages/DataTables.Mvc.0.1.0.85/DataTables.Mvc.0.1.0.85.nupkg differ diff --git a/packages/DataTables.Mvc.0.1.0.85/tools/install.ps1 b/packages/DataTables.Mvc.0.1.0.85/tools/install.ps1 new file mode 100644 index 000000000..7e1f5357f --- /dev/null +++ b/packages/DataTables.Mvc.0.1.0.85/tools/install.ps1 @@ -0,0 +1,5 @@ +param($installPath, $toolsPath, $package, $project) + +$path = [System.IO.Path] +$appstart = $path::Combine($path::GetDirectoryName($project.FileName), "App_Start\DataTablesMvc.cs") +$DTE.ItemOperations.OpenFile($appstart) \ No newline at end of file diff --git a/packages/DataTables.Mvc.Core.0.1.0.85/DataTables.Mvc.Core.0.1.0.85.nupkg b/packages/DataTables.Mvc.Core.0.1.0.85/DataTables.Mvc.Core.0.1.0.85.nupkg new file mode 100644 index 000000000..3863bd0b1 Binary files /dev/null and b/packages/DataTables.Mvc.Core.0.1.0.85/DataTables.Mvc.Core.0.1.0.85.nupkg differ diff --git a/packages/DataTables.Mvc.Core.0.1.0.85/lib/DataTables.Mvc.Core.dll b/packages/DataTables.Mvc.Core.0.1.0.85/lib/DataTables.Mvc.Core.dll new file mode 100644 index 000000000..f90ce2740 Binary files /dev/null and b/packages/DataTables.Mvc.Core.0.1.0.85/lib/DataTables.Mvc.Core.dll differ diff --git a/packages/WebActivator.1.5.1/WebActivator.1.5.1.nupkg b/packages/WebActivator.1.5.1/WebActivator.1.5.1.nupkg new file mode 100644 index 000000000..3650d0bd8 Binary files /dev/null and b/packages/WebActivator.1.5.1/WebActivator.1.5.1.nupkg differ diff --git a/packages/WebActivator.1.5.1/lib/net40/WebActivator.dll b/packages/WebActivator.1.5.1/lib/net40/WebActivator.dll new file mode 100644 index 000000000..b67532d04 Binary files /dev/null and b/packages/WebActivator.1.5.1/lib/net40/WebActivator.dll differ