2014-10-11 06:57:02 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Web;
|
|
|
|
|
using System.Web.Mvc;
|
2014-11-01 03:28:16 +08:00
|
|
|
|
using System.Web.Routing;
|
2014-10-11 06:57:02 +08:00
|
|
|
|
using System.Web.Security;
|
2014-11-01 03:28:16 +08:00
|
|
|
|
using BuildFeed.Models;
|
2014-10-11 06:57:02 +08:00
|
|
|
|
using BuildFeed.Models.ViewModel;
|
2014-11-22 06:49:00 +08:00
|
|
|
|
using System.Xml.Linq;
|
2015-01-05 06:14:43 +08:00
|
|
|
|
using System.Net.Mail;
|
|
|
|
|
using System.Configuration;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2014-10-11 06:57:02 +08:00
|
|
|
|
|
|
|
|
|
namespace BuildFeed.Controllers
|
|
|
|
|
{
|
|
|
|
|
public class supportController : Controller
|
|
|
|
|
{
|
|
|
|
|
// GET: support
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult index()
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult login()
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult login(LoginUser ru)
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
if (ModelState.IsValid)
|
|
|
|
|
{
|
|
|
|
|
bool isAuthenticated = Membership.ValidateUser(ru.UserName, ru.Password);
|
|
|
|
|
|
|
|
|
|
if (isAuthenticated)
|
|
|
|
|
{
|
2014-12-05 05:42:47 +08:00
|
|
|
|
int expiryLength = ru.RememberMe ? 129600 : 60;
|
|
|
|
|
var ticket = new FormsAuthenticationTicket(ru.UserName, true, expiryLength);
|
|
|
|
|
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
|
|
|
|
|
var cookieTicket = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
|
|
|
|
|
cookieTicket.Expires = DateTime.Now.AddMinutes(expiryLength);
|
|
|
|
|
cookieTicket.Path = FormsAuthentication.FormsCookiePath;
|
|
|
|
|
Response.Cookies.Add(cookieTicket);
|
2014-10-11 06:57:02 +08:00
|
|
|
|
|
|
|
|
|
string returnUrl = string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]) ? "/" : Request.QueryString["ReturnUrl"];
|
|
|
|
|
|
|
|
|
|
return Redirect(returnUrl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ViewData["ErrorMessage"] = "The username and password are not valid.";
|
|
|
|
|
return View(ru);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Authorize]
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult password()
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult password(ChangePassword cp)
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
if (ModelState.IsValid)
|
|
|
|
|
{
|
|
|
|
|
var user = Membership.GetUser();
|
|
|
|
|
bool success = user.ChangePassword(cp.OldPassword, cp.NewPassword);
|
|
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
|
{
|
|
|
|
|
return Redirect("/");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ViewData["ErrorMessage"] = "There was an error changing your password.";
|
|
|
|
|
return View(cp);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult logout()
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
FormsAuthentication.SignOut();
|
|
|
|
|
return Redirect("/");
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult register()
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
2014-10-29 07:39:18 +08:00
|
|
|
|
public ActionResult register(RegistrationUser ru)
|
2014-10-11 06:57:02 +08:00
|
|
|
|
{
|
|
|
|
|
if (ModelState.IsValid)
|
|
|
|
|
{
|
|
|
|
|
MembershipCreateStatus status;
|
|
|
|
|
Membership.CreateUser(ru.UserName, ru.Password, ru.EmailAddress, "THIS WILL BE IGNORED", "I WILL BE IGNORED", false, out status);
|
|
|
|
|
|
|
|
|
|
switch (status)
|
|
|
|
|
{
|
|
|
|
|
case MembershipCreateStatus.Success:
|
|
|
|
|
return RedirectToAction("thanks_register");
|
|
|
|
|
case MembershipCreateStatus.InvalidPassword:
|
|
|
|
|
ViewData["ErrorMessage"] = "The password is invalid.";
|
|
|
|
|
break;
|
|
|
|
|
case MembershipCreateStatus.DuplicateEmail:
|
|
|
|
|
ViewData["ErrorMessage"] = "A user account with this email address already exists.";
|
|
|
|
|
break;
|
|
|
|
|
case MembershipCreateStatus.DuplicateUserName:
|
|
|
|
|
ViewData["ErrorMessage"] = "A user account with this user name already exists.";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ViewData["ErrorMessage"] = "Unspecified error.";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return View(ru);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ActionResult thanks_register()
|
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
2014-10-21 20:53:27 +08:00
|
|
|
|
|
2015-01-05 06:14:43 +08:00
|
|
|
|
public ActionResult question()
|
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
|
|
|
|
public async Task<ActionResult> question(QuestionForm qf)
|
|
|
|
|
{
|
2015-01-07 19:27:24 +08:00
|
|
|
|
if (ModelState.IsValid)
|
2015-01-05 06:14:43 +08:00
|
|
|
|
{
|
|
|
|
|
SmtpClient sc = new SmtpClient();
|
|
|
|
|
MailMessage mm = new MailMessage(ConfigurationManager.AppSettings["form:QuestionFromEmail"], ConfigurationManager.AppSettings["form:QuestionToEmail"]);
|
|
|
|
|
mm.Subject = "BuildFeed Question from " + qf.Name;
|
|
|
|
|
mm.ReplyToList.Add(qf.Email);
|
|
|
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
sb.AppendLine("BuildFeed Question");
|
|
|
|
|
sb.AppendLine("==================");
|
|
|
|
|
sb.AppendLine();
|
|
|
|
|
sb.AppendFormat("Name: {0}\r\n", qf.Name);
|
|
|
|
|
sb.AppendFormat("Email: {0}\r\n", qf.Email);
|
|
|
|
|
sb.AppendLine();
|
|
|
|
|
sb.AppendLine("Question: ");
|
|
|
|
|
sb.AppendLine(qf.Comment);
|
|
|
|
|
|
|
|
|
|
mm.Body = sb.ToString();
|
|
|
|
|
|
|
|
|
|
await sc.SendMailAsync(mm);
|
|
|
|
|
|
|
|
|
|
return View("thanks_question");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return View(qf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-21 20:53:27 +08:00
|
|
|
|
public ActionResult rss()
|
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
2014-11-01 03:28:16 +08:00
|
|
|
|
|
2015-03-12 07:30:11 +08:00
|
|
|
|
[Route("support/sitemap")]
|
|
|
|
|
[OutputCache(Duration = 3600, VaryByParam = "none")]
|
2014-11-01 03:28:16 +08:00
|
|
|
|
public ActionResult sitemap()
|
|
|
|
|
{
|
|
|
|
|
IEnumerable<Build> builds = Build.SelectInVersionOrder();
|
|
|
|
|
Dictionary<string, SitemapPagedAction[]> actions = new Dictionary<string, SitemapPagedAction[]>();
|
|
|
|
|
|
|
|
|
|
actions.Add("Pages", new SitemapPagedAction[] { new SitemapPagedAction()
|
|
|
|
|
{
|
|
|
|
|
UrlParams = new RouteValueDictionary(new {
|
|
|
|
|
controller = "build",
|
|
|
|
|
action = "index",
|
|
|
|
|
page = 1
|
|
|
|
|
}),
|
|
|
|
|
Pages = (builds.Count() + (buildController.pageSize - 1)) / buildController.pageSize
|
|
|
|
|
} });
|
|
|
|
|
|
|
|
|
|
actions.Add("Versions", (from b in builds
|
|
|
|
|
group b by new BuildVersion() { Major = b.MajorVersion, Minor = b.MinorVersion } into bv
|
|
|
|
|
orderby bv.Key.Major descending,
|
|
|
|
|
bv.Key.Minor descending
|
|
|
|
|
select new SitemapPagedAction()
|
|
|
|
|
{
|
|
|
|
|
Name = string.Format("Windows NT {0}.{1}", bv.Key.Major, bv.Key.Minor),
|
|
|
|
|
UrlParams = new RouteValueDictionary(new
|
|
|
|
|
{
|
|
|
|
|
controller = "build",
|
|
|
|
|
action = "version",
|
|
|
|
|
major = bv.Key.Major,
|
|
|
|
|
minor = bv.Key.Minor,
|
|
|
|
|
page = 1
|
|
|
|
|
}),
|
|
|
|
|
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
|
|
|
|
|
}).ToArray());
|
|
|
|
|
|
|
|
|
|
actions.Add("Labs", (from b in builds
|
|
|
|
|
where !string.IsNullOrEmpty(b.Lab)
|
|
|
|
|
group b by b.Lab into bv
|
|
|
|
|
orderby bv.Key
|
|
|
|
|
select new SitemapPagedAction()
|
|
|
|
|
{
|
|
|
|
|
Name = bv.Key,
|
|
|
|
|
UrlParams = new RouteValueDictionary(new
|
|
|
|
|
{
|
|
|
|
|
controller = "build",
|
2014-11-01 05:30:48 +08:00
|
|
|
|
action = "lab",
|
2014-11-01 03:28:16 +08:00
|
|
|
|
lab = bv.Key,
|
|
|
|
|
page = 1
|
|
|
|
|
}),
|
|
|
|
|
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
|
|
|
|
|
}).ToArray());
|
|
|
|
|
|
|
|
|
|
actions.Add("Years", (from b in builds
|
2015-01-07 19:27:24 +08:00
|
|
|
|
where b.BuildTime.HasValue
|
|
|
|
|
group b by b.BuildTime.Value.Year into bv
|
|
|
|
|
orderby bv.Key
|
|
|
|
|
select new SitemapPagedAction()
|
|
|
|
|
{
|
|
|
|
|
Name = bv.Key.ToString(),
|
|
|
|
|
UrlParams = new RouteValueDictionary(new
|
|
|
|
|
{
|
|
|
|
|
controller = "build",
|
|
|
|
|
action = "year",
|
|
|
|
|
year = bv.Key,
|
|
|
|
|
page = 1
|
|
|
|
|
}),
|
|
|
|
|
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
|
|
|
|
|
}).ToArray());
|
2014-11-01 03:28:16 +08:00
|
|
|
|
|
|
|
|
|
actions.Add("Sources", (from b in builds
|
2015-01-07 19:27:24 +08:00
|
|
|
|
group b by b.SourceType into bv
|
|
|
|
|
orderby bv.Key
|
|
|
|
|
select new SitemapPagedAction()
|
|
|
|
|
{
|
|
|
|
|
Name = DisplayHelpers.GetDisplayTextForEnum(bv.Key),
|
|
|
|
|
UrlParams = new RouteValueDictionary(new
|
|
|
|
|
{
|
|
|
|
|
controller = "build",
|
|
|
|
|
action = "source",
|
|
|
|
|
source = bv.Key,
|
|
|
|
|
page = 1
|
|
|
|
|
}),
|
|
|
|
|
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
|
|
|
|
|
}).ToArray());
|
2014-11-01 03:28:16 +08:00
|
|
|
|
|
|
|
|
|
SitemapData model = new SitemapData()
|
|
|
|
|
{
|
|
|
|
|
Builds = (from b in builds
|
|
|
|
|
select new SitemapDataBuild()
|
|
|
|
|
{
|
|
|
|
|
Id = b.Id,
|
|
|
|
|
Name = b.FullBuildString
|
|
|
|
|
}).ToArray(),
|
|
|
|
|
|
|
|
|
|
Actions = actions
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return View(model);
|
|
|
|
|
}
|
2014-11-22 06:49:00 +08:00
|
|
|
|
|
2015-03-12 07:30:11 +08:00
|
|
|
|
[Route("support/xmlsitemap")]
|
|
|
|
|
[OutputCache(Duration = 3600, VaryByParam = "none")]
|
2014-11-22 06:49:00 +08:00
|
|
|
|
public ActionResult xmlsitemap()
|
|
|
|
|
{
|
2014-12-16 22:43:26 +08:00
|
|
|
|
XNamespace xn = XNamespace.Get("http://www.sitemaps.org/schemas/sitemap/0.9");
|
2014-11-22 06:49:00 +08:00
|
|
|
|
List<XElement> xlist = new List<XElement>();
|
|
|
|
|
|
|
|
|
|
// home page
|
2014-12-16 22:43:26 +08:00
|
|
|
|
XElement home = new XElement(xn + "url");
|
|
|
|
|
home.Add(new XElement(xn + "loc", Request.Url.GetLeftPart(UriPartial.Authority) + "/"));
|
|
|
|
|
home.Add(new XElement(xn + "changefreq", "daily"));
|
2014-11-22 06:49:00 +08:00
|
|
|
|
xlist.Add(home);
|
|
|
|
|
|
2015-01-07 19:27:24 +08:00
|
|
|
|
foreach (var b in Build.Select())
|
2014-11-22 06:49:00 +08:00
|
|
|
|
{
|
2014-12-16 22:43:26 +08:00
|
|
|
|
XElement url = new XElement(xn + "url");
|
|
|
|
|
url.Add(new XElement(xn + "loc", Request.Url.GetLeftPart(UriPartial.Authority) + Url.Action("info", "build", new { id = b.Id })));
|
2015-01-07 19:27:24 +08:00
|
|
|
|
if (b.Modified != DateTime.MinValue)
|
2014-11-22 06:49:00 +08:00
|
|
|
|
{
|
2014-12-16 22:43:26 +08:00
|
|
|
|
url.Add(new XElement(xn + "lastmod", b.Modified.ToString("yyyy-MM-dd")));
|
2014-11-22 06:49:00 +08:00
|
|
|
|
}
|
|
|
|
|
xlist.Add(url);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-16 22:43:26 +08:00
|
|
|
|
XDeclaration decl = new XDeclaration("1.0", "utf-8", "");
|
|
|
|
|
XElement root = new XElement(xn + "urlset", xlist);
|
2014-11-22 06:49:00 +08:00
|
|
|
|
|
2014-12-16 22:43:26 +08:00
|
|
|
|
XDocument xdoc = new XDocument(decl, root);
|
2014-11-22 06:49:00 +08:00
|
|
|
|
|
|
|
|
|
Response.ContentType = "application/xml";
|
|
|
|
|
xdoc.Save(Response.OutputStream);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new EmptyResult();
|
|
|
|
|
}
|
2015-01-07 19:27:24 +08:00
|
|
|
|
|
2015-03-12 07:30:11 +08:00
|
|
|
|
[Route("support/stats")]
|
|
|
|
|
[OutputCache(Duration = 3600, VaryByParam = "none")]
|
2015-01-07 19:27:24 +08:00
|
|
|
|
public ActionResult stats()
|
|
|
|
|
{
|
|
|
|
|
var builds = Build.Select();
|
|
|
|
|
|
|
|
|
|
List<MonthCount> Additions = new List<MonthCount>();
|
|
|
|
|
var rawAdditions = from b in builds
|
|
|
|
|
where b.Added > DateTime.Now.AddYears(-1)
|
|
|
|
|
group b by new { Year = b.Added.Year, Week = Convert.ToInt32(Math.Floor(b.Added.DayOfYear / 7m)) } into bm
|
|
|
|
|
select new MonthCount()
|
|
|
|
|
{
|
|
|
|
|
Month = bm.Key.Week,
|
|
|
|
|
Year = bm.Key.Year,
|
|
|
|
|
Count = bm.Count()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (int i = -52; i <= 0; i++)
|
|
|
|
|
{
|
|
|
|
|
DateTime dt = DateTime.Now.AddDays(i * 7);
|
|
|
|
|
Additions.Add(new MonthCount()
|
|
|
|
|
{
|
|
|
|
|
Month = Convert.ToInt32(Math.Floor(dt.DayOfYear / 7m)),
|
|
|
|
|
Year = dt.Year,
|
|
|
|
|
Count = rawAdditions.SingleOrDefault(a => a.Month == Convert.ToInt32(Math.Floor(dt.DayOfYear / 7m)) && a.Year == dt.Year).Count
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<MonthCount> Compiles = new List<MonthCount>();
|
|
|
|
|
var rawCompiles = from b in builds
|
|
|
|
|
where b.BuildTime.HasValue
|
|
|
|
|
group b by new { Year = b.BuildTime.Value.Year, Month = Convert.ToInt32(Math.Floor((b.BuildTime.Value.Month - 0.1m) / 3m) * 3) + 1 } into bm
|
|
|
|
|
select new MonthCount()
|
|
|
|
|
{
|
|
|
|
|
Month = bm.Key.Month,
|
|
|
|
|
Year = bm.Key.Year,
|
|
|
|
|
Count = bm.Count()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var rawLabCounts = from bl in (from b in builds
|
|
|
|
|
where !string.IsNullOrEmpty(b.Lab)
|
|
|
|
|
group b by b.Lab into bl
|
|
|
|
|
select bl)
|
2015-03-12 07:30:11 +08:00
|
|
|
|
where bl.Count() > 24
|
2015-01-07 19:27:24 +08:00
|
|
|
|
orderby bl.Count() descending
|
|
|
|
|
select new Tuple<string, int>(bl.Key, bl.Count());
|
|
|
|
|
|
|
|
|
|
StatsPage m = new StatsPage()
|
|
|
|
|
{
|
|
|
|
|
AdditionsByMonth = Additions,
|
|
|
|
|
CompilesByMonth = rawCompiles.OrderBy(r => r.Year).ThenBy(r => r.Month),
|
|
|
|
|
BuildsByLab = rawLabCounts
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return View(m);
|
|
|
|
|
}
|
2014-10-11 06:57:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|