public IList <XElement> GetNewValidEntries(FeedSyncProfilePart feedSyncProfilePart, string feedType)
        {
            var newEntries = new List <XElement>();

            if (FeedType != feedType || string.IsNullOrEmpty(feedSyncProfilePart.FeedItemIdType))
            {
                return(newEntries);
            }

            try
            {
                var feedXml        = XDocument.Load(feedSyncProfilePart.FeedUrl);
                var channelElement = feedXml.Root.GetDescendantNodeByName("channel");
                if (channelElement == null)
                {
                    return(newEntries);
                }
                var feedItems = channelElement.Descendants("item");
                if (feedItems == null)
                {
                    return(newEntries);
                }

                foreach (var feedItem in feedItems)
                {
                    // If this is the init and the init count is more than the set one.
                    if (!feedSyncProfilePart.SuccesfulInit &&
                        newEntries.Count() >= feedSyncProfilePart.NumberOfItemsToSyncDuringInit)
                    {
                        break;
                    }

                    var pubDateElement   = feedItem.GetDescendantNodeByName("pubDate");
                    var idElement        = feedItem.GetDescendantNodeByName(feedSyncProfilePart.FeedItemIdType);
                    var modificationDate = new DateTime();
                    if (pubDateElement == null ||
                        idElement == null ||
                        !DateTimeHelper.TryParseDateTime(pubDateElement.Value, out modificationDate))
                    {
                        continue;
                    }

                    if (modificationDate.ToUniversalTime() <= feedSyncProfilePart.LatestCreatedItemModificationDate)
                    {
                        break;
                    }

                    newEntries.Add(feedItem);
                }

                return(newEntries);
            }
            catch (Exception ex) when(ex is FileNotFoundException || ex is XmlException || ex is NotSupportedException)
            {
                Logger.Error(ex, "Cannot find or parse the feed with the given url.");
                throw;
            }
        }
        public IList <XElement> GetNewValidEntries(FeedSyncProfilePart feedSyncProfilePart, string feedType)
        {
            var newEntries = new List <XElement>();

            if (FeedType != feedType || string.IsNullOrEmpty(feedSyncProfilePart.FeedItemIdType))
            {
                return(newEntries);
            }

            try
            {
                var feedXml     = XDocument.Load(feedSyncProfilePart.FeedUrl);
                var feedEntries = feedXml.Root.GetDescendantNodesByName("entry");
                var i           = 0;
                while (feedEntries != null && i < feedEntries.Count())
                {
                    // If this is the init and the init count is more than the set one.
                    if (!feedSyncProfilePart.SuccesfulInit &&
                        newEntries.Count() >= feedSyncProfilePart.NumberOfItemsToSyncDuringInit)
                    {
                        break;
                    }

                    var updatedElement = feedEntries.ElementAt(i).GetDescendantNodeByName("updated");
                    var idElement      = feedEntries
                                         .ElementAt(i)
                                         .GetDescendantNodeByName(feedSyncProfilePart.FeedItemIdType);
                    var modificationDate = new DateTime();
                    if (updatedElement == null ||
                        idElement == null ||
                        !DateTimeHelper.TryParseDateTime(updatedElement.Value, out modificationDate))
                    {
                        i++;
                        continue;
                    }

                    if (modificationDate.ToUniversalTime() <= feedSyncProfilePart.LatestCreatedItemModificationDate)
                    {
                        break;
                    }

                    newEntries.Add(feedEntries.ElementAt(i));

                    i++;

                    // If this entry is the last one in this batch, then getting the next batch.
                    if (feedEntries.Count() == i)
                    {
                        // Getting the "next" element, it contains a link to the next feed page.
                        var nextAtomElement = feedXml
                                              .Root
                                              .Elements()
                                              .FirstOrDefault(element =>
                        {
                            if (element.Name.LocalName != "link")
                            {
                                return(false);
                            }
                            var relAttribute = element.Attribute("rel");
                            if (relAttribute == null)
                            {
                                return(false);
                            }
                            return(relAttribute.Value == "next");
                        });

                        if (nextAtomElement == null)
                        {
                            break;
                        }
                        feedXml     = XDocument.Load(nextAtomElement.Value);
                        feedEntries = feedXml.Root.GetDescendantNodesByName("entry");
                        i           = 0;
                    }
                }

                return(newEntries);
            }
            catch (Exception ex) when(ex is FileNotFoundException || ex is XmlException || ex is NotSupportedException)
            {
                Logger.Error(ex, "Cannot find or parse the feed with the given url.");
                throw;
            }
        }
        public string GetValidFeedType(FeedSyncProfilePart feedSyncProfilePart)
        {
            try
            {
                var feedXml = XDocument.Load(feedSyncProfilePart.FeedUrl);

                // Checking if the feed is valid RSS.
                if (feedXml.Root.Name.LocalName == "rss")
                {
                    var channelElement = feedXml.Root.GetDescendantNodeByName("channel");
                    if (channelElement == null)
                    {
                        Logger.Error("Feed is invalid. No channel element.");
                        return(null);
                    }

                    var firstItemElement = channelElement.GetDescendantNodeByName("item");
                    if (firstItemElement == null)
                    {
                        Logger.Error("Feed is invalid. No item element.");
                        return(null);
                    }

                    var pubDateElement = firstItemElement.GetDescendantNodeByName("pubDate");
                    if (pubDateElement == null)
                    {
                        Logger.Error("Feed is invalid. No pubDate element.");
                        return(null);
                    }

                    if (!firstItemElement
                        .Elements()
                        .Any(element =>
                             element.Name.LocalName == "guid" ||
                             element.Name.LocalName == "title" ||
                             element.Name.LocalName == "description"))
                    {
                        Logger.Error("Feed is invalid. No guid, title or description element.");
                        return(null);
                    }
                    // Since the feed is valid, set the id type.
                    else if (string.IsNullOrEmpty(feedSyncProfilePart.FeedItemIdType))
                    {
                        if (firstItemElement.ElementContainsNodeWithName("guid"))
                        {
                            feedSyncProfilePart.FeedItemIdType = "guid";
                        }
                        else if (firstItemElement.ElementContainsNodeWithName("title"))
                        {
                            feedSyncProfilePart.FeedItemIdType = "title";
                        }
                        else if (firstItemElement.ElementContainsNodeWithName("description"))
                        {
                            feedSyncProfilePart.FeedItemIdType = "description";
                        }
                    }

                    if (string.IsNullOrEmpty(feedSyncProfilePart.FeedItemModificationDateType))
                    {
                        feedSyncProfilePart.FeedItemModificationDateType = "pubDate";
                    }

                    return("Rss");
                }

                // Checking if the feed is valid Atom.
                if (feedXml.Root.Name.LocalName == "feed")
                {
                    var xmlnsAttribute = feedXml.Root.Attribute("xmlns");
                    if (xmlnsAttribute != null && xmlnsAttribute.Value == "http://www.w3.org/2005/Atom")
                    {
                        var firstEntryElement = feedXml.Root.GetDescendantNodeByName("entry");
                        if (firstEntryElement == null)
                        {
                            Logger.Error("Feed is invalid. No entry element.");
                            return(null);
                        }

                        var updatedElement = firstEntryElement.GetDescendantNodeByName("updated");
                        if (updatedElement == null)
                        {
                            Logger.Error("Feed is invalid. No updated element.");
                            return(null);
                        }

                        var idElement = firstEntryElement.GetDescendantNodeByName("id");
                        if (idElement == null)
                        {
                            Logger.Error("Feed is invalid. No id element.");
                            return(null);
                        }
                        // Since the feed is valid, set the id type.
                        else if (string.IsNullOrEmpty(feedSyncProfilePart.FeedItemIdType))
                        {
                            feedSyncProfilePart.FeedItemIdType = "id";
                        }

                        if (string.IsNullOrEmpty(feedSyncProfilePart.FeedItemModificationDateType))
                        {
                            feedSyncProfilePart.FeedItemModificationDateType = "updated";
                        }

                        return("Atom");
                    }
                }
            }
            catch (Exception ex) when(ex is FileNotFoundException || ex is XmlException || ex is NotSupportedException)
            {
                Logger.Error(ex, "Cannot find or parse the feed with the given url.");
                return(null);
            }

            Logger.Error("Cannot get the feed type, so it's unsupported.");
            return(null);
        }