diff --git a/NzbDrone.6.0.ReSharper b/NzbDrone.6.0.ReSharper
new file mode 100644
index 000000000..c918885f0
--- /dev/null
+++ b/NzbDrone.6.0.ReSharper
@@ -0,0 +1,87 @@
+
+
+
+
+ SOLUTION
+
+
+
+
+
+
+
+ - public
+ - protected
+ - internal
+ - private
+ - new
+ - abstract
+ - virtual
+ - override
+ - sealed
+ - static
+ - readonly
+ - extern
+ - unsafe
+ - volatile
+
+
+
+
+ $object$_On$event$
+ $event$Handler
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $object$_On$event$
+ $event$Handler
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $object$_On$event$
+ $event$Handler
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NzbDrone.Web/Content/style.css b/NzbDrone.Web/Content/style.css
index 7f44c4fa0..8a49c718d 100644
--- a/NzbDrone.Web/Content/style.css
+++ b/NzbDrone.Web/Content/style.css
@@ -190,9 +190,9 @@ hr
/* Config Pages */
.config-section
{
- width: 550px;
+ width: 650px;
+ height: 45px;
display: block;
- padding-bottom: 25px;
}
.config-group
@@ -200,6 +200,15 @@ hr
width: 300px;
display: block;
float: left;
+ height: 20px;
+}
+
+.config-group2
+{
+ width: 300px;
+ display: block;
+ float: right;
+ height: 20px;
}
.config-title
@@ -217,7 +226,11 @@ hr
.config-validation
{
color: Red;
- float: right;
+}
+
+.config-description
+{
+
}
.sub-field
@@ -227,7 +240,15 @@ hr
margin-bottom: 10px;
}
+.config-value
+{
+ float: right;
+}
+.config-checkbox
+{
+ margin-right: 135px;
+}
button, input[type="button"], input[type="submit"], input[type="reset"]
{
diff --git a/NzbDrone.Web/Models/AccountModels.cs b/NzbDrone.Web/Models/AccountModels.cs
deleted file mode 100644
index 98b1d99c2..000000000
--- a/NzbDrone.Web/Models/AccountModels.cs
+++ /dev/null
@@ -1,299 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
-using System.Globalization;
-using System.Web.Security;
-
-namespace NzbDrone.Web.Models
-{
-
- #region Models
-
- [PropertiesMustMatch("NewPassword", "ConfirmPassword",
- ErrorMessage = "The new password and confirmation password do not match.")]
- public class ChangePasswordModel
- {
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Current password")]
- public string OldPassword { get; set; }
-
- [Required]
- [ValidatePasswordLength]
- [DataType(DataType.Password)]
- [DisplayName("New password")]
- public string NewPassword { get; set; }
-
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Confirm new password")]
- public string ConfirmPassword { get; set; }
- }
-
- public class LogOnModel
- {
- [Required]
- [DisplayName("User name")]
- public string UserName { get; set; }
-
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Password")]
- public string Password { get; set; }
-
- [DisplayName("Remember me?")]
- public bool RememberMe { get; set; }
- }
-
- [PropertiesMustMatch("Password", "ConfirmPassword",
- ErrorMessage = "The password and confirmation password do not match.")]
- public class RegisterModel
- {
- [Required]
- [DisplayName("User name")]
- public string UserName { get; set; }
-
- [Required]
- [DataType(DataType.EmailAddress)]
- [DisplayName("Email address")]
- public string Email { get; set; }
-
- [Required]
- [ValidatePasswordLength]
- [DataType(DataType.Password)]
- [DisplayName("Password")]
- public string Password { get; set; }
-
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Confirm password")]
- public string ConfirmPassword { get; set; }
- }
-
- #endregion
-
- #region Services
-
- // The FormsAuthentication type is sealed and contains static members, so it is difficult to
- // unit test code that calls its members. The interface and helper class below demonstrate
- // how to create an abstract wrapper around such a type in order to make the AccountController
- // code unit testable.
-
- public interface IMembershipService
- {
- int MinPasswordLength { get; }
-
- bool ValidateUser(string userName, string password);
- MembershipCreateStatus CreateUser(string userName, string password, string email);
- bool ChangePassword(string userName, string oldPassword, string newPassword);
- }
-
- public class AccountMembershipService : IMembershipService
- {
- private readonly MembershipProvider _provider;
-
- public AccountMembershipService()
- : this(null)
- {
- }
-
- public AccountMembershipService(MembershipProvider provider)
- {
- _provider = provider ?? Membership.Provider;
- }
-
- #region IMembershipService Members
-
- public int MinPasswordLength
- {
- get { return _provider.MinRequiredPasswordLength; }
- }
-
- public bool ValidateUser(string userName, string password)
- {
- if (String.IsNullOrEmpty(userName))
- throw new ArgumentException("Value cannot be null or empty.", "userName");
- if (String.IsNullOrEmpty(password))
- throw new ArgumentException("Value cannot be null or empty.", "password");
-
- return _provider.ValidateUser(userName, password);
- }
-
- public MembershipCreateStatus CreateUser(string userName, string password, string email)
- {
- if (String.IsNullOrEmpty(userName))
- throw new ArgumentException("Value cannot be null or empty.", "userName");
- if (String.IsNullOrEmpty(password))
- throw new ArgumentException("Value cannot be null or empty.", "password");
- if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");
-
- MembershipCreateStatus status;
- _provider.CreateUser(userName, password, email, null, null, true, null, out status);
- return status;
- }
-
- public bool ChangePassword(string userName, string oldPassword, string newPassword)
- {
- if (String.IsNullOrEmpty(userName))
- throw new ArgumentException("Value cannot be null or empty.", "userName");
- if (String.IsNullOrEmpty(oldPassword))
- throw new ArgumentException("Value cannot be null or empty.", "oldPassword");
- if (String.IsNullOrEmpty(newPassword))
- throw new ArgumentException("Value cannot be null or empty.", "newPassword");
-
- // The underlying ChangePassword() will throw an exception rather
- // than return false in certain failure scenarios.
- try
- {
- MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
- return currentUser.ChangePassword(oldPassword, newPassword);
- }
- catch (ArgumentException)
- {
- return false;
- }
- catch (MembershipPasswordException)
- {
- return false;
- }
- }
-
- #endregion
- }
-
- public interface IFormsAuthenticationService
- {
- void SignIn(string userName, bool createPersistentCookie);
- void SignOut();
- }
-
- public class FormsAuthenticationService : IFormsAuthenticationService
- {
- #region IFormsAuthenticationService Members
-
- public void SignIn(string userName, bool createPersistentCookie)
- {
- if (String.IsNullOrEmpty(userName))
- throw new ArgumentException("Value cannot be null or empty.", "userName");
-
- FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
- }
-
- public void SignOut()
- {
- FormsAuthentication.SignOut();
- }
-
- #endregion
- }
-
- #endregion
-
- #region Validation
-
- public static class AccountValidation
- {
- public static string ErrorCodeToString(MembershipCreateStatus createStatus)
- {
- // See http://go.microsoft.com/fwlink/?LinkID=177550 for
- // a full list of status codes.
- switch (createStatus)
- {
- case MembershipCreateStatus.DuplicateUserName:
- return "Username already exists. Please enter a different user name.";
-
- case MembershipCreateStatus.DuplicateEmail:
- return "A username for that e-mail address already exists. Please enter a different e-mail address.";
-
- case MembershipCreateStatus.InvalidPassword:
- return "The password provided is invalid. Please enter a valid password value.";
-
- case MembershipCreateStatus.InvalidEmail:
- return "The e-mail address provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.InvalidAnswer:
- return "The password retrieval answer provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.InvalidQuestion:
- return "The password retrieval question provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.InvalidUserName:
- return "The user name provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.ProviderError:
- return
- "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
-
- case MembershipCreateStatus.UserRejected:
- return
- "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
-
- default:
- return
- "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
- }
- }
- }
-
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
- public sealed class PropertiesMustMatchAttribute : ValidationAttribute
- {
- private const string _defaultErrorMessage = "'{0}' and '{1}' do not match.";
- private readonly object _typeId = new object();
-
- public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
- : base(_defaultErrorMessage)
- {
- OriginalProperty = originalProperty;
- ConfirmProperty = confirmProperty;
- }
-
- public string ConfirmProperty { get; private set; }
- public string OriginalProperty { get; private set; }
-
- public override object TypeId
- {
- get { return _typeId; }
- }
-
- public override string FormatErrorMessage(string name)
- {
- return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
- OriginalProperty, ConfirmProperty);
- }
-
- public override bool IsValid(object value)
- {
- PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
- object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
- object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
- return Equals(originalValue, confirmValue);
- }
- }
-
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
- public sealed class ValidatePasswordLengthAttribute : ValidationAttribute
- {
- private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long.";
- private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;
-
- public ValidatePasswordLengthAttribute()
- : base(_defaultErrorMessage)
- {
- }
-
- public override string FormatErrorMessage(string name)
- {
- return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
- name, _minCharacters);
- }
-
- public override bool IsValid(object value)
- {
- string valueAsString = value as string;
- return (valueAsString != null && valueAsString.Length >= _minCharacters);
- }
- }
-
- #endregion
-}
\ No newline at end of file
diff --git a/NzbDrone.Web/Models/DownloadSettingsModel.cs b/NzbDrone.Web/Models/DownloadSettingsModel.cs
index 675064ed7..f80b33322 100644
--- a/NzbDrone.Web/Models/DownloadSettingsModel.cs
+++ b/NzbDrone.Web/Models/DownloadSettingsModel.cs
@@ -15,56 +15,68 @@ namespace NzbDrone.Web.Models
[Range(15, 120, ErrorMessage = "Must be between 15 and 120 minutes")]
[DataType(DataType.Text)]
[DisplayName("Sync Frequency")]
+ [Description("Specifies how often NzbDrone should check RSS Feeds (Minutes)")]
public int SyncFrequency { get; set; }
[DisplayName("Download Propers")]
+ [Description("Should NzbDrone download proper releases (to replace non-proper files)?")]
public bool DownloadPropers { get; set; }
[Required(ErrorMessage = "Please enter a valid number")]
[DataType(DataType.Text)]
[DisplayName("Retention")]
+ [Description("Your newsgroup provider retention (Days)")]
public int Retention { get; set; }
[Required(ErrorMessage = "Please enter a valid host")]
[DataType(DataType.Text)]
[DisplayName("SABnzbd Host")]
+ [Description("Hostname or IP Address running SABnzbd")]
public String SabHost { get; set; }
[Required(ErrorMessage = "Please enter a valid port")]
[DataType(DataType.Text)]
[DisplayName("SABnzbd Port")]
+ [Description("Port for SABnzbd web interface")]
public int SabPort { get; set; }
[DataType(DataType.Text)]
[DisplayName("SABnzbd API Key")]
+ [Description("API Key for SABNzbd, Found in Config: General")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public String SabApiKey { get; set; }
[DataType(DataType.Text)]
[DisplayName("SABnzbd Username")]
+ [Description("Username for SABnzbd WebUI (Not Required when using APIKey)")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public String SabUsername { get; set; }
[DataType(DataType.Text)]
[DisplayName("SABnzbd Password")]
+ [Description("Password for SABnzbd WebUI (Not required when using APIKey)")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public String SabPassword { get; set; }
[DataType(DataType.Text)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
[DisplayName("SABnzbd TV Category")]
+ [Description("Category to use when sending NZBs to SABnzbd")]
public String SabTvCategory { get; set; }
[Required(ErrorMessage = "Please select a valid priority")]
[DisplayName("SABnzbd Priority")]
+ [Description("Priority to use when sending NZBs to SABnzbd")]
public SabnzbdPriorityType SabTvPriority { get; set; }
[DisplayName("Use Blackhole")]
+ [Description("Whether to use the blackhole directory instead of sending NZB to SABnzbd")]
public bool UseBlackHole { get; set; }
[DataType(DataType.Text)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
[DisplayName("Blackhole Directory")]
+ [Description("Path to the blackhole directory")]
public String BlackholeDirectory { get; set; }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj
index ba5c544b6..3cb296bbf 100644
--- a/NzbDrone.Web/NzbDrone.Web.csproj
+++ b/NzbDrone.Web/NzbDrone.Web.csproj
@@ -227,7 +227,6 @@
-
diff --git a/NzbDrone.Web/Views/Settings/Downloads.cshtml b/NzbDrone.Web/Views/Settings/Downloads.cshtml
index 9dd5a7467..03554016f 100644
--- a/NzbDrone.Web/Views/Settings/Downloads.cshtml
+++ b/NzbDrone.Web/Views/Settings/Downloads.cshtml
@@ -1,4 +1,5 @@
-@model NzbDrone.Web.Models.DownloadSettingsModel
+@using NzbDrone.Web.Helpers;
+@model NzbDrone.Web.Models.DownloadSettingsModel