Beispiel #1
0
        /// <summary>
        /// Processes the item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public IFeedDetails ProcessItem(IFeedDetails item)
        {
            try {
                _feedChannelsLock.AcquireReaderLock(0);
                try {
                    if (_feedChannels.Count == 0)
                    {
                        return(item);
                    }

                    // process in prio order:
                    foreach (FeedChannelBase sink in _feedChannels.Values)
                    {
                        item = sink.Process(item);
                    }
                } finally {
                    _feedChannelsLock.ReleaseReaderLock();
                }
            } catch (ApplicationException) {
                // lock timeout
            } catch (Exception ex) {
                _log.Error("Failed to process IFeedDetails.", ex);
            }
            return(item);
        }
        [Test]//, Ignore("New API changes makes this hard to test."), FileIOPermission(SecurityAction.Demand)]
        public void MarkAllCachedItemsAsReadPlacesItemsIntoTheRecentlyViewedCount()
        {
            //Load feed list.

            var handler = new BanditFeedSource(ConfigurationWithoutSearchIndexerAndUnitTestCache, new SubscriptionLocation(WEBROOT_PATH + @"\NewsHandlerTestFiles\LocalTestFeedList.xml"));

            handler.MaxItemAge = TimeSpan.MaxValue.Subtract(TimeSpan.FromDays(1));
            handler.LoadFeedlist();

            Assert.IsTrue(handler.FeedsListOK, "Feeds should be valid!");

            //Grab a feed.
            var          feed     = handler.GetFeeds()[BASE_URL + "LocalTestFeed.xml"];
            IFeedDetails feedInfo = handler.GetFeedDetails(feed.link);

            Assert.IsNotNull(feedInfo);
            Console.WriteLine("CACHEURL: " + feed.cacheurl);

            //Save the cache.
            handler.ApplyFeedModifications(feed.link);

            Assert.AreEqual(feed.title, "Rss Bandit Unit Test Feed");
            Assert.AreEqual(1, feed.storiesrecentlyviewed.Count);

            //Grab feed items
            var items = handler.GetItemsForFeed(feed.link, false);

            Assert.AreEqual(2, items.Count);

            //The first one should have been read. the second not.
            NewsItem item = (NewsItem)items[0];

            Assert.IsTrue(item.BeenRead);
            item = (NewsItem)items[1];
            Assert.IsTrue(!item.BeenRead);

            //So let's read the second item.
            handler.MarkAllCachedItemsAsRead(feed);
            handler.ApplyFeedModifications(feed.link);

            //Let's save this guy.
            using (FileStream newFeedStream = File.OpenWrite(Path.Combine(WEBROOT_PATH, @"NewsHandlerTestFiles\LocalTestFeedList_NEW.xml")))
            {
                handler.SaveFeedList(newFeedStream, FeedListFormat.NewsHandler);
                newFeedStream.Close();
                Assert.IsTrue(File.Exists(Path.Combine(WEBROOT_PATH, @"NewsHandlerTestFiles\LocalTestFeedList_NEW.xml")));
            }

            //Let's reload and see what happens.
            handler = new BanditFeedSource(ConfigurationWithoutSearchIndexerAndUnitTestCache, new SubscriptionLocation(BASE_URL + "LocalTestFeedList_NEW.xml"));
            handler.LoadFeedlist();

            feed = handler.GetFeeds().Values.FirstOrDefault();
            //Assertion.AssertEquals("Should be two now.", 2, feed.storiesrecentlyviewed.Count);
            Assert.AreEqual(2, feed.storiesrecentlyviewed.Count, "Should be two now.");
        }
