RssChannelDom DownloadChannelDom(string url) { // look for disk cache first RssChannelDom dom = TryLoadFromDisk(url); if (dom != null) { return(dom); } // download the feed byte[] feed = new WebClient().DownloadData(url); // parse it as XML XmlDocument doc = new XmlDocument(); doc.Load(new MemoryStream(feed)); // parse into DOM dom = RssXmlHelper.ParseChannelXml(doc); // set expiry string ttlString = null; dom.Channel.TryGetValue("ttl", out ttlString); int ttlMinutes = GetTtlFromString(ttlString, _defaultTtlMinutes); DateTime utcExpiry = DateTime.UtcNow.AddMinutes(ttlMinutes); dom.SetExpiry(utcExpiry); // save to disk TrySaveToDisk(doc, url, utcExpiry); return(dom); }
RssChannelDom GetChannelDom(string url) { RssChannelDom dom = null; lock (_cache) { if (_cache.TryGetValue(url, out dom)) { if (DateTime.UtcNow > dom.UtcExpiry) { _cache.Remove(url); dom = null; } } } if (dom == null) { dom = DownloadChannelDom(url); lock (_cache) { _cache[url] = dom; } } return(dom); }
protected void LoadFromXml(XmlDocument doc) { // parse XML RssChannelDom dom = RssXmlHelper.ParseChannelXml(doc); // create the channel LoadFromDom(dom); }
protected void LoadFromUrl(string url) { // download the feed RssChannelDom dom = RssDownloadManager.GetChannel(url); // create the channel LoadFromDom(dom); // remember the url _url = url; }
internal void LoadFromDom(RssChannelDom dom) { // channel attributes SetAttributes(dom.Channel); // image attributes if (dom.Image != null) { RssImageType image = new RssImageType(); image.SetAttributes(dom.Image); _image = image; } // items foreach (Dictionary <string, string> i in dom.Items) { RssItemType item = new RssItemType(); item.SetAttributes(i); _items.Add(item); } }
RssChannelDom TryLoadFromDisk(string url) { if (_directoryOnDisk == null) { return(null); // no place to cache } // look for all files matching the prefix // looking for the one matching url that is not expired // removing expired (or invalid) ones string pattern = GetTempFileNamePrefixFromUrl(url) + "_*.rss"; string[] files = Directory.GetFiles(_directoryOnDisk, pattern, SearchOption.TopDirectoryOnly); foreach (string rssFilename in files) { XmlDocument rssDoc = null; bool isRssFileValid = false; DateTime utcExpiryFromRssFile = DateTime.MinValue; string urlFromRssFile = null; try { rssDoc = new XmlDocument(); rssDoc.Load(rssFilename); // look for special XML comment (before the root tag)' // containing expiration and url XmlComment comment = rssDoc.DocumentElement.PreviousSibling as XmlComment; if (comment != null) { string c = comment.Value; int i = c.IndexOf('@'); long expiry; if (long.TryParse(c.Substring(0, i), out expiry)) { utcExpiryFromRssFile = DateTime.FromBinary(expiry); urlFromRssFile = c.Substring(i + 1); isRssFileValid = true; } } } catch { // error processing one file shouldn't stop processing other files } // remove invalid or expired file if (!isRssFileValid || utcExpiryFromRssFile < DateTime.UtcNow) { try { File.Delete(rssFilename); } catch { } // try next file continue; } // match url if (urlFromRssFile == url) { // found a good one - create DOM and set expiry (as found on disk) RssChannelDom dom = RssXmlHelper.ParseChannelXml(rssDoc); dom.SetExpiry(utcExpiryFromRssFile); return(dom); } } // not found return(null); }