-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 88b47a9
Showing
16 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Nuget Packages and compiled files | ||
**/bin | ||
**/obj | ||
|
||
# Jetbrains Rider files | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System.Collections.Generic; | ||
using Reader.Parser.Opml; | ||
using Xunit; | ||
|
||
namespace Reader.Parser.Tests | ||
{ | ||
public class OpmlParserTests | ||
{ | ||
[Fact] | ||
public void GetFeeds_ValidInpunt_ReturnAllFeeds() | ||
{ | ||
// TODO: write proper unit tests | ||
var parser = new Reader.Parser.Opml.Parser("<rss></rss>"); | ||
|
||
var expected = new List<OpmlSubscription>(); | ||
var actual = parser.GetFeeds(); | ||
|
||
Assert.Equal(expected, actual); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
<IsPackable>false</IsPackable> | ||
<AssemblyName>Reader.Parser.Tests</AssemblyName> | ||
<RootNamespace>Reader.Parser.Tests</RootNamespace> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | ||
<PackageReference Include="xunit" Version="2.3.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | ||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\Reader.Parser\Reader.Parser.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System; | ||
|
||
namespace Reader.Parser.Feed | ||
{ | ||
public class Entry | ||
{ | ||
public string Title { get; set; } | ||
public string Link { get; set; } | ||
public string Description { get; set; } | ||
public DateTime PubDate { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using Reader.Parser.Feed.Rss; | ||
|
||
namespace Reader.Parser.Feed | ||
{ | ||
public static class FeedParserFactory | ||
{ | ||
|
||
public static IFeedParser GetParser(FeedType type) | ||
{ | ||
switch (type) | ||
{ | ||
case FeedType.Rss: | ||
return new RssParser(); | ||
case FeedType.Atom: | ||
return null; | ||
default: | ||
return null; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace Reader.Parser.Feed | ||
{ | ||
public enum FeedType | ||
{ | ||
Rss, | ||
Atom | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Reader.Parser.Feed | ||
{ | ||
public interface IFeedParser | ||
{ | ||
void Load(string feed); | ||
|
||
List<Entry> GetEntries(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Xml.Linq; | ||
|
||
namespace Reader.Parser.Feed.Rss | ||
{ | ||
public class RssParser : IFeedParser | ||
{ | ||
private XElement _document; | ||
|
||
public void Load(string feed) | ||
{ | ||
_document = XElement.Parse(feed); | ||
} | ||
|
||
public List<Entry> GetEntries() | ||
{ | ||
var elements = _document.Elements(); | ||
var channel = elements.Where(node => node.Name == "channel"); | ||
var entries = channel.Elements().Where(node => node.Name == "item"); | ||
return entries.Select(entry => new Entry | ||
{ | ||
Title = entry.Elements().First(node => node.Name == "title").Value, | ||
Description = entry.Elements().First(node => node.Name == "description").Value, | ||
Link = entry.Elements().First(node => node.Name == "link").Value, | ||
PubDate = Convert.ToDateTime(entry.Elements().First(node => node.Name == "pubDate").Value) | ||
}) | ||
.ToList(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Reader.Parser.Feed; | ||
|
||
namespace Reader.Parser.Opml | ||
{ | ||
public class OpmlSubscription | ||
{ | ||
public string Name { get; set; } | ||
public string XMlUrl { get; set; } | ||
public string HtmlUrl { get; set; } | ||
public FeedType Type { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Xml.Linq; | ||
using Reader.Parser.Feed; | ||
|
||
namespace Reader.Parser.Opml | ||
{ | ||
public class Parser | ||
{ | ||
private readonly XElement _document; | ||
|
||
public Parser(string opml) | ||
{ | ||
_document = XElement.Parse(opml); | ||
} | ||
|
||
public List<OpmlSubscription> GetFeeds() | ||
{ | ||
var elements = _document.Elements(); | ||
var body = elements.Where(node => node.Name == "body"); | ||
var categories = body.Elements().Where(node => node.Name == "outline" && node.HasElements); | ||
var feeds = categories.Elements() | ||
.Where(feed => feed.Name == "outline" && (string) feed.Attribute("type") == "rss"); | ||
|
||
return feeds.Select(feed => new OpmlSubscription | ||
{ | ||
Name = feed.Attribute("title")?.Value, | ||
HtmlUrl = feed.Attribute("htmlUrl")?.Value, | ||
XMlUrl = feed.Attribute("xmlUrl")?.Value, | ||
Type = FeedType.Rss | ||
}) | ||
.ToList(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>netstandard1.3</TargetFramework> | ||
<LangVersion>7.2</LangVersion> | ||
<AssemblyName>Reader.Parser</AssemblyName> | ||
<RootNamespace>Reader.Parser</RootNamespace> | ||
</PropertyGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reader", "Reader\Reader.csproj", "{8AE72769-0EEF-42FB-AF4A-37C4FE5BCE36}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reader.Parser", "Reader.Parser\Reader.Parser.csproj", "{D48C357E-29DC-457B-967F-34BFB1C66408}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reader.Parser.Tests", "Reader.Parser.Tests\Reader.Parser.Tests.csproj", "{FD30BA95-C3DD-483E-9F98-9AEAC809DF32}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{8AE72769-0EEF-42FB-AF4A-37C4FE5BCE36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{8AE72769-0EEF-42FB-AF4A-37C4FE5BCE36}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{8AE72769-0EEF-42FB-AF4A-37C4FE5BCE36}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{8AE72769-0EEF-42FB-AF4A-37C4FE5BCE36}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{D48C357E-29DC-457B-967F-34BFB1C66408}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{D48C357E-29DC-457B-967F-34BFB1C66408}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{D48C357E-29DC-457B-967F-34BFB1C66408}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{D48C357E-29DC-457B-967F-34BFB1C66408}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{FD30BA95-C3DD-483E-9F98-9AEAC809DF32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{FD30BA95-C3DD-483E-9F98-9AEAC809DF32}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{FD30BA95-C3DD-483E-9F98-9AEAC809DF32}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{FD30BA95-C3DD-483E-9F98-9AEAC809DF32}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
|
||
namespace Reader | ||
{ | ||
public static class HttpClient | ||
{ | ||
private static System.Net.Http.HttpClient _instance; | ||
|
||
public static System.Net.Http.HttpClient GetInstance() | ||
{ | ||
return _instance ?? (_instance = new System.Net.Http.HttpClient()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
namespace Reader | ||
{ | ||
class Program | ||
{ | ||
static async Task Main(string[] args) | ||
{ | ||
var data = System.IO.File.ReadAllText("feed.xml"); | ||
|
||
var opmlParser = new Parser.Opml.Parser(data); | ||
var feeds = opmlParser.GetFeeds(); | ||
|
||
var subscription = new Subscription(); | ||
var entries = await subscription.GetEntriesAsync(feeds); | ||
|
||
foreach (var entry in entries.OrderByDescending(entry => entry.PubDate)) | ||
{ | ||
Console.WriteLine( | ||
$"{entry.PubDate.ToLocalTime().ToShortDateString()} {entry.PubDate.ToLocalTime().ToShortTimeString()} - {entry.Title} {entry.Link}"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
<LangVersion>7.2</LangVersion> | ||
<AssemblyName>Reader</AssemblyName> | ||
<RootNamespace>Reader</RootNamespace> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\Reader.Parser\Reader.Parser.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Reader.Parser.Feed; | ||
using Reader.Parser.Opml; | ||
|
||
namespace Reader | ||
{ | ||
public class Subscription | ||
{ | ||
public async Task<List<Entry>> GetEntriesAsync(List<OpmlSubscription> subscriptions) | ||
{ | ||
var entries = new List<Entry>(); | ||
foreach (var feed in subscriptions) | ||
{ | ||
try | ||
{ | ||
var client = HttpClient.GetInstance(); | ||
var feedData = await client.GetAsync(feed.XMlUrl); | ||
var body = await feedData.Content.ReadAsStringAsync(); | ||
|
||
var parser = FeedParserFactory.GetParser(feed.Type); | ||
parser.Load(body); | ||
|
||
parser.GetEntries().ForEach(entry => { entries.Add(entry); }); | ||
} | ||
catch (Exception) | ||
{ | ||
// ignored | ||
} | ||
} | ||
|
||
return entries; | ||
} | ||
} | ||
} |