Updated SharePoint RSS Aggregator Web Part - Zlatan's Blog [MVP SharePoint]

Updated SharePoint RSS Aggregator Web Part

 

I've decided to start using CodePlex so I uploaded SharePoint RSS Aggregator Web Part that I posted some months earlier (http://dotnet.org.za/zlatan/archive/2008/06/06/multiple-rss-aggregator-web-part-example.aspx).

I took this opportunity to update the web part as well (actually on request from some people that are using it), so I changed it to use LINQ for parsing the XML data.

I also fixed up a small issue with filtering tag/category terms.

Here's the link to the Codeplex project were you can download the wsp file and source code:

http://www.codeplex.com/RSSAggregator

Here's the code as well:

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Collections.Generic;
using System.Xml;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Xml.Linq;
using System.Net;
using System.Text;

namespace RSSAggregator
{
    [Guid("561df9ae-1742-4d17-9a88-5548f05bff25")]
    public class RSSAggregator : System.Web.UI.WebControls.WebParts.WebPart
    {
        private string rssUrl;
        private string feedName;
        private const string constDefFeedCriteriaValue = "SAArchitect";
        private string filterCriteria = constDefFeedCriteriaValue;
        private const string constDefFeedLimitValue = "5";
        private string feedLimit = constDefFeedLimitValue;
        private int feedLmt;
        private string tagValue;

        public RSSAggregator()
        {
        }


        protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
        {
            try
            {
                feedLmt = Convert.ToInt32(feedLimit);
            }
            catch (Exception)
            {
                feedLmt = 0;
            }
            RssFeed feed = new RssFeed(rssUrl);
            feed.Sort(delegate(RssItem r1, RssItem r2)
            {
                return r2.PubDate.CompareTo(r1.PubDate);
            });

            int i = 0;

            foreach (RssItem singleRssItem in feed)
            {
                if (i < feedLmt)
                {
                    if (singleRssItem.Tags != null)
                    {
                        if (filterCriteria != null)
                            tagValue = singleRssItem.Tags.ToLower();

                        if (tagValue.Contains(filterCriteria) == true || filterCriteria == null)
                        {
                            writer.Write("<div class=\"container\">");
                            writer.Write("<font size=\"4\" face=\"Verdana\"><b><a href =\"");
                            writer.Write(singleRssItem.Href);
                            writer.Write("\"><font size=\"2\" face=\"Verdana\">");
                            writer.Write(singleRssItem.Title);
                            writer.Write("</a></b></font>");

                            writer.Write("<div class=\"module-content\"><table width=\"100%\" border=\"0\"><tr><td><font size=\"2\" face=\"Verdana\">");
                            writer.Write(singleRssItem.Body);
                            writer.Write("</font></td></tr></table></div>");
                            writer.Write("</div>");

                            writer.Write("<div class=\"module-content\"><table width=\"100%\" border=\"0\"><tr><td><font size=\"2\" face=\"Verdana\">");
                            writer.Write(singleRssItem.Tags);
                            writer.Write("</font></td></tr></table></div>");
                            writer.Write("</div>");

                            writer.Write("<div class=\"module-content\"><table width=\"100%\" border=\"0\"><tr><td><font size=\"2\" face=\"Verdana\">");
                            writer.Write(singleRssItem.PubDate.ToString());
                            writer.Write("</font></td></tr></table></div>");
                            writer.Write("</div>");
                            i++;
                        }
                    }
                }
            }
        }

        public string FeedName
        {
            get
            {
                return feedName;
            }
            set
            {
                feedName = value;
            }
        }


        [WebBrowsable(true),
        Personalizable(true),
        Category("RSS Aggregator Web Part"),
        DisplayName("URLs of the Feed"),
        WebDisplayName("URLs of the Feed"),
        Description("Please enter the URLs of the feed separated by ';' character.")]
        public string FeedURL
        {
            get
            {
                return rssUrl;
            }
            set
            {
                rssUrl = value;
            }
        }

        [WebBrowsable(true),
        Personalizable(true),
        Category("RSS Aggregator Web Part"),
        DisplayName("Filter Criteria"),
        WebDisplayName("Filter Criteria"),
        Description("Please enter the tag value you wish to filter on for desired RSS feeds."),
        DefaultValue(constDefFeedCriteriaValue)]
        public string FilterOn
        {
            get
            {
                return filterCriteria.ToLower();
            }
            set
            {
                filterCriteria = value.ToLower();
            }
        }

        [WebBrowsable(true)]
        [Personalizable(true),
        Category("RSS Aggregator Web Part"),
        DisplayName("Feed Limit"),
        WebDisplayName("Feed Limit"),
        Description("Defines the list the web part will read from."),
        DefaultValue(constDefFeedLimitValue)]
        public string FeedLimit
        {
            get
            {
                return feedLimit;
            }
            set
            {
                feedLimit = value;
            }
        }
    }


