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