From 864be9bb11546db789f9e7a60ebb95a1aeb5360d Mon Sep 17 00:00:00 2001 From: Chris Kaczor Date: Tue, 29 Mar 2016 20:10:43 -0400 Subject: [PATCH] Add a few new ways to drag/drop a URL - from a few Chrome extensions or the page URL itself - page URL only supports single links right now --- Application/FeedCenter.csproj | 4 ++ Application/FeedParsers/FeedParserBase.cs | 6 +- Application/Feeds/Feed.cs | 12 ++++ Application/MainWindow.xaml.cs | 71 ++++++++++++++++++----- Application/packages.config | 1 + Setup/Product.wxs | 2 + 6 files changed, 81 insertions(+), 15 deletions(-) diff --git a/Application/FeedCenter.csproj b/Application/FeedCenter.csproj index 789e79a..e31cf55 100644 --- a/Application/FeedCenter.csproj +++ b/Application/FeedCenter.csproj @@ -157,6 +157,10 @@ ..\packages\EntityFramework.SqlServerCompact.6.1.1\lib\net45\EntityFramework.SqlServerCompact.dll + + ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll + True + diff --git a/Application/FeedParsers/FeedParserBase.cs b/Application/FeedParsers/FeedParserBase.cs index b95e7f4..86b7583 100644 --- a/Application/FeedParsers/FeedParserBase.cs +++ b/Application/FeedParsers/FeedParserBase.cs @@ -119,7 +119,7 @@ namespace FeedCenter.FeedParsers throw new ArgumentException($"Feed type {feedType} is not supported"); } - private static FeedType DetectFeedType(string feedText) + public static FeedType DetectFeedType(string feedText) { try { @@ -150,7 +150,9 @@ namespace FeedCenter.FeedParsers } catch (Exception exception) { - throw new InvalidFeedFormatException(exception); + Tracer.WriteException(exception); + + return FeedType.Unknown; } } diff --git a/Application/Feeds/Feed.cs b/Application/Feeds/Feed.cs index 9b709d4..fff032c 100644 --- a/Application/Feeds/Feed.cs +++ b/Application/Feeds/Feed.cs @@ -99,6 +99,18 @@ namespace FeedCenter return await Task.Run(() => Read(database, forceRead)); } + public Tuple DetectFeedType() + { + var retrieveResult = RetrieveFeed(); + + if (retrieveResult.Item1 != FeedReadResult.Success) + { + return new Tuple(FeedType.Unknown, string.Empty); + } + + return new Tuple(FeedParserBase.DetectFeedType(retrieveResult.Item2), retrieveResult.Item2); + } + private Tuple RetrieveFeed() { try diff --git a/Application/MainWindow.xaml.cs b/Application/MainWindow.xaml.cs index 511628c..ab54f9d 100644 --- a/Application/MainWindow.xaml.cs +++ b/Application/MainWindow.xaml.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; +using System.Net; using System.Threading; using System.Web.UI; using System.Windows; @@ -17,11 +18,14 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; +using Common.Internet; namespace FeedCenter { public partial class MainWindow { + private readonly string[] _chromeExtensions = { "chrome-extension://ehojfdcmnajoklleckniaifaijfnkpbi/subscribe.html?", "chrome-extension://nlbjncdgjeocebhnmkbbbdekmmmcbfjd/subscribe.html?" }; + #region Member variables private int _feedIndex; @@ -354,7 +358,7 @@ namespace FeedCenter OpenAllToolbarButton.IsEnabled = (feedCount > 0); MarkReadToolbarButton.IsEnabled = (feedCount > 0); FeedLabel.Visibility = (feedCount == 0 ? Visibility.Hidden : Visibility.Visible); - FeedButton.Visibility = (feedCount > 1 ? Visibility.Hidden : Visibility.Visible); + FeedButton.Visibility = (feedCount > 1 ? Visibility.Hidden : Visibility.Visible); } private void InitializeFeed() @@ -788,6 +792,37 @@ namespace FeedCenter feed.Source = feedUrl; feed.Category = _database.DefaultCategory; + // Try to detect the feed type + var feedTypeResult = feed.DetectFeedType(); + + // If we can't figure it out it could be an HTML page + if (feedTypeResult.Item1 == FeedType.Unknown) + { + // Only check if the feed was able to be read - otherwise fall through and show the dialog + if (feedTypeResult.Item2.Length > 0) + { + // Create and load an HTML document with the text + var htmlDocument = new HtmlAgilityPack.HtmlDocument(); + htmlDocument.LoadHtml(feedTypeResult.Item2); + + // Look for all RSS or atom links in the document + var rssLinks = htmlDocument.DocumentNode.Descendants("link") + .Where(n => n.Attributes["type"] != null && (n.Attributes["type"].Value == "application/rss+xml" || n.Attributes["type"].Value == "application/atom+xml")) + .Select(n => UrlHelper.GetAbsoluteUrlString(feed.Source, n.Attributes["href"].Value)) + .ToArray(); + + // If there was only one link found then switch to feed to it + if (rssLinks.Length == 1) + { + feed.Source = rssLinks[0]; + } + else + { + // TODO - show dialog to choose feed + } + } + } + // Read the feed for the first time var feedReadResult = feed.Read(_database); @@ -899,6 +934,16 @@ namespace FeedCenter // Get the data as a string var data = (string) e.Data.GetData(DataFormats.Text); + // Check to see if the data starts with any known Chrome extension + var chromeExtension = _chromeExtensions.FirstOrDefault(c => data.StartsWith(c)); + + // Remove the Chrome extension URL and decode the URL + if (chromeExtension != null) + { + data = data.Substring(chromeExtension.Length); + data = WebUtility.UrlDecode(data); + } + // Handle the new feed but allow the drag/drop to complete Dispatcher.BeginInvoke(new NewFeedDelegate(HandleNewFeed), data); } @@ -981,13 +1026,13 @@ namespace FeedCenter // Create a menu item var menuItem = new MenuItem - { - Header = display, - Tag = feed, + { + Header = display, + Tag = feed, - // Set the current item to bold - FontWeight = feed == _currentFeed ? FontWeights.Bold : FontWeights.Normal - }; + // Set the current item to bold + FontWeight = feed == _currentFeed ? FontWeights.Bold : FontWeights.Normal + }; // Handle the click @@ -1046,12 +1091,12 @@ namespace FeedCenter var screen = System.Windows.Forms.Screen.FromHandle(windowInteropHelper.Handle); var rectangle = new System.Drawing.Rectangle - { - X = (int) Left, - Y = (int) Top, - Width = (int) Width, - Height = (int) Height - }; + { + X = (int) Left, + Y = (int) Top, + Width = (int) Width, + Height = (int) Height + }; var borderThickness = new Thickness(); diff --git a/Application/packages.config b/Application/packages.config index 019450a..503c402 100644 --- a/Application/packages.config +++ b/Application/packages.config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/Setup/Product.wxs b/Setup/Product.wxs index 6032891..194ee96 100644 --- a/Setup/Product.wxs +++ b/Setup/Product.wxs @@ -175,6 +175,8 @@ + +