public FeedInfo Parse(XmlReader reader) { try { FeedInfo info = new FeedInfo(); //create a List of type Dictionary<string,string> for the element names and values List<Dictionary<string, string>> items = new List<Dictionary<string, string>>(); // declare a Dictionary to capture each current Item in the while loop Dictionary<string, string> currentItem = null; bool parsingItems = false; /// Read each element with the reader while (reader.Read()) { // if it's an element, we want to process it if (reader.NodeType == XmlNodeType.Element) { string name = reader.Name.ToLowerInvariant(); // handle title if (!parsingItems && name == "title") { reader.Read(); info.Title = reader.Value; } // handle language if (!parsingItems && name == "language") { reader.Read(); info.Language = reader.Value; } /* most feed logos/images/icons are not square, so we are not using this for now // handle icon if (!parsingItems && name == "logo") // atom { reader.Read(); info.Icon = reader.Value; } else if (!parsingItems && name == "image") // rss { bool search = true; while (search) { reader.Read(); if (reader.Name == "url") { reader.Read(); info.Icon = reader.Value; } if (reader.Name == "image" && reader.NodeType == XmlNodeType.EndElement) search = false; } } * */ if (name == "item" || name == "entry") { parsingItems = true; // Save previous item if (currentItem != null) items.Add(currentItem); // Create new item currentItem = new Dictionary<string, string>(); } else if (currentItem != null) { // some feeds can have duplicate keys, so we don't want to blow up here: if (!currentItem.ContainsKey(name)) { // handle <link> href attribute string href = String.Empty; if (name == "link" && reader.HasAttributes) { href = reader.GetAttribute("href"); } reader.Read(); string val = reader.Value.Trim(); if (!String.IsNullOrEmpty(href) && String.IsNullOrEmpty(val)) val = href; currentItem.Add(name, val); } } } } // Save previous item if (currentItem != null) items.Add(currentItem); // now create a List of type GenericFeedItem List<FeedItem> itemList = new List<FeedItem>(); // iterate all our items from the reader foreach (Dictionary<string, string> d in items) { FeedItem itm = new FeedItem(); //do a switch on the Key of the Dictionary <string, string> of each item foreach (string k in d.Keys) { switch (k) { case "title": itm.Title = d[k]; break; case "link": itm.Link = d[k]; break; case "published": case "pubdate": case "issued": case "updated": DateTime dt; bool ok = Rfc822DateTime.TryParse(d[k], info.Language, out dt); itm.PubDate = ok ? dt : DateTime.Now; // log failed date parsing so we can update the format.xml file if needed if (!ok) { string msg = String.Format("Feed Plugin: DateTime parsing failed for value '{0}'; Feed '{1}'", d[k], info.Url); Growl.CoreLibrary.DebugInfo.WriteLine(msg); } break; case "content": case "description": itm.Description = d[k]; break; default: break; } } // add the created item to our List itemList.Add(itm); } info.Items = itemList; return info; } catch { return null; } }
public FeedInfo Parse(XmlReader reader) { try { FeedInfo info = new FeedInfo(); //create a List of type Dictionary<string,string> for the element names and values List <Dictionary <string, string> > items = new List <Dictionary <string, string> >(); // declare a Dictionary to capture each current Item in the while loop Dictionary <string, string> currentItem = null; bool parsingItems = false; /// Read each element with the reader while (reader.Read()) { // if it's an element, we want to process it if (reader.NodeType == XmlNodeType.Element) { string name = reader.Name.ToLowerInvariant(); // handle title if (!parsingItems && name == "title") { reader.Read(); info.Title = reader.Value; } // handle language if (!parsingItems && name == "language") { reader.Read(); info.Language = reader.Value; } /* most feed logos/images/icons are not square, so we are not using this for now * // handle icon * if (!parsingItems && name == "logo") // atom * { * reader.Read(); * info.Icon = reader.Value; * } * else if (!parsingItems && name == "image") // rss * { * bool search = true; * while (search) * { * reader.Read(); * if (reader.Name == "url") * { * reader.Read(); * info.Icon = reader.Value; * } * * if (reader.Name == "image" && reader.NodeType == XmlNodeType.EndElement) * search = false; * } * } * */ if (name == "item" || name == "entry") { parsingItems = true; // Save previous item if (currentItem != null) { items.Add(currentItem); } // Create new item currentItem = new Dictionary <string, string>(); } else if (currentItem != null) { // some feeds can have duplicate keys, so we don't want to blow up here: if (!currentItem.ContainsKey(name)) { // handle <link> href attribute string href = String.Empty; if (name == "link" && reader.HasAttributes) { href = reader.GetAttribute("href"); } reader.Read(); string val = reader.Value.Trim(); if (!String.IsNullOrEmpty(href) && String.IsNullOrEmpty(val)) { val = href; } currentItem.Add(name, val); } } } } // Save previous item if (currentItem != null) { items.Add(currentItem); } // now create a List of type GenericFeedItem List <FeedItem> itemList = new List <FeedItem>(); // iterate all our items from the reader foreach (Dictionary <string, string> d in items) { FeedItem itm = new FeedItem(); //do a switch on the Key of the Dictionary <string, string> of each item foreach (string k in d.Keys) { switch (k) { case "title": itm.Title = d[k]; break; case "link": itm.Link = d[k]; break; case "published": case "pubdate": case "issued": case "updated": DateTime dt; bool ok = Rfc822DateTime.TryParse(d[k], info.Language, out dt); itm.PubDate = ok ? dt : DateTime.Now; // log failed date parsing so we can update the format.xml file if needed if (!ok) { string msg = String.Format("Feed Plugin: DateTime parsing failed for value '{0}'; Feed '{1}'", d[k], info.Url); Growl.CoreLibrary.DebugInfo.WriteLine(msg); } break; case "content": case "description": itm.Description = d[k]; break; default: break; } } // add the created item to our List itemList.Add(itm); } info.Items = itemList; return(info); } catch { return(null); } }
private void ProcessFeed(FeedInfo feed) { DateTimeOffset mostRecentItem = this.feedLastUpdated; if (mostRecentItem == DateTimeOffset.MaxValue) mostRecentItem = DateTimeOffset.MinValue; Growl.CoreLibrary.DebugInfo.WriteLine(String.Format("Feed Retrieved: {0} - Last Most Recent Item: {1}", this.Description, mostRecentItem)); foreach (FeedItem item in feed.Items) { DateTimeOffset itemDate = item.PubDate; if (itemDate > mostRecentItem) mostRecentItem = itemDate; if (itemDate > this.feedLastUpdated) { Growl.CoreLibrary.DebugInfo.WriteLine(String.Format("{0} - New Feed Item - Published at: {1} - (last update at: {2})", this.Description, itemDate, this.feedLastUpdated)); item.SourceFeed = feed; Notification n = new Notification(this.AppName, this.ntNewFeedItem.Name, String.Empty, this.AppName, item.Title); n.Icon = feed.Icon; CallbackContext c = null; if (!String.IsNullOrEmpty(item.Link)) { c = new CallbackContext(item.Link); } // the NotificationQueue provides some simple throttling so that the screen is not flooded with new items // (especially important at load time when there could be lots of new items) NotificationQueue.Enqueue(n, c); } } this.feedLastUpdated = mostRecentItem; // feed.LastUpdatedTime is not always set =( }