Example #1
0
        /// <summary>
        /// Overridden OnNavigatedTo handler
        /// </summary>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (isNewInstance)
            {
                if( State.ContainsKey( "CurrentItem" ) )
                {
                    item = (RSSItem)State["CurrentItem"];
                }
                else
                {
                    item = RSSService.SelectedItem;
                }

                isNewInstance = false;
            }
        }
        /// <summary>
        /// Creates the primitive HTML page from the article text.
        /// Displays the first img-tag found (if any) and strips
        /// other HTML away.
        /// </summary>
        /// <param name="article">Article text</param>
        /// <returns>HTML page</returns>
        public static String CreateArticleHTML(RSSItem item)
        {
            String start = @"<html>
                                <head>
                                    <meta name=""Viewport"" content=""width=480; user-scaleable=no; initial-scale=1.0"" />
                                    <style>
                                        * { background: #fff !important; color: #000 !important; width: auto !important; font-size: 1em !important; }
                                        h1 { font-size: 1.125em !important }
                                        img { max-width: 200px !important; display: block; margin: 0 auto; }
                                        .timestamp { font-size: 0.875em !important; font-style: italic; display: block; margin-top: 2em; }
                                    </style>
                                </head>
                                <body>
                                    <table>
                                        <tr><td>";

            String end = @"</td></tr></table></body></html>";

            String headerTemplate = @"<tr><td><h1>{0}</h1></td></tr>";
            String imageTemplate = @"<tr><td>{0}";
            String articleTemplate = @"<span class=""article"">{0}</span></td></tr>";
            String timestampTemplate = @"<tr><td><span class=""timestamp"">{0}</span></td></tr>";

            String header = String.Format(headerTemplate, item.Title);

            // If RSS item references an image in "enclosure" tag, use it. Otherwise try to extract the first image from the article
            // Note about images: if we're using an image retrieved from closure, or the first image we retrieve
            // from the article, doesn't specify image width or height, IE will not apply max-width property. This will
            // result in us showing larger pictures than intended. This could be worked around by using JavaScript resize
            // the images.

            String image = "";
            if (item.Image != null && item.Image != "")
            {
                // Image from enclosure
                String imgTemplate = @"<img src=""{0}"" />";
                image = String.Format( imageTemplate, String.Format(imgTemplate, item.Image ));
            }
            else
            {
                Regex img = new Regex("<img.*?>", RegexOptions.IgnoreCase);
                MatchCollection matches = img.Matches(item.Text);
                if (matches.Count > 0 && matches[0] != null)
                {
                    // Image from article content
                    image = String.Format(imageTemplate, matches[0].Groups[0].Value);
                }
                else
                {
                    // No image
                    image = String.Format(imageTemplate, "");
                }

            }

            String article = String.Format( articleTemplate, HttpUtility.HtmlDecode(Regex.Replace(item.Text, "<.*?>", "") ) );

            String timestamp = String.Format(timestampTemplate, item.Datestamp);

            StringBuilder builder = new StringBuilder();
            builder.Append(start);
            builder.Append(header);
            builder.Append(image);
            builder.Append(article);
            builder.Append(timestamp);
            builder.Append(end);
            return builder.ToString();
        }
        /// <summary>
        /// Gets the RSS items
        /// </summary>
        /// <param name="feed">The RSS feed</param>
        /// <param name="onGetRSSItemsCompleted">Callback on complete</param>
        /// <param name="onError">Callback for errors</param>
        public static void GetRSSItems(int pageId, int feedId, bool useCache, Action<IEnumerable<RSSItem>> onGetRSSItemsCompleted = null, Action<Exception> onError = null)
        {
            DateTime validUntilThis = DateTime.Now;
            validUntilThis = validUntilThis.AddMinutes(-EXPIRE_TIME);

            RSSFeed feed = GetRSSFeed(pageId, feedId);
            bool feedExists = (feed != null);
            bool feedHasItems = (feedExists && feed.Items != null && feed.Items.Count > 0);
            bool cacheHasExpired = (DateTime.Compare(validUntilThis, feed.Timestamp) > 0);

            // First check if this valid items for this feed exist in the cache already
            if (feedExists &&
                feedHasItems &&
                useCache &&
                !cacheHasExpired &&
                onGetRSSItemsCompleted != null)
            {
                onGetRSSItemsCompleted(feed.Items);
            }
            // Items not found in cache, perform a web request
            else
            {
                WebClient webClient = new WebClient();

                webClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)
                {
                    try
                    {
                        if (e.Error != null)
                        {
                            if (onError != null)
                            {
                                onError(e.Error);
                            }
                            return;
                        }

                        List<RSSItem> rssItems = new List<RSSItem>();
                        XmlReader response = XmlReader.Create(e.Result);
                        SyndicationFeed rssFeed = SyndicationFeed.Load(response);
                        foreach (SyndicationItem syndicationItem in rssFeed.Items)
                        {
                            // Clean the title in case it includes line breaks
                            string title = syndicationItem.Title.Text;
                            title = title.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", " ");

                            // Check for "enclosure" tag that references an image
                            string image = "";
                            foreach (SyndicationLink link in syndicationItem.Links)
                            {
                                if (link.RelationshipType == "enclosure" &&
                                    link.MediaType.StartsWith( "image/" ) )
                                {
                                    image = link.Uri.ToString();
                                    break;
                                }
                            }

                            RSSItem rssItem = new RSSItem(
                                title,
                                syndicationItem.Summary.Text,
                                syndicationItem.Links[0].Uri.AbsoluteUri,
                                syndicationItem.PublishDate,
                                feed,
                                image);
                            rssItems.Add(rssItem);
                        }

                        // Cache the results
                        feed.Items = rssItems;
                        feed.Timestamp = DateTime.Now;

                        // Call the callback with the list of RSSItems
                        if (onGetRSSItemsCompleted != null)
                        {
                            onGetRSSItemsCompleted(rssItems);
                        }
                    }
                    catch (Exception error)
                    {
                        if (onError != null)
                        {
                            onError(error);
                        }
                    }
                };

                webClient.OpenReadAsync(new Uri(feed.URL));
            }
        }
        /// <summary>
        /// Creates the primitive HTML page from the article text.
        /// Displays the first img-tag found (if any) and strips
        /// other HTML away.
        /// </summary>
        /// <param name="article">Article text</param>
        /// <returns>HTML page</returns>
        public static String CreateArticleHTML(RSSItem item)
        {
            String start = @"<html>
                                <head>
                                    <meta name=""Viewport"" content=""width=480; user-scaleable=no; initial-scale=1.0"" />
                                    <style>
                                        * { background: #fff !important; color: #000 !important; width: auto !important; font-size: 1em !important; }
                                        h1 { font-size: 1.125em !important }
                                        img { max-width: 200px !important; display: block; margin: 0 auto; }
                                        .timestamp { font-size: 0.875em !important; font-style: italic; display: block; margin-top: 2em; }
                                    </style>
                                </head>
                                <body>
                                    <table>
                                        <tr><td>";

            String end = @"</td></tr></table></body></html>";

            String headerTemplate    = @"<tr><td><h1>{0}</h1></td></tr>";
            String imageTemplate     = @"<tr><td>{0}";
            String articleTemplate   = @"<span class=""article"">{0}</span></td></tr>";
            String timestampTemplate = @"<tr><td><span class=""timestamp"">{0}</span></td></tr>";

            String header = String.Format(headerTemplate, item.Title);

            // If RSS item references an image in "enclosure" tag, use it. Otherwise try to extract the first image from the article
            // Note about images: if we're using an image retrieved from closure, or the first image we retrieve
            // from the article, doesn't specify image width or height, IE will not apply max-width property. This will
            // result in us showing larger pictures than intended. This could be worked around by using JavaScript resize
            // the images.

            String image = "";

            if (item.Image != null && item.Image != "")
            {
                // Image from enclosure
                String imgTemplate = @"<img src=""{0}"" />";
                image = String.Format(imageTemplate, String.Format(imgTemplate, item.Image));
            }
            else
            {
                Regex           img     = new Regex("<img.*?>", RegexOptions.IgnoreCase);
                MatchCollection matches = img.Matches(item.Text);
                if (matches.Count > 0 && matches[0] != null)
                {
                    // Image from article content
                    image = String.Format(imageTemplate, matches[0].Groups[0].Value);
                }
                else
                {
                    // No image
                    image = String.Format(imageTemplate, "");
                }
            }

            String article = String.Format(articleTemplate, HttpUtility.HtmlDecode(Regex.Replace(item.Text, "<.*?>", "")));

            String timestamp = String.Format(timestampTemplate, item.Datestamp);

            StringBuilder builder = new StringBuilder();

            builder.Append(start);
            builder.Append(header);
            builder.Append(image);
            builder.Append(article);
            builder.Append(timestamp);
            builder.Append(end);
            return(builder.ToString());
        }
        /// <summary>
        /// Gets the RSS items
        /// </summary>
        /// <param name="feed">The RSS feed</param>
        /// <param name="onGetRSSItemsCompleted">Callback on complete</param>
        /// <param name="onError">Callback for errors</param>
        public static void GetRSSItems(int pageId, int feedId, bool useCache, Action <IEnumerable <RSSItem> > onGetRSSItemsCompleted = null, Action <Exception> onError = null)
        {
            DateTime validUntilThis = DateTime.Now;

            validUntilThis = validUntilThis.AddMinutes(-EXPIRE_TIME);

            RSSFeed feed            = GetRSSFeed(pageId, feedId);
            bool    feedExists      = (feed != null);
            bool    feedHasItems    = (feedExists && feed.Items != null && feed.Items.Count > 0);
            bool    cacheHasExpired = (DateTime.Compare(validUntilThis, feed.Timestamp) > 0);

            // First check if this valid items for this feed exist in the cache already
            if (feedExists &&
                feedHasItems &&
                useCache &&
                !cacheHasExpired &&
                onGetRSSItemsCompleted != null)
            {
                onGetRSSItemsCompleted(feed.Items);
            }
            // Items not found in cache, perform a web request
            else
            {
                WebClient webClient = new WebClient();

                webClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)
                {
                    try
                    {
                        if (e.Error != null)
                        {
                            if (onError != null)
                            {
                                onError(e.Error);
                            }
                            return;
                        }

                        List <RSSItem>  rssItems = new List <RSSItem>();
                        XmlReader       response = XmlReader.Create(e.Result);
                        SyndicationFeed rssFeed  = SyndicationFeed.Load(response);
                        foreach (SyndicationItem syndicationItem in rssFeed.Items)
                        {
                            // Clean the title in case it includes line breaks
                            string title = syndicationItem.Title.Text;
                            title = title.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", " ");

                            // Check for "enclosure" tag that references an image
                            string image = "";
                            foreach (SyndicationLink link in syndicationItem.Links)
                            {
                                if (link.RelationshipType == "enclosure" &&
                                    link.MediaType.StartsWith("image/"))
                                {
                                    image = link.Uri.ToString();
                                    break;
                                }
                            }

                            RSSItem rssItem = new RSSItem(
                                title,
                                syndicationItem.Summary.Text,
                                syndicationItem.Links[0].Uri.AbsoluteUri,
                                syndicationItem.PublishDate,
                                feed,
                                image);
                            rssItems.Add(rssItem);
                        }

                        // Cache the results
                        feed.Items     = rssItems;
                        feed.Timestamp = DateTime.Now;

                        // Call the callback with the list of RSSItems
                        if (onGetRSSItemsCompleted != null)
                        {
                            onGetRSSItemsCompleted(rssItems);
                        }
                    }
                    catch (Exception error)
                    {
                        if (onError != null)
                        {
                            onError(error);
                        }
                    }
                };

                webClient.OpenReadAsync(new Uri(feed.URL));
            }
        }