From b348bc56ad211bc561e16e480c69ef9258daec88 Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Wed, 7 Oct 2015 19:19:23 -0400 Subject: [PATCH] add github provider --- .../Controllers/HomeController.cs | 8 +-- .../Factory/RepositoryFactory.cs | 51 +++++++++++++++++++ src/DotNetMashup.Web/Model/Author.cs | 15 ++++++ .../Model/BaseExternalData.cs | 22 ++++++++ .../Model/{MetaData.cs => BlogMetaData.cs} | 2 +- src/DotNetMashup.Web/Model/BlogPost.cs | 3 +- .../Model/GithubAnnouncement.cs | 6 +++ .../Model/{IMetaData.cs => IBlogMetaData.cs} | 2 +- src/DotNetMashup.Web/Model/IExternalData.cs | 3 +- .../Repositories/BlogPostRepository.cs | 21 +++----- .../Repositories/GitHubRepository.cs | 33 ++++++++++++ src/DotNetMashup.Web/Startup.cs | 9 ++-- src/DotNetMashup.Web/project.json | 5 +- 13 files changed, 151 insertions(+), 29 deletions(-) create mode 100644 src/DotNetMashup.Web/Factory/RepositoryFactory.cs create mode 100644 src/DotNetMashup.Web/Model/Author.cs create mode 100644 src/DotNetMashup.Web/Model/BaseExternalData.cs rename src/DotNetMashup.Web/Model/{MetaData.cs => BlogMetaData.cs} (89%) create mode 100644 src/DotNetMashup.Web/Model/GithubAnnouncement.cs rename src/DotNetMashup.Web/Model/{IMetaData.cs => IBlogMetaData.cs} (90%) create mode 100644 src/DotNetMashup.Web/Repositories/GitHubRepository.cs diff --git a/src/DotNetMashup.Web/Controllers/HomeController.cs b/src/DotNetMashup.Web/Controllers/HomeController.cs index af5e77b..dea5487 100644 --- a/src/DotNetMashup.Web/Controllers/HomeController.cs +++ b/src/DotNetMashup.Web/Controllers/HomeController.cs @@ -9,16 +9,16 @@ namespace DotNetMashup.Web.Controllers { public class HomeController : Controller { - private readonly BlogPostRepository factory; + private readonly Factory.RepositoryFactory factory; - public HomeController(BlogPostRepository factory) + public HomeController(Factory.RepositoryFactory factory) { this.factory = factory; } - public IActionResult Index() + public async Task Index() { - var data = factory.GetData(); + var data = await factory.GetData(); return View(); } diff --git a/src/DotNetMashup.Web/Factory/RepositoryFactory.cs b/src/DotNetMashup.Web/Factory/RepositoryFactory.cs new file mode 100644 index 0000000..0e2395f --- /dev/null +++ b/src/DotNetMashup.Web/Factory/RepositoryFactory.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DotNetMashup.Web.Global; +using DotNetMashup.Web.Model; +using DotNetMashup.Web.Repositories; +using Microsoft.Framework.Caching.Memory; + +namespace DotNetMashup.Web.Factory +{ + public class RepositoryFactory + { + private readonly IMemoryCache cache; + private List Repos; + private const string cacheKey = "data"; + + public RepositoryFactory(IEnumerable data, ISiteSetting setting, IMemoryCache cache) + { + if(data == null) + { + throw new ArgumentNullException("data"); + } + if(setting == null) + { + throw new ArgumentNullException("setting"); + } + if(cache == null) + { + throw new ArgumentNullException("cache"); + } + Repos = new List() + { + new GitHubRepository(), + new BlogPostRepository(data, setting) + }; + this.cache = cache; + } + + public async Task> GetData() + { + var cachedData = this.cache.Get>(cacheKey); + if(cachedData != null && cachedData.Count > 0) 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(); + cache.Set(cacheKey, result, new MemoryCacheEntryOptions { AbsoluteExpiration = DateTime.Now.AddHours(4) }); + return result; + } + } +} \ No newline at end of file diff --git a/src/DotNetMashup.Web/Model/Author.cs b/src/DotNetMashup.Web/Model/Author.cs new file mode 100644 index 0000000..3101abd --- /dev/null +++ b/src/DotNetMashup.Web/Model/Author.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace DotNetMashup.Web.Model +{ + public struct Author + { + public string Name { get; set; } + public string ImageUrl { get; set; } + public string AuthorUrl { get; set; } + public string Email { get; set; } + } +} \ No newline at end of file diff --git a/src/DotNetMashup.Web/Model/BaseExternalData.cs b/src/DotNetMashup.Web/Model/BaseExternalData.cs new file mode 100644 index 0000000..d7e4921 --- /dev/null +++ b/src/DotNetMashup.Web/Model/BaseExternalData.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace DotNetMashup.Web.Model +{ + /// + /// Simple class to implement the standard external interface + /// + public class BaseExternalData : IExternalData + { + public Author Author { get; set; } + + public string Content { get; set; } + + public string OriginalLink { get; set; } + + public string Title { get; set; } + public DateTime PublishedDate { get; set; } + } +} \ No newline at end of file diff --git a/src/DotNetMashup.Web/Model/MetaData.cs b/src/DotNetMashup.Web/Model/BlogMetaData.cs similarity index 89% rename from src/DotNetMashup.Web/Model/MetaData.cs rename to src/DotNetMashup.Web/Model/BlogMetaData.cs index b1cbe17..46fddb6 100644 --- a/src/DotNetMashup.Web/Model/MetaData.cs +++ b/src/DotNetMashup.Web/Model/BlogMetaData.cs @@ -1,7 +1,7 @@ namespace DotNetMashup.Web.Model { //stolen idea from: https://github.com/NancyFx/Nancy.Blog/blob/master/src/Nancy.Blog/Model/MetaData.cs - public class MetaData : IMetaData + public class BlogMetaData : IBlogMetaData { public string FeedUrl { get; set; } public string Author { get; set; } diff --git a/src/DotNetMashup.Web/Model/BlogPost.cs b/src/DotNetMashup.Web/Model/BlogPost.cs index 7f152f8..0fd5509 100644 --- a/src/DotNetMashup.Web/Model/BlogPost.cs +++ b/src/DotNetMashup.Web/Model/BlogPost.cs @@ -13,7 +13,6 @@ namespace DotNetMashup.Web.Model public string Summary { get; set; } public string Localink { get; set; } public string OriginalLink { get; set; } - public string Author { get; set; } - public string AuthorEmail { get; set; } + public Author Author { get; set; } } } \ No newline at end of file diff --git a/src/DotNetMashup.Web/Model/GithubAnnouncement.cs b/src/DotNetMashup.Web/Model/GithubAnnouncement.cs new file mode 100644 index 0000000..aa15ecc --- /dev/null +++ b/src/DotNetMashup.Web/Model/GithubAnnouncement.cs @@ -0,0 +1,6 @@ +namespace DotNetMashup.Web.Model +{ + public class GithubAnnouncement : BaseExternalData + { + } +} diff --git a/src/DotNetMashup.Web/Model/IMetaData.cs b/src/DotNetMashup.Web/Model/IBlogMetaData.cs similarity index 90% rename from src/DotNetMashup.Web/Model/IMetaData.cs rename to src/DotNetMashup.Web/Model/IBlogMetaData.cs index 5899247..025e408 100644 --- a/src/DotNetMashup.Web/Model/IMetaData.cs +++ b/src/DotNetMashup.Web/Model/IBlogMetaData.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; namespace DotNetMashup.Web.Model { - public interface IMetaData + public interface IBlogMetaData { string FeedUrl { get; set; } string Author { get; set; } diff --git a/src/DotNetMashup.Web/Model/IExternalData.cs b/src/DotNetMashup.Web/Model/IExternalData.cs index 557a5be..3d8e974 100644 --- a/src/DotNetMashup.Web/Model/IExternalData.cs +++ b/src/DotNetMashup.Web/Model/IExternalData.cs @@ -10,6 +10,7 @@ namespace DotNetMashup.Web.Model string Title { get; set; } string Content { get; set; } string OriginalLink { get; set; } - string Author { get; set; } + Author Author { get; set; } + DateTime PublishedDate { get; set; } } } \ No newline at end of file diff --git a/src/DotNetMashup.Web/Repositories/BlogPostRepository.cs b/src/DotNetMashup.Web/Repositories/BlogPostRepository.cs index 4a9a4e9..28a7684 100644 --- a/src/DotNetMashup.Web/Repositories/BlogPostRepository.cs +++ b/src/DotNetMashup.Web/Repositories/BlogPostRepository.cs @@ -17,10 +17,10 @@ namespace DotNetMashup.Web.Repositories private readonly ISiteSetting setting; private readonly IMemoryCache cache; - private readonly IEnumerable _data; + private readonly IEnumerable _data; private const string cacheKey = "blogposts"; - public BlogPostRepository(IEnumerable data, IMemoryCache cache, ISiteSetting setting) + public BlogPostRepository(IEnumerable data, ISiteSetting setting) { this._data = data; this.cache = cache; @@ -37,8 +37,6 @@ namespace DotNetMashup.Web.Repositories public async Task> GetData() { - var cachedata = cache.Get>(cacheKey); - if(cachedata != null) return cachedata; var syndicationFeeds = await GetSyndicationFeeds(_data); var data = syndicationFeeds @@ -91,21 +89,18 @@ namespace DotNetMashup.Web.Repositories { Title = x.Item.Title.Text, Summary = truncatedSummary, - Author = authorname, - AuthorEmail = authoremail, + Author = new Author { Email = authoremail, Name = authorname }, Localink = locallink, OriginalLink = originallink, PublishedDate = x.Item.PublishDate.DateTime, Content = content }; }) - .OrderByDescending(x => x.PublishedDate) .ToList(); - cache.Set(cacheKey, data.Cast()); return data; } - private async static Task>> GetSyndicationFeeds(IEnumerable metadataEntries) + private async static Task>> GetSyndicationFeeds(IEnumerable metadataEntries) { var syndicationFeeds = new List>(); foreach(var metadata in metadataEntries) @@ -122,15 +117,14 @@ namespace DotNetMashup.Web.Repositories try { SyndicationFeed feed = null; - await Task.Run(() => { + await Task.Run(() => + { using(var reader = XmlReader.Create(url)) { feed = SyndicationFeed.Load(reader); } - }); - - + if(feed != null) { feeds.Add(new KeyValuePair(id, feed)); @@ -152,7 +146,6 @@ namespace DotNetMashup.Web.Repositories //Unable to load RSS feed } return feeds; - } } } \ No newline at end of file diff --git a/src/DotNetMashup.Web/Repositories/GitHubRepository.cs b/src/DotNetMashup.Web/Repositories/GitHubRepository.cs new file mode 100644 index 0000000..7ca6c50 --- /dev/null +++ b/src/DotNetMashup.Web/Repositories/GitHubRepository.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DotNetMashup.Web.Model; +using Octokit; + +namespace DotNetMashup.Web.Repositories +{ + public class GitHubRepository : IRepository + { + public string FactoryName + { + get + { + return "Github"; + } + } + + public async Task> GetData() + { + var client = new GitHubClient(new ProductHeaderValue("dotnetmashup")); + 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, + Title = a.Title, + OriginalLink = a.Url.AbsoluteUri + }); + } + } +} \ No newline at end of file diff --git a/src/DotNetMashup.Web/Startup.cs b/src/DotNetMashup.Web/Startup.cs index cfc80c0..5ac1f65 100644 --- a/src/DotNetMashup.Web/Startup.cs +++ b/src/DotNetMashup.Web/Startup.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.IO; -using DotNetMashup.Web.Repositories; +using DotNetMashup.Web.Factory; using DotNetMashup.Web.Global; using DotNetMashup.Web.Model; +using DotNetMashup.Web.Repositories; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.Dnx.Runtime; @@ -16,7 +17,7 @@ namespace DotNetMashup.Web { public class Startup { - private IEnumerable _feedData = null; + private IEnumerable _feedData = null; public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv) { @@ -25,7 +26,7 @@ namespace DotNetMashup.Web .AddJsonFile("config.json") .AddEnvironmentVariables(); Configuration = builder.Build(); - _feedData = JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(appEnv.ApplicationBasePath, "blogfeed.json"))); + _feedData = JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(appEnv.ApplicationBasePath, "blogfeed.json"))); } public IConfigurationRoot Configuration { get; set; } @@ -42,7 +43,7 @@ namespace DotNetMashup.Web return new MemoryCache(new MemoryCacheOptions()); }); services.AddInstance(_feedData); - services.AddSingleton(); + services.AddSingleton(); // Add MVC services to the services container. services.AddMvc(); diff --git a/src/DotNetMashup.Web/project.json b/src/DotNetMashup.Web/project.json index 4c7cd2a..03b406b 100644 --- a/src/DotNetMashup.Web/project.json +++ b/src/DotNetMashup.Web/project.json @@ -16,7 +16,8 @@ "Microsoft.Framework.Logging.Debug": "1.0.0-beta7", "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta7", "Newtonsoft.Json": "7.0.1", - "TweetinviAPI": "0.9.9.7" + "TweetinviAPI": "0.9.9.7", + "Octokit": "0.16.0" }, "commands": { @@ -24,7 +25,7 @@ }, "frameworks": { - "dnx46": { + "dnx451": { "frameworkAssemblies": { "System.ServiceModel": "4.0.0.0" }