Beispiel #3
0
        /// <summary>
        /// Converts the input comments and list of users into a collection of INewsItem objects.
        /// </summary>
        /// <param name="feed">The parent news feed of the item whose comments are being generated</param>
        /// <param name="feedDetails">The parent feed details object for the comments being generated</param>
        /// <param name="comments">The comments from Facebook</param>
        /// <param name="users">The list of users who posted the comments </param>
        /// <returns>A list of news items representing the Facebook comments</returns>
        private static List <INewsItem> CreateCommentNewsItems(INewsFeed feed, IFeedDetails feedDetails, List <FacebookComment> comments, List <FacebookUser> users)
        {
            string htmlBody = @"<div class='comment_box'><div class='ufi_section'>
                                <div class='comment_profile_pic'>
                                 <a title='{0}' href='{1}'>
                                  <span class='UIRoundedImage UIRoundedImage_Small'><img class='UIRoundedImage_Image' src='{2}' /></span>
                                 </a>
                                </div>
                                <div class='comment_content'>
                                 <div class='comment_actions'>
                                  <a href='{1}'>{0}</a> - <span class='comment_meta_data'>{3}</span>
                                 </div>
                                 <div class='comment_text'><div class='comment_actual_text'>{4}</div>
                                </div>
                               </div>";

            List <INewsItem> items = new List <INewsItem>();

            foreach (FacebookComment c in comments)
            {
                FacebookUser u       = users.FirstOrDefault(user => user.uid == c.fromid.ToString());
                DateTime     pubdate = ConvertFromUnixTimestamp(c.time);

                //handle situations where all nulls returned because commenter isn't viewer's friend or in their network
                string name = String.IsNullOrEmpty(u.firstname) && String.IsNullOrEmpty(u.lastname) ?
                              ComponentsText.FacebookUnknownUser : u.firstname + " " + u.lastname;
                u.picsquare  = u.picsquare ?? DefaultFacebookProfilePic;
                u.profileurl = u.profileurl ?? DefaultFacebookProfileUrl;
                string content = String.Format(htmlBody, name, u.profileurl, u.picsquare, pubdate.ToString("h:mmtt MMM dd"), c.text);

                NewsItem n = new NewsItem(feed, String.Empty, String.Empty, content, pubdate, String.Empty);
                n.Author      = name;
                n.FeedDetails = feedDetails;
                n.Id          = c.id;

                items.Add(n);
            }

            return(items);
        }
Beispiel #4
0
 /// <summary>
 /// Creates a FeedInfo initialized from the specified IFeedDetails object
 /// </summary>
 /// <param name="ifd">The object to copy from</param>
 /// <param name="itemsList">The items list to use.</param>
 public FeedInfo(IFeedDetails ifd, IEnumerable <INewsItem> itemsList)
     : this(ifd.Id, String.Empty, new List <INewsItem>(itemsList ?? new List <INewsItem>()),
            ifd.Title, ifd.Link, ifd.Description,
            new Dictionary <XmlQualifiedName, string>(ifd.OptionalElements), ifd.Language)
 {
 }
Beispiel #5
0
 /// <summary>
 /// Creates a FeedInfo initialized from the specified IFeedDetails object.
 /// It also take over the IFeedDetails.ItemsList entries.
 /// </summary>
 /// <param name="ifd">The object to copy from</param>
 public FeedInfo(IFeedDetails ifd)
     : this(ifd, ifd.ItemsList)
 {
 }
Beispiel #6
0
 /// <summary>
 /// Base implementation does nothing then return the non-modified item.
 /// </summary>
 /// <param name="item">IFeedDetails</param>
 /// <returns></returns>
 public virtual IFeedDetails Process(IFeedDetails item)
 {
     return(item);
 }
Beispiel #7
0
 /// <summary>
 /// Helper to create a wrapped Exception, that provides more error infos for a feed
 /// </summary>
 /// <param name="e">Exception</param>
 /// <param name="f">NewsFeed</param>
 /// <param name="fi">IFeedDetails</param>
 /// <returns></returns>
 internal static FeedRequestException CreateLocalFeedRequestException(Exception e, INewsFeed f, IFeedDetails fi)
 {
     return(new FeedRequestException(e.Message, e, FeedSource.CreateFailureContext(f, fi)));
 }
