diff --git a/BuildFeed/BuildFeed.csproj b/BuildFeed/BuildFeed.csproj index 2953aa8..faa272d 100644 --- a/BuildFeed/BuildFeed.csproj +++ b/BuildFeed/BuildFeed.csproj @@ -196,10 +196,10 @@ - - - - + + + + Global.asax @@ -751,6 +751,7 @@ + diff --git a/BuildFeed/Controllers/apiController.cs b/BuildFeed/Controllers/apiController.cs index 563f2c0..c52e059 100644 --- a/BuildFeed/Controllers/apiController.cs +++ b/BuildFeed/Controllers/apiController.cs @@ -11,31 +11,30 @@ namespace BuildFeed.Controllers { - public class apiController : ApiController + public class ApiController : System.Web.Http.ApiController { - private Build bModel; + private readonly Build _bModel; - public apiController() : base() + public ApiController() : base() { - bModel = new Build(); + _bModel = new Build(); } public async Task GetBuilds(int limit = 20, int skip = 0) { - throw new NotImplementedException(); - // var builds = await bModel.SelectInBuildOrder(limit, skip); - // return builds.ToArray(); + var builds = await _bModel.SelectBuildsByOrder(limit, skip); + return builds.ToArray(); } public async Task GetBuildGroups(int limit = 20, int skip = 20) { - var bgroups = await bModel.SelectAllGroups(limit, skip); + var bgroups = await _bModel.SelectAllGroups(limit, skip); return bgroups.ToArray(); } public async Task GetBuildsForBuildGroup(uint major, uint minor, uint number, uint? revision = null) { - var builds = await bModel.SelectGroup(new BuildGroup() + var builds = await _bModel.SelectGroup(new BuildGroup() { Major = major, Minor = minor, @@ -48,16 +47,15 @@ public async Task GetBuildsForBuildGroup(uint major, uint minor, u public async Task> GetWin10Labs() { - throw new NotImplementedException(); - //List labs = new List(); - //labs.AddRange(await bModel.SelectLabs(6, 4)); - //labs.AddRange(await bModel.SelectLabs(10, 0)); + List labs = new List(); + labs.AddRange(await _bModel.SelectLabsForVersion(6, 4)); + labs.AddRange(await _bModel.SelectLabsForVersion(10, 0)); - //return labs - // .GroupBy(l => l) - // .Select(l => l.Key) - // .Where(l => l.All(c => c != '(')) - // .ToArray(); + return labs + .GroupBy(l => l) + .Select(l => l.Key) + .Where(l => l.All(c => c != '(')) + .ToArray(); } [HttpPost] @@ -69,7 +67,7 @@ public async Task AddWin10Builds(NewBuild apiModel) } if (Membership.ValidateUser(apiModel.Username, apiModel.Password)) { - await bModel.InsertAll(apiModel.NewBuilds.Select(nb => new BuildModel() + await _bModel.InsertAll(apiModel.NewBuilds.Select(nb => new BuildModel() { MajorVersion = nb.MajorVersion, MinorVersion = nb.MinorVersion, @@ -81,10 +79,7 @@ public async Task AddWin10Builds(NewBuild apiModel) })); return true; } - else - { - return false; - } + return false; } public async Task> GetSearchResult(string id) @@ -110,7 +105,7 @@ orderby s.Text.ToLower().IndexOf(id.ToLower(), StringComparison.Ordinal) ascendi results.AddRange(sourceResults); - var versionResults = from v in await bModel.SelectAllVersions() + var versionResults = from v in await _bModel.SelectAllVersions() where $"{v.Major}.{v.Minor}".StartsWith(id) orderby v.Major descending, v.Minor descending select new SearchResult() @@ -124,7 +119,7 @@ orderby s.Text.ToLower().IndexOf(id.ToLower(), StringComparison.Ordinal) ascendi results.AddRange(versionResults); - var yearResults = from y in await bModel.SelectAllYears() + var yearResults = from y in await _bModel.SelectAllYears() where y.ToString().Contains(id) orderby y descending select new SearchResult() @@ -138,21 +133,19 @@ orderby y descending results.AddRange(yearResults); - //var labResults = from l in await bModel.SearchBuildLabs(id) - // orderby l.IndexOf(id.ToLower()) ascending, - // l.Length ascending - // select new SearchResult() - // { - // Url = Url.Route("Lab Root", new { controller = "Front", action = "ViewLab", lab = l.Replace('/', '-') }), - // Label = l.Replace(id, $"{id}"), - // Title = l, - // Group = Common.SearchLab - // }; + var labResults = from l in await _bModel.SearchLabs(id) + select new SearchResult() + { + Url = Url.Route("Lab Root", new { controller = "Front", action = "ViewLab", lab = l.Replace('/', '-') }), + Label = l.Replace(id, $"{id}"), + Title = l, + Group = Common.SearchLab + }; - //results.AddRange(labResults); + results.AddRange(labResults); - var buildResults = from b in await bModel.Select() + var buildResults = from b in await _bModel.Select() where b.FullBuildString.ToLower().Contains(id.ToLower()) orderby b.FullBuildString.ToLower().IndexOf(id.ToLower(), StringComparison.Ordinal) ascending, b.BuildTime descending diff --git a/BuildFeed/Controllers/frontController.cs b/BuildFeed/Controllers/frontController.cs index a8096bf..ddbd183 100644 --- a/BuildFeed/Controllers/frontController.cs +++ b/BuildFeed/Controllers/frontController.cs @@ -15,7 +15,7 @@ namespace BuildFeed.Controllers { public class FrontController : LocalController { - private const int PAGE_SIZE = 72; + public const int PageSize = 72; private readonly Build _bModel; private readonly MetaItem _mModel; @@ -38,12 +38,12 @@ public FrontController() #endif public async Task IndexPage(int page) { - var buildGroups = await _bModel.SelectAllGroups(PAGE_SIZE, (page - 1) * PAGE_SIZE); + var buildGroups = await _bModel.SelectAllGroups(PageSize, (page - 1) * PageSize); ViewBag.PageNumber = page; ViewBag.PageCount = Math.Ceiling( Convert.ToDouble(await _bModel.SelectAllGroupsCount()) / - Convert.ToDouble(PAGE_SIZE)); + Convert.ToDouble(PageSize)); if (ViewBag.PageNumber > ViewBag.PageCount) { @@ -189,12 +189,12 @@ public async Task ViewLabPage(string lab, int page) Value = lab }); - var builds = await _bModel.SelectLab(lab, PAGE_SIZE, (page - 1) * PAGE_SIZE); + var builds = await _bModel.SelectLab(lab, PageSize, (page - 1) * PageSize); ViewBag.ItemId = builds.FirstOrDefault() ?.Lab; ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectLabCount(lab)) / Convert.ToDouble(PAGE_SIZE)); + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectLabCount(lab)) / Convert.ToDouble(PageSize)); if (ViewBag.PageNumber > ViewBag.PageCount) { @@ -223,10 +223,10 @@ public async Task ViewSourcePage(TypeOfSource source, int page) }); ViewBag.ItemId = DisplayHelpers.GetDisplayTextForEnum(source); - var builds = await _bModel.SelectSource(source, PAGE_SIZE, (page - 1) * PAGE_SIZE); + var builds = await _bModel.SelectSource(source, PageSize, (page - 1) * PageSize); ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectSourceCount(source)) / Convert.ToDouble(PAGE_SIZE)); + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectSourceCount(source)) / Convert.ToDouble(PageSize)); if (ViewBag.PageNumber > ViewBag.PageCount) { @@ -255,10 +255,10 @@ public async Task ViewYearPage(int year, int page) }); ViewBag.ItemId = year.ToString(); - var builds = await _bModel.SelectYear(year, PAGE_SIZE, (page - 1) * PAGE_SIZE); + var builds = await _bModel.SelectYear(year, PageSize, (page - 1) * PageSize); ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(await _bModel.SelectYearCount(year) / Convert.ToDouble(PAGE_SIZE)); + ViewBag.PageCount = Math.Ceiling(await _bModel.SelectYearCount(year) / Convert.ToDouble(PageSize)); if (ViewBag.PageNumber > ViewBag.PageCount) { @@ -288,10 +288,10 @@ public async Task ViewVersionPage(uint major, uint minor, int page }); ViewBag.ItemId = valueString; - var builds = await _bModel.SelectVersion(major, minor, PAGE_SIZE, (page - 1) * PAGE_SIZE); + var builds = await _bModel.SelectVersion(major, minor, PageSize, (page - 1) * PageSize); ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectVersionCount(major, minor)) / Convert.ToDouble(PAGE_SIZE)); + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectVersionCount(major, minor)) / Convert.ToDouble(PageSize)); if (ViewBag.PageNumber > ViewBag.PageCount) { diff --git a/BuildFeed/Controllers/rssController.cs b/BuildFeed/Controllers/rssController.cs index 8d9d737..c922340 100644 --- a/BuildFeed/Controllers/rssController.cs +++ b/BuildFeed/Controllers/rssController.cs @@ -1,10 +1,11 @@ using System; -using BuildFeed.Code; -using BuildFeed.Models; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; using System.Web.Mvc; +using BuildFeed.Code; +using BuildFeed.Models; using X.Web.RSS; using X.Web.RSS.Enumerators; using X.Web.RSS.Structure; @@ -12,244 +13,242 @@ namespace BuildFeed.Controllers { - public class rssController : LocalController + public class RssController : LocalController { - private Build bModel; private const int RSS_SIZE = 25; + private readonly Build _bModel; - public rssController() : base() - { - bModel = new Build(); - } + public RssController() { _bModel = new Build(); } [Route("rss/compiled")] - public async Task index() + public async Task Index() { - throw new NotImplementedException(); - //var builds = await bModel.SelectInBuildOrder(RSS_SIZE, 0); + var builds = await _bModel.SelectBuildsByCompileDate(RSS_SIZE, 0); - //RssDocument rdoc = new RssDocument() - //{ - // Channel = new RssChannel() - // { - // Title = "BuildFeed RSS - Recently Compiled", - // Description = "", - // Generator = "BuildFeed.net RSS Controller", - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), - // SkipHours = new List(), - // SkipDays = new List(), + RssDocument rdoc = new RssDocument + { + Channel = new RssChannel + { + Title = "BuildFeed RSS - Recently Compiled", + Description = "", + Generator = "BuildFeed.net RSS Controller", + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), + SkipHours = new List(), + SkipDays = new List(), + Items = (from build in builds + select new RssItem + { + Title = build.FullBuildString, + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}"), + Guid = new RssGuid + { + IsPermaLink = true, + Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}" + } + }).ToList() + } + }; - // Items = (from build in builds - // select new RssItem() - // { - // Title = build.FullBuildString, - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}"), - // Guid = new RssGuid() { IsPermaLink = true, Value = string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Action("viewBuild", new { controller = "Front", id = build.Id })) }, - // }).ToList() - // } - //}; - - //Response.ContentType = "application/rss+xml"; - - //await Response.Output.WriteAsync(rdoc.ToXml()); - - //return new EmptyResult(); + return new ContentResult + { + Content = rdoc.ToXml(), + ContentType = "application/rss+xml", + ContentEncoding = Encoding.UTF8 + }; } [Route("rss/added")] - public async Task added() + public async Task Added() { - throw new NotImplementedException(); - //var builds = await bModel.SelectLatest(RSS_SIZE, 0); + var builds = await _bModel.SelectBuildsByAddedDate(RSS_SIZE, 0); - //RssDocument rdoc = new RssDocument() - //{ - // Channel = new RssChannel() - // { - // Title = "BuildFeed RSS - Recently Added", - // Description = "", - // Generator = "BuildFeed.net RSS Controller", - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), - // SkipHours = new List(), - // SkipDays = new List(), + RssDocument rdoc = new RssDocument() + { + Channel = new RssChannel() + { + Title = "BuildFeed RSS - Recently Added", + Description = "", + Generator = "BuildFeed.net RSS Controller", + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), + SkipHours = new List(), + SkipDays = new List(), - // Items = (from build in builds - // select new RssItem() - // { - // Title = build.FullBuildString, - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}"), - // Guid = new RssGuid() - // { - // IsPermaLink = true, - // Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}" - // }, - // Category = new RssCategory() { Text = build.Family.ToString() }, - // InternalPubDate = new RssDate(build.Added).DateStringISO8601 // bit of a dirty hack to work around problem in X.Web.RSS with the date format. - // }).ToList() - // } - //}; + Items = (from build in builds + select new RssItem() + { + Title = build.FullBuildString, + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}"), + Guid = new RssGuid() + { + IsPermaLink = true, + Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}" + }, + Category = new RssCategory() { Text = build.Family.ToString() }, + InternalPubDate = new RssDate(build.Added).DateStringISO8601 // bit of a dirty hack to work around problem in X.Web.RSS with the date format. + }).ToList() + } + }; - //Response.ContentType = "application/rss+xml"; - - //await Response.Output.WriteAsync(rdoc.ToXml()); - - //return new EmptyResult(); + return new ContentResult + { + Content = rdoc.ToXml(), + ContentType = "application/rss+xml", + ContentEncoding = Encoding.UTF8 + }; } [Route("rss/leaked")] - public async Task leaked() + public async Task Leaked() { - throw new NotImplementedException(); - //var builds = await bModel.SelectLatestLeaked(RSS_SIZE, 0); + var builds = await _bModel.SelectBuildsByLeakedDate(RSS_SIZE, 0); - //RssDocument rdoc = new RssDocument() - //{ - // Channel = new RssChannel() - // { - // Title = "BuildFeed RSS - Recently Leaked", - // Description = "", - // Generator = "BuildFeed.net RSS Controller", - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), - // SkipHours = new List(), - // SkipDays = new List(), + RssDocument rdoc = new RssDocument() + { + Channel = new RssChannel() + { + Title = "BuildFeed RSS - Recently Leaked", + Description = "", + Generator = "BuildFeed.net RSS Controller", + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), + SkipHours = new List(), + SkipDays = new List(), - // Items = (from build in builds - // select new RssItem() - // { - // Title = build.FullBuildString, - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}"), - // Guid = new RssGuid() - // { - // IsPermaLink = true, - // Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}" - // }, - // InternalPubDate = new RssDate(build.LeakDate.Value).DateStringISO8601 // bit of a dirty hack to work around problem in X.Web.RSS with the date format. - // }).ToList() - // } - //}; + Items = (from build in builds + select new RssItem() + { + Title = build.FullBuildString, + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}"), + Guid = new RssGuid() + { + IsPermaLink = true, + Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}" + }, + InternalPubDate = new RssDate(build.LeakDate.Value).DateStringISO8601 // bit of a dirty hack to work around problem in X.Web.RSS with the date format. + }).ToList() + } + }; - //Response.ContentType = "application/rss+xml"; - - //await Response.Output.WriteAsync(rdoc.ToXml()); - - //return new EmptyResult(); + return new ContentResult + { + Content = rdoc.ToXml(), + ContentType = "application/rss+xml", + ContentEncoding = Encoding.UTF8 + }; } [Route("rss/version")] - public async Task version() + public async Task Version() { - throw new NotImplementedException(); - //var builds = await bModel.SelectInVersionOrder(RSS_SIZE, 0); + var builds = await _bModel.SelectBuildsByOrder(RSS_SIZE, 0); - //RssDocument rdoc = new RssDocument() - //{ - // Channel = new RssChannel() - // { - // Title = "BuildFeed RSS - Highest Version", - // Description = "", - // Generator = "BuildFeed.net RSS Controller", - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), - // SkipHours = new List(), - // SkipDays = new List(), + RssDocument rdoc = new RssDocument() + { + Channel = new RssChannel() + { + Title = "BuildFeed RSS - Highest Version", + Description = "", + Generator = "BuildFeed.net RSS Controller", + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), + SkipHours = new List(), + SkipDays = new List(), - // Items = (from build in builds - // select new RssItem() - // { - // Title = build.FullBuildString, - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}"), - // Guid = new RssGuid() - // { - // IsPermaLink = true, - // Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}" - // }, - // }).ToList() - // } - //}; + Items = (from build in builds + select new RssItem() + { + Title = build.FullBuildString, + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}"), + Guid = new RssGuid() + { + IsPermaLink = true, + Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}" + }, + }).ToList() + } + }; - //Response.ContentType = "application/rss+xml"; - - //await Response.Output.WriteAsync(rdoc.ToXml()); - - //return new EmptyResult(); + return new ContentResult + { + Content = rdoc.ToXml(), + ContentType = "application/rss+xml", + ContentEncoding = Encoding.UTF8 + }; } [Route("rss/flight/{id}")] - public async Task flight(LevelOfFlight id) + public async Task Flight(LevelOfFlight id) { - throw new NotImplementedException(); - //var builds = await bModel.SelectFlight(id, RSS_SIZE, 0); + var builds = await _bModel.SelectFlight(id, RSS_SIZE, 0); + RssDocument rdoc = new RssDocument() + { + Channel = new RssChannel() + { + Title = $"BuildFeed RSS - {id} Flight Level", + Description = "", + Generator = "BuildFeed.net RSS Controller", + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), + SkipHours = new List(), + SkipDays = new List(), - //RssDocument rdoc = new RssDocument() - //{ - // Channel = new RssChannel() - // { - // Title = $"BuildFeed RSS - {id} Flight Level", - // Description = "", - // Generator = "BuildFeed.net RSS Controller", - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), - // SkipHours = new List(), - // SkipDays = new List(), + Items = (from build in builds + select new RssItem() + { + Title = build.FullBuildString, + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}"), + Guid = new RssGuid() + { + IsPermaLink = true, + Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}" + }, + }).ToList() + } + }; - // Items = (from build in builds - // select new RssItem() - // { - // Title = build.FullBuildString, - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}"), - // Guid = new RssGuid() - // { - // IsPermaLink = true, - // Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}" - // }, - // }).ToList() - // } - //}; - - //Response.ContentType = "application/rss+xml"; - - //await Response.Output.WriteAsync(rdoc.ToXml()); - - //return new EmptyResult(); + return new ContentResult + { + Content = rdoc.ToXml(), + ContentType = "application/rss+xml", + ContentEncoding = Encoding.UTF8 + }; } [Route("rss/lab/{lab}")] - public async Task lab(string lab) + public async Task Lab(string lab) { - throw new NotImplementedException(); - //var builds = await bModel.SelectLab(lab, 0, RSS_SIZE); + var builds = await _bModel.SelectLab(lab, RSS_SIZE, 0); + RssDocument rdoc = new RssDocument() + { + Channel = new RssChannel() + { + Title = $"BuildFeed RSS - {lab} Lab", + Description = "", + Generator = "BuildFeed.net RSS Controller", + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), + SkipHours = new List(), + SkipDays = new List(), - //RssDocument rdoc = new RssDocument() - //{ - // Channel = new RssChannel() - // { - // Title = $"BuildFeed RSS - {lab} Lab", - // Description = "", - // Generator = "BuildFeed.net RSS Controller", - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}"), - // SkipHours = new List(), - // SkipDays = new List(), + Items = (from build in builds + select new RssItem() + { + Title = build.FullBuildString, + Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}"), + Guid = new RssGuid() + { + IsPermaLink = true, + Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("ViewBuild", new { controller = "Front", id = build.Id })}" + }, + }).ToList() + } + }; - // Items = (from build in builds - // select new RssItem() - // { - // Title = build.FullBuildString, - // Link = new RssUrl($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}"), - // Guid = new RssGuid() - // { - // IsPermaLink = true, - // Value = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action("viewBuild", new { controller = "Front", id = build.Id })}" - // }, - // }).ToList() - // } - //}; - - //Response.ContentType = "application/rss+xml"; - - //await Response.Output.WriteAsync(rdoc.ToXml()); - - //return new EmptyResult(); + return new ContentResult + { + Content = rdoc.ToXml(), + ContentType = "application/rss+xml", + ContentEncoding = Encoding.UTF8 + }; } } } \ No newline at end of file diff --git a/BuildFeed/Controllers/supportController.cs b/BuildFeed/Controllers/supportController.cs index fdbe02e..7ef4bd1 100644 --- a/BuildFeed/Controllers/supportController.cs +++ b/BuildFeed/Controllers/supportController.cs @@ -14,23 +14,23 @@ namespace BuildFeed.Controllers { - public class supportController : LocalController + public class SupportController : LocalController { - private Build bModel; + private readonly Build _bModel; - public supportController() : base() + public SupportController() : base() { - bModel = new Build(); + _bModel = new Build(); } [Route("login/")] - public ActionResult login() + public ActionResult Login() { return View(); } [HttpPost, Route("login/")] - public ActionResult login(LoginUser ru) + public ActionResult Login(LoginUser ru) { if (ModelState.IsValid) { @@ -59,10 +59,10 @@ public ActionResult login(LoginUser ru) } [Authorize, Route("password/")] - public ActionResult password() => View(); + public ActionResult Password() => View(); [HttpPost, Authorize, Route("password/")] - public ActionResult password(ChangePassword cp) + public ActionResult Password(ChangePassword cp) { if (ModelState.IsValid) { @@ -84,17 +84,17 @@ public ActionResult password(ChangePassword cp) } [Route("logout/")] - public ActionResult logout() + public ActionResult Logout() { FormsAuthentication.SignOut(); return Redirect("/"); } [Route("register/")] - public ActionResult register() => View(); + public ActionResult Register() => View(); [HttpPost, Route("register/")] - public ActionResult register(RegistrationUser ru) + public ActionResult Register(RegistrationUser ru) { if (ModelState.IsValid) { @@ -127,9 +127,9 @@ public ActionResult register(RegistrationUser ru) public ActionResult thanks_register() => View(); [Route("rss")] - public async Task rss() + public async Task Rss() { - ViewBag.Labs = await bModel.SelectAllLabs(); + ViewBag.Labs = await _bModel.SelectAllLabs(); return View(); } @@ -137,145 +137,157 @@ public async Task rss() #if !DEBUG // [OutputCache(Duration = 3600, VaryByParam = "none", VaryByCustom = "userName")] #endif - public async Task sitemap() + public async Task Sitemap() { - throw new NotImplementedException(); - //var builds = await bModel.SelectInVersionOrder(); - //Dictionary actions = new Dictionary(); - //actions.Add("Pages", new[] - // { - // new SitemapPagedAction() - // { - // UrlParams = new RouteValueDictionary(new - // { - // controller = "front", - // action = "index", - // page = 1 - // }), - // Pages = (builds.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize - // } - // }); + var builds = await _bModel.SelectBuildsByOrder(); + Dictionary actions = new Dictionary + { + { + "Pages", new[] + { + new SitemapPagedAction() + { + UrlParams = new RouteValueDictionary(new + { + controller = "Front", + action = "Index", + page = 1 + }), + Pages = (builds.Count + (FrontController.PageSize - 1)) / FrontController.PageSize + } + } + }, + { + "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 = $"{Common.ProductName} {bv.Key.Major}.{bv.Key.Minor}", + UrlParams = new RouteValueDictionary(new + { + controller = "Front", + action = "ViewVersion", + major = bv.Key.Major, + minor = bv.Key.Minor, + page = 1 + }), + Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize + }).ToArray() + }, + { + "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 = "Front", + action = "ViewLab", + lab = bv.Key, + page = 1 + }), + Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize + }).ToArray() + }, + { + "Years", (from b in builds + where b.BuildTime.HasValue + group b by b.BuildTime.Value.Year + into bv + orderby bv.Key descending + select new SitemapPagedAction() + { + Name = bv.Key.ToString(), + UrlParams = new RouteValueDictionary(new + { + controller = "Front", + action = "ViewYear", + year = bv.Key, + page = 1 + }), + Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize + }).ToArray() + }, + { + "Sources", (from b in builds + group b by b.SourceType + into bv + orderby bv.Key + select new SitemapPagedAction() + { + Name = DisplayHelpers.GetDisplayTextForEnum(bv.Key), + UrlParams = new RouteValueDictionary(new + { + controller = "Front", + action = "ViewSource", + source = bv.Key, + page = 1 + }), + Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize + }).ToArray() + } + }; - //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 = $"{Common.ProductName} {bv.Key.Major}.{bv.Key.Minor}", - // UrlParams = new RouteValueDictionary(new - // { - // controller = "front", - // action = "viewVersion", - // major = bv.Key.Major, - // minor = bv.Key.Minor, - // page = 1 - // }), - // Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.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 = "front", - // action = "viewLab", - // lab = bv.Key, - // page = 1 - // }), - // Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize - // }).ToArray()); - //actions.Add("Years", (from b in builds - // where b.BuildTime.HasValue - // group b by b.BuildTime.Value.Year - // into bv - // orderby bv.Key descending - // select new SitemapPagedAction() - // { - // Name = bv.Key.ToString(), - // UrlParams = new RouteValueDictionary(new - // { - // controller = "front", - // action = "viewYear", - // year = bv.Key, - // page = 1 - // }), - // Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize - // }).ToArray()); - //actions.Add("Sources", (from b in builds - // group b by b.SourceType - // into bv - // orderby bv.Key - // select new SitemapPagedAction() - // { - // Name = DisplayHelpers.GetDisplayTextForEnum(bv.Key), - // UrlParams = new RouteValueDictionary(new - // { - // controller = "front", - // action = "viewSource", - // source = bv.Key, - // page = 1 - // }), - // Pages = (bv.Count() + (FrontController.PageSize - 1)) / FrontController.PageSize - // }).ToArray()); - //SitemapData model = new SitemapData() - //{ - // Builds = (from b in builds - // group b by new - // { - // Major = b.MajorVersion, - // Minor = b.MinorVersion, - // Build = b.Number, - // Revision = b.Revision - // } into bg - // orderby bg.Key.Major descending, - // bg.Key.Minor descending, - // bg.Key.Build descending, - // bg.Key.Revision descending - // select new SitemapDataBuildGroup() - // { - // Id = new BuildGroup() { - // Major = bg.Key.Major, - // Minor = bg.Key.Minor, - // Build = bg.Key.Build, - // Revision = bg.Key.Revision - // }, - // Builds = (from bgb in bg - // select new SitemapDataBuild() - // { - // Id = bgb.Id, - // Name = bgb.FullBuildString - // }).ToArray() - // }).ToArray(), + SitemapData model = new SitemapData() + { + Builds = (from b in builds + group b by new + { + Major = b.MajorVersion, + Minor = b.MinorVersion, + Build = b.Number, + Revision = b.Revision + } into bg + orderby bg.Key.Major descending, + bg.Key.Minor descending, + bg.Key.Build descending, + bg.Key.Revision descending + select new SitemapDataBuildGroup() + { + Id = new BuildGroup() + { + Major = bg.Key.Major, + Minor = bg.Key.Minor, + Build = bg.Key.Build, + Revision = bg.Key.Revision + }, + Builds = (from bgb in bg + select new SitemapDataBuild() + { + Id = bgb.Id, + Name = bgb.FullBuildString + }).ToArray() + }).ToArray(), - // Actions = actions, - // Labs = (from b in builds - // group b by b.Lab into lab - // select lab.Key).ToArray() - //}; + Actions = actions, + Labs = (from b in builds + group b by b.Lab into lab + select lab.Key).ToArray() + }; - //return View(model); + return View(model); } [Route("xml-sitemap/")] #if !DEBUG // [OutputCache(Duration = 3600, VaryByParam = "none", VaryByCustom = "userName")] #endif - public async Task xmlsitemap() + public async Task XmlSitemap() { XNamespace xn = XNamespace.Get("http://www.sitemaps.org/schemas/sitemap/0.9"); List xlist = new List(); @@ -286,10 +298,10 @@ public async Task xmlsitemap() home.Add(new XElement(xn + "changefreq", "daily")); xlist.Add(home); - foreach (var b in await bModel.Select()) + foreach (var b in await _bModel.Select()) { XElement url = new XElement(xn + "url"); - url.Add(new XElement(xn + "loc", Request.Url?.GetLeftPart(UriPartial.Authority) + Url.Action("viewBuild", "Front", new { id = b.Id }))); + url.Add(new XElement(xn + "loc", Request.Url?.GetLeftPart(UriPartial.Authority) + Url.Action("ViewBuild", "Front", new { id = b.Id }))); if (b.Modified != DateTime.MinValue) { url.Add(new XElement(xn + "lastmod", b.Modified.ToString("yyyy-MM-dd"))); @@ -312,9 +324,9 @@ public async Task xmlsitemap() #if !DEBUG // [OutputCache(Duration = 3600, VaryByParam = "none", VaryByCustom = "userName")] #endif - public async Task stats() + public async Task Stats() { - var builds = await bModel.Select(); + var builds = await _bModel.Select(); List additions = new List(); var rawAdditions = (from b in builds @@ -378,6 +390,6 @@ orderby bl.Count() descending } [Route("credits/")] - public ActionResult credits() => View(); + public ActionResult Credits() => View(); } } \ No newline at end of file diff --git a/BuildFeed/Models/Build/Build-Flights.cs b/BuildFeed/Models/Build/Build-Flights.cs new file mode 100644 index 0000000..e1b5ff0 --- /dev/null +++ b/BuildFeed/Models/Build/Build-Flights.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Web; +using MongoDB.Bson; +using MongoDB.Driver; + +namespace BuildFeed.Models +{ + public partial class Build + { + public Task SelectAllFlights(int limit = -1, int skip = 0) + { + return Task.Run(() => Enum.GetValues(typeof(LevelOfFlight)) as LevelOfFlight[]); + } + + public Task SelectAllFlightsCount() + { + return Task.Run(() => Enum.GetValues(typeof(LevelOfFlight)) + .LongLength); + } + + public async Task> SelectFlight(LevelOfFlight flight, int limit = -1, int skip = 0) + { + var query = _buildCollection.Find(new BsonDocument(nameof(BuildModel.FlightLevel), flight)) + .Sort(sortByOrder) + .Skip(skip); + + if (limit > 0) + { + query = query.Limit(limit); + } + + return await query.ToListAsync(); + } + + public async Task SelectFlightCount(LevelOfFlight flight) { return await _buildCollection.CountAsync(new BsonDocument(nameof(BuildModel.FlightLevel), flight)); } + } +} \ No newline at end of file diff --git a/BuildFeed/Models/Build/Build-Lab.cs b/BuildFeed/Models/Build/Build-Lab.cs index 2235377..ff1397f 100644 --- a/BuildFeed/Models/Build/Build-Lab.cs +++ b/BuildFeed/Models/Build/Build-Lab.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MongoDB.Bson; @@ -23,9 +24,43 @@ public async Task SelectAllLabs(int limit = -1, int skip = 0) var grouping = await query.ToListAsync(); return (from g in grouping + where !g["_id"].IsBsonNull select g["_id"].AsString).ToArray(); } + public async Task SelectLabsForVersion(int major, int minor) + { + var query = _buildCollection.Aggregate() + .Match(new BsonDocument + { + new BsonElement(nameof(BuildModel.MajorVersion), major), + new BsonElement(nameof(BuildModel.MinorVersion), minor) + }) + .Group(new BsonDocument("_id", $"${nameof(BuildModel.Lab)}")) + .Sort(new BsonDocument("_id", 1)); + + var grouping = await query.ToListAsync(); + + return (from g in grouping + where !g["_id"].IsBsonNull + select g["_id"].AsString).ToArray(); + } + + public async Task> SearchLabs(string search) + { + var result = await _buildCollection.Aggregate() + .Match(b => b.Lab != null) + .Match(b => b.Lab != "") + .Match(b => b.Lab.ToLower().Contains(search.ToLower())) + .Group(b => b.Lab.ToLower(), + // incoming bullshit hack + bg => new Tuple(bg.Key)) + .ToListAsync(); + + // work ourselves out of aforementioned bullshit hack + return result.Select(b => b.Item1).ToList(); + } + public async Task SelectAllLabsCount() { var query = _buildCollection.Aggregate() @@ -40,7 +75,7 @@ public async Task SelectAllLabsCount() public async Task> SelectLab(string lab, int limit = -1, int skip = 0) { var query = _buildCollection.Find(new BsonDocument(nameof(BuildModel.LabUrl), lab)) - .Sort(sortByDate) + .Sort(sortByCompileDate) .Skip(skip); if (limit > 0) @@ -51,9 +86,6 @@ public async Task> SelectLab(string lab, int limit = -1, int sk return await query.ToListAsync(); } - public async Task SelectLabCount(string lab) - { - return await _buildCollection.CountAsync(new BsonDocument(nameof(BuildModel.LabUrl), lab)); - } + public async Task SelectLabCount(string lab) { return await _buildCollection.CountAsync(new BsonDocument(nameof(BuildModel.LabUrl), lab)); } } } \ No newline at end of file diff --git a/BuildFeed/Models/Build/Build-Source.cs b/BuildFeed/Models/Build/Build-Source.cs index 723baf3..22e6ace 100644 --- a/BuildFeed/Models/Build/Build-Source.cs +++ b/BuildFeed/Models/Build/Build-Source.cs @@ -10,9 +10,16 @@ namespace BuildFeed.Models { public partial class Build { - public async Task SelectAllSources(int limit = -1, int skip = 0) { throw new NotImplementedException(); } + public Task SelectAllSources(int limit = -1, int skip = 0) + { + return Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) as TypeOfSource[]); + } - public async Task SelectAllSourcesCount() { throw new NotImplementedException(); } + public Task SelectAllSourcesCount() + { + return Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) + .LongLength); + } public async Task> SelectSource(TypeOfSource source, int limit = -1, int skip = 0) { diff --git a/BuildFeed/Models/Build/Build-Year.cs b/BuildFeed/Models/Build/Build-Year.cs index ab62f48..89af675 100644 --- a/BuildFeed/Models/Build/Build-Year.cs +++ b/BuildFeed/Models/Build/Build-Year.cs @@ -12,7 +12,8 @@ public partial class Build public async Task SelectAllYears(int limit = -1, int skip = 0) { var query = _buildCollection.Aggregate() - .Group(new BsonDocument("_id", $"${nameof(BuildModel.BuildTime)}.{nameof(DateTime.Year)}")) + .Match(Builders.Filter.Ne(b => b.BuildTime, null)) + .Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(BuildModel.BuildTime)}"))) .Sort(new BsonDocument("_id", -1)) .Skip(skip); @@ -24,13 +25,15 @@ public async Task SelectAllYears(int limit = -1, int skip = 0) var grouping = await query.ToListAsync(); return (from g in grouping + where !g["_id"].IsBsonNull select g["_id"].AsInt32).ToArray(); } public async Task SelectAllYearsCount() { var query = await _buildCollection.Aggregate() - .Group(new BsonDocument("_id", $"${nameof(BuildModel.BuildTime)}.{nameof(DateTime.Year)}")) + .Match(Builders.Filter.Ne(b => b.BuildTime, null)) + .Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(BuildModel.BuildTime)}"))) .ToListAsync(); return query.Count; @@ -42,7 +45,7 @@ public async Task> SelectYear(int year, int limit = -1, int ski new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)), Builders.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc)))) - .Sort(sortByDate) + .Sort(sortByCompileDate) .Skip(skip); if (limit > 0) diff --git a/BuildFeed/Models/Build/Build.cs b/BuildFeed/Models/Build/Build.cs index 524b19e..b9ae628 100644 --- a/BuildFeed/Models/Build/Build.cs +++ b/BuildFeed/Models/Build/Build.cs @@ -11,7 +11,9 @@ namespace BuildFeed.Models public partial class Build { private const string BUILD_COLLECTION_NAME = "builds"; - private static readonly BsonDocument sortByDate = new BsonDocument(nameof(BuildModel.BuildTime), -1); + private static readonly BsonDocument sortByCompileDate = new BsonDocument(nameof(BuildModel.BuildTime), -1); + private static readonly BsonDocument sortByAddedDate = new BsonDocument(nameof(BuildModel.Added), -1); + private static readonly BsonDocument sortByLeakedDate = new BsonDocument(nameof(BuildModel.LeakDate), -1); private static readonly BsonDocument sortByOrder = new BsonDocument { @@ -59,6 +61,14 @@ await _buildCollection.Indexes.CreateOneAsync(Builders.IndexKeys.Com Name = "_idx_legacy" }); } + + if (indexes.All(i => i["name"] != "_idx_lab")) + { + await _buildCollection.Indexes.CreateOneAsync(Builders.IndexKeys.Ascending(b => b.Lab), new CreateIndexOptions + { + Name = "_idx_lab" + }); + } } [DataObjectMethod(DataObjectMethodType.Select, true)] @@ -84,6 +94,70 @@ public async Task SelectByLegacyId(long id) .SingleOrDefaultAsync(); } + [DataObjectMethod(DataObjectMethodType.Select, false)] + public async Task> SelectBuildsByOrder(int limit = -1, int skip = 0) + { + var query = _buildCollection + .Find(new BsonDocument()) + .Sort(sortByOrder) + .Skip(skip); + + if (limit > 0) + { + query = query.Limit(limit); + } + + return await query.ToListAsync(); + } + + [DataObjectMethod(DataObjectMethodType.Select, false)] + public async Task> SelectBuildsByCompileDate(int limit = -1, int skip = 0) + { + var query = _buildCollection + .Find(new BsonDocument()) + .Sort(sortByCompileDate) + .Skip(skip); + + if (limit > 0) + { + query = query.Limit(limit); + } + + return await query.ToListAsync(); + } + + [DataObjectMethod(DataObjectMethodType.Select, false)] + public async Task> SelectBuildsByAddedDate(int limit = -1, int skip = 0) + { + var query = _buildCollection + .Find(new BsonDocument()) + .Sort(sortByAddedDate) + .Skip(skip); + + if (limit > 0) + { + query = query.Limit(limit); + } + + return await query.ToListAsync(); + } + + [DataObjectMethod(DataObjectMethodType.Select, false)] + public async Task> SelectBuildsByLeakedDate(int limit = -1, int skip = 0) + { + var query = _buildCollection + .Find(new BsonDocument()) + .Sort(sortByLeakedDate) + .Skip(skip); + + if (limit > 0) + { + query = query.Limit(limit); + } + + return await query.ToListAsync(); + } + [DataObjectMethod(DataObjectMethodType.Insert, true)] public async Task Insert(BuildModel item) { diff --git a/BuildFeed/Views/front/viewGroup.cshtml b/BuildFeed/Views/front/viewGroup.cshtml index 5ed66eb..9469759 100644 --- a/BuildFeed/Views/front/viewGroup.cshtml +++ b/BuildFeed/Views/front/viewGroup.cshtml @@ -1,7 +1,7 @@ @model Tuple> @using Humanizer; @{ - ViewBag.Title = string.Format("{0} | {1}", Model.Item1.ToString(), BuildFeed.Local.Common.SiteName); + ViewBag.Title = $"{Model.Item1} | {BuildFeed.Local.Common.SiteName}"; }

@Model.Item1.ToString()

@@ -10,11 +10,11 @@ @foreach (var build in Model.Item2) {
-

@build.Lab

+

@(string.IsNullOrEmpty(build.Lab) ? "{Unknown}" : build.Lab)

@if (User.Identity.IsAuthenticated) {

- @BuildFeed.Local.Front.Edit + @BuildFeed.Local.Front.Edit @if (Roles.IsUserInRole("Administrators")) { @BuildFeed.Local.Front.Delete diff --git a/BuildFeed/Views/front/viewLab.cshtml b/BuildFeed/Views/front/viewLab.cshtml index bad92dc..abd01e9 100644 --- a/BuildFeed/Views/front/viewLab.cshtml +++ b/BuildFeed/Views/front/viewLab.cshtml @@ -37,7 +37,7 @@ @foreach (var build in Model) {

-

@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)

+

@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)

@if (User.Identity.IsAuthenticated) {

diff --git a/BuildFeed/Views/front/viewSource.cshtml b/BuildFeed/Views/front/viewSource.cshtml index 6acfb01..610f6ff 100644 --- a/BuildFeed/Views/front/viewSource.cshtml +++ b/BuildFeed/Views/front/viewSource.cshtml @@ -31,7 +31,7 @@ @foreach (var build in Model) {

-

@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)

+

@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)

@if (User.Identity.IsAuthenticated) {

diff --git a/BuildFeed/Views/front/viewVersion.cshtml b/BuildFeed/Views/front/viewVersion.cshtml index fcbe448..3255d70 100644 --- a/BuildFeed/Views/front/viewVersion.cshtml +++ b/BuildFeed/Views/front/viewVersion.cshtml @@ -31,7 +31,7 @@ @foreach (var build in Model) {

-

@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)

+

@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)

@if (User.Identity.IsAuthenticated) {

diff --git a/BuildFeed/Views/shared/_default.cshtml b/BuildFeed/Views/shared/_default.cshtml index 0bc9630..dcedd60 100644 --- a/BuildFeed/Views/shared/_default.cshtml +++ b/BuildFeed/Views/shared/_default.cshtml @@ -1,9 +1,9 @@ @using System.Globalization; @{ - bool IsRTL = CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft; + bool isRtl = CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft; } - + @@ -17,7 +17,7 @@ @Styles.Render("~/content/css") - @if (IsRTL) + @if (isRtl) { @Styles.Render("~/content/rtl") } @@ -66,22 +66,22 @@