Skip to content

Commit

Permalink
v1.3.0 - More Robust Feed Parsing & Description Limiter
Browse files Browse the repository at this point in the history
  • Loading branch information
Qolors committed Jan 20, 2024
1 parent b7593ed commit b92153f
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 29 deletions.
1 change: 1 addition & 0 deletions FeedCord/FeedCord.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CodeHollow.FeedReader" Version="1.2.6" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.54" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0-rc.2.23479.6" />
Expand Down
1 change: 1 addition & 0 deletions FeedCord/docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- **AuthorUrl**: The external link it will send users to when they click on the Author's Name.
- **FallbackImage**: FeedCord always attemps to grab the webpage's image from metadata. If for some reason this fails, it will display this image instead.
- **Color**: Color of the Post's embedded message.
- **DescriptionLimit**: Limits the length of the description of the post to this number.

---

5 changes: 4 additions & 1 deletion FeedCord/src/Common/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal class Config
public int Color { get; }
public int RssCheckIntervalMinutes { get; }
public bool EnableAutoRemove { get; }
public int DescriptionLimit { get; }

public Config(
string[] urls,
Expand All @@ -29,7 +30,8 @@ public Config(
string footerImage,
int color,
int rssCheckIntervalMinutes,
bool enableAutoRemove)
bool enableAutoRemove,
int descriptionLimit)
{
Urls = urls ?? throw new ArgumentNullException(nameof(urls));
YoutubeUrls = youtubeurls ?? new string[] { };
Expand All @@ -44,6 +46,7 @@ public Config(
Color = color;
RssCheckIntervalMinutes = rssCheckIntervalMinutes;
EnableAutoRemove = enableAutoRemove;
DescriptionLimit = descriptionLimit;
}
}
}
2 changes: 1 addition & 1 deletion FeedCord/src/Common/Interfaces/IRssProcessorService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace FeedCord.src.Common.Interfaces
{
internal interface IRssProcessorService
{
Task<Post?> ParseRssFeedAsync(string xmlContent);
Task<Post?> ParseRssFeedAsync(string xmlContent, int trim);
Task<Post?> ParseYoutubeFeedAsync(string channelUrl);
}
}
16 changes: 9 additions & 7 deletions FeedCord/src/RssReader/FeedProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public async Task<List<Post>> CheckForNewPostsAsync()
{
ConcurrentBag<Post> newPosts = new();

var rsstasks = rssFeedData.Select(rssFeed => CheckAndAddNewPostAsync(rssFeed, newPosts, false)).ToList();
var youtubetasks = youtubeFeedData.Select(youtubeFeed => CheckAndAddNewPostAsync(youtubeFeed, newPosts, true)).ToList();
var rsstasks = rssFeedData.Select(rssFeed => CheckAndAddNewPostAsync(rssFeed, newPosts, false, config.DescriptionLimit)).ToList();
var youtubetasks = youtubeFeedData.Select(youtubeFeed => CheckAndAddNewPostAsync(youtubeFeed, newPosts, true, config.DescriptionLimit)).ToList();

var tasks = rsstasks.Concat(youtubetasks).ToList();

Expand Down Expand Up @@ -133,11 +133,11 @@ private async Task<bool> TestUrlAsync(string url)
}
}

