diff --git a/PlexRequests.Core.Tests/AuthenticationSettingsTests.cs b/PlexRequests.Core.Tests/AuthenticationSettingsTests.cs index 784117cfa..3072ab82a 100644 --- a/PlexRequests.Core.Tests/AuthenticationSettingsTests.cs +++ b/PlexRequests.Core.Tests/AuthenticationSettingsTests.cs @@ -1,59 +1,91 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: AuthenticationSettingsTests.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 -using NUnit.Framework; - -using PlexRequests.Core.SettingModels; - -namespace PlexRequests.Core.Tests -{ - [TestFixture] - public class AuthenticationSettingsTests - { - [Test, TestCaseSource(nameof(UserData))] - public void DeniedUserListTest(string users, string[] expected) - { - var model = new AuthenticationSettings { DeniedUsers = users }; - - var result = model.DeniedUserList; - - Assert.That(result.Count, Is.EqualTo(expected.Length)); - for (var i = 0; i < expected.Length; i++) - { - Assert.That(result[i], Is.EqualTo(expected[i])); - } - } - - static readonly object[] UserData = - { - new object[] { "john", new [] {"john"} }, - new object[] { "john , abc ,", new [] {"john", "abc"} }, - new object[] { "john,, cde", new [] {"john", "cde"} }, - new object[] { "john,,, aaa , baaa , ", new [] {"john","aaa","baaa"} }, - new object[] { "john, aaa , baaa , maaa, caaa", new [] {"john","aaa","baaa", "maaa", "caaa"} }, - }; - } +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: AuthenticationSettingsTests.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 +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using PlexRequests.Core.Models; +using PlexRequests.Core.SettingModels; + +namespace PlexRequests.Core.Tests +{ + [TestFixture] + public class NotificationMessageResolverTests + { + [TestCaseSource(nameof(MessageResolver))] + public string Resolve(Dictionary message, Dictionary param) + { + var n = new NotificationMessageResolver(); + var s = new NotificationSettings + { + Message = message, + CustomParamaters = param + }; + + return n.ParseMessage(s, NotificationType.NewRequest); + } + + private static IEnumerable MessageResolver + { + get + { + yield return new TestCaseData( + new Dictionary { { NotificationType.NewRequest, "There has been a new request from {Username}, Title: {Title} for {Type}" } }, + new Dictionary{{"Username", "Jamie" },{"Title", "Finding Dory" },{"Type", "Movie" }}) + .Returns("There has been a new request from Jamie, Title: Finding Dory for Movie") + .SetName("FindingDory"); + + yield return new TestCaseData( + new Dictionary { { NotificationType.NewRequest, string.Empty } }, + new Dictionary()) + .Returns(string.Empty) + .SetName("Empty Message"); + + yield return new TestCaseData( + new Dictionary { { NotificationType.NewRequest, "{{Wowwzer}} Damn}{{son}}}}" } }, + new Dictionary { {"son","HEY!"} }) + .Returns("{{Wowwzer}} Damn}{HEY!}}}") + .SetName("Multiple Curlys"); + + + yield return new TestCaseData( + new Dictionary { { NotificationType.NewRequest, "This is a message with no curlys" } }, + new Dictionary { { "son", "HEY!" } }) + .Returns("This is a message with no curlys") + .SetName("No Curlys"); + + yield return new TestCaseData( + new Dictionary { { NotificationType.NewRequest, new string(')', 5000)} }, + new Dictionary { { "son", "HEY!" } }) + .Returns(new string(')', 5000)) + .SetName("Long String"); + } + } + + } } \ No newline at end of file diff --git a/PlexRequests.Core.Tests/NotificationMessageResolverTests.cs b/PlexRequests.Core.Tests/NotificationMessageResolverTests.cs new file mode 100644 index 000000000..62b03470c --- /dev/null +++ b/PlexRequests.Core.Tests/NotificationMessageResolverTests.cs @@ -0,0 +1,59 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: AuthenticationSettingsTests.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 +using NUnit.Framework; + +using PlexRequests.Core.SettingModels; + +namespace PlexRequests.Core.Tests +{ + [TestFixture] + public class AuthenticationSettingsTests + { + [Test, TestCaseSource(nameof(UserData))] + public void DeniedUserListTest(string users, string[] expected) + { + var model = new AuthenticationSettings { DeniedUsers = users }; + + var result = model.DeniedUserList; + + Assert.That(result.Count, Is.EqualTo(expected.Length)); + for (var i = 0; i < expected.Length; i++) + { + Assert.That(result[i], Is.EqualTo(expected[i])); + } + } + + static readonly object[] UserData = + { + new object[] { "john", new [] {"john"} }, + new object[] { "john , abc ,", new [] {"john", "abc"} }, + new object[] { "john,, cde", new [] {"john", "cde"} }, + new object[] { "john,,, aaa , baaa , ", new [] {"john","aaa","baaa"} }, + new object[] { "john, aaa , baaa , maaa, caaa", new [] {"john","aaa","baaa", "maaa", "caaa"} }, + }; + } +} \ No newline at end of file diff --git a/PlexRequests.Core.Tests/PlexRequests.Core.Tests.csproj b/PlexRequests.Core.Tests/PlexRequests.Core.Tests.csproj index b0d9a25ef..3a456e243 100644 --- a/PlexRequests.Core.Tests/PlexRequests.Core.Tests.csproj +++ b/PlexRequests.Core.Tests/PlexRequests.Core.Tests.csproj @@ -1,107 +1,108 @@ - - - - Debug - AnyCPU - {FCFECD5D-47F6-454D-8692-E27A921BE655} - Library - Properties - PlexRequests.Core.Tests - PlexRequests.Core.Tests - v4.5.2 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll - True - - - ..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll - True - - - ..\packages\AutoFixture.3.40.0\lib\net40\Ploeh.AutoFixture.dll - True - - - - - - - - - - - - - - - - - - - - - - - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581} - PlexRequests.Core - - - {1252336D-42A3-482A-804C-836E60173DFA} - PlexRequests.Helpers - - - - - - - False - - - False - - - False - - - False - - - - - - - + + + + Debug + AnyCPU + {FCFECD5D-47F6-454D-8692-E27A921BE655} + Library + Properties + PlexRequests.Core.Tests + PlexRequests.Core.Tests + v4.5.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll + True + + + ..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll + True + + + ..\packages\AutoFixture.3.40.0\lib\net40\Ploeh.AutoFixture.dll + True + + + + + + + + + + + + + + + + + + + + + + + + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581} + PlexRequests.Core + + + {1252336D-42A3-482A-804C-836E60173DFA} + PlexRequests.Helpers + + + + + + + False + + + False + + + False + + + False + + + + + + + \ No newline at end of file diff --git a/PlexRequests.Services/Notification/NotificationType.cs b/PlexRequests.Core/Models/NotificationType.cs similarity index 94% rename from PlexRequests.Services/Notification/NotificationType.cs rename to PlexRequests.Core/Models/NotificationType.cs index 5e7b32370..a01d153dd 100644 --- a/PlexRequests.Services/Notification/NotificationType.cs +++ b/PlexRequests.Core/Models/NotificationType.cs @@ -1,39 +1,39 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: NotificationType.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.Services.Notification -{ - public enum NotificationType - { - NewRequest, - Issue, - RequestAvailable, - RequestApproved, - AdminNote, - Test, - - } -} +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: NotificationType.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.Core.Models +{ + public enum NotificationType + { + NewRequest, + Issue, + RequestAvailable, + RequestApproved, + AdminNote, + Test, + + } +} diff --git a/PlexRequests.Core/NotificationMessageResolver.cs b/PlexRequests.Core/NotificationMessageResolver.cs new file mode 100644 index 000000000..5e26e9300 --- /dev/null +++ b/PlexRequests.Core/NotificationMessageResolver.cs @@ -0,0 +1,102 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: CustomNotificationService.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 +using System.Collections.Generic; +using System.Linq; + +using PlexRequests.Core.Models; +using PlexRequests.Core.SettingModels; + +namespace PlexRequests.Core +{ + public class NotificationMessageResolver + { + public string ParseMessage(T notification, NotificationType type) where T : NotificationSettings + { + var notificationToParse = notification.Message.FirstOrDefault(x => x.Key == type).Value; + if (string.IsNullOrEmpty(notificationToParse)) + return string.Empty; + + return Resolve(notificationToParse, notification.CustomParamaters); + } + + private string Resolve(string message, Dictionary paramaters) + { + var fields = FindCurlyFields(message); + + + foreach (var f in fields) + { + string outString; + if (paramaters.TryGetValue(f, out outString)) + { + message = message.Replace($"{{{f}}}", outString); + } + } + + return message; + } + + private IEnumerable FindCurlyFields(string message) + { + var insideCurly = false; + var fields = new List(); + var currentWord = string.Empty; + var chars = message.ToCharArray(); + + foreach (var c in chars) + { + if (char.IsWhiteSpace(c)) + { + currentWord = string.Empty; + continue; + } + + if (c == 123) // Start of curly '{' + { + insideCurly = true; + continue; + } + + if (c == 125) // End of curly '}' + { + fields.Add(currentWord); // We have finished the curly, add the word into the list + currentWord = string.Empty; + insideCurly = false; + continue; + } + + if (insideCurly) + { + currentWord += c.ToString(); // Add the character onto the word. + } + + } + + return fields; + } + } +} \ No newline at end of file diff --git a/PlexRequests.Core/PlexRequests.Core.csproj b/PlexRequests.Core/PlexRequests.Core.csproj index 555c02754..964bb6d01 100644 --- a/PlexRequests.Core/PlexRequests.Core.csproj +++ b/PlexRequests.Core/PlexRequests.Core.csproj @@ -67,17 +67,20 @@ + + + diff --git a/PlexRequests.Core/SettingModels/EmailNotificationSettings.cs b/PlexRequests.Core/SettingModels/EmailNotificationSettings.cs index 2e3db9451..c00342789 100644 --- a/PlexRequests.Core/SettingModels/EmailNotificationSettings.cs +++ b/PlexRequests.Core/SettingModels/EmailNotificationSettings.cs @@ -1,40 +1,40 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: EmailNotificationSettings.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.Core.SettingModels -{ - public class EmailNotificationSettings : Settings - { - public string EmailHost { get; set; } - public string EmailPassword { get; set; } - public int EmailPort { get; set; } - public string EmailSender { get; set; } - public string EmailUsername { get; set; } - public bool Enabled { get; set; } - public bool EnableUserEmailNotifications { get; set; } - public string RecipientEmail { get; set; } - } +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: EmailNotificationSettings.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.Core.SettingModels +{ + public class EmailNotificationSettings : NotificationSettings + { + public string EmailHost { get; set; } + public string EmailPassword { get; set; } + public int EmailPort { get; set; } + public string EmailSender { get; set; } + public string EmailUsername { get; set; } + public bool Enabled { get; set; } + public bool EnableUserEmailNotifications { get; set; } + public string RecipientEmail { get; set; } + } } \ No newline at end of file diff --git a/PlexRequests.Core/SettingModels/NotificationSettings.cs b/PlexRequests.Core/SettingModels/NotificationSettings.cs new file mode 100644 index 000000000..0ba781958 --- /dev/null +++ b/PlexRequests.Core/SettingModels/NotificationSettings.cs @@ -0,0 +1,38 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: NotificationSettings.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 +using System.Collections.Generic; + +using PlexRequests.Core.Models; + +namespace PlexRequests.Core.SettingModels +{ + public class NotificationSettings : Settings + { + public Dictionary Message { get; set; } + public Dictionary CustomParamaters { get; set; } + } +} \ No newline at end of file diff --git a/PlexRequests.Core/SettingModels/PushBulletNotificationSettings.cs b/PlexRequests.Core/SettingModels/PushBulletNotificationSettings.cs index 1b3ce26f5..a8cc43ef9 100644 --- a/PlexRequests.Core/SettingModels/PushBulletNotificationSettings.cs +++ b/PlexRequests.Core/SettingModels/PushBulletNotificationSettings.cs @@ -1,9 +1,9 @@ -namespace PlexRequests.Core.SettingModels -{ - public class PushbulletNotificationSettings : Settings - { - public bool Enabled { get; set; } - public string AccessToken { get; set; } - public string DeviceIdentifier { get; set; } - } +namespace PlexRequests.Core.SettingModels +{ + public class PushbulletNotificationSettings : NotificationSettings + { + public bool Enabled { get; set; } + public string AccessToken { get; set; } + public string DeviceIdentifier { get; set; } + } } \ No newline at end of file diff --git a/PlexRequests.Core/SettingModels/PushoverNotificationSettings.cs b/PlexRequests.Core/SettingModels/PushoverNotificationSettings.cs index ac6c4c435..87772ffa2 100644 --- a/PlexRequests.Core/SettingModels/PushoverNotificationSettings.cs +++ b/PlexRequests.Core/SettingModels/PushoverNotificationSettings.cs @@ -1,9 +1,9 @@ -namespace PlexRequests.Core.SettingModels -{ - public class PushoverNotificationSettings : Settings - { - public bool Enabled { get; set; } - public string AccessToken { get; set; } - public string UserToken { get; set; } - } +namespace PlexRequests.Core.SettingModels +{ + public class PushoverNotificationSettings : NotificationSettings + { + public bool Enabled { get; set; } + public string AccessToken { get; set; } + public string UserToken { get; set; } + } } \ No newline at end of file diff --git a/PlexRequests.Core/SettingModels/SlackNotificationSettings.cs b/PlexRequests.Core/SettingModels/SlackNotificationSettings.cs index 2b412ed3e..93562e8a1 100644 --- a/PlexRequests.Core/SettingModels/SlackNotificationSettings.cs +++ b/PlexRequests.Core/SettingModels/SlackNotificationSettings.cs @@ -4,7 +4,7 @@ using Newtonsoft.Json; namespace PlexRequests.Core.SettingModels { - public class SlackNotificationSettings : Settings + public class SlackNotificationSettings : NotificationSettings { public bool Enabled { get; set; } public string WebhookUrl { get; set; } diff --git a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs index 68b8da01b..dfadadd80 100644 --- a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs +++ b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs @@ -33,6 +33,7 @@ using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Api.Models.Plex; using PlexRequests.Core; +using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Helpers; using PlexRequests.Helpers.Analytics; diff --git a/PlexRequests.Services/Notification/EmailMessageNotification.cs b/PlexRequests.Services/Notification/EmailMessageNotification.cs index 77b71e58a..e67e42e5f 100644 --- a/PlexRequests.Services/Notification/EmailMessageNotification.cs +++ b/PlexRequests.Services/Notification/EmailMessageNotification.cs @@ -33,6 +33,7 @@ using MimeKit; using NLog; using PlexRequests.Core; +using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Services.Interfaces; using SmtpClient = MailKit.Net.Smtp.SmtpClient; diff --git a/PlexRequests.Services/Notification/NotificationModel.cs b/PlexRequests.Services/Notification/NotificationModel.cs index e74f90dd4..11ebcbae3 100644 --- a/PlexRequests.Services/Notification/NotificationModel.cs +++ b/PlexRequests.Services/Notification/NotificationModel.cs @@ -27,6 +27,8 @@ using PlexRequests.Store; using System; +using PlexRequests.Core.Models; + namespace PlexRequests.Services.Notification { public class NotificationModel diff --git a/PlexRequests.Services/Notification/PushbulletNotification.cs b/PlexRequests.Services/Notification/PushbulletNotification.cs index f6003bf1d..e2ae3c4c4 100644 --- a/PlexRequests.Services/Notification/PushbulletNotification.cs +++ b/PlexRequests.Services/Notification/PushbulletNotification.cs @@ -31,6 +31,7 @@ using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Core; +using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Services.Interfaces; using PlexRequests.Store; diff --git a/PlexRequests.Services/Notification/PushoverNotification.cs b/PlexRequests.Services/Notification/PushoverNotification.cs index b259a6faa..2adafb11e 100644 --- a/PlexRequests.Services/Notification/PushoverNotification.cs +++ b/PlexRequests.Services/Notification/PushoverNotification.cs @@ -31,6 +31,7 @@ using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Core; +using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Services.Interfaces; using PlexRequests.Store; diff --git a/PlexRequests.Services/Notification/SlackNotification.cs b/PlexRequests.Services/Notification/SlackNotification.cs index 5da0c156a..f8c90d3ca 100644 --- a/PlexRequests.Services/Notification/SlackNotification.cs +++ b/PlexRequests.Services/Notification/SlackNotification.cs @@ -32,6 +32,7 @@ using NLog; using PlexRequests.Api.Interfaces; using PlexRequests.Api.Models.Notifications; using PlexRequests.Core; +using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Services.Interfaces; diff --git a/PlexRequests.Services/PlexRequests.Services.csproj b/PlexRequests.Services/PlexRequests.Services.csproj index bd385cba3..4f50fcac0 100644 --- a/PlexRequests.Services/PlexRequests.Services.csproj +++ b/PlexRequests.Services/PlexRequests.Services.csproj @@ -93,7 +93,6 @@ - diff --git a/PlexRequests.UI/Modules/AdminModule.cs b/PlexRequests.UI/Modules/AdminModule.cs index 7834e120d..ab1b8cb4d 100644 --- a/PlexRequests.UI/Modules/AdminModule.cs +++ b/PlexRequests.UI/Modules/AdminModule.cs @@ -51,6 +51,7 @@ using Nancy.Responses; using PlexRequests.Api; using PlexRequests.Api.Interfaces; using PlexRequests.Core; +using PlexRequests.Core.Models; using PlexRequests.Core.SettingModels; using PlexRequests.Helpers; using PlexRequests.Helpers.Analytics; diff --git a/PlexRequests.UI/Modules/RequestsModule.cs b/PlexRequests.UI/Modules/RequestsModule.cs index 8d73c0bb0..13f557186 100644 --- a/PlexRequests.UI/Modules/RequestsModule.cs +++ b/PlexRequests.UI/Modules/RequestsModule.cs @@ -1,377 +1,379 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: RequestsModule.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 - -using System; -using System.Linq; - -using Nancy; -using Nancy.Responses.Negotiation; -using Nancy.Security; - -using PlexRequests.Core; -using PlexRequests.Core.SettingModels; -using PlexRequests.Services.Interfaces; -using PlexRequests.Services.Notification; -using PlexRequests.Store; -using PlexRequests.UI.Models; -using PlexRequests.Helpers; -using PlexRequests.UI.Helpers; -using System.Collections.Generic; -using PlexRequests.Api.Interfaces; -using System.Threading.Tasks; - -using NLog; - -namespace PlexRequests.UI.Modules -{ - public class RequestsModule : BaseAuthModule - { - public RequestsModule( - IRequestService service, - ISettingsService prSettings, - ISettingsService plex, - INotificationService notify, - ISettingsService sonarrSettings, - ISettingsService sickRageSettings, - ISettingsService cpSettings, - ICouchPotatoApi cpApi, - ISonarrApi sonarrApi, - ISickRageApi sickRageApi, - ICacheProvider cache) : base("requests", prSettings) - { - Service = service; - PrSettings = prSettings; - PlexSettings = plex; - NotificationService = notify; - SonarrSettings = sonarrSettings; - SickRageSettings = sickRageSettings; - CpSettings = cpSettings; - SonarrApi = sonarrApi; - SickRageApi = sickRageApi; - CpApi = cpApi; - Cache = cache; - - Get["/", true] = async (x, ct) => await LoadRequests(); - Get["/movies", true] = async (x, ct) => await GetMovies(); - Get["/tvshows", true] = async (c, ct) => await GetTvShows(); - Get["/albums", true] = async (x, ct) => await GetAlbumRequests(); - Post["/delete", true] = async (x, ct) => await DeleteRequest((int)Request.Form.id); - Post["/reportissue", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null); - Post["/reportissuecomment", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, IssueState.Other, (string)Request.Form.commentArea); - - Post["/clearissues", true] = async (x, ct) => await ClearIssue((int)Request.Form.Id); - - Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); - } - - private static Logger Log = LogManager.GetCurrentClassLogger(); - private IRequestService Service { get; } - private INotificationService NotificationService { get; } - private ISettingsService PrSettings { get; } - private ISettingsService PlexSettings { get; } - private ISettingsService SonarrSettings { get; } - private ISettingsService SickRageSettings { get; } - private ISettingsService CpSettings { get; } - private ISonarrApi SonarrApi { get; } - private ISickRageApi SickRageApi { get; } - private ICouchPotatoApi CpApi { get; } - private ICacheProvider Cache { get; } - - private async Task LoadRequests() - { - var settings = await PrSettings.GetSettingsAsync(); - return View["Index", settings]; - } - - private async Task GetMovies() - { - var settings = PrSettings.GetSettings(); - - var allRequests = await Service.GetAllAsync(); - allRequests = allRequests.Where(x => x.Type == RequestType.Movie); - - var dbMovies = allRequests.ToList(); - - if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) - { - dbMovies = dbMovies.Where(x => x.UserHasRequested(Username)).ToList(); - } - - List qualities = new List(); - - if (IsAdmin) - { - var cpSettings = CpSettings.GetSettings(); - if (cpSettings.Enabled) - { - try - { - var result = await Cache.GetOrSetAsync(CacheKeys.CouchPotatoQualityProfiles, async () => - { - return await Task.Run(() => CpApi.GetProfiles(cpSettings.FullUri, cpSettings.ApiKey)).ConfigureAwait(false); - }); - - qualities = result.list.Select(x => new QualityModel() { Id = x._id, Name = x.label }).ToList(); - - } - catch (Exception e) - { - Log.Info(e); - } - } - } - - var viewModel = dbMovies.Select(movie => new RequestViewModel - { - ProviderId = movie.ProviderId, - Type = movie.Type, - Status = movie.Status, - ImdbId = movie.ImdbId, - Id = movie.Id, - PosterPath = movie.PosterPath, - ReleaseDate = movie.ReleaseDate, - ReleaseDateTicks = movie.ReleaseDate.Ticks, - RequestedDate = movie.RequestedDate, - Released = DateTime.Now > movie.ReleaseDate, - RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(movie.RequestedDate, DateTimeOffset).Ticks, - Approved = movie.Available || movie.Approved, - Title = movie.Title, - Overview = movie.Overview, - RequestedUsers = IsAdmin ? movie.AllUsers.ToArray() : new string[] { }, - ReleaseYear = movie.ReleaseDate.Year.ToString(), - Available = movie.Available, - Admin = IsAdmin, - IssueId = movie.IssueId, - Qualities = qualities.ToArray() - }).ToList(); - - return Response.AsJson(viewModel); - } - - private async Task GetTvShows() - { - var settings = PrSettings.GetSettings(); - - var requests = await Service.GetAllAsync(); - requests = requests.Where(x => x.Type == RequestType.TvShow); - - var dbTv = requests; - - if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) - { - dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); - } - - IEnumerable qualities = new List(); - if (IsAdmin) - { - try - { - var sonarrSettings = SonarrSettings.GetSettings(); - if (sonarrSettings.Enabled) - { - var result = Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async () => - { - return await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri)); - }); - qualities = result.Result.Select(x => new QualityModel() { Id = x.id.ToString(), Name = x.name }).ToList(); - } - else - { - var sickRageSettings = SickRageSettings.GetSettings(); - if (sickRageSettings.Enabled) - { - qualities = sickRageSettings.Qualities.Select(x => new QualityModel() { Id = x.Key, Name = x.Value }).ToList(); - } - } - } - catch (Exception e) - { - Log.Info(e); - } - - } - - var viewModel = dbTv.Select(tv => - { - return new RequestViewModel - { - ProviderId = tv.ProviderId, - Type = tv.Type, - Status = tv.Status, - ImdbId = tv.ImdbId, - Id = tv.Id, - PosterPath = tv.PosterPath, - ReleaseDate = tv.ReleaseDate, - ReleaseDateTicks = tv.ReleaseDate.Ticks, - RequestedDate = tv.RequestedDate, - RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(tv.RequestedDate, DateTimeOffset).Ticks, - Released = DateTime.Now > tv.ReleaseDate, - Approved = tv.Available || tv.Approved, - Title = tv.Title, - Overview = tv.Overview, - RequestedUsers = IsAdmin ? tv.AllUsers.ToArray() : new string[] { }, - ReleaseYear = tv.ReleaseDate.Year.ToString(), - Available = tv.Available, - Admin = IsAdmin, - IssueId = tv.IssueId, - TvSeriesRequestType = tv.SeasonsRequested, - Qualities = qualities.ToArray() - }; - }).ToList(); - - return Response.AsJson(viewModel); - } - - private async Task GetAlbumRequests() - { - var settings = PrSettings.GetSettings(); - var dbAlbum = await Service.GetAllAsync(); - dbAlbum = dbAlbum.Where(x => x.Type == RequestType.Album); - if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) - { - dbAlbum = dbAlbum.Where(x => x.UserHasRequested(Username)); - } - - var viewModel = dbAlbum.Select(album => - { - return new RequestViewModel - { - ProviderId = album.ProviderId, - Type = album.Type, - Status = album.Status, - ImdbId = album.ImdbId, - Id = album.Id, - PosterPath = album.PosterPath, - ReleaseDate = album.ReleaseDate, - ReleaseDateTicks = album.ReleaseDate.Ticks, - RequestedDate = album.RequestedDate, - RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(album.RequestedDate, DateTimeOffset).Ticks, - Released = DateTime.Now > album.ReleaseDate, - Approved = album.Available || album.Approved, - Title = album.Title, - Overview = album.Overview, - RequestedUsers = IsAdmin ? album.AllUsers.ToArray() : new string[] { }, - ReleaseYear = album.ReleaseDate.Year.ToString(), - Available = album.Available, - Admin = IsAdmin, - IssueId = album.IssueId, - TvSeriesRequestType = album.SeasonsRequested, - MusicBrainzId = album.MusicBrainzId, - ArtistName = album.ArtistName - - }; - }).ToList(); - - return Response.AsJson(viewModel); - } - - private async Task DeleteRequest(int requestid) - { - this.RequiresClaims(UserClaims.Admin); - - var currentEntity = await Service.GetAsync(requestid); - await Service.DeleteRequestAsync(currentEntity); - return Response.AsJson(new JsonResponseModel { Result = true }); - } - - /// - /// Reports the issue. - /// Comment can be null if the IssueState != Other - /// - /// The request identifier. - /// The issue. - /// The comment. - /// - private async Task ReportIssue(int requestId, IssueState issue, string comment) - { - var originalRequest = await Service.GetAsync(requestId); - if (originalRequest == null) - { - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" }); - } - originalRequest.Issues = issue; - originalRequest.OtherMessage = !string.IsNullOrEmpty(comment) - ? $"{Username} - {comment}" - : string.Empty; - - - var result = await Service.UpdateRequestAsync(originalRequest); - - var model = new NotificationModel - { - User = Username, - NotificationType = NotificationType.Issue, - Title = originalRequest.Title, - DateTime = DateTime.Now, - Body = issue == IssueState.Other ? comment : issue.ToString().ToCamelCaseWords() - }; - await NotificationService.Publish(model); - - return Response.AsJson(result - ? new JsonResponseModel { Result = true } - : new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" }); - } - - private async Task ClearIssue(int requestId) - { - this.RequiresClaims(UserClaims.Admin); - - var originalRequest = await Service.GetAsync(requestId); - if (originalRequest == null) - { - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to clear it!" }); - } - originalRequest.Issues = IssueState.None; - originalRequest.OtherMessage = string.Empty; - - var result = await Service.UpdateRequestAsync(originalRequest); - return Response.AsJson(result - ? new JsonResponseModel { Result = true } - : new JsonResponseModel { Result = false, Message = "Could not clear issue, please try again or check the logs" }); - } - - private async Task ChangeRequestAvailability(int requestId, bool available) - { - this.RequiresClaims(UserClaims.Admin); - var originalRequest = await Service.GetAsync(requestId); - if (originalRequest == null) - { - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to change the availability!" }); - } - - originalRequest.Available = available; - - var result = await Service.UpdateRequestAsync(originalRequest); - return Response.AsJson(result - ? new { Result = true, Available = available, Message = string.Empty } - : new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" }); - } - - - } -} +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: RequestsModule.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 + +using System; +using System.Linq; + +using Nancy; +using Nancy.Responses.Negotiation; +using Nancy.Security; + +using PlexRequests.Core; +using PlexRequests.Core.SettingModels; +using PlexRequests.Services.Interfaces; +using PlexRequests.Services.Notification; +using PlexRequests.Store; +using PlexRequests.UI.Models; +using PlexRequests.Helpers; +using PlexRequests.UI.Helpers; +using System.Collections.Generic; +using PlexRequests.Api.Interfaces; +using System.Threading.Tasks; + +using NLog; + +using PlexRequests.Core.Models; + +namespace PlexRequests.UI.Modules +{ + public class RequestsModule : BaseAuthModule + { + public RequestsModule( + IRequestService service, + ISettingsService prSettings, + ISettingsService plex, + INotificationService notify, + ISettingsService sonarrSettings, + ISettingsService sickRageSettings, + ISettingsService cpSettings, + ICouchPotatoApi cpApi, + ISonarrApi sonarrApi, + ISickRageApi sickRageApi, + ICacheProvider cache) : base("requests", prSettings) + { + Service = service; + PrSettings = prSettings; + PlexSettings = plex; + NotificationService = notify; + SonarrSettings = sonarrSettings; + SickRageSettings = sickRageSettings; + CpSettings = cpSettings; + SonarrApi = sonarrApi; + SickRageApi = sickRageApi; + CpApi = cpApi; + Cache = cache; + + Get["/", true] = async (x, ct) => await LoadRequests(); + Get["/movies", true] = async (x, ct) => await GetMovies(); + Get["/tvshows", true] = async (c, ct) => await GetTvShows(); + Get["/albums", true] = async (x, ct) => await GetAlbumRequests(); + Post["/delete", true] = async (x, ct) => await DeleteRequest((int)Request.Form.id); + Post["/reportissue", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null); + Post["/reportissuecomment", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, IssueState.Other, (string)Request.Form.commentArea); + + Post["/clearissues", true] = async (x, ct) => await ClearIssue((int)Request.Form.Id); + + Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); + } + + private static Logger Log = LogManager.GetCurrentClassLogger(); + private IRequestService Service { get; } + private INotificationService NotificationService { get; } + private ISettingsService PrSettings { get; } + private ISettingsService PlexSettings { get; } + private ISettingsService SonarrSettings { get; } + private ISettingsService SickRageSettings { get; } + private ISettingsService CpSettings { get; } + private ISonarrApi SonarrApi { get; } + private ISickRageApi SickRageApi { get; } + private ICouchPotatoApi CpApi { get; } + private ICacheProvider Cache { get; } + + private async Task LoadRequests() + { + var settings = await PrSettings.GetSettingsAsync(); + return View["Index", settings]; + } + + private async Task GetMovies() + { + var settings = PrSettings.GetSettings(); + + var allRequests = await Service.GetAllAsync(); + allRequests = allRequests.Where(x => x.Type == RequestType.Movie); + + var dbMovies = allRequests.ToList(); + + if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) + { + dbMovies = dbMovies.Where(x => x.UserHasRequested(Username)).ToList(); + } + + List qualities = new List(); + + if (IsAdmin) + { + var cpSettings = CpSettings.GetSettings(); + if (cpSettings.Enabled) + { + try + { + var result = await Cache.GetOrSetAsync(CacheKeys.CouchPotatoQualityProfiles, async () => + { + return await Task.Run(() => CpApi.GetProfiles(cpSettings.FullUri, cpSettings.ApiKey)).ConfigureAwait(false); + }); + + qualities = result.list.Select(x => new QualityModel() { Id = x._id, Name = x.label }).ToList(); + + } + catch (Exception e) + { + Log.Info(e); + } + } + } + + var viewModel = dbMovies.Select(movie => new RequestViewModel + { + ProviderId = movie.ProviderId, + Type = movie.Type, + Status = movie.Status, + ImdbId = movie.ImdbId, + Id = movie.Id, + PosterPath = movie.PosterPath, + ReleaseDate = movie.ReleaseDate, + ReleaseDateTicks = movie.ReleaseDate.Ticks, + RequestedDate = movie.RequestedDate, + Released = DateTime.Now > movie.ReleaseDate, + RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(movie.RequestedDate, DateTimeOffset).Ticks, + Approved = movie.Available || movie.Approved, + Title = movie.Title, + Overview = movie.Overview, + RequestedUsers = IsAdmin ? movie.AllUsers.ToArray() : new string[] { }, + ReleaseYear = movie.ReleaseDate.Year.ToString(), + Available = movie.Available, + Admin = IsAdmin, + IssueId = movie.IssueId, + Qualities = qualities.ToArray() + }).ToList(); + + return Response.AsJson(viewModel); + } + + private async Task GetTvShows() + { + var settings = PrSettings.GetSettings(); + + var requests = await Service.GetAllAsync(); + requests = requests.Where(x => x.Type == RequestType.TvShow); + + var dbTv = requests; + + if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) + { + dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); + } + + IEnumerable qualities = new List(); + if (IsAdmin) + { + try + { + var sonarrSettings = SonarrSettings.GetSettings(); + if (sonarrSettings.Enabled) + { + var result = Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async () => + { + return await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri)); + }); + qualities = result.Result.Select(x => new QualityModel() { Id = x.id.ToString(), Name = x.name }).ToList(); + } + else + { + var sickRageSettings = SickRageSettings.GetSettings(); + if (sickRageSettings.Enabled) + { + qualities = sickRageSettings.Qualities.Select(x => new QualityModel() { Id = x.Key, Name = x.Value }).ToList(); + } + } + } + catch (Exception e) + { + Log.Info(e); + } + + } + + var viewModel = dbTv.Select(tv => + { + return new RequestViewModel + { + ProviderId = tv.ProviderId, + Type = tv.Type, + Status = tv.Status, + ImdbId = tv.ImdbId, + Id = tv.Id, + PosterPath = tv.PosterPath, + ReleaseDate = tv.ReleaseDate, + ReleaseDateTicks = tv.ReleaseDate.Ticks, + RequestedDate = tv.RequestedDate, + RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(tv.RequestedDate, DateTimeOffset).Ticks, + Released = DateTime.Now > tv.ReleaseDate, + Approved = tv.Available || tv.Approved, + Title = tv.Title, + Overview = tv.Overview, + RequestedUsers = IsAdmin ? tv.AllUsers.ToArray() : new string[] { }, + ReleaseYear = tv.ReleaseDate.Year.ToString(), + Available = tv.Available, + Admin = IsAdmin, + IssueId = tv.IssueId, + TvSeriesRequestType = tv.SeasonsRequested, + Qualities = qualities.ToArray() + }; + }).ToList(); + + return Response.AsJson(viewModel); + } + + private async Task GetAlbumRequests() + { + var settings = PrSettings.GetSettings(); + var dbAlbum = await Service.GetAllAsync(); + dbAlbum = dbAlbum.Where(x => x.Type == RequestType.Album); + if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) + { + dbAlbum = dbAlbum.Where(x => x.UserHasRequested(Username)); + } + + var viewModel = dbAlbum.Select(album => + { + return new RequestViewModel + { + ProviderId = album.ProviderId, + Type = album.Type, + Status = album.Status, + ImdbId = album.ImdbId, + Id = album.Id, + PosterPath = album.PosterPath, + ReleaseDate = album.ReleaseDate, + ReleaseDateTicks = album.ReleaseDate.Ticks, + RequestedDate = album.RequestedDate, + RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(album.RequestedDate, DateTimeOffset).Ticks, + Released = DateTime.Now > album.ReleaseDate, + Approved = album.Available || album.Approved, + Title = album.Title, + Overview = album.Overview, + RequestedUsers = IsAdmin ? album.AllUsers.ToArray() : new string[] { }, + ReleaseYear = album.ReleaseDate.Year.ToString(), + Available = album.Available, + Admin = IsAdmin, + IssueId = album.IssueId, + TvSeriesRequestType = album.SeasonsRequested, + MusicBrainzId = album.MusicBrainzId, + ArtistName = album.ArtistName + + }; + }).ToList(); + + return Response.AsJson(viewModel); + } + + private async Task DeleteRequest(int requestid) + { + this.RequiresClaims(UserClaims.Admin); + + var currentEntity = await Service.GetAsync(requestid); + await Service.DeleteRequestAsync(currentEntity); + return Response.AsJson(new JsonResponseModel { Result = true }); + } + + /// + /// Reports the issue. + /// Comment can be null if the IssueState != Other + /// + /// The request identifier. + /// The issue. + /// The comment. + /// + private async Task ReportIssue(int requestId, IssueState issue, string comment) + { + var originalRequest = await Service.GetAsync(requestId); + if (originalRequest == null) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" }); + } + originalRequest.Issues = issue; + originalRequest.OtherMessage = !string.IsNullOrEmpty(comment) + ? $"{Username} - {comment}" + : string.Empty; + + + var result = await Service.UpdateRequestAsync(originalRequest); + + var model = new NotificationModel + { + User = Username, + NotificationType = NotificationType.Issue, + Title = originalRequest.Title, + DateTime = DateTime.Now, + Body = issue == IssueState.Other ? comment : issue.ToString().ToCamelCaseWords() + }; + await NotificationService.Publish(model); + + return Response.AsJson(result + ? new JsonResponseModel { Result = true } + : new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" }); + } + + private async Task ClearIssue(int requestId) + { + this.RequiresClaims(UserClaims.Admin); + + var originalRequest = await Service.GetAsync(requestId); + if (originalRequest == null) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to clear it!" }); + } + originalRequest.Issues = IssueState.None; + originalRequest.OtherMessage = string.Empty; + + var result = await Service.UpdateRequestAsync(originalRequest); + return Response.AsJson(result + ? new JsonResponseModel { Result = true } + : new JsonResponseModel { Result = false, Message = "Could not clear issue, please try again or check the logs" }); + } + + private async Task ChangeRequestAvailability(int requestId, bool available) + { + this.RequiresClaims(UserClaims.Admin); + var originalRequest = await Service.GetAsync(requestId); + if (originalRequest == null) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to change the availability!" }); + } + + originalRequest.Available = available; + + var result = await Service.UpdateRequestAsync(originalRequest); + return Response.AsJson(result + ? new { Result = true, Available = available, Message = string.Empty } + : new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" }); + } + + + } +}