using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Dpz.Core.Service.ObjectStorage.Services;
using Dpz.Core.Service.V4.Services;
using Dpz.Core.Web.Library.Hub;
using Hangfire;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using IMumbleService = Dpz.Core.Service.V4.Services.IMumbleService;
/*
* 生成站点地图
* siteMapPushMessage 参数说明
* 0:推送消息
* 1:推送时间
* 2:推送消息样式
*
*/
namespace Dpz.Core.Web.Library.Activator
{
public class SiteMapTaskActivator : JobActivator
{
/// <summary>
/// 链接生成器
/// </summary>
private readonly LinkGenerator _linkGenerator;
/// <summary>
/// SignalR hub
/// </summary>
private readonly IHubContext<Notification> _hubContext;
/// <summary>
/// 日志记录
/// </summary>
private readonly ILogger<SiteMapTaskActivator> _logger;
/// <summary>
/// 提供web应用程序托管环境的信息
/// </summary>
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IMumbleService _mumbleService;
private readonly IObjectStorageOperation _objectStorageService;
/// <summary>
/// 互斥信号
/// </summary>
private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
/// <summary>
/// sitemap data
/// </summary>
private readonly DataSource _sitemap = new DataSource
{
Source = new List<SiteData>()
};
private readonly IArticleService _service;
public SiteMapTaskActivator(
LinkGenerator linkGenerator,
IHubContext<Notification> hubContext,
ILogger<SiteMapTaskActivator> logger,
IArticleService service,
IWebHostEnvironment webHostEnvironment,
IMumbleService mumbleService,
IObjectStorageOperation objectStorageService)
{
_linkGenerator = linkGenerator;
_hubContext = hubContext;
_logger = logger;
_webHostEnvironment = webHostEnvironment;
_mumbleService = mumbleService;
_objectStorageService = objectStorageService;
_service = service;
}
[ProlongExpirationTime]
public async Task StartAsync()
{
await SemaphoreSlim.WaitAsync();
try
{
await _hubContext.Clients.All.SendCoreAsync("siteMapPushMessage",
new object[] { "任务已开始!", DateTime.Now, "color:rgb(123, 213, 98)" });
await GenerateArticleLink();
await GenerateTalkLink();
// 源码
_sitemap.Source.Add(new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Code", new { path = "" }),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// 音乐
_sitemap.Source.Insert(0, new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Music"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// 时间轴
_sitemap.Source.Insert(0, new SiteData
{
Url = _linkGenerator.GetPathByAction("Timeline", "Home"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// steam
_sitemap.Source.Insert(0, new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Steam"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// 首页
_sitemap.Source.Insert(0, new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Home"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// 友链
_sitemap.Source.Add(new SiteData
{
Url = _linkGenerator.GetPathByAction("Friends", "Home"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// 书签
_sitemap.Source.Add(new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Bookmark"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
// markdown guide
_sitemap.Source.Add(new SiteData
{
Url = _linkGenerator.GetPathByAction("Markdown", "Home"),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
_sitemap.Source.ForEach(x => x.Url = "https://core.dpangzi.com" + x.Url);
// _sitemap.Source.Add(new SiteData
// {
// Url = "https://www.dpangzi.com",
// Frequency = "weekly",
// Priority = 0.5f,
// UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
// });
var serializer = new XmlSerializer(typeof(DataSource));
// await using var writer =
// new StreamWriter(Path.Combine(path, "sitemap.xml"), false);
// serializer.Serialize(writer, _sitemap);
using var stream = new MemoryStream();
serializer.Serialize(stream, _sitemap);
var bytes = stream.ToArray();
var uploadPath =
#if DEBUG
new[] { "Test", "sitemap" };
#else
new[] { "sitemap" };
#endif
await _objectStorageService.UploadAsync(bytes, uploadPath, "sitemap.xml");
_logger.LogInformation("站点地图生成成功!");
await _hubContext.Clients.All.SendCoreAsync("siteMapPushMessage",
new object[] { "站点地图生成成功!", DateTime.Now, "color:rgb(123, 213, 98)" });
}
catch (Exception ex)
{
_logger.LogError(ex, "sitemap生成失败");
await _hubContext.Clients.All.SendCoreAsync("siteMapPushMessage",
new object[] { "sitemap生成失败", DateTime.Now, "color:red;font-weight:bold" });
throw;
}
finally
{
SemaphoreSlim.Release();
}
}
/// <summary>
/// 生成文章相关链接
/// </summary>
/// <returns></returns>
private async Task GenerateArticleLink()
{
var articlePages = Enumerable.Range(1, 200).Select(x => new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Article", new { pageIndex = x }),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
}).ToList();
_sitemap.Source.AddRange(articlePages);
var tags = await _service.GetAllTagsAsync();
_sitemap.Source.AddRange(tags.Select(x => new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Article", new { tag = x }),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
}));
var publishArticles = await _service.GetPublishArticlesAsync();
_sitemap.Source.AddRange(publishArticles.Select(x => new SiteData
{
Url = _linkGenerator.GetPathByAction("Read", "Article", new { id = x.Id }),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = x.CreateTime.ToString("yyyy-MM-dd")
}));
}
/// <summary>
/// 生成talk相关链接
/// </summary>
/// <returns></returns>
private async Task GenerateTalkLink()
{
await _hubContext.Clients.All.SendCoreAsync("siteMapPushMessage",
new object[] { "正在查询talk相关数据", DateTime.Now, "color:rgba(247,140,108,1)" });
var pager = await _mumbleService.GetPagesAsync(1, 10);
await _hubContext.Clients.All.SendCoreAsync("siteMapPushMessage",
new object[] { "正在生成 talk 分页相关链接", DateTime.Now, "color:rgba(247,140,108,1)" });
var talkPage = Enumerable.Range(1, pager.TotalPageCount).Select(x => new SiteData
{
Url = _linkGenerator.GetPathByAction("Index", "Talk", new { pageIndex = x }),
Frequency = "weekly",
Priority = 0.5f,
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd")
});
_sitemap.Source.AddRange(talkPage);
}
}
}