From 3d944b32a8fb6e6bad4c3688586007dd80b17a32 Mon Sep 17 00:00:00 2001 From: Drewster727 Date: Sun, 27 Mar 2016 16:54:54 -0500 Subject: [PATCH 01/57] fix up sorting on the request page --- PlexRequests.UI/Content/requests.js | 79 +++++++++++---------- PlexRequests.UI/Models/RequestViewModel.cs | 2 + PlexRequests.UI/Modules/RequestsModule.cs | 4 ++ PlexRequests.UI/Views/Requests/Index.cshtml | 7 +- 4 files changed, 51 insertions(+), 41 deletions(-) diff --git a/PlexRequests.UI/Content/requests.js b/PlexRequests.UI/Content/requests.js index 3872da2c2..bbca674af 100644 --- a/PlexRequests.UI/Content/requests.js +++ b/PlexRequests.UI/Content/requests.js @@ -9,6 +9,16 @@ var searchSource = $("#search-template").html(); var searchTemplate = Handlebars.compile(searchSource); var movieTimer = 0; var tvimer = 0; +var mixItUpDefault = { + animation: { enable: true }, + load: { + filter: 'all', + sort: 'default:asc' + }, + layout: { + display: 'block' + } +}; movieLoad(); tvLoad(); @@ -17,40 +27,26 @@ tvLoad(); $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { var target = $(e.target).attr('href'); var activeState = ""; - if (target === "#TvShowTab") { - if ($('#movieList').mixItUp('isLoaded')) { - activeState = $('#movieList').mixItUp('getState'); - $('#movieList').mixItUp('destroy'); - } - if (!$('#tvList').mixItUp('isLoaded')) { - $('#tvList').mixItUp({ - load: { - filter: activeState.activeFilter || 'all', - sort: activeState.activeSort || 'default:asc' - }, - layout: { - display: 'block' - } - }); + var $ml = $('#movieList'); + var $tvl = $('#tvList'); + + if (target === "#TvShowTab") { + + if ($ml.mixItUp('isLoaded')) { + activeState = $ml.mixItUp('getState'); + $ml.mixItUp('destroy'); } + if ($tvl.mixItUp('isLoaded')) $tvl.mixItUp('destroy'); + $tvl.mixItUp(mixItUpConfig(activeState)); // init or reinit } if (target === "#MoviesTab") { - if ($('#tvList').mixItUp('isLoaded')) { - activeState = $('#tvList').mixItUp('getState'); - $('#tvList').mixItUp('destroy'); - } - if (!$('#movieList').mixItUp('isLoaded')) { - $('#movieList').mixItUp({ - load: { - filter: activeState.activeFilter || 'all', - sort: activeState.activeSort || 'default:asc' - }, - layout: { - display: 'block' - } - }); + if ($tvl.mixItUp('isLoaded')) { + activeState = $tvl.mixItUp('getState'); + $tvl.mixItUp('destroy'); } + if ($ml.mixItUp('isLoaded')) $ml.mixItUp('destroy'); + $ml.mixItUp(mixItUpConfig(activeState)); // init or reinit } }); @@ -315,24 +311,26 @@ $(document).on("click", ".change", function (e) { }); +function mixItUpConfig(activeState) { + var conf = mixItUpDefault; + + if (activeState) { + if (activeState.activeFilter) conf['load']['filter'] = activeState.activeFilter; + if (activeState.activeSort) conf['load']['sort'] = activeState.activeSort; + } + return conf; +}; + function movieLoad() { $("#movieList").html(""); $.ajax("/requests/movies/").success(function (results) { results.forEach(function (result) { var context = buildRequestContext(result, "movie"); - var html = searchTemplate(context); $("#movieList").append(html); }); - $('#movieList').mixItUp({ - layout: { - display: 'block' - }, - load: { - filter: 'all' - } - }); + $('#movieList').mixItUp(mixItUpConfig()); }); }; @@ -345,6 +343,7 @@ function tvLoad() { var html = searchTemplate(context); $("#tvList").append(html); }); + $('#tvList').mixItUp(mixItUpConfig()); }); }; @@ -359,9 +358,11 @@ function buildRequestContext(result, type) { type: type, status: result.status, releaseDate: result.releaseDate, + releaseDateTicks: result.releaseDateTicks, approved: result.approved, requestedBy: result.requestedBy, requestedDate: result.requestedDate, + requestedDateTicks: result.requestedDateTicks, available: result.available, admin: result.admin, issues: result.issues, @@ -376,7 +377,7 @@ function buildRequestContext(result, type) { } function startFilter(elementId) { - $('#'+element).mixItUp({ + $('#' + element).mixItUp({ load: { filter: activeState.activeFilter || 'all', sort: activeState.activeSort || 'default:asc' diff --git a/PlexRequests.UI/Models/RequestViewModel.cs b/PlexRequests.UI/Models/RequestViewModel.cs index 011b9977d..5ee389be9 100644 --- a/PlexRequests.UI/Models/RequestViewModel.cs +++ b/PlexRequests.UI/Models/RequestViewModel.cs @@ -37,11 +37,13 @@ namespace PlexRequests.UI.Models public string Title { get; set; } public string PosterPath { get; set; } public string ReleaseDate { get; set; } + public long ReleaseDateTicks { get; set; } public RequestType Type { get; set; } public string Status { get; set; } public bool Approved { get; set; } public string RequestedBy { get; set; } public string RequestedDate { get; set; } + public long RequestedDateTicks { get; set; } public string ReleaseYear { get; set; } public bool Available { get; set; } public bool Admin { get; set; } diff --git a/PlexRequests.UI/Modules/RequestsModule.cs b/PlexRequests.UI/Modules/RequestsModule.cs index a951e0db8..47dcf3369 100644 --- a/PlexRequests.UI/Modules/RequestsModule.cs +++ b/PlexRequests.UI/Modules/RequestsModule.cs @@ -90,7 +90,9 @@ namespace PlexRequests.UI.Modules Id = movie.Id, PosterPath = movie.PosterPath, ReleaseDate = movie.ReleaseDate.Humanize(), + ReleaseDateTicks = movie.ReleaseDate.Ticks, RequestedDate = movie.RequestedDate.Humanize(), + RequestedDateTicks = movie.RequestedDate.Ticks, Approved = movie.Approved, Title = movie.Title, Overview = movie.Overview, @@ -119,7 +121,9 @@ namespace PlexRequests.UI.Modules Id = tv.Id, PosterPath = tv.PosterPath, ReleaseDate = tv.ReleaseDate.Humanize(), + ReleaseDateTicks = tv.ReleaseDate.Ticks, RequestedDate = tv.RequestedDate.Humanize(), + RequestedDateTicks = tv.RequestedDate.Ticks, Approved = tv.Approved, Title = tv.Title, Overview = tv.Overview, diff --git a/PlexRequests.UI/Views/Requests/Index.cshtml b/PlexRequests.UI/Views/Requests/Index.cshtml index cd73d64d9..bf79ac7dd 100644 --- a/PlexRequests.UI/Views/Requests/Index.cshtml +++ b/PlexRequests.UI/Views/Requests/Index.cshtml @@ -43,7 +43,10 @@ @if (Model.SearchForMovies) @@ -78,7 +81,7 @@ \ No newline at end of file diff --git a/PlexRequests.UI/Views/Admin/PushoverNotifications.cshtml b/PlexRequests.UI/Views/Admin/PushoverNotifications.cshtml index 0877739d0..b5fcab7f5 100644 --- a/PlexRequests.UI/Views/Admin/PushoverNotifications.cshtml +++ b/PlexRequests.UI/Views/Admin/PushoverNotifications.cshtml @@ -36,6 +36,12 @@ +
+
+ +
+
+
@@ -70,5 +76,28 @@ } }); }); + + $('#testPushover').click(function (e) { + e.preventDefault(); + + var $form = $("#mainForm"); + $.ajax({ + type: $form.prop("method"), + data: $form.serialize(), + url: '/admin/testpushovernotification', + dataType: "json", + success: function (response) { + if (response.result === true) { + generateNotify(response.message, "success"); + } else { + generateNotify(response.message, "warning"); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); + }); }); \ No newline at end of file From eddce77ff5347ad91a243a260e65359d6afa6401 Mon Sep 17 00:00:00 2001 From: Drewster727 Date: Mon, 28 Mar 2016 14:53:35 -0500 Subject: [PATCH 13/57] UI - increase icon size of nav menu (they were too small before) --- PlexRequests.UI/Content/custom.css | 7 +++++++ PlexRequests.UI/Content/custom.min.css | 2 +- PlexRequests.UI/Content/custom.scss | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/PlexRequests.UI/Content/custom.css b/PlexRequests.UI/Content/custom.css index 7ff72e7f4..cb9a400b5 100644 --- a/PlexRequests.UI/Content/custom.css +++ b/PlexRequests.UI/Content/custom.css @@ -45,6 +45,13 @@ label { .nav-tabs > li.active > a:focus { background: #4e5d6c; } +.navbar .nav a .fa { + font-size: 130%; + top: 1px; + position: relative; + display: inline-block; + margin-right: 5px; } + .btn-danger-outline { color: #d9534f !important; background-color: transparent; diff --git a/PlexRequests.UI/Content/custom.min.css b/PlexRequests.UI/Content/custom.min.css index 2a046eb7d..2966b6610 100644 --- a/PlexRequests.UI/Content/custom.min.css +++ b/PlexRequests.UI/Content/custom.min.css @@ -1 +1 @@ -@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;} \ No newline at end of file +@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;} \ No newline at end of file diff --git a/PlexRequests.UI/Content/custom.scss b/PlexRequests.UI/Content/custom.scss index 029748ecd..96afda8e8 100644 --- a/PlexRequests.UI/Content/custom.scss +++ b/PlexRequests.UI/Content/custom.scss @@ -71,6 +71,14 @@ label { background: #4e5d6c; } +.navbar .nav a .fa { + font-size: 130%; + top: 1px; + position: relative; + display: inline-block; + margin-right: 5px; +} + .btn-danger-outline { color: $danger-colour $i; background-color: transparent; From a2cbcaa4f1f02eaae761021da3c628a8eceb6a2a Mon Sep 17 00:00:00 2001 From: Drewster727 Date: Mon, 28 Mar 2016 20:50:18 -0500 Subject: [PATCH 14/57] fix notification tests --- .../Notification/NotificationService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/PlexRequests.Services/Notification/NotificationService.cs b/PlexRequests.Services/Notification/NotificationService.cs index 8477a2159..35e52fd7d 100644 --- a/PlexRequests.Services/Notification/NotificationService.cs +++ b/PlexRequests.Services/Notification/NotificationService.cs @@ -67,8 +67,14 @@ namespace PlexRequests.Services.Notification private static async Task NotifyAsync(INotification notification, NotificationModel model) { - - await NotifyAsync(notification, model, null); + try + { + await notification.NotifyAsync(model).ConfigureAwait(false); + } + catch (Exception ex) + { + Log.Error(ex, $"Notification '{notification.NotificationName}' failed with exception"); + } } From 855689d0b95a60245fd4ff976a96b9f7df22e13a Mon Sep 17 00:00:00 2001 From: Drewster727 Date: Mon, 28 Mar 2016 21:51:48 -0500 Subject: [PATCH 15/57] add some "no results" feedback to the searching + minor UI improvements --- PlexRequests.UI/Content/custom.css | 15 +++++++++- PlexRequests.UI/Content/custom.min.css | 2 +- PlexRequests.UI/Content/custom.scss | 35 +++++++++++++++++------ PlexRequests.UI/Content/search.js | 8 ++++++ PlexRequests.UI/Views/Search/Index.cshtml | 2 +- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/PlexRequests.UI/Content/custom.css b/PlexRequests.UI/Content/custom.css index cb9a400b5..51130e9e9 100644 --- a/PlexRequests.UI/Content/custom.css +++ b/PlexRequests.UI/Content/custom.css @@ -22,7 +22,9 @@ .form-control-custom { background-color: #4e5d6c !important; - color: white !important; } + color: white !important; + border-radius: 0; + box-shadow: 0 0 0 !important; } h1 { font-size: 3.5rem !important; @@ -138,3 +140,14 @@ label { #tvList .mix { display: none; } +.no-search-results { + text-align: center; } + +.no-search-results .no-search-results-icon { + font-size: 10em; + color: #4e5d6c; } + +.no-search-results .no-search-results-text { + margin: 20px 0; + color: #ccc; } + diff --git a/PlexRequests.UI/Content/custom.min.css b/PlexRequests.UI/Content/custom.min.css index 2966b6610..9e3d7e793 100644 --- a/PlexRequests.UI/Content/custom.min.css +++ b/PlexRequests.UI/Content/custom.min.css @@ -1 +1 @@ -@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;} \ No newline at end of file +@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;} \ No newline at end of file diff --git a/PlexRequests.UI/Content/custom.scss b/PlexRequests.UI/Content/custom.scss index 96afda8e8..f2703ee4a 100644 --- a/PlexRequests.UI/Content/custom.scss +++ b/PlexRequests.UI/Content/custom.scss @@ -5,7 +5,9 @@ $info-colour: #5bc0de; $warning-colour: #f0ad4e; $danger-colour: #d9534f; $success-colour: #5cb85c; -$i:!important; +$i: +!important +; @media (min-width: 768px ) { .row { @@ -42,6 +44,8 @@ $i:!important; .form-control-custom { background-color: $form-color $i; color: white $i; + border-radius: 0; + box-shadow: 0 0 0 !important; } @@ -65,8 +69,8 @@ label { font-size: 16px $i; } -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { background: #4e5d6c; } @@ -170,9 +174,24 @@ label { border-color: $success-colour $i; } -#movieList .mix{ - display: none; +#movieList .mix { + display: none; +} + +#tvList .mix { + display: none; +} + +.no-search-results { + text-align: center; +} + +.no-search-results .no-search-results-icon { + font-size: 10em; + color: $form-color; +} + +.no-search-results .no-search-results-text { + margin: 20px 0; + color: #ccc; } -#tvList .mix{ - display: none; -} \ No newline at end of file diff --git a/PlexRequests.UI/Content/search.js b/PlexRequests.UI/Content/search.js index cea4eca66..4d7b001bb 100644 --- a/PlexRequests.UI/Content/search.js +++ b/PlexRequests.UI/Content/search.js @@ -7,6 +7,8 @@ var searchSource = $("#search-template").html(); var searchTemplate = Handlebars.compile(searchSource); +var noResultsHtml = "
" + + "
Sorry, we didn't find any results!
"; var movieTimer = 0; var tvimer = 0; @@ -124,6 +126,9 @@ function movieSearch() { $("#movieList").append(html); }); } + else { + $("#movieList").html(noResultsHtml); + } $('#movieSearchButton').attr("class","fa fa-search"); }); }; @@ -140,6 +145,9 @@ function tvSearch() { $("#tvList").append(html); }); } + else { + $("#tvList").html(noResultsHtml); + } $('#tvSearchButton').attr("class", "fa fa-search"); }); }; diff --git a/PlexRequests.UI/Views/Search/Index.cshtml b/PlexRequests.UI/Views/Search/Index.cshtml index 4356c069a..5006a58c2 100644 --- a/PlexRequests.UI/Views/Search/Index.cshtml +++ b/PlexRequests.UI/Views/Search/Index.cshtml @@ -1,6 +1,7 @@ 

Search

Want to watch something that is not currently on Plex?! No problem! Just search for it below and request it!

+
- \ No newline at end of file diff --git a/PlexRequests.UI/Views/Admin/_Sidebar.cshtml b/PlexRequests.UI/Views/Admin/_Sidebar.cshtml index efb8ce36b..e6d21e3fc 100644 --- a/PlexRequests.UI/Views/Admin/_Sidebar.cshtml +++ b/PlexRequests.UI/Views/Admin/_Sidebar.cshtml @@ -52,6 +52,14 @@ { SickRage } + @if (Context.Request.Path == "/admin/headphones") + { + Headphones + } + else + { + Headphones + } @if (Context.Request.Path == "/admin/emailnotification") { From fe0f6873e5af6ae8e17d1dcdd1b1b030cae6a392 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 29 Mar 2016 10:34:20 +0100 Subject: [PATCH 18/57] Made the feedback from Sonarr better when Sonarr already has the series #85 --- .../PlexRequests.Api.Models.csproj | 1 + .../Sonarr/SonarrAddSeries.cs | 4 +++ PlexRequests.Api.Models/Sonarr/SonarrError.cs | 36 +++++++++++++++++++ PlexRequests.Api/ApiRequest.cs | 11 +++--- PlexRequests.Api/SonarrApi.cs | 15 ++++++-- PlexRequests.UI/Helpers/TvSender.cs | 4 --- PlexRequests.UI/Modules/ApprovalModule.cs | 5 +-- PlexRequests.UI/Modules/SearchModule.cs | 9 ++--- 8 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 PlexRequests.Api.Models/Sonarr/SonarrError.cs diff --git a/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj b/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj index 1ec1a67ae..d67958e0d 100644 --- a/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj +++ b/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj @@ -64,6 +64,7 @@ + diff --git a/PlexRequests.Api.Models/Sonarr/SonarrAddSeries.cs b/PlexRequests.Api.Models/Sonarr/SonarrAddSeries.cs index 534f3068f..23540521f 100644 --- a/PlexRequests.Api.Models/Sonarr/SonarrAddSeries.cs +++ b/PlexRequests.Api.Models/Sonarr/SonarrAddSeries.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; +using Newtonsoft.Json; + namespace PlexRequests.Api.Models.Sonarr { public class Season @@ -23,6 +25,8 @@ namespace PlexRequests.Api.Models.Sonarr public string imdbId { get; set; } public string titleSlug { get; set; } public int id { get; set; } + [JsonIgnore] + public string ErrorMessage { get; set; } } public class AddOptions diff --git a/PlexRequests.Api.Models/Sonarr/SonarrError.cs b/PlexRequests.Api.Models/Sonarr/SonarrError.cs new file mode 100644 index 000000000..ae3fbdfca --- /dev/null +++ b/PlexRequests.Api.Models/Sonarr/SonarrError.cs @@ -0,0 +1,36 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: SonarrError.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +namespace PlexRequests.Api.Models.Sonarr +{ + public class SonarrError + { + public string propertyName { get; set; } + public string errorMessage { get; set; } + public string attemptedValue { get; set; } + public string[] formattedMessageArguments { get; set; } + } +} \ No newline at end of file diff --git a/PlexRequests.Api/ApiRequest.cs b/PlexRequests.Api/ApiRequest.cs index 62391386b..ad056fbfe 100644 --- a/PlexRequests.Api/ApiRequest.cs +++ b/PlexRequests.Api/ApiRequest.cs @@ -26,13 +26,9 @@ #endregion using System; using System.IO; -using System.Net; -using System.Text; -using System.Xml; using System.Xml.Serialization; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using NLog; @@ -99,17 +95,18 @@ namespace PlexRequests.Api try { var json = JsonConvert.DeserializeObject(response.Content); + return json; } catch (Exception e) { - Log.Fatal(e); - Log.Info(response.Content); + Log.Error(e); + Log.Error(response.Content); throw; } } - public T DeserializeXml(string input) + private T DeserializeXml(string input) where T : class { var ser = new XmlSerializer(typeof(T)); diff --git a/PlexRequests.Api/SonarrApi.cs b/PlexRequests.Api/SonarrApi.cs index 1d1a57f34..d70ba2eef 100644 --- a/PlexRequests.Api/SonarrApi.cs +++ b/PlexRequests.Api/SonarrApi.cs @@ -30,6 +30,8 @@ using System.Linq; using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Api.Models.Sonarr; +using PlexRequests.Helpers; + using RestSharp; namespace PlexRequests.Api @@ -56,7 +58,8 @@ namespace PlexRequests.Api public SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int seasonCount, int[] seasons, string apiKey, Uri baseUrl) { - + Log.Debug("Adding series {0}", title); + Log.Debug("Seasons = {0}, out of {1} seasons", seasons.DumpJson(), seasonCount); var request = new RestRequest { Resource = "/api/Series?", @@ -74,7 +77,6 @@ namespace PlexRequests.Api rootFolderPath = rootPath }; - for (var i = 1; i <= seasonCount; i++) { var season = new Season @@ -85,11 +87,20 @@ namespace PlexRequests.Api options.seasons.Add(season); } + Log.Debug("Sonarr API Options:"); + Log.Debug(options.DumpJson()); + request.AddHeader("X-Api-Key", apiKey); request.AddJsonBody(options); var obj = Api.ExecuteJson(request, baseUrl); + if (obj == null) + { + var error = Api.ExecuteJson(request, baseUrl); + obj = new SonarrAddSeries { ErrorMessage = error.errorMessage }; + } + return obj; } diff --git a/PlexRequests.UI/Helpers/TvSender.cs b/PlexRequests.UI/Helpers/TvSender.cs index d26611321..703c813fd 100644 --- a/PlexRequests.UI/Helpers/TvSender.cs +++ b/PlexRequests.UI/Helpers/TvSender.cs @@ -24,17 +24,13 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ #endregion - -using Nancy; using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Api.Models.SickRage; using PlexRequests.Api.Models.Sonarr; -using PlexRequests.Core; using PlexRequests.Core.SettingModels; using PlexRequests.Helpers; using PlexRequests.Store; -using PlexRequests.UI.Models; namespace PlexRequests.UI.Helpers { diff --git a/PlexRequests.UI/Modules/ApprovalModule.cs b/PlexRequests.UI/Modules/ApprovalModule.cs index b2c6217bb..1e129e3b3 100644 --- a/PlexRequests.UI/Modules/ApprovalModule.cs +++ b/PlexRequests.UI/Modules/ApprovalModule.cs @@ -131,7 +131,7 @@ namespace PlexRequests.UI.Modules return Response.AsJson(new JsonResponseModel { Result = false, - Message = "Could not add the series to Sonarr" + Message = result.ErrorMessage ?? "Could not add the series to Sonarr" }); } @@ -276,7 +276,7 @@ namespace PlexRequests.UI.Modules if (sonarr.Enabled) { var result = sender.SendToSonarr(sonarr, r); - if (result != null) + if (!string.IsNullOrEmpty(result?.title)) { r.Approved = true; updatedRequests.Add(r); @@ -284,6 +284,7 @@ namespace PlexRequests.UI.Modules else { Log.Error("Could not approve and send the TV {0} to Sonarr!", r.Title); + Log.Error("Error message: {0}", result?.ErrorMessage); } } } diff --git a/PlexRequests.UI/Modules/SearchModule.cs b/PlexRequests.UI/Modules/SearchModule.cs index 2a98e8933..9b307f983 100644 --- a/PlexRequests.UI/Modules/SearchModule.cs +++ b/PlexRequests.UI/Modules/SearchModule.cs @@ -371,18 +371,19 @@ namespace PlexRequests.UI.Modules if (sonarrSettings.Enabled) { var result = sender.SendToSonarr(sonarrSettings, model); - if (result != null) + if (result != null && !string.IsNullOrEmpty(result.title)) { model.Approved = true; Log.Debug("Adding tv to database requests (No approval required & Sonarr)"); RequestService.AddRequest(model); + var notify1 = new NotificationModel { Title = model.Title, User = model.RequestedBy, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; + NotificationService.Publish(notify1); return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" }); } - var notify1 = new NotificationModel { Title = model.Title, User = model.RequestedBy, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notify1); - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something went wrong adding the movie to Sonarr! Please check your settings." }); + + return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.ErrorMessage ?? "Something went wrong adding the movie to Sonarr! Please check your settings." }); } From 7349f78b80596e16eefa1586e70925e212d99926 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 29 Mar 2016 10:44:23 +0100 Subject: [PATCH 19/57] Fixed the tests --- PlexRequests.UI.Tests/AdminModuleTests.cs | 3 +++ PlexRequests.UI/Modules/AdminModule.cs | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/PlexRequests.UI.Tests/AdminModuleTests.cs b/PlexRequests.UI.Tests/AdminModuleTests.cs index fc8686086..34b2af4a7 100644 --- a/PlexRequests.UI.Tests/AdminModuleTests.cs +++ b/PlexRequests.UI.Tests/AdminModuleTests.cs @@ -59,6 +59,7 @@ namespace PlexRequests.UI.Tests private Mock> EmailMock { get; set; } private Mock> PushbulletSettings { get; set; } private Mock> PushoverSettings { get; set; } + private Mock> HeadphonesSettings { get; set; } private Mock PlexMock { get; set; } private Mock SonarrApiMock { get; set; } private Mock PushbulletApi { get; set; } @@ -94,6 +95,7 @@ namespace PlexRequests.UI.Tests PushoverSettings = new Mock>(); PushoverApi = new Mock(); NotificationService = new Mock(); + HeadphonesSettings = new Mock>(); Bootstrapper = new ConfigurableBootstrapper(with => { @@ -114,6 +116,7 @@ namespace PlexRequests.UI.Tests with.Dependency(PushoverSettings.Object); with.Dependency(PushoverApi.Object); with.Dependency(NotificationService.Object); + with.Dependency(HeadphonesSettings.Object); with.RootPathProvider(); with.RequestStartup((container, pipelines, context) => { diff --git a/PlexRequests.UI/Modules/AdminModule.cs b/PlexRequests.UI/Modules/AdminModule.cs index 4009f1b5e..e62b8b97b 100644 --- a/PlexRequests.UI/Modules/AdminModule.cs +++ b/PlexRequests.UI/Modules/AdminModule.cs @@ -67,7 +67,7 @@ namespace PlexRequests.UI.Modules private ISettingsService EmailService { get; } private ISettingsService PushbulletService { get; } private ISettingsService PushoverService { get; } - private ISettingsService HeadphonesSerivce { get; } + private ISettingsService HeadphonesService { get; } private IPlexApi PlexApi { get; } private ISonarrApi SonarrApi { get; } private IPushbulletApi PushbulletApi { get; } @@ -111,7 +111,7 @@ namespace PlexRequests.UI.Modules PushoverService = pushoverSettings; PushoverApi = pushoverApi; NotificationService = notify; - HeadphonesSerivce = headphones; + HeadphonesService = headphones; #if !DEBUG this.RequiresAuthentication(); @@ -520,7 +520,7 @@ namespace PlexRequests.UI.Modules private Negotiator Headphones() { - var settings = HeadphonesSerivce.GetSettings(); + var settings = HeadphonesService.GetSettings(); return View["Headphones", settings]; } @@ -537,7 +537,7 @@ namespace PlexRequests.UI.Modules } Log.Trace(settings.DumpJson()); - var result = HeadphonesSerivce.SaveSettings(settings); + var result = HeadphonesService.SaveSettings(settings); Log.Info("Saved headphones settings, result: {0}", result); return Response.AsJson(result From 1f9ed51320459fe7f0ec0d5c3f45e3d54c1b0f6e Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 29 Mar 2016 10:49:30 +0100 Subject: [PATCH 20/57] Made #85 better --- PlexRequests.Api/ApiRequest.cs | 14 +++----------- PlexRequests.Api/SonarrApi.cs | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/PlexRequests.Api/ApiRequest.cs b/PlexRequests.Api/ApiRequest.cs index ad056fbfe..1b7975462 100644 --- a/PlexRequests.Api/ApiRequest.cs +++ b/PlexRequests.Api/ApiRequest.cs @@ -92,18 +92,10 @@ namespace PlexRequests.Api throw new ApplicationException(message, response.ErrorException); } - try - { - var json = JsonConvert.DeserializeObject(response.Content); - return json; - } - catch (Exception e) - { - Log.Error(e); - Log.Error(response.Content); - throw; - } + var json = JsonConvert.DeserializeObject(response.Content); + + return json; } private T DeserializeXml(string input) diff --git a/PlexRequests.Api/SonarrApi.cs b/PlexRequests.Api/SonarrApi.cs index d70ba2eef..f9d68da31 100644 --- a/PlexRequests.Api/SonarrApi.cs +++ b/PlexRequests.Api/SonarrApi.cs @@ -27,6 +27,9 @@ using System; using System.Collections.Generic; using System.Linq; + +using Newtonsoft.Json; + using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Api.Models.Sonarr; @@ -93,15 +96,19 @@ namespace PlexRequests.Api request.AddHeader("X-Api-Key", apiKey); request.AddJsonBody(options); - var obj = Api.ExecuteJson(request, baseUrl); - - if (obj == null) + SonarrAddSeries result; + try { + result = Api.ExecuteJson(request, baseUrl); + } + catch (JsonSerializationException jse) + { + Log.Error(jse); var error = Api.ExecuteJson(request, baseUrl); - obj = new SonarrAddSeries { ErrorMessage = error.errorMessage }; + result = new SonarrAddSeries { ErrorMessage = error.errorMessage }; } - return obj; + return result; } public SystemStatus SystemStatus(string apiKey, Uri baseUrl) From e2aa4016a8f3fc93c35233492f47e9b12f75ed65 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 29 Mar 2016 14:13:13 +0100 Subject: [PATCH 21/57] Added some tests and fixed the issue where the DB would get created in the wrong place depending on how you launched the application --- PlexRequests.Core/JsonRequestService.cs | 4 + .../PlexAvailabilityCheckerTests.cs | 200 +++++++++++++++++- .../PlexRequests.Services.Tests.csproj | 4 + .../PlexAvailabilityChecker.cs | 19 +- PlexRequests.Store/DbConfiguration.cs | 15 +- PlexRequests.Store/PlexRequests.Store.csproj | 1 + PlexRequests.UI/Bootstrapper.cs | 9 +- PlexRequests.UI/Jobs/PlexTaskFactory.cs | 4 +- 8 files changed, 221 insertions(+), 35 deletions(-) diff --git a/PlexRequests.Core/JsonRequestService.cs b/PlexRequests.Core/JsonRequestService.cs index 1504faed6..64033b50c 100644 --- a/PlexRequests.Core/JsonRequestService.cs +++ b/PlexRequests.Core/JsonRequestService.cs @@ -79,6 +79,10 @@ namespace PlexRequests.Core public RequestedModel Get(int id) { var blob = Repo.Get(id); + if (blob == null) + { + return new RequestedModel(); + } var model = ByteConverterHelper.ReturnObject(blob.Content); return model; } diff --git a/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs b/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs index 8e641181e..d9c3f1881 100644 --- a/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs +++ b/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs @@ -32,12 +32,12 @@ using Moq; using NUnit.Framework; using PlexRequests.Api.Interfaces; -using PlexRequests.Api.Models; using PlexRequests.Api.Models.Plex; using PlexRequests.Core; using PlexRequests.Core.SettingModels; using PlexRequests.Helpers.Exceptions; using PlexRequests.Services.Interfaces; +using PlexRequests.Store; namespace PlexRequests.Services.Tests { @@ -66,7 +66,7 @@ namespace PlexRequests.Services.Tests var requestMock = new Mock(); var plexMock = new Mock(); - var searchResult = new PlexSearch {Video = new List
} + + @if (Model.SearchForMusic) + { + +
+
+ +
+ +
+
+
+
+ +
+
+
+ } + + + + + From 64125cc44c692dbc7a220e3928359f2fc469e65d Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 31 Mar 2016 10:23:17 +0100 Subject: [PATCH 36/57] First attempt at #123 Added a bunch of tracing and also some more error handling --- .../AvailabilityUpdateService.cs | 7 ++- .../PlexAvailabilityChecker.cs | 57 ++++++++++++++++--- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/PlexRequests.Services/AvailabilityUpdateService.cs b/PlexRequests.Services/AvailabilityUpdateService.cs index 0774307e6..19b23bbe0 100644 --- a/PlexRequests.Services/AvailabilityUpdateService.cs +++ b/PlexRequests.Services/AvailabilityUpdateService.cs @@ -48,9 +48,12 @@ namespace PlexRequests.Services { public AvailabilityUpdateService() { + var memCache = new MemoryCacheProvider(); + var dbConfig = new DbConfiguration(new SqliteFactory()); + var repo = new SettingsJsonRepository(dbConfig, memCache); + ConfigurationReader = new ConfigurationReader(); - var repo = new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider()); - Checker = new PlexAvailabilityChecker(new SettingsServiceV2(repo), new SettingsServiceV2(repo), new JsonRequestService(new RequestJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider())), new PlexApi()); + Checker = new PlexAvailabilityChecker(new SettingsServiceV2(repo), new SettingsServiceV2(repo), new JsonRequestService(new RequestJsonRepository(dbConfig, memCache)), new PlexApi()); HostingEnvironment.RegisterObject(this); } diff --git a/PlexRequests.Services/PlexAvailabilityChecker.cs b/PlexRequests.Services/PlexAvailabilityChecker.cs index 915cbda28..e7cf9812e 100644 --- a/PlexRequests.Services/PlexAvailabilityChecker.cs +++ b/PlexRequests.Services/PlexAvailabilityChecker.cs @@ -31,8 +31,10 @@ using System.Linq; using NLog; using PlexRequests.Api.Interfaces; +using PlexRequests.Api.Models.Plex; using PlexRequests.Core; using PlexRequests.Core.SettingModels; +using PlexRequests.Helpers; using PlexRequests.Helpers.Exceptions; using PlexRequests.Services.Interfaces; using PlexRequests.Store; @@ -58,27 +60,66 @@ namespace PlexRequests.Services public void CheckAndUpdateAll(long check) { + Log.Trace("Getting the settings"); var plexSettings = Plex.GetSettings(); var authSettings = Auth.GetSettings(); + Log.Trace("Getting all the requests"); var requests = RequestService.GetAll(); var requestedModels = requests as RequestedModel[] ?? requests.ToArray(); + Log.Trace("Requests Count {0}", requestedModels.Length); + if (!ValidateSettings(plexSettings, authSettings) || !requestedModels.Any()) { + Log.Info("Validation of the settings failed or there is no requests."); return; } var modifiedModel = new List(); foreach (var r in requestedModels) { - var results = PlexApi.SearchContent(authSettings.PlexAuthToken, r.Title, plexSettings.FullUri); - var result = results.Video.FirstOrDefault(x => x.Title == r.Title); - var originalRequest = RequestService.Get(r.Id); + Log.Trace("We are going to see if Plex has the following title: {0}", r.Title); + PlexSearch results; + try + { + results = PlexApi.SearchContent(authSettings.PlexAuthToken, r.Title, plexSettings.FullUri); + } + catch (Exception e) + { + Log.Error("We failed to search Plex for the following request:"); + Log.Error(r.DumpJson()); + Log.Error(e); + break; // Let's finish processing and not crash the process, there is a reason why we cannot connect. + } + + if (results == null) + { + Log.Trace("Could not find any matching result for this title."); + continue; + } + + Log.Trace("Search results from Plex for the following request: {0}", r.Title); + Log.Trace(results.DumpJson()); + + var videoResult = results.Video.FirstOrDefault(x => x.Title == r.Title); + var directoryResult = results.Directory?.Title.Equals(r.Title, StringComparison.CurrentCultureIgnoreCase); + + Log.Trace("The result from Plex where the title matches for the video : {0}", videoResult != null); + Log.Trace("The result from Plex where the title matches for the directory : {0}", directoryResult != null); - originalRequest.Available = result != null; - modifiedModel.Add(originalRequest); + if (videoResult != null || directoryResult != null) + { + r.Available = true; + modifiedModel.Add(r); + continue; + } + + Log.Trace("The result from Plex where the title's match was null, so that means the content is not yet in Plex."); } + Log.Trace("Updating the requests now"); + Log.Trace("Requests that will be updates:"); + Log.Trace(modifiedModel.SelectMany(x => x.Title).DumpJson()); RequestService.BatchUpdate(modifiedModel); } @@ -91,24 +132,26 @@ namespace PlexRequests.Services /// The settings are not configured for Plex or Authentication public bool IsAvailable(string title, string year) { + Log.Trace("Checking if the following {0} {1} is available in Plex", title, year); var plexSettings = Plex.GetSettings(); var authSettings = Auth.GetSettings(); if (!ValidateSettings(plexSettings, authSettings)) { + Log.Warn("The settings are not configured"); throw new ApplicationSettingsException("The settings are not configured for Plex or Authentication"); } var results = PlexApi.SearchContent(authSettings.PlexAuthToken, title, plexSettings.FullUri); if (!string.IsNullOrEmpty(year)) { var result = results.Video?.FirstOrDefault(x => x.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase) && x.Year == year); - var directoryTitle = results.Directory?.Title == title && results.Directory?.Year == year; + var directoryTitle = string.Equals(results.Directory?.Title, title, StringComparison.CurrentCultureIgnoreCase) && results.Directory?.Year == year; return result?.Title != null || directoryTitle; } else { var result = results.Video?.FirstOrDefault(x => x.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase)); - var directoryTitle = results.Directory?.Title == title; + var directoryTitle = string.Equals(results.Directory?.Title, title, StringComparison.CurrentCultureIgnoreCase); return result?.Title != null || directoryTitle; } From d6763bf43503dfd40e635ec30bfe0510ee68576c Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 31 Mar 2016 10:40:54 +0100 Subject: [PATCH 37/57] Added happy path tests for the Checker --- .../PlexAvailabilityCheckerTests.cs | 102 +++++++++++++++++- .../PlexAvailabilityChecker.cs | 10 +- 2 files changed, 104 insertions(+), 8 deletions(-) diff --git a/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs b/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs index d9c3f1881..2fd0f4803 100644 --- a/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs +++ b/PlexRequests.Services.Tests/PlexAvailabilityCheckerTests.cs @@ -284,8 +284,7 @@ namespace PlexRequests.Services.Tests [Test] - [Ignore("Need to work out Plex Directory vs Video objects")] - public void CheckAndUpdateRequestsTest() + public void CheckAndUpdateRequestsThatDoNotExistInPlexTest() { var requests = new List { @@ -315,7 +314,26 @@ namespace PlexRequests.Services.Tests } }; - var search = new PlexSearch { }; + var search = new PlexSearch + { + Video = new List