it worksgit add .

This commit is contained in:
Tommy Parnell
2015-10-07 22:23:33 -04:00
parent b348bc56ad
commit 95cb733e84
23 changed files with 204 additions and 229 deletions

View File

@@ -2,38 +2,41 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotNetMashup.Web.Global;
using DotNetMashup.Web.Repositories;
using DotNetMashup.Web.ViewModel;
using Microsoft.AspNet.Mvc;
namespace DotNetMashup.Web.Controllers
{
public class HomeController : Controller
{
private readonly ISiteSetting setting;
private readonly Factory.RepositoryFactory factory;
public HomeController(Factory.RepositoryFactory factory)
public HomeController(Factory.RepositoryFactory factory, ISiteSetting setting)
{
if(factory == null)
{
throw new ArgumentNullException("factory");
}
if(setting == null)
{
throw new ArgumentNullException("setting");
}
this.factory = factory;
this.setting = setting;
}
public async Task<IActionResult> Index()
public async Task<IActionResult> Index(int page = 1)
{
var data = await factory.GetData();
return View();
var factoryData = (await factory.GetData());
var data = factoryData.OrderByDescending(a => a.PublishedDate).Skip((page - 1) * setting.AmountPerPage).Take(setting.AmountPerPage * 2).ToList();
if(data.Count < 1)
{
return new HttpStatusCodeResult(404);
}
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
return View();
return View(new MashupViewModel { CurrentPage = 1, NextPage = data.Count > setting.AmountPerPage ? (int?)page + 1: null, Header = "DotNet Mashups", Posts = data.Take(setting.AmountPerPage)});
}
public IActionResult Error()

View File

@@ -37,13 +37,13 @@ namespace DotNetMashup.Web.Factory
this.cache = cache;
}
public async Task<List<IExternalData>> GetData()
public async Task<IEnumerable<IExternalData>> GetData()
{
var cachedData = this.cache.Get<List<IExternalData>>(cacheKey);
if(cachedData != null && cachedData.Count > 0) return cachedData;
var cachedData = this.cache.Get<IEnumerable<IExternalData>>(cacheKey);
if(cachedData != null && cachedData.Any()) return cachedData;
var tasks = Repos.Select(a => a.GetData());
await Task.WhenAll(tasks);
var result = tasks.SelectMany(a => a.Result).OrderBy(a => a.PublishedDate).ToList();
var result = tasks.SelectMany(a => a.Result).ToList();
cache.Set(cacheKey, result, new MemoryCacheEntryOptions { AbsoluteExpiration = DateTime.Now.AddHours(4) });
return result;
}

View File

@@ -8,5 +8,6 @@ namespace DotNetMashup.Web.Global
public interface ISiteSetting
{
List<string> Categories { get; }
short AmountPerPage { get; }
}
}

View File

@@ -7,6 +7,8 @@ namespace DotNetMashup.Web.Global
{
public class SiteSettings : ISiteSetting
{
public short AmountPerPage { get { return 12; } }
public List<string> Categories { get; } = new List<string> { "c#", "csharp", "cs", "asp.net", "NancyFx", "Nancy", "vNext", "asp.net 5" };
}
}

View File

@@ -17,6 +17,6 @@ namespace DotNetMashup.Web.Model
public string OriginalLink { get; set; }
public string Title { get; set; }
public DateTime PublishedDate { get; set; }
public DateTimeOffset PublishedDate { get; set; }
}
}

View File

@@ -1,12 +1,15 @@
namespace DotNetMashup.Web.Model
using System;
namespace DotNetMashup.Web.Model
{
//stolen idea from: https://github.com/NancyFx/Nancy.Blog/blob/master/src/Nancy.Blog/Model/MetaData.cs
public class BlogMetaData : IBlogMetaData
{
public string FeedUrl { get; set; }
public string Author { get; set; }
public string AuthorName { get; set; }
public string AuthorEmail { get; set; }
public string GravatarUrl { get; set; }
public string ImageUrl { get; set; }
public string Id { get; set; }
public string BlogHomepage { get; set;}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNetMashup.Web.Model
{
public class BlogPostExternalData : IExternalData
{
public string Title { get; set; }
public string Content { get; set; }
public DateTimeOffset PublishedDate { get; set; }
public string Summary { get; set; }
public string Localink { get; set; }
public string OriginalLink { get; set; }
public Author Author { get; set; }
}
}

View File

@@ -2,5 +2,6 @@
{
public class GithubAnnouncement : BaseExternalData
{
public int IssueNumber { get; set; }
}
}

View File

@@ -8,9 +8,10 @@ namespace DotNetMashup.Web.Model
public interface IBlogMetaData
{
string FeedUrl { get; set; }
string Author { get; set; }
string AuthorName { get; set; }
string AuthorEmail { get; set; }
string GravatarUrl { get; set; }
string ImageUrl { get; set; }
string Id { get; set; }
string BlogHomepage { get; set; }
}
}

View File

@@ -11,6 +11,6 @@ namespace DotNetMashup.Web.Model
string Content { get; set; }
string OriginalLink { get; set; }
Author Author { get; set; }
DateTime PublishedDate { get; set; }
DateTimeOffset PublishedDate { get; set; }
}
}