Beispiel #8
0
        /// <summary>
        /// Transform a NewsItem, FeedInfo or FeedInfoList using the specified stylesheet
        /// </summary>
        /// <param name="stylesheet">The stylesheet to use for transformation</param>
        /// <param name="transformTarget">The object to transform</param>
        /// <param name="xslArgs"></param>
        /// <returns>The results of the transformation</returns>
        public virtual string ToHtml(string stylesheet, object transformTarget, XsltArgumentList xslArgs)
        {
            string link = String.Empty, content = String.Empty;

            if (transformTarget == null)
            {
                return("<html><head><title>empty</title></head><body></body></html>");
            }

            // use a streamed output to get the "disable-output-escaping"
            // working:
            StringWriter swr = new StringWriter();

            try     {
                XPathDocument doc;

                if (transformTarget is INewsItem)
                {
                    INewsItem item = (INewsItem)transformTarget;
                    link    = item.FeedLink;
                    content = item.Content;
                    doc     = new XPathDocument(new XmlTextReader(new StringReader(item.ToString(NewsItemSerializationFormat.NewsPaper, false))), XmlSpace.Preserve);
                }
                else if (transformTarget is IFeedDetails)
                {
                    IFeedDetails feed = (IFeedDetails)transformTarget;
                    link = feed.Link;
                    doc  = new XPathDocument(new XmlTextReader(new StringReader(feed.ToString(NewsItemSerializationFormat.NewsPaper, false))), XmlSpace.Preserve);
                }
                else if (transformTarget is FeedInfoList)
                {
                    FeedInfoList feeds = (FeedInfoList)transformTarget;
                    doc = new XPathDocument(new XmlTextReader(new StringReader(feeds.ToString())), XmlSpace.Preserve);
                }
                else
                {
                    throw new ArgumentException("transformTarget");
                }

                XslCompiledTransform transform;

                if (this.stylesheetTable.ContainsKey(stylesheet))
                {
                    transform = this.stylesheetTable[stylesheet].CompiledTransform;
                }
                else
                {
                    transform = this.stylesheetTable[String.Empty].CompiledTransform;
                }

                // support simple localizations (some common predefined strings to display):
                xslArgs.AddExtensionObject("urn:localization-extension", new LocalizerExtensionObject());
                transform.Transform(doc, xslArgs, swr);
            } catch (ThreadAbortException) {
                // ignored
            }       catch (Exception e)     {
                this.OnTransformationError(this, new FeedExceptionEventArgs(e, link, SR.ExceptionNewsItemTransformation));
                return(content);                // try to display unformatted simple text
            }

            return(swr.ToString());
        }
