Initial
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class ActionLogAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext filterContext)
|
||||
{
|
||||
if (filterContext != null)
|
||||
{
|
||||
string controller = filterContext.RouteData.Values["controller"].ToString();
|
||||
string action = filterContext.RouteData.Values["action"].ToString();
|
||||
string loggerName = string.Format("{0}Controller.{1}", controller, action);
|
||||
string @params = string.Join(", ", filterContext.ActionParameters.Select(i => i.Key + ": " + i.Value));
|
||||
|
||||
string hostAddress = "UserHostAddress: " + filterContext.HttpContext.Request.UserHostAddress;
|
||||
|
||||
log4net.LogManager.GetLogger(loggerName).Info(hostAddress + ", " + @params);
|
||||
}
|
||||
base.OnActionExecuting(filterContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public static class Algorithms
|
||||
{
|
||||
public static double Similarity<T>(IEnumerable<T> x, IEnumerable<T> y)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
return 1.0 - (double)EditDistance(x, y) / Math.Max(x.Count(), y.Count());
|
||||
}
|
||||
|
||||
/// <SUMMARY>Computes the Levenshtein Edit Distance between two enumerables.</SUMMARY>
|
||||
/// <TYPEPARAM name="T">The type of the items in the enumerables.</TYPEPARAM>
|
||||
/// <PARAM name="x">The first enumerable.</PARAM>
|
||||
/// <PARAM name="y">The second enumerable.</PARAM>
|
||||
/// <RETURNS>The edit distance.</RETURNS>
|
||||
/// <remarks>http://blogs.msdn.com/b/toub/archive/2006/05/05/590814.aspx</remarks>
|
||||
public static int EditDistance<T>(IEnumerable<T> x, IEnumerable<T> y)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
// Validate parameters
|
||||
if (x == null) throw new ArgumentNullException("x");
|
||||
if (y == null) throw new ArgumentNullException("y");
|
||||
|
||||
// Convert the parameters into IList instances
|
||||
// in order to obtain indexing capabilities
|
||||
var first = x as IList<T> ?? new List<T>(x);
|
||||
var second = y as IList<T> ?? new List<T>(y);
|
||||
|
||||
// Get the length of both. If either is 0, return
|
||||
// the length of the other, since that number of insertions
|
||||
// would be required.
|
||||
int n = first.Count, m = second.Count;
|
||||
if (n == 0) return m;
|
||||
if (m == 0) return n;
|
||||
|
||||
// Rather than maintain an entire matrix (which would require O(n*m) space),
|
||||
// just store the current row and the next row, each of which has a length m+1,
|
||||
// so just O(m) space. Initialize the current row.
|
||||
int curRow = 0, nextRow = 1;
|
||||
var rows = new[] {new int[m + 1], new int[m + 1]};
|
||||
for (var j = 0; j <= m; ++j) rows[curRow][j] = j;
|
||||
|
||||
// For each virtual row (since we only have physical storage for two)
|
||||
for (var i = 1; i <= n; ++i)
|
||||
{
|
||||
// Fill in the values in the row
|
||||
rows[nextRow][0] = i;
|
||||
for (var j = 1; j <= m; ++j)
|
||||
{
|
||||
int dist1 = rows[curRow][j] + 1;
|
||||
int dist2 = rows[nextRow][j - 1] + 1;
|
||||
int dist3 = rows[curRow][j - 1] +
|
||||
(first[i - 1].Equals(second[j - 1]) ? 0 : 1);
|
||||
|
||||
rows[nextRow][j] = Math.Min(dist1, Math.Min(dist2, dist3));
|
||||
}
|
||||
|
||||
// Swap the current and next rows
|
||||
if (curRow == 0)
|
||||
{
|
||||
curRow = 1;
|
||||
nextRow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
curRow = 0;
|
||||
nextRow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the computed edit distance
|
||||
return rows[curRow][m];
|
||||
}
|
||||
|
||||
public static bool IsChronological(DateTime existingDate, int existingNumber, DateTime date, int number)
|
||||
{
|
||||
return existingDate == date
|
||||
|| existingNumber == number
|
||||
|| existingDate < date && existingNumber < number
|
||||
|| existingDate > date && existingNumber > number;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public static class CustomExtensions
|
||||
{
|
||||
public static string Wordify(this string str)
|
||||
{
|
||||
return str.Aggregate(string.Empty, (current, c) => current + (char.IsUpper(c) ? " " + c : c.ToString()));
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(this Enum enumeration) where T : Attribute
|
||||
{
|
||||
var type = enumeration.GetType();
|
||||
var memInfo = type.GetMember(enumeration.ToString());
|
||||
if (memInfo.Length > 0)
|
||||
{
|
||||
var attributes = memInfo[0].GetCustomAttributes(typeof (T), false);
|
||||
if (attributes.Length > 0)
|
||||
return (T) attributes[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetDisplayName(this Enum enumeration)
|
||||
{
|
||||
var displayAttribute = GetAttribute<DisplayAttribute>(enumeration);
|
||||
return displayAttribute != null ? displayAttribute.Name : enumeration.ToString();
|
||||
}
|
||||
|
||||
public static string GetDisplayShortName(this Enum enumeration)
|
||||
{
|
||||
var displayAttribute = GetAttribute<DisplayAttribute>(enumeration);
|
||||
return displayAttribute != null
|
||||
? (!String.IsNullOrEmpty(displayAttribute.ShortName)
|
||||
? displayAttribute.ShortName
|
||||
: displayAttribute.Name)
|
||||
: enumeration.ToString();
|
||||
}
|
||||
|
||||
public static IEnumerable<SelectListItem> GetSelectListItems(this Enum enumeration)
|
||||
{
|
||||
var type = enumeration.GetType();
|
||||
return Enum.GetValues(type).OfType<Enum>().Select(e =>
|
||||
new SelectListItem
|
||||
{
|
||||
Text = e.GetDisplayName(),
|
||||
Value = e.ToString(),
|
||||
Selected = e.Equals(enumeration)
|
||||
});
|
||||
}
|
||||
|
||||
public static SelectList ToSelectList(this Type enumType, string selectedItem, string noItemSelected)
|
||||
{
|
||||
var items = (from item in Enum.GetValues(enumType).OfType<Enum>()
|
||||
let title = item.GetDisplayName()
|
||||
select new SelectListItem
|
||||
{
|
||||
Value = item.ToString(),
|
||||
Text = title,
|
||||
Selected = selectedItem == item.ToString()
|
||||
}).ToList();
|
||||
|
||||
return new SelectList(new[]{new SelectListItem{Text = noItemSelected}}.Concat(items), "Value", "Text");
|
||||
}
|
||||
|
||||
public static string GetPropertyName<T>(Expression<Func<T>> expression)
|
||||
{
|
||||
var propertyExpression = (MemberExpression)expression.Body;
|
||||
return propertyExpression.Member.GetName();
|
||||
}
|
||||
|
||||
public static string GetName(this MemberInfo propertyMember)
|
||||
{
|
||||
var displayAttr = propertyMember.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute;
|
||||
return displayAttr != null
|
||||
? displayAttr.Name
|
||||
: propertyMember.Name;
|
||||
}
|
||||
|
||||
public static object GetValue(this PropertyInfo propertyMember, object obj)
|
||||
{
|
||||
var value = propertyMember.GetValue(obj, null);
|
||||
var displayAttr = propertyMember.GetCustomAttributes(typeof(DisplayFormatAttribute), true).FirstOrDefault() as DisplayFormatAttribute;
|
||||
|
||||
if (displayAttr != null)
|
||||
{
|
||||
if (value == null && !String.IsNullOrEmpty(displayAttr.NullDisplayText))
|
||||
return displayAttr.NullDisplayText;
|
||||
|
||||
if (!String.IsNullOrEmpty(displayAttr.DataFormatString))
|
||||
return String.Format(displayAttr.DataFormatString, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static string ToVerboseStringHistoric(this TimeSpan ts)
|
||||
{
|
||||
if (ts.TotalDays == 0)
|
||||
return "Today";
|
||||
if (ts.TotalDays == 1)
|
||||
return "Yesterday";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
Action<int, string> b = (var, name) =>
|
||||
{
|
||||
if (var > 0)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append(", ");
|
||||
sb.Append(var + " " + name);
|
||||
if (var > 1)
|
||||
sb.Append("s");
|
||||
}
|
||||
};
|
||||
|
||||
var timeLeft = ts;
|
||||
|
||||
var years = timeLeft.Days / 365; //no leap year accounting
|
||||
b(years, "year");
|
||||
timeLeft -= new TimeSpan(years*365, 0, 0, 0);
|
||||
|
||||
var months = timeLeft.Days / 30; //naive guess at month size
|
||||
b(months, "month");
|
||||
timeLeft -= new TimeSpan(months * 30, 0, 0, 0);
|
||||
|
||||
var weeks = timeLeft.Days / 7;
|
||||
b(weeks, "week");
|
||||
timeLeft -= new TimeSpan(weeks * 7, 0, 0, 0);
|
||||
|
||||
var days = timeLeft.Days;
|
||||
b(days, "day");
|
||||
|
||||
sb.Append(" ago");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static PropertyInfo[] GetProperties<T>(T type)
|
||||
{
|
||||
return typeof(T).GetProperties();
|
||||
}
|
||||
|
||||
public static bool IsBlackBerry(this HttpRequestBase request)
|
||||
{
|
||||
//return true;
|
||||
return request.UserAgent != null && request.UserAgent.Contains("BlackBerry");
|
||||
}
|
||||
|
||||
public static bool IsCollection(this Type type)
|
||||
{
|
||||
Func<Type, bool> isCollection =
|
||||
t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof (ICollection<>);
|
||||
|
||||
return isCollection(type) || type.GetInterfaces().Any(isCollection);
|
||||
}
|
||||
|
||||
public static string LowercaseFirst(string s)
|
||||
{
|
||||
// Check for empty string.
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
// Return char and concat substring.
|
||||
return char.ToLower(s[0]) + s.Substring(1);
|
||||
}
|
||||
|
||||
public static IEnumerable<int> GetNumbers()
|
||||
{
|
||||
var i = 0;
|
||||
while (true) yield return i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using AutoMapper;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
|
||||
{
|
||||
public DateTime Convert(ResolutionContext context)
|
||||
{
|
||||
return System.Convert.ToDateTime(context.SourceValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class DenyFutureDateAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object value)
|
||||
{
|
||||
var date = DateTime.Parse(value.ToString());
|
||||
return date.Date <= DateTime.Today;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class DenyPreviousMonthDateAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object value)
|
||||
{
|
||||
var date = DateTime.Parse(value.ToString());
|
||||
return date.Date >= GetCutoff();
|
||||
}
|
||||
|
||||
private static DateTime GetCutoff()
|
||||
{
|
||||
var today = DateTime.Today;
|
||||
return today.AddMonths(-1).AddDays(-today.Day + 1); // last two months
|
||||
if (today.Day > 10)
|
||||
return today.AddDays(-today.Day); // beginning of this month
|
||||
return today.AddMonths(-1).AddDays(-today.Day); // beginning of previous month
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ExcelLibrary.SpreadSheet;
|
||||
using MileageTraker.Web.Models;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public static class ExcelWriter
|
||||
{
|
||||
public static void WriteXls<T>(IEnumerable<T> items, string filename, string worksheetTitle, string worksheetName)
|
||||
{
|
||||
using (var fileStream = new FileStream(filename, FileMode.Create))
|
||||
WriteXls(items, fileStream, worksheetTitle, worksheetName);
|
||||
}
|
||||
|
||||
public static byte[] WriteXls<T>(IEnumerable<T> items, string worksheetTitle, string worksheetName)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
WriteXls(items, stream, worksheetTitle, worksheetName);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteXls<T>(IEnumerable<T> items, Stream stream, string worksheetTitle, string worksheetName)
|
||||
{
|
||||
var workbook = new Workbook();
|
||||
var worksheet = new Worksheet(worksheetName);
|
||||
|
||||
// write worksheet header
|
||||
worksheet.Cells[0, 3] = new Cell(worksheetTitle);
|
||||
|
||||
// write column headers
|
||||
var properties =
|
||||
typeof(T).GetProperties()
|
||||
.Where(p => !p.PropertyType.IsCollection());
|
||||
|
||||
properties.Zip(
|
||||
CustomExtensions.GetNumbers(),
|
||||
(p, c) =>
|
||||
worksheet.Cells[2, c] = new Cell(p.GetName())
|
||||
).ToList();
|
||||
|
||||
// write the data
|
||||
items.Zip(
|
||||
CustomExtensions.GetNumbers().Skip(3),
|
||||
(vehicle, r) =>
|
||||
properties.Zip(CustomExtensions.GetNumbers(),
|
||||
(p, c) => {
|
||||
var value = p.GetValue(vehicle);
|
||||
|
||||
string formatString = null;
|
||||
|
||||
if (value is decimal) // assume that it's currency
|
||||
formatString = "#,##0.00";
|
||||
|
||||
if (value is DateTime && p.Name == "Date")
|
||||
formatString = @"YYYY\-MM\-DD";
|
||||
else if (value is DateTime)
|
||||
formatString = @"YYYY\-MM\-DD hh:mm:ss";
|
||||
|
||||
int intValue; // write int-looking values as numbers
|
||||
if (value is string && int.TryParse((string)value, out intValue))
|
||||
value = intValue;
|
||||
|
||||
double doubleValue; // write double-looking values as numbers
|
||||
if (value is string && double.TryParse((string)value, out doubleValue))
|
||||
value = doubleValue;
|
||||
|
||||
if (value is MileageLogTypeWrapper)
|
||||
value = ((MileageLogTypeWrapper) value).Enum.GetDisplayName();
|
||||
|
||||
var cell = formatString != null ? new Cell(value,formatString) : new Cell(value);
|
||||
worksheet.Cells[r, c] = cell;
|
||||
|
||||
return (string)null;
|
||||
}).ToList()).ToList();
|
||||
|
||||
PadWorksheet(worksheet);
|
||||
|
||||
workbook.Worksheets.Add(worksheet);
|
||||
workbook.Save(stream);
|
||||
}
|
||||
|
||||
private static void PadWorksheet(Worksheet worksheet)
|
||||
{
|
||||
Func<int> totalCells = () => (worksheet.Cells.LastRowIndex + 1)*(worksheet.Cells.LastColIndex + 1);
|
||||
for (var r = worksheet.Cells.LastRowIndex + 1; totalCells() < 320; r++)
|
||||
{
|
||||
for (var c = 0; c < worksheet.Cells.LastColIndex; c++)
|
||||
{
|
||||
worksheet.Cells[r, c] = new Cell("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public class FormatHintAttribute : Attribute
|
||||
{
|
||||
public string Text { get; set; }
|
||||
|
||||
public FormatHintAttribute(string text)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public class UnitsAttribute : Attribute
|
||||
{
|
||||
public string Text { get; set; }
|
||||
|
||||
public UnitsAttribute(string text)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public class NoEditLabelAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class RenderModeAttribute : Attribute
|
||||
{
|
||||
public RenderMode RenderMode { get; set; }
|
||||
|
||||
public RenderModeAttribute(RenderMode renderMode)
|
||||
{
|
||||
RenderMode = renderMode;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RenderMode
|
||||
{
|
||||
Any,
|
||||
EditModeOnly,
|
||||
DisplayModeOnly
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class HttpParamActionAttribute : ActionNameSelectorAttribute
|
||||
{
|
||||
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
|
||||
{
|
||||
if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
|
||||
return true;
|
||||
|
||||
if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
|
||||
return false;
|
||||
|
||||
var request = controllerContext.RequestContext.HttpContext.Request;
|
||||
return request[methodInfo.Name] != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class RequireRequestValueAttribute : ActionMethodSelectorAttribute
|
||||
{
|
||||
public RequireRequestValueAttribute(string valueName)
|
||||
{
|
||||
ValueName = valueName;
|
||||
}
|
||||
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
|
||||
{
|
||||
return (controllerContext.HttpContext.Request[ValueName] != null);
|
||||
}
|
||||
public string ValueName { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Globalization;
|
||||
using AutoMapper;
|
||||
|
||||
namespace MileageTraker.Web.Utility
|
||||
{
|
||||
public class TitleCaseFormatter : ValueFormatter<string>
|
||||
{
|
||||
protected override string FormatValueCore(string value)
|
||||
{
|
||||
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user