101 lines
4.4 KiB
C#
101 lines
4.4 KiB
C#
namespace Yes.Application.Core.HostedServices
|
|
{
|
|
public class RssGenerationJob
|
|
{
|
|
private readonly BlogSettings _settings;
|
|
private readonly BlogDbContext _db;
|
|
private readonly ILogger<RssGenerationJob> _logger;
|
|
private readonly IWebHostEnvironment _env;
|
|
public RssGenerationJob(
|
|
IOptionsMonitor<BlogSettings> options,
|
|
BlogDbContext db,
|
|
IWebHostEnvironment env,
|
|
ILogger<RssGenerationJob> logger)
|
|
{
|
|
_settings = options.CurrentValue;
|
|
_db = db;
|
|
_env = env;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task Execute()
|
|
{
|
|
try
|
|
{
|
|
var queryArticle = _db.Articles.Where(x => x.Type == ArticleTypeEnum.Article && x.Status == ArticleStatusEnum.Normal).AsQueryable();
|
|
var pubDate = queryArticle.Any() ? _db.Articles.Min(x => x.PublishDate) : DateTime.MinValue;
|
|
|
|
var channel = new Channel
|
|
{
|
|
Title = _settings.Name,
|
|
Link = _settings.Url,
|
|
Description = _settings.Description,
|
|
Language = "zh-CN",
|
|
FeedUrl = $"{_settings.Url}/feed/",
|
|
PubDate = pubDate
|
|
};
|
|
|
|
// 添加扩展元素(示例)
|
|
channel.Extensions.Add(new XElement("generator", _settings.Name));
|
|
channel.Extensions.Add(new XElement("docs", "http://www.rssboard.org/rss-specification"));
|
|
|
|
var query = from article in queryArticle
|
|
join categoryTemp in _db.Categories.AsNoTracking() on article.CategoryId equals categoryTemp.Id into tempCategory
|
|
from category in tempCategory.DefaultIfEmpty()
|
|
join userTemp in _db.Users.AsNoTracking() on article.UserId equals userTemp.Id into tempUser
|
|
from user in tempUser.DefaultIfEmpty()
|
|
orderby article.Id descending
|
|
select new ArticleModel
|
|
{
|
|
Id = article.Id,
|
|
CanComment = article.CanComment,
|
|
CommentCount = article.CommentCount,
|
|
CategoryId = article.CategoryId,
|
|
ModifyDate = article.ModifyDate.ToSafeTime(),
|
|
PublishDate = article.PublishDate.ToSafeTime(),
|
|
CreateDate = article.CreateDate.ToSafeTime(),
|
|
Content = article.Content,
|
|
CoverUrl = article.CoverUrl,
|
|
Slug = article.Slug,
|
|
ReadCount = article.ReadCount,
|
|
Title = article.Title,
|
|
Summary = article.Summary,
|
|
UserId = article.UserId,
|
|
Category = new CategoryModel
|
|
{
|
|
CoverUrl = category.CoverUrl,
|
|
Description = category.Description,
|
|
Id = category.Id,
|
|
Name = category.Name,
|
|
Slug = category.Slug
|
|
}
|
|
};
|
|
|
|
var items = query.Select(x => new Item
|
|
{
|
|
Content = x.Content,
|
|
Title = x.Title,
|
|
Url = $"{_settings.Url}/{_settings.ArticleRoute.ToRoute(x.Category, x)}",
|
|
Description = x.Summary,
|
|
CommentsCount = x.CommentCount,
|
|
Creator = x.UserId.ToString(),
|
|
PublishDate = x.PublishDate,
|
|
CommentsUrl = $"{_settings.Url}/{_settings.ArticleRoute.ToRoute(x.Category, x)}#comments",
|
|
CommentRssUrl = $"{_settings.Url}/feed/"
|
|
});
|
|
|
|
|
|
var generator = new RssGenerator();
|
|
string xml = generator.GenerateRss(channel, items);
|
|
|
|
|
|
File.WriteAllText(Path.Combine(_env.WebRootPath, "feed.xml"), xml);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "RSS generation failed");
|
|
}
|
|
}
|
|
}
|
|
}
|