This commit is contained in:
2012-11-30 21:35:06 -05:00
commit 3963d6363a
346 changed files with 351799 additions and 0 deletions
+24
View File
@@ -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);
}
}
}
+87
View File
@@ -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;
}
}
}
+185
View File
@@ -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++;
}
}
}
+13
View File
@@ -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);
}
}
}
+14
View File
@@ -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
}
}
}
+99
View File
@@ -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("");
}
}
}
}
}
+48
View File
@@ -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
}
}
+21
View File
@@ -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; }
}
}
+13
View File
@@ -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);
}
}
}