RSS & Twitter card changes

This commit is contained in:
Thomas Hounsell 2016-08-30 11:39:52 +01:00
parent 2d6364655d
commit fe082872d7
25 changed files with 104 additions and 84 deletions

View File

@ -94,6 +94,34 @@ public string FullBuildString
} }
} }
public string AlternateBuildString
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append($"{MajorVersion}.{MinorVersion}.{Number}");
if (Revision.HasValue)
{
sb.Append($".{Revision}");
}
if (!string.IsNullOrWhiteSpace(Lab))
{
sb.Append($" ({Lab}");
if (BuildTime.HasValue)
{
sb.Append($".{BuildTime.Value.ToString("yyMMdd-HHmm", CultureInfo.InvariantCulture.DateTimeFormat)}");
}
sb.Append(")");
}
return sb.ToString();
}
}
public ProjectFamily Family public ProjectFamily Family
{ {
get get

View File

@ -206,10 +206,13 @@
<ItemGroup> <ItemGroup>
<Content Include="BingSiteAuth.xml" /> <Content Include="BingSiteAuth.xml" />
<Content Include="browserconfig.xml" /> <Content Include="browserconfig.xml" />
<Content Include="content\card\Redstone2.png" /> <Content Include="res\card\Longhorn.png" />
<Content Include="content\card\Redstone.png" /> <Content Include="res\card\Redstone2.png" />
<Content Include="content\card\Threshold2.png" /> <Content Include="res\card\Redstone.png" />
<Content Include="content\card\Threshold.png" /> <Content Include="res\card\Threshold2.png" />
<Content Include="res\card\Threshold.png" />
<Content Include="res\card\Windows7.png" />
<Content Include="res\card\WindowsVista.png" />
<Content Include="res\css\dark.css"> <Content Include="res\css\dark.css">
<DependentUpon>dark.scss</DependentUpon> <DependentUpon>dark.scss</DependentUpon>
</Content> </Content>

View File

@ -2,7 +2,7 @@
using System.Globalization; using System.Globalization;
using System.Web.Mvc; using System.Web.Mvc;
namespace BuildFeed namespace BuildFeed.Code
{ {
public class DateTimeModelBinder : DefaultModelBinder public class DateTimeModelBinder : DefaultModelBinder
{ {

View File

@ -48,16 +48,13 @@ public async Task<ActionResult> IndexPage(int page)
ViewBag.PageNumber = page; ViewBag.PageNumber = page;
ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectAllGroupsCount()) / Convert.ToDouble(PAGE_SIZE)); ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectAllGroupsCount()) / Convert.ToDouble(PAGE_SIZE));
if (ViewBag.PageNumber > ViewBag.PageCount) if (ViewBag.PageNumber > ViewBag.PageCount) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return View("Pages", buildGroups); return View("Pages", buildGroups);
} }
[Route("group/{major}.{minor}.{number}.{revision}/", Order = 1)] [Route("group/{major}.{minor}.{number}.{revision}/", Order = 1), Route("group/{major}.{minor}.{number}/", Order = 5)]
[Route("group/{major}.{minor}.{number}/", Order = 5)] // for when there is no revision // for when there is no revision
#if !DEBUG #if !DEBUG
[OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme"), OutputCachePush(Order = 2)] [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName;lang;theme"), OutputCachePush(Order = 2)]
#endif #endif
@ -89,10 +86,7 @@ public async Task<ActionResult> ViewGroup(uint major, uint minor, uint number, u
public async Task<ActionResult> ViewBuild(Guid id) public async Task<ActionResult> ViewBuild(Guid id)
{ {
Build b = await _bModel.SelectById(id); Build b = await _bModel.SelectById(id);
if (b == null) if (b == null) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return View(b); return View(b);
} }
@ -100,10 +94,7 @@ public async Task<ActionResult> ViewBuild(Guid id)
public async Task<ActionResult> ViewBuild(long id) public async Task<ActionResult> ViewBuild(long id)
{ {
Build b = await _bModel.SelectByLegacyId(id); Build b = await _bModel.SelectByLegacyId(id);
if (b == null) if (b == null) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return RedirectToAction(nameof(ViewBuild), return RedirectToAction(nameof(ViewBuild),
new new
{ {
@ -119,12 +110,9 @@ public async Task<ActionResult> ViewBuild(long id)
public async Task<ActionResult> TwitterCard(Guid id) public async Task<ActionResult> TwitterCard(Guid id)
{ {
Build b = await _bModel.SelectById(id); Build b = await _bModel.SelectById(id);
if (b == null) if (b == null) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
string path = Path.Combine(Server.MapPath("~/content/card/"), $"{b.Family}.png"); string path = Path.Combine(Server.MapPath("~/res/card/"), $"{b.Family}.png");
bool backExists = System.IO.File.Exists(path); bool backExists = System.IO.File.Exists(path);
using (Bitmap bm = backExists using (Bitmap bm = backExists
@ -133,7 +121,6 @@ public async Task<ActionResult> TwitterCard(Guid id)
{ {
using (Graphics gr = Graphics.FromImage(bm)) using (Graphics gr = Graphics.FromImage(bm))
{ {
GraphicsPath gp = new GraphicsPath();
gr.CompositingMode = CompositingMode.SourceOver; gr.CompositingMode = CompositingMode.SourceOver;
gr.CompositingQuality = CompositingQuality.HighQuality; gr.CompositingQuality = CompositingQuality.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic; gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
@ -141,23 +128,52 @@ public async Task<ActionResult> TwitterCard(Guid id)
gr.SmoothingMode = SmoothingMode.HighQuality; gr.SmoothingMode = SmoothingMode.HighQuality;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality; gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
if (!backExists) if (!backExists) gr.FillRectangle(new SolidBrush(Color.FromArgb(0x24, 0x24, 0x23)), 0, 0, 1120, 600);
int left = 40;
using (GraphicsPath gp = new GraphicsPath())
{ {
gr.FillRectangle(new SolidBrush(Color.FromArgb(0x27, 0x2b, 0x30)), 0, 0, 1120, 600); foreach (char c in "BUILDFEED")
{
gp.AddString(c.ToString(), new FontFamily("Segoe UI Semibold"), 0, 32, new Point(left, 32), StringFormat.GenericTypographic);
RectangleF bounds = gp.GetBounds();
left = Convert.ToInt32(bounds.Width);
left += 52;
}
gr.FillPath(Brushes.White, gp);
} }
gp.AddString("BUILDFEED", new FontFamily("Segoe UI"), (int)FontStyle.Bold, 32, new Point(40, 32), StringFormat.GenericTypographic); using (GraphicsPath gp = new GraphicsPath())
gp.AddString($"{MvcExtensions.GetDisplayTextForEnum(b.Family)} (WinNT {b.MajorVersion}.{b.MinorVersion})", new FontFamily("Segoe UI"), 0, 48, new Point(40, 80), StringFormat.GenericTypographic); {
gp.AddString(b.Number.ToString(), new FontFamily("Segoe UI Light"), 0, 280, new Point(32, 96), StringFormat.GenericTypographic); gp.AddString(b.Number.ToString(), new FontFamily("Segoe UI Light"), 0, 260, new Point(32, 114), StringFormat.GenericTypographic);
gp.AddString(b.BuildTime.HasValue
? $"{b.Lab}\r\n{b.BuildTime.Value:yyyy/MM/dd HH:mm}" RectangleF bounds = gp.GetBounds();
: $"{b.Lab}", left = Convert.ToInt32(bounds.Width);
new FontFamily("Segoe UI"), left += 44;
0,
44, if (b.Revision.HasValue) gp.AddString($".{b.Revision}", new FontFamily("Segoe UI Light"), 0, 160, new Point(left, 220), StringFormat.GenericTypographic);
new Point(40, 440),
StringFormat.GenericTypographic); gr.DrawPath(new Pen(new SolidBrush(Color.FromArgb(0x24, 0x24, 0x23)), 4), gp);
gr.FillPath(Brushes.White, gp); gr.FillPath(Brushes.White, gp);
}
using (GraphicsPath gp = new GraphicsPath())
{
gp.AddString($"{MvcExtensions.GetDisplayTextForEnum(b.Family)} (NT {b.MajorVersion}.{b.MinorVersion})", new FontFamily("Segoe UI Light"), 0, 48, new Point(40, 80), StringFormat.GenericTypographic);
gp.AddString(char.ConvertFromUtf32(0xf126), new FontFamily("FontAwesome"), 0, 28, new Point(46, 468), StringFormat.GenericTypographic);
gp.AddString(b.Lab, new FontFamily("Segoe UI Light"), 0, 40, new Point(88, 450), StringFormat.GenericTypographic);
if (b.BuildTime.HasValue)
{
gp.AddString(char.ConvertFromUtf32(0xf017), new FontFamily("FontAwesome"), 0, 28, new Point(40, 538), StringFormat.GenericTypographic);
gp.AddString($"{b.BuildTime.Value.ToShortTimeString()} on {b.BuildTime.Value.ToLongDateString()}", new FontFamily("Segoe UI Light"), 0, 40, new Point(88, 520), StringFormat.GenericTypographic);
}
gr.FillPath(Brushes.White, gp);
}
Response.ContentType = "image/png"; Response.ContentType = "image/png";
bm.Save(Response.OutputStream, ImageFormat.Png); bm.Save(Response.OutputStream, ImageFormat.Png);
@ -171,10 +187,7 @@ public async Task<ActionResult> TwitterCard(Guid id)
public async Task<ActionResult> TwitterCard(long id) public async Task<ActionResult> TwitterCard(long id)
{ {
Build b = await _bModel.SelectByLegacyId(id); Build b = await _bModel.SelectByLegacyId(id);
if (b == null) if (b == null) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return RedirectToAction(nameof(TwitterCard), return RedirectToAction(nameof(TwitterCard),
new new
{ {
@ -209,10 +222,7 @@ public async Task<ActionResult> ViewLabPage(string lab, int page)
ViewBag.PageNumber = page; 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(PAGE_SIZE));
if (ViewBag.PageNumber > ViewBag.PageCount) if (ViewBag.PageNumber > ViewBag.PageCount) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return View("viewLab", builds); return View("viewLab", builds);
} }
@ -244,10 +254,7 @@ public async Task<ActionResult> ViewSourcePage(TypeOfSource source, int page)
ViewBag.PageNumber = page; 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(PAGE_SIZE));
if (ViewBag.PageNumber > ViewBag.PageCount) if (ViewBag.PageNumber > ViewBag.PageCount) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return View("viewSource", builds); return View("viewSource", builds);
} }
@ -279,10 +286,7 @@ public async Task<ActionResult> ViewYearPage(int year, int page)
ViewBag.PageNumber = page; 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(PAGE_SIZE));
if (ViewBag.PageNumber > ViewBag.PageCount) if (ViewBag.PageNumber > ViewBag.PageCount) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return View("viewYear", builds); return View("viewYear", builds);
} }
@ -315,10 +319,7 @@ public async Task<ActionResult> ViewVersionPage(uint major, uint minor, int page
ViewBag.PageNumber = page; 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(PAGE_SIZE));
if (ViewBag.PageNumber > ViewBag.PageCount) if (ViewBag.PageNumber > ViewBag.PageCount) return new HttpNotFoundResult();
{
return new HttpNotFoundResult();
}
return View("viewVersion", builds); return View("viewVersion", builds);
} }
@ -342,14 +343,8 @@ public async Task<ActionResult> AddBuild(Build build)
{ {
build.Added = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc); build.Added = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
build.Modified = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc); build.Modified = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
if (build.BuildTime.HasValue) if (build.BuildTime.HasValue) build.BuildTime = DateTime.SpecifyKind(build.BuildTime.Value, DateTimeKind.Utc);
{ if (build.LeakDate.HasValue) build.LeakDate = DateTime.SpecifyKind(build.LeakDate.Value, DateTimeKind.Utc);
build.BuildTime = DateTime.SpecifyKind(build.BuildTime.Value, DateTimeKind.Utc);
}
if (build.LeakDate.HasValue)
{
build.LeakDate = DateTime.SpecifyKind(build.LeakDate.Value, DateTimeKind.Utc);
}
await _bModel.Insert(build); await _bModel.Insert(build);
} }
catch catch
@ -379,14 +374,8 @@ public async Task<ActionResult> EditBuild(Guid id, Build build)
{ {
try try
{ {
if (build.BuildTime.HasValue) if (build.BuildTime.HasValue) build.BuildTime = DateTime.SpecifyKind(build.BuildTime.Value, DateTimeKind.Utc);
{ if (build.LeakDate.HasValue) build.LeakDate = DateTime.SpecifyKind(build.LeakDate.Value, DateTimeKind.Utc);
build.BuildTime = DateTime.SpecifyKind(build.BuildTime.Value, DateTimeKind.Utc);
}
if (build.LeakDate.HasValue)
{
build.LeakDate = DateTime.SpecifyKind(build.LeakDate.Value, DateTimeKind.Utc);
}
await _bModel.Update(build); await _bModel.Update(build);
} }
catch catch

View File

@ -28,7 +28,7 @@ public async Task<ActionResult> Index()
Items = (from build in builds Items = (from build in builds
select new Item select new Item
{ {
Title = build.FullBuildString, Title = build.AlternateBuildString,
Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"), Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"),
Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}", Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}",
Categories = { Categories = {
@ -58,7 +58,7 @@ public async Task<ActionResult> Added()
Items = (from build in builds Items = (from build in builds
select new Item select new Item
{ {
Title = build.FullBuildString, Title = build.AlternateBuildString,
Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"), Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"),
Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}", Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}",
Categories = { Categories = {
@ -88,7 +88,7 @@ public async Task<ActionResult> Leaked()
Items = (from build in builds Items = (from build in builds
select new Item select new Item
{ {
Title = build.FullBuildString, Title = build.AlternateBuildString,
Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"), Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"),
Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}", Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}",
Categories = { Categories = {
@ -118,7 +118,7 @@ public async Task<ActionResult> Version()
Items = (from build in builds Items = (from build in builds
select new Item select new Item
{ {
Title = build.FullBuildString, Title = build.AlternateBuildString,
Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"), Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"),
Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}", Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}",
Categories = { Categories = {
@ -147,7 +147,7 @@ public async Task<ActionResult> Lab(string lab)
Items = (from build in builds Items = (from build in builds
select new Item select new Item
{ {
Title = build.FullBuildString, Title = build.AlternateBuildString,
Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"), Link = new Uri($"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}"),
Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}", Permalink = $"{Request.Url.Scheme}://{Request.Url.Authority}{Url.Action(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}",
Categories = { Categories = {

View File

@ -1,10 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Web; using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
using BuildFeed.Code;
using BuildFeed.Code.Options; using BuildFeed.Code.Options;
using BuildFeed.Model; using BuildFeed.Model;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@ -179,7 +179,7 @@ article {
justify-content: center; justify-content: center;
margin: 0 -0.75em; } margin: 0 -0.75em; }
article .build-group-listing .build-group { article .build-group-listing .build-group {
width: 180px; width: 175px;
flex-grow: 1; flex-grow: 1;
margin: 0 0.75em 1em; margin: 0 0.75em 1em;
box-sizing: border-box; } box-sizing: border-box; }

File diff suppressed because one or more lines are too long

View File

@ -304,7 +304,7 @@ article
.build-group .build-group
{ {
width: 180px; width: 175px;
flex-grow: 1; flex-grow: 1;
margin: 0 0.75em 1em; margin: 0 0.75em 1em;
box-sizing: border-box; box-sizing: border-box;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.