Beispiel #9
0
        /// <summary>
        /// The worker method.
        /// </summary>
        /// <param name="task"></param>
        protected override Exception DoTaskWork(ThreadWorkerTaskBase task)
        {
            //if ((Task)task.TaskID == Task.AnonymousDelegate)
            //{
            //    Action action = (Action)task.Arguments[0];
            //    if (action == null)
            //        throw new InvalidOperationException("no Action delegate specified");

            //    action();
            //    // default event if no result(s) from processing:
            //    RaiseBackgroundTaskFinished(task, 1, 1, null, null);
            //    return null;
            //}

            RssBanditApplication app = ((ThreadWorkerTask)task).Application;
            int maxTasks = 0, currentTask = 0;

            bool          force;
            UltraTreeNode feedNode;
            string        stylesheet, html;

            switch ((Task)task.TaskID)
            {
            case Task.LoadAllFeedSourcesSubscriptions:
                List <FeedSourceEntry> entries = (List <FeedSourceEntry>)task.Arguments[0];
                var finished = new ManualResetEvent(false);
                int max      = entries.Count;
                int current  = 0;

                for (int i = 0; i < max; i++)
                {
                    IndexedFeedSourceEntry e = new IndexedFeedSourceEntry(entries[i], i);

                    PriorityThreadPool.QueueUserWorkItem(
                        delegate(object state)
                    {
                        IndexedFeedSourceEntry fs = (IndexedFeedSourceEntry)state;
                        int threadCurrent         = fs.Index + 1;

                        try
                        {
                            app.LoadFeedSourceSubscriptions(fs.Entry, true);
                            this.RaiseBackroundTaskProgress(task, max, threadCurrent, null, fs.Entry);
                        }
                        catch (Exception loadEx)
                        {
                            this.RaiseBackroundTaskProgress(task, max, threadCurrent, loadEx, fs.Entry);
                        }
                        finally
                        {
                            if (Interlocked.Increment(ref current) >= max)
                            {
                                if (finished != null)
                                {
                                    finished.Set();
                                }
                            }
                        }
                    }, e, 1);
                }

                if (max > 0)
                {
                    finished.WaitOne(Timeout.Infinite, true);
                }

                break;

            case Task.LoadFeedSourceSubscriptions:
                app.LoadFeedSourceSubscriptions((FeedSourceEntry)task.Arguments[0], true);
                break;

            // code mocved to FlaggedItemsFeed migrate method:
            //case Task.LoadSpecialFeeds:
            //    app.InitializeFlaggedItems();
            //    break;

            case Task.RefreshFeeds:
                force = (bool)task.Arguments[0];
                app.FeedSources.ForEach(s => s.RefreshFeeds(force));
                break;

            case Task.RefreshCommentFeeds:
                force = (bool)task.Arguments[0];
                app.CommentFeedsHandler.RefreshFeeds(force);
                break;

            case Task.RefreshCategoryFeeds:
                FeedSourceEntry entry    = (FeedSourceEntry)task.Arguments[0];
                string          category = (string)task.Arguments[1];
                force = (bool)task.Arguments[2];
                entry.Source.RefreshFeeds(category, force);
                break;

            case Task.LoadCommentFeed:
                INewsItem item = (INewsItem)task.Arguments[0];
                if (item == null)
                {
                    throw new InvalidOperationException("Non-Null task argument 'item' expected.");
                }

                object result = null;

                if ((item.Feed != null) && (item.Feed.owner is IFacebookFeedSource))
                {
                    IFacebookFeedSource fbSource = item.Feed.owner as IFacebookFeedSource;
                    result = fbSource.GetCommentsForItem(item);
                }
                else
                {
                    NewsFeed cmtFeed = new NewsFeed();
                    cmtFeed.link  = item.CommentRssUrl;
                    cmtFeed.title = item.Feed.title;

                    if (!string.IsNullOrEmpty(item.Feed.authUser))
                    {           // take over credential settings
                        string u = null, p = null;
                        FeedSource.GetFeedCredentials(item.Feed, ref u, ref p);
                        FeedSource.SetFeedCredentials(cmtFeed, u, p);
                    }

                    result = RssParser.DownloadItemsFromFeed(cmtFeed, app.Proxy, FeedSource.Offline);
                }
                RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null, new object[] { result, item, task.Arguments[1], task.Arguments[2] });
                return(null);

            case Task.TransformFeed:
                IFeedDetails feed = (IFeedDetails)task.Arguments[0];
                feedNode   = (UltraTreeNode)task.Arguments[1];
                stylesheet = (string)task.Arguments[2];
                html       = app.FormatFeed(stylesheet, feed);

                RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null,
                                            new object[] { feedNode, html });
                return(null);

            case Task.TransformCategory:
                FeedInfoList feeds = (FeedInfoList)task.Arguments[0];
                feedNode   = (UltraTreeNode)task.Arguments[1];
                stylesheet = (string)task.Arguments[2];

                html = app.FormatFeeds(stylesheet, feeds);

                RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null,
                                            new object[] { feedNode, html });
                return(null);

            default:
                throw new InvalidOperationException("Unhandled ThreadWorker Task: " + task.TaskID);
            }

            // default event if no result(s) from processing:
            RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null, null);
            return(null);
        }