/// <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)); } }