private Opml DownloadOpmlFeed(Uri uri) { // look for disk cache first Opml opmlFeed = TryLoadFromDisk(uri); if (opmlFeed != null) { return(opmlFeed); } // May fail under partial trust try { byte[] feed = new WebClient().DownloadData(uri.AbsoluteUri); var opmlDoc = new XmlDocument(); opmlDoc.Load(new MemoryStream(feed)); opmlFeed = Opml.LoadFromXml(opmlDoc); opmlFeed.UtcExpiry = DateTime.UtcNow.AddMinutes(_defaultTtlMinutes); // save to disk TrySaveToDisk(opmlDoc, uri, opmlFeed.UtcExpiry); } catch { return(new Opml()); } return(opmlFeed); }
private Opml TryLoadFromDisk(Uri uri) { 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(uri) + "_*.opml.resources"; string[] files = Directory.GetFiles(_directoryOnDisk, pattern, SearchOption.TopDirectoryOnly); foreach (string opmlFilename in files) { XmlDocument opmlDoc = null; bool isOpmlFileValid = false; DateTime utcExpiryFromOpmlFile = DateTime.MinValue; string urlFromOpmlFile = null; try { opmlDoc = new XmlDocument(); opmlDoc.Load(opmlFilename); // look for special XML comment (before the root tag)' // containing expiration and url var comment = opmlDoc.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)) { utcExpiryFromOpmlFile = DateTime.FromBinary(expiry); urlFromOpmlFile = c.Substring(i + 1); isOpmlFileValid = true; } } } catch { // error processing one file shouldn't stop processing other files } // remove invalid or expired file if (!isOpmlFileValid || utcExpiryFromOpmlFile < DateTime.UtcNow) { try { File.Delete(opmlFilename); } catch (Exception ex) { Logger.Error(ex); } // try next file continue; } // match url if (urlFromOpmlFile.ToLower() == uri.AbsoluteUri.ToLower()) { // found a good one - create DOM and set expiry (as found on disk) Opml opmlFeed = Opml.LoadFromXml(opmlDoc); opmlFeed.UtcExpiry = utcExpiryFromOpmlFile; return(opmlFeed); } } // not found return(null); }