Added SMTP settings editing to the UI.

Added testing of SMTP settings to the settings page.
Cleaned up some extraneous lines of JS and HTML.
This commit is contained in:
Mark McDowall 2011-10-26 22:46:54 -07:00
parent 9957aef811
commit 2c93a27962
13 changed files with 368 additions and 107 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using NLog;
@ -21,8 +22,6 @@ namespace NzbDrone.Core.Providers
}
public virtual bool SendEmail(string subject, string body, bool htmlBody = false)
{
try
{
//Create the Email message
var email = new MailMessage();
@ -45,14 +44,67 @@ namespace NzbDrone.Core.Providers
//Html Body
email.IsBodyHtml = htmlBody;
//Handle credentials
var username = _configProvider.SmtpUsername;
var password = _configProvider.SmtpPassword;
NetworkCredential credentials = null;
if (!String.IsNullOrWhiteSpace(username))
credentials = new NetworkCredential(username, password);
//Send the email
return Send(email, _configProvider.SmtpServer, _configProvider.SmtpPort, _configProvider.SmtpUseSsl, credentials);
}
public virtual bool SendTestEmail(string server, int port, bool ssl, string username, string password, string fromAddress, string toAddresses)
{
var subject = "NzbDrone SMTP Test Notification";
var body = "This is a test email from NzbDrone, if you received this message you properly configured your SMTP settings! (Now save them!)";
//Create the Email message
var email = new MailMessage();
//Set the addresses
email.From = new MailAddress(fromAddress);
//Allow multiple to addresses (split on each comma)
foreach (var toAddress in toAddresses.Split(','))
{
email.To.Add(toAddress.Trim());
}
//Set the Subject
email.Subject = subject;
//Set the Body
email.Body = body;
//Html Body
email.IsBodyHtml = false;
//Handle credentials
NetworkCredential credentials = null;
if (!String.IsNullOrWhiteSpace(username))
credentials = new NetworkCredential(username, password);
//Send the email
return Send(email, _configProvider.SmtpServer, _configProvider.SmtpPort, _configProvider.SmtpUseSsl, credentials);
}
public virtual bool Send(MailMessage email, string server, int port, bool ssl, NetworkCredential credentials)
{
try
{
//Create the SMTP connection
var smtp = new SmtpClient(_configProvider.SmtpServer, _configProvider.SmtpPort);
var smtp = new SmtpClient(server, port);
//Enable SSL
smtp.EnableSsl = true;
smtp.EnableSsl = ssl;
//Credentials
smtp.Credentials = new System.Net.NetworkCredential(_configProvider.SmtpUsername, _configProvider.SmtpPassword);
smtp.Credentials = credentials;
//Send the email
smtp.Send(email);
@ -64,9 +116,8 @@ namespace NzbDrone.Core.Providers
{
Logger.Error("There was an error sending an email.");
Logger.TraceException(ex.Message, ex);
}
return false;
}
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Jobs;
@ -13,11 +14,16 @@ namespace NzbDrone.Web.Controllers
{
private readonly JobProvider _jobProvider;
private readonly SabProvider _sabProvider;
private readonly SmtpProvider _smtpProvider;
public CommandController(JobProvider jobProvider, SabProvider sabProvider)
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public CommandController(JobProvider jobProvider, SabProvider sabProvider,
SmtpProvider smtpProvider)
{
_jobProvider = jobProvider;
_sabProvider = sabProvider;
_smtpProvider = smtpProvider;
}
public JsonResult RssSync()
@ -58,9 +64,19 @@ namespace NzbDrone.Web.Controllers
catch (Exception ex)
{
//Todo: Log the error
throw;
}
Logger.Warn("Unable to get Categories from SABnzbd");
Logger.DebugException(ex.Message, ex);
return Json(new NotificationResult { Title = "Failed", Text = "Unable to get SABnzbd Categories", NotificationType = NotificationType.Error });
}
}
[HttpPost]
public JsonResult SendTestEmail(string server, int port, bool ssl, string username, string password, string fromAddress, string toAddresses)
{
if (_smtpProvider.SendTestEmail(server, port, ssl, username, password, fromAddress, toAddresses))
return Json(new NotificationResult { Title = "Successfully sent test email." });
return Json(new NotificationResult { Title = "Failed", Text = "Unable to send Email, please check your settings", NotificationType = NotificationType.Error });
}
}
}

View File

