/// <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."); }
/// <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); }
/// <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) { }
/// <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) { }
/// <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); }
/// <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))); }
/// <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()); }
/// <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); }