Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        protected void LoadFromXml(XmlDocument doc)
        {
            // parse XML
            RssChannelDom dom = RssXmlHelper.ParseChannelXml(doc);

            // create the channel
            LoadFromDom(dom);
        }
Пример #4
0
        protected void LoadFromUrl(string url)
        {
            // download the feed
            RssChannelDom dom = RssDownloadManager.GetChannel(url);

            // create the channel
            LoadFromDom(dom);

            // remember the url
            _url = url;
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
        }