@ -160,7 +160,17 @@ namespace NzbDrone.Web.Controllers
XbmcCleanLibrary = _configProvider.XbmcCleanLibrary,
XbmcHosts = _configProvider.XbmcHosts,
XbmcUsername = _configProvider.XbmcUsername,
XbmcPassword = _configProvider.XbmcPassword
XbmcPassword = _configProvider.XbmcPassword,
SmtpEnabled = _externalNotificationProvider.GetSettings(typeof(Smtp)).Enable,
SmtpNotifyOnGrab = _configProvider.SmtpNotifyOnGrab,
SmtpNotifyOnDownload = _configProvider.SmtpNotifyOnGrab,
SmtpServer = _configProvider.SmtpServer,
SmtpPort = _configProvider.SmtpPort,
SmtpUseSsl = _configProvider.SmtpUseSsl,
SmtpUsername = _configProvider.SmtpUsername,
SmtpPassword = _configProvider.SmtpPassword,
SmtpFromAddress = _configProvider.SmtpFromAddress,
SmtpToAddresses = _configProvider.SmtpToAddresses
};
return View(model);
@ -433,6 +443,21 @@ namespace NzbDrone.Web.Controllers
_configProvider.XbmcUsername = data.XbmcUsername;
_configProvider.XbmcPassword = data.XbmcPassword;
//SMTP
var smtpSettings = _externalNotificationProvider.GetSettings(typeof (Smtp));
smtpSettings.Enable = data.SmtpEnabled;
_externalNotificationProvider.SaveSettings(smtpSettings);
_configProvider.SmtpNotifyOnGrab = data.SmtpNotifyOnGrab;
_configProvider.SmtpNotifyOnGrab = data.SmtpNotifyOnDownload;
_configProvider.SmtpServer = data.SmtpServer;
_configProvider.SmtpPort = data.SmtpPort;
_configProvider.SmtpUseSsl = data.SmtpUseSsl;
_configProvider.SmtpUsername = data.SmtpUsername;
_configProvider.SmtpPassword = data.SmtpPassword;
_configProvider.SmtpFromAddress = data.SmtpFromAddress;
_configProvider.SmtpToAddresses = data.SmtpToAddresses;
return GetSuccessResult();
}

View File

