예제 #1
0
        public virtual async Task <RssChannel> GetChannel(CancellationToken cancellationToken = default(CancellationToken))
        {
            var project = await ProjectService.GetCurrentProjectSettings();

            if (project == null)
            {
                return(null);
            }

            var itemsToGet         = project.DefaultFeedItems;
            var requestedFeedItems = ContextAccessor.HttpContext?.Request.Query["maxItems"].ToString();

            if (!string.IsNullOrWhiteSpace(requestedFeedItems))
            {
                int.TryParse(requestedFeedItems, out itemsToGet);
                if (itemsToGet > project.MaxFeedItems)
                {
                    itemsToGet = project.MaxFeedItems;
                }
            }

            var posts = await BlogService.GetRecentPosts(itemsToGet);

            if (posts == null)
            {
                return(null);
            }

            var channel = new RssChannel
            {
                Title         = project.Title,
                Copyright     = project.CopyrightNotice,
                Generator     = Name,
                RemoteFeedUrl = project.RemoteFeedUrl,
                RemoteFeedProcessorUseAgentFragment = project.RemoteFeedProcessorUseAgentFragment
            };

            if (!string.IsNullOrEmpty(project.Description))
            {
                channel.Description = project.Description;
            }
            else
            {
                // prevent error, channel desc cannot be empty
                channel.Description = "Welcome to my blog";
            }

            if (!string.IsNullOrEmpty(project.ChannelCategoriesCsv))
            {
                var channelCats = project.ChannelCategoriesCsv.Split(',');
                foreach (var cat in channelCats)
                {
                    channel.Categories.Add(new RssCategory(cat));
                }
            }

            var urlHelper = UrlHelperFactory.GetUrlHelper(ActionContextAccesor.ActionContext);

            if (!string.IsNullOrEmpty(project.Image))
            {
                channel.Image.Url = new Uri(urlHelper.Content(project.Image));
            }
            if (!string.IsNullOrEmpty(project.LanguageCode))
            {
                channel.Language = new CultureInfo(project.LanguageCode);
            }

            var baseUrl = string.Concat(
                ContextAccessor.HttpContext.Request.Scheme,
                "://",
                ContextAccessor.HttpContext.Request.Host.ToUriComponent()
                );

            // asp.net bug? the comments for this method say it returns an absolute fully qualified url but it returns relative
            // looking at latest code seems ok so maybe just a bug in rc1
            //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/UrlHelperExtensions.cs
            //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelper.cs

            var indexUrl = urlHelper.RouteUrl(BlogRoutes.BlogIndexRouteName);

            if (indexUrl == null)
            {
                indexUrl = urlHelper.Action("Index", "Blog");
            }

            if (indexUrl.StartsWith("/"))
            {
                indexUrl = string.Concat(baseUrl, indexUrl);
            }
            channel.Link = new Uri(indexUrl);
            if (!string.IsNullOrEmpty(project.ManagingEditorEmail))
            {
                channel.ManagingEditor = project.ManagingEditorEmail;
            }

            if (!string.IsNullOrEmpty(project.ChannelRating))
            {
                channel.Rating = project.ChannelRating;
            }

            var feedUrl = string.Concat(
                ContextAccessor.HttpContext.Request.Scheme,
                "://",
                ContextAccessor.HttpContext.Request.Host.ToUriComponent(),
                ContextAccessor.HttpContext.Request.PathBase.ToUriComponent(),
                ContextAccessor.HttpContext.Request.Path.ToUriComponent(),
                ContextAccessor.HttpContext.Request.QueryString.ToUriComponent());

            channel.SelfLink = new Uri(feedUrl);

            channel.TimeToLive = project.ChannelTimeToLive;
            if (!string.IsNullOrEmpty(project.WebmasterEmail))
            {
                channel.Webmaster = project.WebmasterEmail;
            }

            DateTime mostRecentPubDate = DateTime.MinValue;
            var      items             = new List <RssItem>();

            foreach (var post in posts)
            {
                if (!post.PubDate.HasValue)
                {
                    continue;
                }

                if (post.PubDate.Value > mostRecentPubDate)
                {
                    mostRecentPubDate = post.PubDate.Value;
                }
                var rssItem = new RssItem
                {
                    Author = post.Author
                };

                if (post.Categories.Count > 0)
                {
                    foreach (var c in post.Categories)
                    {
                        rssItem.Categories.Add(new RssCategory(c));
                    }
                }

                var postUrl = await BlogUrlResolver.ResolvePostUrl(post, project).ConfigureAwait(false);

                if (string.IsNullOrEmpty(postUrl))
                {
                    //TODO: log
                    continue;
                }

                if (postUrl.StartsWith("/"))
                {
                    //postUrl = urlHelper.Content(postUrl);
                    postUrl = string.Concat(
                        ContextAccessor.HttpContext.Request.Scheme,
                        "://",
                        ContextAccessor.HttpContext.Request.Host.ToUriComponent(),
                        postUrl);
                }

                var filteredResult = ContentProcessor.FilterHtmlForRss(post, project, baseUrl);
                rssItem.Description = filteredResult.FilteredContent;
                if (!filteredResult.IsFullContent)
                {
                    //TODO: localize
                    var readMore = " <a href='" + postUrl + "'>...read more</a>";
                    rssItem.Description += readMore;
                }

                //rssItem.Enclosures

                rssItem.Guid            = new RssGuid(postUrl, true);
                rssItem.Link            = new Uri(postUrl);
                rssItem.PublicationDate = post.PubDate.Value;
                //rssItem.Source
                rssItem.Title = post.Title;

                items.Add(rssItem);
            }

            channel.PublicationDate = mostRecentPubDate;
            channel.Items           = items;

            return(channel);
        }