SubscribeController.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. using Masuit.MyBlogs.Core.Common;
  2. using Masuit.MyBlogs.Core.Extensions;
  3. using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
  4. using Masuit.MyBlogs.Core.Models.Enum;
  5. using Masuit.MyBlogs.Core.Models.ViewModel;
  6. using Masuit.Tools.Core.Net;
  7. using Microsoft.AspNetCore.Mvc;
  8. using Microsoft.Extensions.Caching.Memory;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Net;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15. using WilderMinds.RssSyndication;
  16. using Z.EntityFramework.Plus;
  17. namespace Masuit.MyBlogs.Core.Controllers
  18. {
  19. /// <summary>
  20. /// 订阅服务
  21. /// </summary>
  22. public class SubscribeController : Controller
  23. {
  24. /// <summary>
  25. /// 文章
  26. /// </summary>
  27. public IPostService PostService { get; set; }
  28. public ICategoryService CategoryService { get; set; }
  29. public ICommentService CommentService { get; set; }
  30. /// <summary>
  31. /// 响应数据
  32. /// </summary>
  33. /// <param name="data">数据</param>
  34. /// <param name="success">响应状态</param>
  35. /// <param name="message">响应消息</param>
  36. /// <param name="isLogin">登录状态</param>
  37. /// <param name="code">http响应码</param>
  38. /// <returns></returns>
  39. public ActionResult ResultData(object data, bool success = true, string message = "", bool isLogin = true, HttpStatusCode code = HttpStatusCode.OK)
  40. {
  41. return Ok(new
  42. {
  43. IsLogin = isLogin,
  44. Success = success,
  45. Message = message,
  46. Data = data,
  47. code
  48. });
  49. }
  50. /// <summary>
  51. /// RSS订阅
  52. /// </summary>
  53. /// <returns></returns>
  54. [Route("/rss"), ResponseCache(Duration = 3600)]
  55. public async Task<IActionResult> Rss()
  56. {
  57. var time = DateTime.Today.AddDays(-1);
  58. string scheme = Request.Scheme;
  59. var host = Request.Host;
  60. var posts = await PostService.GetQueryNoTracking(p => p.Status == Status.Published && p.ModifyDate >= time, p => p.ModifyDate, false).Select(p => new Item()
  61. {
  62. Author = new Author
  63. {
  64. Name = p.Author,
  65. Email = p.Email
  66. },
  67. Body = p.Content.GetSummary(300, 50),
  68. Categories = new List<string>
  69. {
  70. p.Category.Name
  71. },
  72. Link = new Uri(scheme + "://" + host + "/" + p.Id),
  73. PublishDate = p.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone)),
  74. Title = p.Title,
  75. Permalink = scheme + "://" + host + "/" + p.Id,
  76. Guid = p.Id.ToString(),
  77. FullHtmlContent = p.Content.GetSummary(300, 50)
  78. }).FromCacheAsync(new MemoryCacheEntryOptions()
  79. {
  80. AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
  81. });
  82. var feed = new Feed()
  83. {
  84. Title = CommonHelper.SystemSettings["Title"],
  85. Description = CommonHelper.SystemSettings["Description"],
  86. Link = new Uri(scheme + "://" + host + "/rss"),
  87. Copyright = CommonHelper.SystemSettings["Title"],
  88. Language = "zh-cn",
  89. Items = posts.ToArray()
  90. };
  91. var rss = feed.Serialize(new SerializeOption()
  92. {
  93. Encoding = Encoding.UTF8
  94. });
  95. return Content(rss, "text/xml");
  96. }
  97. /// <summary>
  98. /// RSS分类订阅
  99. /// </summary>
  100. /// <returns></returns>
  101. [Route("/cat/{id}/rss"), ResponseCache(Duration = 3600)]
  102. public async Task<IActionResult> CategoryRss(int id)
  103. {
  104. var time = DateTime.Today.AddDays(-1);
  105. string scheme = Request.Scheme;
  106. var host = Request.Host;
  107. var category = await CategoryService.GetByIdAsync(id) ?? throw new NotFoundException("分类未找到");
  108. var posts = await PostService.GetQueryNoTracking(p => p.CategoryId == id && p.Status == Status.Published && p.ModifyDate >= time, p => p.ModifyDate, false).Select(p => new Item()
  109. {
  110. Author = new Author
  111. {
  112. Name = p.Author,
  113. Email = p.Email
  114. },
  115. Body = p.Content.GetSummary(300, 50),
  116. Categories = new List<string>
  117. {
  118. p.Category.Name
  119. },
  120. Link = new Uri(scheme + "://" + host + "/" + p.Id),
  121. PublishDate = p.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone)),
  122. Title = p.Title,
  123. Permalink = scheme + "://" + host + "/" + p.Id,
  124. Guid = p.Id.ToString(),
  125. FullHtmlContent = p.Content.GetSummary(300, 50)
  126. }).FromCacheAsync(new MemoryCacheEntryOptions()
  127. {
  128. AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
  129. });
  130. var feed = new Feed()
  131. {
  132. Title = Request.Host + $":分类{category.Name}文章订阅",
  133. Description = category.Description,
  134. Link = new Uri(scheme + "://" + host + "/rss"),
  135. Copyright = CommonHelper.SystemSettings["Title"],
  136. Language = "zh-cn",
  137. Items = posts.ToArray()
  138. };
  139. var rss = feed.Serialize(new SerializeOption()
  140. {
  141. Encoding = Encoding.UTF8
  142. });
  143. return Content(rss, "text/xml");
  144. }
  145. /// <summary>
  146. /// RSS文章订阅
  147. /// </summary>
  148. /// <returns></returns>
  149. [Route("/{id}/rss"), ResponseCache(Duration = 3600)]
  150. public async Task<IActionResult> PostRss(int id)
  151. {
  152. string scheme = Request.Scheme;
  153. var host = Request.Host;
  154. var p = await PostService.GetAsync(p => p.Status == Status.Published && p.Id == id) ?? throw new NotFoundException("文章未找到");
  155. var summary = p.Content.GetSummary(300, 50);
  156. var item = new Item()
  157. {
  158. Author = new Author
  159. {
  160. Name = p.Author,
  161. Email = p.Email
  162. },
  163. Body = summary,
  164. Categories = new List<string>
  165. {
  166. p.Category.Name
  167. },
  168. Link = new Uri(scheme + "://" + host + "/" + p.Id),
  169. PublishDate = p.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone)),
  170. Title = p.Title,
  171. Permalink = scheme + "://" + host + "/" + p.Id,
  172. Guid = p.Id.ToString(),
  173. FullHtmlContent = summary
  174. };
  175. var feed = new Feed()
  176. {
  177. Title = Request.Host + $":文章【{p.Title}】更新订阅",
  178. Description = summary,
  179. Link = new Uri(scheme + "://" + host + "/rss/" + id),
  180. Copyright = CommonHelper.SystemSettings["Title"],
  181. Language = "zh-cn",
  182. Items = new List<Item>() { item }
  183. };
  184. var rss = feed.Serialize(new SerializeOption()
  185. {
  186. Encoding = Encoding.UTF8
  187. });
  188. return Content(rss, "text/xml");
  189. }
  190. /// <summary>
  191. /// RSS文章评论订阅
  192. /// </summary>
  193. /// <returns></returns>
  194. [Route("/{id}/comments/rss"), ResponseCache(Duration = 600)]
  195. public async Task<IActionResult> CommentsRss(int id)
  196. {
  197. string scheme = Request.Scheme;
  198. var host = Request.Host;
  199. var post = await PostService.GetAsync(p => p.Status == Status.Published && p.Id == id) ?? throw new NotFoundException("文章不存在");
  200. var start = DateTime.Today.AddDays(-7);
  201. var comments = await CommentService.GetQuery(c => c.PostId == post.Id && c.CommentDate > start).Select(c => new Item()
  202. {
  203. Author = new Author
  204. {
  205. Name = c.NickName
  206. },
  207. Body = c.Content,
  208. Categories = new List<string>
  209. {
  210. c.Post.Title
  211. },
  212. Link = new Uri($"{scheme}://{host}/{post.Id}?cid={c.Id}#comment"),
  213. PublishDate = c.CommentDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone)),
  214. Title = c.NickName,
  215. Permalink = $"{scheme}://{host}/{post.Id}?cid={c.Id}#comment",
  216. Guid = c.Id.ToString(),
  217. FullHtmlContent = c.Content
  218. }).FromCacheAsync(new MemoryCacheEntryOptions()
  219. {
  220. AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
  221. });
  222. var feed = new Feed()
  223. {
  224. Title = Request.Host + $":文章【{post.Title}】文章评论更新订阅",
  225. Description = post.Content.GetSummary(300, 50),
  226. Link = new Uri(scheme + "://" + host + "/rss/" + id + "/comments"),
  227. Copyright = CommonHelper.SystemSettings["Title"],
  228. Language = "zh-cn",
  229. Items = comments.ToArray()
  230. };
  231. var rss = feed.Serialize(new SerializeOption()
  232. {
  233. Encoding = Encoding.UTF8
  234. });
  235. return Content(rss, "text/xml");
  236. }
  237. }
  238. }