@ -5,6 +5,7 @@ namespace NzbDrone.Web.Models
{
public class NotificationSettingsModel
{
//XBMC
[DisplayName("Enabled")]
[Description("Enable notifications for XBMC?")]
public bool XbmcEnabled { get; set; }
@ -42,5 +43,59 @@ namespace NzbDrone.Web.Models
[Description("XBMC webserver password")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string XbmcPassword { get; set; }
//SMTP
[DisplayName("Enabled")]
[Description("Enable SMTP notifications?")]
public bool SmtpEnabled { get; set; }
[DisplayName("Notify on Grab")]
[Description("Send notification when episode is sent to SABnzbd?")]
public bool SmtpNotifyOnGrab { get; set; }
[DisplayName("Notify on Download")]
[Description("Send notification when episode is downloaded?")]
public bool SmtpNotifyOnDownload { get; set; }
[DataType(DataType.Text)]
[DisplayName("Server")]
[Description("SMTP Server Hostname")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SmtpServer{ get; set; }
[DataType(DataType.Text)]
[DisplayName("Port")]
[Description("SMTP Server Port")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public int SmtpPort { get; set; }
[DisplayName("SSL")]
[Description("Does the SMTP Server use SSL?")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public bool SmtpUseSsl { get; set; }
[DataType(DataType.Text)]
[DisplayName("Username")]
[Description("SMTP Server authentication username")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SmtpUsername { get; set; }
[DataType(DataType.Text)]
[DisplayName("Password")]
[Description("SMTP Server authentication password")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SmtpPassword { get; set; }
[DataType(DataType.Text)]
[DisplayName("Send From Address")]
[Description("Sender Email address")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SmtpFromAddress { get; set; }
[DataType(DataType.Text)]
[DisplayName("Send To Addresses")]
[Description("Comma separated list of addresses to email")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SmtpToAddresses { get; set; }
}
}

View File

@ -932,6 +932,12 @@
<ItemGroup>
<Content Include="Views\Shared\LocalSearch.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Settings\Xbmc.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Settings\Smtp.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -1,23 +1,8 @@
$(document).ready(function () {
var options = {
target: '#result',
//beforeSubmit: showRequest,
//success: showResponse,
type: 'post',
resetForm: false
};
$('#form').ajaxForm(options);
$('#save_button').removeAttr('disabled');
});
function showRequest(formData, jqForm, options) {
$("#result").empty().html('Saving...');
$("#form :input").attr("disabled", true);
$('#saveAjax').show();
}
function showResponse(responseText, statusText, xhr, $form) {
$("#result").empty().html(responseText);
$("#form :input").attr("disabled", false);
$('#saveAjax').hide();
}

View File

@ -92,7 +92,7 @@
<button type="submit" id="save_button" disabled="disabled">Save</button>
}
</div>
<div id="result" class="hiddenResult"></div>
}
@section Scripts{
<script src="/Scripts/settingsForm.js" type="text/javascript"></script>

View File

@ -129,8 +129,6 @@
}
</div>
<div id="result" class="hiddenResult"></div>
}
@section Scripts{

View File

@ -10,7 +10,7 @@
width: 560px;
border:solid 2px #CCCCCD;
padding: 5px;
margin-bottom: 10px;
margin-left: -8px;
}
.notifier h4
@ -29,6 +29,11 @@
border-bottom:solid 1px #CCCCCD;
padding-bottom:10px;
}
#save_button
{
margin-top: 10px;
}
</style>
}
@ -47,58 +52,30 @@
<h1>Notifications</h1>
<p></p>
<div id="xbmc" class="notifier clearfix">
<h4>XBMC</h4>
<div class="notifierLine"></div>
<label class="labelClass">@Html.LabelFor(m => m.XbmcEnabled)
<span class="small">@Html.DescriptionFor(m => m.XbmcEnabled)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcEnabled, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcNotifyOnGrab)
<span class="small">@Html.DescriptionFor(m => m.XbmcNotifyOnGrab)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcNotifyOnGrab, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcNotifyOnDownload)
<span class="small">@Html.DescriptionFor(m => m.XbmcNotifyOnDownload)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcNotifyOnDownload, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcUpdateLibrary)
<span class="small">@Html.DescriptionFor(m => m.XbmcUpdateLibrary)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcUpdateLibrary, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcCleanLibrary)
<span class="small">@Html.DescriptionFor(m => m.XbmcCleanLibrary)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcCleanLibrary, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcHosts)
<span class="small">@Html.DescriptionFor(m => m.XbmcHosts)</span>
</label>
@Html.TextBoxFor(m => m.XbmcHosts, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcUsername)
<span class="small">@Html.DescriptionFor(m => m.XbmcUsername)</span>
</label>
@Html.TextBoxFor(m => m.XbmcUsername, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcPassword)
<span class="small">@Html.DescriptionFor(m => m.XbmcPassword)</span>
</label>
@Html.TextBoxFor(m => m.XbmcPassword, new { @class = "inputClass" })
<div id="tabs">
<ul>
<li><a href="#tabs-xbmc">XBMC</a></li>
<li><a href="#tabs-smtp">SMTP</a></li>
</ul>
<div id="tabs-xbmc">
@{Html.RenderPartial("Xbmc", Model);}
</div>
<div id="tabs-smtp">
@{Html.RenderPartial("Smtp", Model);}
</div>
</div>
<button type="submit" id="save_button" disabled="disabled">Save</button>
}
</div>
<div id="result" class="hiddenResult"></div>
}
@section Scripts{
<script src="/Scripts/settingsForm.js" type="text/javascript"></script>
<script>
$(function () {
$("#tabs").tabs();
});
</script>
}

View File