private async Task CheckAndAddNewPostAsync(KeyValuePair<string, DateTime> rssFeed, ConcurrentBag<Post> newPosts, bool isYoutube)
private async Task CheckAndAddNewPostAsync(KeyValuePair<string, DateTime> rssFeed, ConcurrentBag<Post> newPosts, bool isYoutube, int trim)
{
logger.LogInformation("Checking if any new posts for {RssFeedKey}...", rssFeed.Key);

var post = await CheckFeedForUpdatesAsync(rssFeed.Key, isYoutube);
var post = await CheckFeedForUpdatesAsync(rssFeed.Key, isYoutube, trim);

if (post is null)
{
Expand Down Expand Up @@ -192,17 +192,19 @@ private async Task CheckAndAddNewPostAsync(KeyValuePair<string, DateTime> rssFee



private async Task<Post?> CheckFeedForUpdatesAsync(string url, bool isYoutube)
private async Task<Post?> CheckFeedForUpdatesAsync(string url, bool isYoutube, int trim)
{
try
{
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();

string xmlContent = await response.Content.ReadAsStringAsync();
string xmlContent = isYoutube ?
await response.Content.ReadAsStringAsync() :
url;
return isYoutube ?
await rssProcessorService.ParseYoutubeFeedAsync(xmlContent) :
await rssProcessorService.ParseRssFeedAsync(xmlContent);
await rssProcessorService.ParseRssFeedAsync(xmlContent, trim);

}
catch (HttpRequestException ex)
Expand Down
37 changes: 19 additions & 18 deletions FeedCord/src/Services/RssProcessorService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using FeedCord.src.Common;
using CodeHollow.FeedReader;
using FeedCord.src.Common;
using FeedCord.src.Common.Interfaces;
using FeedCord.src.Helpers;
using Microsoft.Extensions.Logging;
using System.Xml.Linq;

namespace FeedCord.src.Services
{
Expand All @@ -22,32 +22,33 @@ public RssProcessorService(
this.youtubeParsingService = youtubeParsingService;
}

public async Task<Post?> ParseRssFeedAsync(string xmlContent)
public async Task<Post?> ParseRssFeedAsync(string xmlContent, int trim)
{
try
{
var xDoc = XDocument.Parse(xmlContent);
var subtitle = xDoc.Descendants("title").FirstOrDefault()?.Value ?? string.Empty;
var latestPost = xDoc.Descendants("item").FirstOrDefault();
var feed = await FeedReader.ReadAsync(xmlContent);

var latestPost = feed.Items.FirstOrDefault();

if (latestPost == null)
{
logger.LogError("No items found in the RSS feed. FeedCord only supports Traditional RSS Feeds");
return null;
}

string rawDescription = latestPost.Element("description")?.Value ?? string.Empty;
string description = StringHelper.StripTags(rawDescription);
if (description.Length > 200)
string title = latestPost.Title;
string imageLink = await openGraphService.ExtractImageUrl(latestPost.Link) ?? feed.ImageUrl ?? string.Empty;
string description = StringHelper.StripTags(latestPost.Description ?? string.Empty);
string link = latestPost.Link ?? string.Empty;
string subtitle = feed.Title;
DateTime pubDate = DateTime.TryParse(latestPost.PublishingDate.ToString(), out var tempDate) ? tempDate : default;

if (trim != 0)
{
description = string.Concat(description.AsSpan(0, 197), "...");
if (description.Length > trim)
{
description = description.Substring(0, trim) + "...";
}
}

string title = StringHelper.StripTags(latestPost.Element("title")?.Value ?? string.Empty);
string imageLink = await openGraphService.ExtractImageUrl(latestPost.Element("link")?.Value ?? string.Empty);
DateTime pubDate = DateTime.TryParse(latestPost.Element("pubDate")?.Value, out var tempDate) ? tempDate : default;

return new Post(title, imageLink, description, latestPost.Element("link")?.Value ?? string.Empty, subtitle, pubDate);
return new Post(title, imageLink, description, link, subtitle, pubDate);
}
catch (Exception ex)
{
Expand Down
4 changes: 3 additions & 1 deletion FeedCord/src/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ private static IHostBuilder CreateHostBuilder(string[] args) =>
var color = config.GetValue<int>("Color");
var rssCheckIntervalMinutes = config.GetValue<int>("RssCheckIntervalMinutes");
var enableAutoRemove = config.GetValue<bool>("EnableAutoRemove");
var descriptionTrimLength = config.GetValue<int>("DescriptionLimit");

var appConfig = new Config(
rssUrls,
Expand All @@ -61,7 +62,8 @@ private static IHostBuilder CreateHostBuilder(string[] args) =>
footerImage,
color,
rssCheckIntervalMinutes,
enableAutoRemove);
enableAutoRemove,
descriptionTrimLength);

services.AddHttpClient("Default", httpClient =>
{
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ FeedCord is a dead-simple RSS Reader designed to integrate seamlessly with Disco
"AuthorUrl": "https://github.com/Qolors/FeedCord",
"FallbackImage": "https://i.imgur.com/f8M2Y5s.png",
"FooterImage": "https://i.imgur.com/f8M2Y5s.png",
"Color": 8411391
"Color": 8411391,
"DescriptionLimit": 200
}
```

Expand Down Expand Up @@ -119,6 +120,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
<details>
<summary>[1.3.0] - 2024-01-20</summary>
### Added
- Added Description Length Configuration
### Changed
- Improved RSS & ATOM Parsing with implementing [FeedReader](https://github.com/arminreiter/FeedReader) library
### Fixed
- RSS/ATOM Feeds returning errors because of parsing issues
</details>
<details>
<summary>[1.2.1] - 2024-01-17</summary>
### Changed
Expand Down

0 comments on commit b92153f

Please sign in to comment.