View File

@@ -18,12 +18,10 @@ namespace DotNetMashup.Web.Repositories
private readonly IMemoryCache cache;
private readonly IEnumerable<IBlogMetaData> _data;
private const string cacheKey = "blogposts";
public BlogPostRepository(IEnumerable<IBlogMetaData> data, ISiteSetting setting)
{
this._data = data;
this.cache = cache;
this.setting = setting;
}
@@ -45,7 +43,7 @@ namespace DotNetMashup.Web.Repositories
.Select(x =>
{
var metaauthor = _data.First(y => y.Id == x.Id);
var authorname = metaauthor.Author;
var authorname = metaauthor.AuthorName;
var authoremail = metaauthor.AuthorEmail;
var link = x.Item.Links.FirstOrDefault(y => y.RelationshipType == "alternate");
@@ -85,18 +83,17 @@ namespace DotNetMashup.Web.Repositories
content = summary;
}
return new BlogPost
return new BlogPostExternalData
{
Title = x.Item.Title.Text,
Summary = truncatedSummary,
Author = new Author { Email = authoremail, Name = authorname },
Author = new Author { Email = authoremail, Name = authorname, ImageUrl = metaauthor.ImageUrl, AuthorUrl = metaauthor.FeedUrl },
Localink = locallink,
OriginalLink = originallink,
PublishedDate = x.Item.PublishDate.DateTime,
Content = content
};
})
.ToList();
});
return data;
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DotNetMashup.Web.Model;
using Octokit;
@@ -19,14 +20,21 @@ namespace DotNetMashup.Web.Repositories
public async Task<IEnumerable<IExternalData>> GetData()
{
var client = new GitHubClient(new ProductHeaderValue("dotnetmashup"));
CommonMark.CommonMarkSettings.Default.AdditionalFeatures = CommonMark.CommonMarkAdditionalFeatures.All;
var client = new GitHubClient(new ProductHeaderValue("dotnetmashup"))
{
Credentials = new Credentials("151e2514adab9e8e44ab99fe8c71899fffa34caa")
};
var issues = await client.Issue.GetAllForRepository("aspnet", "Announcements");
return issues.Select(a => new GithubAnnouncement
{
Author = new Model.Author { Name = string.IsNullOrWhiteSpace(a.User.Name) ? a.User.Name : a.User.Login, AuthorUrl = a.User.Url, ImageUrl = a.User.AvatarUrl, Email = a.User.Email },
Content = a.Body,
Author = new Model.Author { Name = !string.IsNullOrWhiteSpace(a.User.Name) ? a.User.Name : a.User.Login, AuthorUrl = a.User.Url, ImageUrl = a.User.AvatarUrl, Email = a.User.Email },
Content = CommonMark.CommonMarkConverter.Convert(a.Body),
Title = a.Title,
OriginalLink = a.Url.AbsoluteUri
OriginalLink = a.HtmlUrl.AbsoluteUri,
IssueNumber = a.Number,
PublishedDate = a.CreatedAt
});
}
}

View File