@ -88,8 +88,6 @@ Settings
</div>
}
</div>
<div id="result" class="hiddenResult">
</div>
}
@section Scripts{
<script src="../../Scripts/Plugins/MicrosoftAjax.js" type="text/javascript"></script>

View File

@ -0,0 +1,103 @@
@using NzbDrone.Web.Helpers
@model NzbDrone.Web.Models.NotificationSettingsModel
@{
Layout = null;
}
<div id="xbmc" class="notifier clearfix">
<label class="labelClass">@Html.LabelFor(m => m.SmtpEnabled)
<span class="small">@Html.DescriptionFor(m => m.SmtpEnabled)</span>
</label>
@Html.CheckBoxFor(m => m.SmtpEnabled, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpNotifyOnGrab)
<span class="small">@Html.DescriptionFor(m => m.SmtpNotifyOnGrab)</span>
</label>
@Html.CheckBoxFor(m => m.SmtpNotifyOnGrab, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpNotifyOnDownload)
<span class="small">@Html.DescriptionFor(m => m.SmtpNotifyOnDownload)</span>
</label>
@Html.CheckBoxFor(m => m.SmtpNotifyOnDownload, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpServer)
<span class="small">@Html.DescriptionFor(m => m.SmtpServer)</span>
</label>
@Html.TextBoxFor(m => m.SmtpServer, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpPort)
<span class="small">@Html.DescriptionFor(m => m.SmtpPort)</span>
</label>
@Html.TextBoxFor(m => m.SmtpPort, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpUseSsl)
<span class="small">@Html.DescriptionFor(m => m.SmtpUseSsl)</span>
</label>
@Html.CheckBoxFor(m => m.SmtpUseSsl, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpUsername)
<span class="small">@Html.DescriptionFor(m => m.SmtpUsername)</span>
</label>
@Html.TextBoxFor(m => m.SmtpUsername, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpPassword)
<span class="small">@Html.DescriptionFor(m => m.SmtpPassword)</span>
</label>
@Html.TextBoxFor(m => m.SmtpPassword, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpFromAddress)
<span class="small">@Html.DescriptionFor(m => m.SmtpFromAddress)</span>
</label>
@Html.TextBoxFor(m => m.SmtpFromAddress, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.SmtpToAddresses)
<span class="small">@Html.DescriptionFor(m => m.SmtpToAddresses)</span>
</label>
@Html.TextBoxFor(m => m.SmtpToAddresses, new { @class = "inputClass" })
</div>
<input type="button" onclick="testSmtpSettings();" value="Test SMTP" id="smtpTest"/>
@*Move this somewhere better*@
<style>
#smtpTest
{
margin-top: 10px;
margin-bottom: 10px;
margin-left: 220px;
}
</style>
<script type="text/javascript">
function testSmtpSettings() {
//Get the variables
var server = $('#SmtpServer').val();
var port = $('#SmtpPort').val();
var ssl = $('#SmtpUseSsl').val();
var username = $('#SmtpUsername').val();
var password = $('#SmtpPassword').val();
var fromAddress = $('#SmtpFromAddress').val();
var toAddresses = $('#SmtpToAddresses').val();
//Send the data!
$.ajax({
type: "POST",
url: '../Command/SendTestEmail',
data: jQuery.param({
server: server,
port: port,
ssl: ssl,
username: username,
password: password,
fromAddress: fromAddress,
toAddresses: toAddresses
}),
error: function (req, status, error) {
alert("Sorry! We could send a test email at this time. " + error);
}
});
return false;
}
</script>

View File

@ -40,7 +40,6 @@
<button type="submit" id="save_button" disabled="disabled">Save</button>
}
</div>
<div id="result" class="hiddenResult"></div>
}
@section Scripts{
<script src="/Scripts/settingsForm.js" type="text/javascript"></script>

View File

@ -0,0 +1,48 @@
@using NzbDrone.Web.Helpers
@model NzbDrone.Web.Models.NotificationSettingsModel
@{
Layout = null;
}
<div id="xbmc" class="notifier clearfix">
<label class="labelClass">@Html.LabelFor(m => m.XbmcEnabled)
<span class="small">@Html.DescriptionFor(m => m.XbmcEnabled)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcEnabled, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcNotifyOnGrab)
<span class="small">@Html.DescriptionFor(m => m.XbmcNotifyOnGrab)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcNotifyOnGrab, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcNotifyOnDownload)
<span class="small">@Html.DescriptionFor(m => m.XbmcNotifyOnDownload)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcNotifyOnDownload, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcUpdateLibrary)
<span class="small">@Html.DescriptionFor(m => m.XbmcUpdateLibrary)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcUpdateLibrary, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcCleanLibrary)
<span class="small">@Html.DescriptionFor(m => m.XbmcCleanLibrary)</span>
</label>
@Html.CheckBoxFor(m => m.XbmcCleanLibrary, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcHosts)
<span class="small">@Html.DescriptionFor(m => m.XbmcHosts)</span>
</label>
@Html.TextBoxFor(m => m.XbmcHosts, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcUsername)
<span class="small">@Html.DescriptionFor(m => m.XbmcUsername)</span>
</label>
@Html.TextBoxFor(m => m.XbmcUsername, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.XbmcPassword)
<span class="small">@Html.DescriptionFor(m => m.XbmcPassword)</span>
</label>
@Html.TextBoxFor(m => m.XbmcPassword, new { @class = "inputClass" })
</div>