    internal class RssFeed : List<RssItem>
    {
        private XElement rssDoc;

        internal RssFeed(string RssURL)
        {

            if (RssURL == null)
            {
                this.Add(new RssItem());
            }
            else
            {
                string[] rssUrlsArray = RssURL.Split(new char[] { ';' });
                foreach (string url in rssUrlsArray)
                {

                    try
                    {
                        WebClient client = new WebClient();
                        byte[] byteData = client.DownloadData(url);
                        string strData = Encoding.UTF8.GetString(byteData);
                        rssDoc = XElement.Parse(strData);

                        foreach (var elm in rssDoc.Descendants("item"))
                        {

                            this.Add(new RssItem(elm));

                        }

                    }
                    catch (Exception)
                    {
                        this.Add(new RssItem());
                    }
                }
            }
        }
    }

    internal class RssItem
    {
        private string title;
        private string href;
        private string body;
        private string tags;
        private DateTime pubDate;


        public string Href
        {
            get { return href; }
        }


        public string Title
        {
            get { return title; }
        }

        internal RssItem()
        {
            title = "Feed not available at this time";
            href = "~";
        }


        public string Body
        {
            get { return body; }
            set { body = value; }
        }

        public string Tags
        {
            get { return tags; }
            set { tags = value; }
        }

        public DateTime PubDate
        {
            get { return pubDate; }
            set { pubDate = value; }
        }

        internal RssItem(XElement xNode)
        {
            if (xNode.NodeType == XmlNodeType.CDATA)
            {
                XCData titleCData = xNode.FirstNode as XCData;
                title = titleCData.Value;
            }
            else
                title = (string)xNode.Element("title").Value;

            if (xNode.NodeType == XmlNodeType.CDATA)
            {
                XCData linkCData = xNode.FirstNode as XCData;
                href = linkCData.Value;
            }
            else
                href = (string)xNode.Element("link").Value;

            if (xNode.NodeType == XmlNodeType.CDATA)
            {
                XCData bodyCData = xNode.FirstNode as XCData;
                body = FixDesc(bodyCData.Value, href);
            }
            else
                body = FixDesc((string)xNode.Element("description").Value, href);

            pubDate = Convert.ToDateTime((string)xNode.Element("pubDate").Value);

            foreach (XElement node in xNode.Elements("category"))
            {
                if (node.NodeType == XmlNodeType.CDATA)
                {
                    XCData categoryCData = node.FirstNode as XCData;
                    if (tags == null)
                        tags = (string)categoryCData.Value;
                    else
                        tags = tags + ", " + (string)categoryCData.Value;
                }
                else
                {
                    if (tags == null)
                        tags = (string)node.Value;
                    else
                        tags = tags + ", " + (string)node.Value;
                }
            }
        }

        public string FixDesc(object desc, object link)
        {
            if (link == null || desc == null) return String.Empty;

            string description = desc.ToString();
            //Replace all HTML tags so none get cut-off and screw up the page
            Regex reg = new Regex("<.*?>", RegexOptions.Compiled);
            string stripDesc = reg.Replace(description, String.Empty);
            if (stripDesc.Length > 250)
            {
                int startPos = 250;
                char[] chars = stripDesc.ToCharArray();
                char c = chars[startPos];
                while (!Char.IsWhiteSpace(c) && startPos < chars.Length)
                {
                    startPos++;
                    c = chars[startPos];
                }
                stripDesc = new String(chars, 0, startPos) + " ... <a href='" + link.ToString() + "'> More</a>";

            }
            return stripDesc;
        }
    }
}

Published Friday, November 28, 2008 11:21 PM by Zlatan

Comments

# Updated SharePoint RSS Aggregator Web Part

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Friday, November 28, 2008 11:51 PM by DotNetKicks.com

# SharePoint AJAX RSS Aggregator WebPart

Ok so I thought to myself.... what if I make the RSS Aggregator ( dotnet.org.za/.../archive

Saturday, November 29, 2008 1:06 AM by Zlatan's Blog [MVP SharePoint]

# SharePoint AJAX RSS Aggregator WebPart

Ok so I thought to myself.... what if I make the RSS Aggregator ( dotnet.org.za/.../archive

Saturday, November 29, 2008 7:02 AM by Zlatan's Blog [MVP SharePoint]

# SharePoint AJAX RSS Aggregator WebPart

Ok so I thought to myself.... what if I make the RSS Aggregator ( dotnet.org.za/.../archive

Saturday, November 29, 2008 7:22 AM by SharePoint MVP Blogs

# Dew Drop - Weekend Edition - November 29-30, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - Weekend Edition - November 29-30, 2008 | Alvin Ashcraft's Morning Dew

# re: Updated SharePoint RSS Aggregator Web Part

Pinging back.

Will add more to this as I go along.

Thursday, December 04, 2008 10:02 AM by Garth