示例#1
0
        /// <summary>
        /// Saves a particular RSS feed.
        /// </summary>
        /// <remarks>This method should be thread-safe</remarks>
        /// <param name="feed">The feed to save. This is an identifier
        /// and not used to actually fetch the feed from the WWW.</param>
        /// <returns>An identifier for the saved feed. </returns>
        public override string SaveFeed(IInternalFeedDetails feed)
        {
            string feedLocation = feed.FeedLocation;

            lock (this)
            {
                if (string.IsNullOrEmpty(feed.FeedLocation))
                {
                    feed.FeedLocation = feedLocation = GetCacheUrlName(feed.Id, new Uri(feed.Link));
                }
            }

            //get location of binary file containing RSS item contents
            string feedContentLocation = feedLocation.Substring(0, feedLocation.Length - 4) + ".bin";

            //write main RSS feed
            var tempFile = Path.GetTempFileName();

            using (FileStream stream = FileHelper.OpenForWrite(tempFile))
            {
                XmlTextWriter writer = new XmlTextWriter(new StreamWriter(stream));
                feed.WriteTo(writer, true);
                writer.Flush();
            }
            FileHelper.MoveFile(tempFile, Path.Combine(CacheLocation, feedLocation), MoveFileFlag.ReplaceExisting);

            //write binary file containing RSS item contents
            tempFile = Path.GetTempFileName();
            using (FileStream stream = FileHelper.OpenForWrite(tempFile))
            {
                var writer = new BinaryWriter(stream);

                FileStream   fs     = null;
                BinaryReader reader = null;

                try
                {
                    if (File.Exists(Path.Combine(CacheLocation, feedContentLocation)))
                    {
                        fs     = new FileStream(Path.Combine(CacheLocation, feedContentLocation), FileMode.OpenOrCreate);
                        reader = new BinaryReader(fs);
                    }

                    feed.WriteItemContents(reader, writer);
                    writer.Write(FileHelper.EndOfBinaryFileMarker);
                    writer.Flush();
                }
                finally
                {
                    if (fs != null)
                    {
                        fs.Close();
                    }
                }
            }            //using(...)

            FileHelper.MoveFile(tempFile, Path.Combine(CacheLocation, feedContentLocation), MoveFileFlag.ReplaceExisting);

            return(feedLocation);
        }
示例#2
0
        /// <summary>
        /// Returns an RSS feed.
        /// </summary>
        /// <param name="feed">The feed whose FeedInfo is required.</param>
        /// <returns>The requested feed or null if it doesn't exist</returns>
        public override IInternalFeedDetails GetFeed(INewsFeed feed)
        {
            if (null == feed || null == feed.cacheurl)
            {
                return(null);
            }

            IInternalFeedDetails fi = null;

            string cachelocation = Path.Combine(CacheLocation, feed.cacheurl);

            if (File.Exists(cachelocation))
            {
                using (Stream feedStream = FileHelper.OpenForRead(cachelocation)) {
                    fi = RssParser.GetItemsForFeed(feed, feedStream, true);
                }
                this.LoadItemContent(fi);
            }

            return(fi);
        }
示例#3
0
 /// <summary>
 /// Saves a particular RSS feed.
 /// </summary>
 /// <remarks>This method should be thread-safe</remarks>
 /// <param name="feed">The feed to save. This is an identifier
 /// and not used to actually fetch the feed from the WWW.</param>
 /// <returns>The feed ID</returns>
 public abstract string SaveFeed(IInternalFeedDetails feed);
示例#4
0
        /// <summary>
        /// Loads the content of the unread NewsItems from the binary file
        /// where item contents are contained. This is a memory-saving performance
        /// optimization so we only have the content of items that are unread on load.
        /// </summary>
        /// <param name="fi"></param>
        private void LoadItemContent(IInternalFeedDetails fi)
        {
            if (fi == null)
            {
                return;
            }

            Hashtable    unreadItems = new Hashtable();
            FileStream   fs          = null;
            BinaryReader reader      = null;


            //get list of unread items
            foreach (NewsItem item in fi.ItemsList)
            {
                if (!item.BeenRead)
                {
                    try
                    {
                        unreadItems.Add(item.Id, item);
                    }
                    catch (ArgumentException)
                    {
                        /* we don't test using ContainsKey() before Add() for performance reasons */
                    }
                }
            }

            try
            {
                string feedContentLocation = fi.FeedLocation.Substring(0, fi.FeedLocation.Length - 4) + ".bin";
                string fileName            = Path.Combine(CacheLocation, feedContentLocation);
                if (File.Exists(fileName))
                {
                    fs     = FileHelper.OpenForRead(fileName);
                    reader = new BinaryReader(fs);

                    string id = reader.ReadString();

                    while (!string.IsNullOrEmpty(id) && !id.Equals(FileHelper.EndOfBinaryFileMarker))
                    {
                        int    count   = reader.ReadInt32();
                        byte[] content = reader.ReadBytes(count);

                        if (unreadItems.Contains(id))
                        {
                            NewsItem ni = (NewsItem)unreadItems[id];
                            ni.SetContent(content, ContentType.Html);
                        }
                        id = reader.ReadString();
                    }                    //while(!id.Equals(...))
                }
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }