Exemplo n.º 1
0
        /// <summary>
        /// Reads the list of articles from the stream and returns the feed item.
        /// </summary>
        /// <param name="f">Information about the feed. This information is updated based
        /// on the results of processing the feed.</param>
        /// <param name="newsgroupListStream">A stream containing an nntp news group list.</param>
        /// <param name="response">The response.</param>
        /// <param name="cacheDataService">The cache data service to store embedded binary content.</param>
        /// <param name="cachedStream">Flag states update last retrieved date on feed only
        /// if the item was not cached. Indicates whether the lastretrieved date is updated
        /// on the NewsFeed object passed in.</param>
        /// <returns>
        /// A FeedInfo containing the NewsItem objects
        /// </returns>
        internal static FeedInfo GetItemsForNewsGroup(INewsFeed f, Stream newsgroupListStream, WebResponse response, IUserCacheDataService cacheDataService, bool cachedStream)
        {
            int readItems          = 0;
            List <INewsItem> items = new List <INewsItem>();
            NewsItem         item;

            StringBuilder content = new StringBuilder();

#if DEBUG
            // just to have the source for the item to build to track down issues:
            StringBuilder itemSource = new StringBuilder();
#endif
            NntpWebResponse nntpResponse = (NntpWebResponse)response;

            FeedInfo fi = new FeedInfo(f.id, f.cacheurl, items, f.title, f.link, String.Empty);

            try
            {
                foreach (MimeMessage msg in nntpResponse.Articles)
                {
                    string   parentId;
                    string   id;
                    string   author  = parentId = id = null;
                    DateTime pubDate = DateTime.UtcNow;

                    content.Length = 0;

                    string title;
                    if (msg.Subject != null)
                    {
                        title = EscapeXML(msg.Subject.Value);
                    }
                    else
                    {
                        title = "";
                    }

                    UnstructuredField fld = msg.Header.GetField(MimeField.MessageID) as UnstructuredField;
                    if (fld != null)
                    {
                        id = fld.Value;
                    }

                    MailboxListField mfld = msg.Header.GetField(MimeField.From) as MailboxListField;
                    if (mfld != null && mfld.MailboxList.Count > 0)
                    {
                        author = mfld.MailboxList[0].AddressString;
                    }

                    fld = msg.Header.GetField(MimeField.References) as UnstructuredField;
                    if (fld != null)
                    {
                        // returns the hierarchy path: the last one is our real parent:
                        string[] singleRefs = fld.Value.Split(' ');
                        if (singleRefs.Length > 0)
                        {
                            parentId = CreateGoogleUrlFromID(singleRefs[singleRefs.Length - 1]);
                        }
                    }
                    DateTimeField dfld = msg.Header.GetField(MimeField.Date) as DateTimeField;
                    if (dfld != null)
                    {
                        pubDate = dfld.DateValue;
                    }

                    ITextBody txtBody = msg.Body as ITextBody;
                    if (txtBody != null)
                    {
                        content.Append(txtBody.Reader.ReadToEnd());

                        content = NntpClient.DecodeBody(content,
                                                        (fileName, bytes) =>
                        {
                            string name = PrepareEmbeddedFileUrl(fileName, id, nntpResponse.ResponseUri);
                            // we replace the uuencoded/yencoded binary content with a clickable link:
                            if (IsImage(fileName))
                            {
                                return(String.Format("<img src='{1}' alt='{0}'></img>", fileName,
                                                     cacheDataService.SaveBinaryContent(name, bytes).AbsoluteUri));
                            }
                            return(String.Format("<a href='{1}'>{0}</a>", fileName,
                                                 cacheDataService.SaveBinaryContent(name, bytes).AbsoluteUri));
                        },
                                                        line =>
                        {
                            // escape HTML/XML special chars:
                            return(line.Replace("<", "&lt;").Replace("]]>", "]]&gt;"));
                        });

                        content = content.Replace(Environment.NewLine, "<br>");
                    }

                    if (id != null)
                    {
                        item              = new NewsItem(f, title, CreateGoogleUrlFromID(id), content.ToString(), author, pubDate, id, parentId);
                        item.FeedDetails  = fi;
                        item.CommentStyle = SupportedCommentStyle.NNTP;
                        item.Enclosures   = Collections.GetList <IEnclosure> .Empty;
                        items.Add(item);
                        FeedSource.ReceivingNewsChannelServices.ProcessItem(item);
                    }
                    else
                    {
#if DEBUG
                        _log.Warn("No message-id header found for item:\r\n" + itemSource.ToString());
#else
                        _log.Warn("No message-id header found for item.");
#endif
                    }
                }


                //update last retrieved date on feed only if the item was not cached.)
                if (!cachedStream)
                {
                    f.lastretrieved          = new DateTime(DateTime.Now.Ticks);
                    f.lastretrievedSpecified = true;
                }

                //any new items in feed?
                if ((items.Count == 0) || (readItems == items.Count))
                {
                    f.containsNewMessages = false;
                }
                else
                {
                    f.containsNewMessages = true;
                }

                FeedSource.ReceivingNewsChannelServices.ProcessItem(fi);
                FeedSource.RelationCosmosAddRange(items);
                fi.itemsList.AddRange(items);
            }
            catch (Exception e)
            {
                _log.Error("Retriving NNTP articles from " + nntpResponse.ResponseUri + " caused an exception", e);
            }


            return(fi);
        }