@@ -17,19 +17,14 @@ namespace DotNetMashup.Web
{
public class Startup
{
private IEnumerable<BlogMetaData> _feedData = null;
private IEnumerable<IBlogMetaData> _feedData = null;
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
// Setup configuration sources.
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("config.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
_feedData = JsonConvert.DeserializeObject<IEnumerable<BlogMetaData>>(File.ReadAllText(Path.Combine(appEnv.ApplicationBasePath, "blogfeed.json")));
}
public IConfigurationRoot Configuration { get; set; }
//public IConfigurationRoot Configuration { get; set; }
// This method gets called by the runtime.
public void ConfigureServices(IServiceCollection services)

View File

@@ -9,6 +9,8 @@ namespace DotNetMashup.Web.ViewModel
public class MashupViewModel
{
public string Header { get; set; }
public IEnumerable<IExternalData> posts { get; set; }
public int CurrentPage { get; set; }
public int? NextPage { get; set; }
public IEnumerable<IExternalData> Posts { get; set; }
}
}

View File

@@ -1,104 +1,21 @@
@{
ViewData["Title"] = "Home Page";
@model DotNetMashup.Web.ViewModel.MashupViewModel
@{
ViewData["Title"] = "Dot Net Mashups!";
}
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="~/images/ASP-NET-Banners-01.png" alt="ASP.NET" class="img-responsive" />
<div class="container">
<div class="carousel-caption">
<p>
Learn how to build ASP.NET apps that can run anywhere.
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
Learn More
</a>
</p>
</div>
</div>
</div>
<div class="item">
<img src="~/images/Banner-02-VS.png" alt="Visual Studio" class="img-responsive" />
<div class="container">
<div class="carousel-caption">
<p>
There are powerful new features in Visual Studio for building modern web apps.
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
Learn More
</a>
</p>
</div>
</div>
</div>
<div class="item">
<img src="~/images/ASP-NET-Banners-02.png" alt="Package Management" class="img-responsive" />
<div class="container">
<div class="carousel-caption">
<p>
Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
Learn More
</a>
</p>
</div>
</div>
</div>
<div class="item">
<img src="~/images/Banner-01-Azure.png" alt="Microsoft Azure" class="img-responsive" />
<div class="container">
<div class="carousel-caption">
<p>
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
Learn More
</a>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<h2>Application uses</h2>
<ul>
<li>Sample pages using ASP.NET 5 (MVC 6)</li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> and <a href="http://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side resources</li>
<li>Theming using <a href="http://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
</ul>
@await Html.PartialAsync("Tiles", Model.Posts)
<br />
<br/>
@if(Model.NextPage.HasValue)
{
<div class="row" style="min-height: 100px">
<a asp-action="Index" asp-route-page="@Model.NextPage" class="pill col-md-offset-5 "> --> Next Page</a>
</div>
<div class="col-md-3">
<h2>New concepts</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of ASP.NET 5</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">Fundamentals in ASP.NET 5</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517849">Client-Side Development using npm, Bower and Gulp</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517850">Develop on different platforms</a></li>
</ul>
</div>
<div class="col-md-3">
<h2>Customize app</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398600">Add Controllers and Views</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398602">Add Data using EntityFramework</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398603">Add Authentication using Identity</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517848">Manage client-side packages using Bower/ Gulp</a></li>
</ul>
</div>
<div class="col-md-3">
<h2>Deploy</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517851">Run your app locally</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517852">Run your app on .NET Core</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517853">Run commands in your app</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
</ul>
</div>
</div>
}

View File

@@ -0,0 +1,14 @@
@model IEnumerable<DotNetMashup.Web.Model.IExternalData>
@{
ViewData["Title"] = "Dot Net Mashups!";
}
<div class="col-sm-12">
@foreach(var x in Model)
{
<div class="row">
@(await Html.PartialAsync("ExternalData", x))
</div>
}
</div>

View File

@@ -0,0 +1,15 @@
@model DotNetMashup.Web.Model.BlogPostExternalData
<div class="tile">
<div class="row">
<div class="col-md-2"><img class="img-responsive img" src="@Model.Author.ImageUrl" /></div>
<div class="col-md-8"><h2><i class="fa fa-book" style="font-size:32px"></i> @Model.Author.Name </h2></div>
</div>
<div class="row">
<div class="col-md-12">
<h2><a href="@Model.OriginalLink">@Model.Title</a></h2>
<p>@Html.Raw(Model.Content)</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,11 @@
@model DotNetMashup.Web.Model.GithubAnnouncement
<div class="tile">
<div class="row">
<div class="col-md-2"><img class="img-responsive img" src="@Model.Author.ImageUrl" /></div>
<div class="col-md-6"><h2><i class="fa fa-github" style="font-size:32px"></i> @Model.Author.Name <a href="@Model.OriginalLink">#@Model.IssueNumber</a> </h2></div>
</div>
<div class="row">
<div class="col-md-12"><p>@Html.Raw(@Model.Content)</p></div>
</div>
</div>

View File

@@ -0,0 +1,3 @@
@model DotNetMashup.Web.Model.IExternalData
@Html.DisplayFor(a => a)

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - DotNetMashup.Web</title>
@@ -8,7 +8,7 @@
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/lib/bootstrap-touch-carousel/dist/css/bootstrap-touch-carousel.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/css/bootstrap.min.css"
@@ -19,34 +19,15 @@
asp-fallback-test-class="carousel-caption" asp-fallback-test-property="display" asp-fallback-test-value="none" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</environment>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-controller="Home" asp-action="Index" class="navbar-brand">DotNetMashup.Web</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
</div>
</div>
</div>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
</head>
<body>
<div class="container body-content">
@RenderBody()
<hr />
</div>
<footer>
<p>&copy; 2015 - DotNetMashup.Web</p>
</footer>
</div>
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
@@ -76,5 +57,5 @@
</environment>
@RenderSection("scripts", required: false)
</body>
</body>
</html>

View File

@@ -2,8 +2,9 @@
{
"id": "tparnell",
"feedurl": "https://blog.tommyparnell.com/rss/",
"author": "Tommy Parnell",
"authoremail": "tparnell8@gmail.com",
"gravatarurl": "http://www.gravatar.com/avatar/333e3cea32cd17ff2007d131df336061.png?s=128"
"authorName": "Tommy Parnell",
"authorEmail": "tparnell8@gmail.com",
"imageUrl": "http://www.gravatar.com/avatar/333e3cea32cd17ff2007d131df336061.png?s=128",
"blogHomepage": "https://blog.tommyparnell.com"
}
]

View File

@@ -6,6 +6,7 @@
"gulp-concat": "2.5.2",
"gulp-cssmin": "0.1.7",
"gulp-uglify": "1.2.0",
"rimraf": "2.2.8"
"rimraf": "2.2.8",
"font-awesome": "4.4.0"
}
}

View File

@@ -17,7 +17,8 @@
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta7",
"Newtonsoft.Json": "7.0.1",
"TweetinviAPI": "0.9.9.7",
"Octokit": "0.16.0"
"Octokit": "0.16.0",
"CommonMark.NET": "0.9.1"
},
"commands": {