using AutoMapper;
using HtmlAgilityPack;
using IP2Region;
using Masuit.Tools;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
#if !DEBUG
using Masuit.MyBlogs.Core.Models.ViewModel;
using Masuit.Tools.Models;
#endif
namespace Masuit.MyBlogs.Core.Common
{
///
/// 公共类库
///
public static class CommonHelper
{
static CommonHelper()
{
ThreadPool.QueueUserWorkItem(s =>
{
while (true)
{
BanRegex = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "ban.txt"), Encoding.UTF8);
ModRegex = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "mod.txt"), Encoding.UTF8);
DenyIP = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "denyip.txt"), Encoding.UTF8);
string[] lines = File.ReadAllLines(Path.Combine(AppContext.BaseDirectory + "App_Data", "DenyIPRange.txt"), Encoding.UTF8);
DenyIPRange = new Dictionary();
foreach (string line in lines)
{
try
{
var strs = line.Split(' ');
DenyIPRange[strs[0]] = strs[1];
}
catch (IndexOutOfRangeException)
{
}
}
IPWhiteList = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "whitelist.txt")).Split(',', ',').ToList();
Console.WriteLine("刷新公共数据...");
Thread.Sleep(TimeSpan.FromMinutes(10));
}
});
}
///
/// 敏感词
///
public static string BanRegex { get; set; }
///
/// 审核词
///
public static string ModRegex { get; set; }
///
/// 全局禁止IP
///
public static string DenyIP { get; set; }
///
/// ip白名单
///
public static List IPWhiteList { get; set; }
///
/// 每IP错误的次数统计
///
public static ConcurrentDictionary IPErrorTimes { get; set; } = new ConcurrentDictionary();
///
/// 系统设定
///
public static ConcurrentDictionary SystemSettings { get; set; } = new ConcurrentDictionary();
///
/// 访问量
///
public static double InterviewCount
{
get
{
try
{
return RedisHelper.Get("Interview:ViewCount");
}
catch
{
return 1;
}
}
set => RedisHelper.IncrBy("Interview:ViewCount");
}
///
/// 平均访问量
///
public static double AverageCount
{
get
{
try
{
return RedisHelper.Get("Interview:ViewCount") / RedisHelper.Get("Interview:RunningDays");
}
catch
{
return 1;
}
}
}
///
/// 网站启动时间
///
public static DateTime StartupTime { get; set; } = DateTime.Now;
///
/// IP黑名单地址段
///
public static Dictionary DenyIPRange { get; set; }
///
/// 判断IP地址是否被黑名单
///
///
///
public static bool IsDenyIpAddress(this string ip)
{
if (IPWhiteList.Contains(ip))
{
return false;
}
return DenyIP.Contains(ip) || DenyIPRange.AsParallel().Any(kv => kv.Key.StartsWith(ip.Split('.')[0]) && ip.IpAddressInRange(kv.Key, kv.Value));
}
///
/// 是否是禁区
///
///
///
public static bool IsInDenyArea(this string ips)
{
if (SystemSettings.GetOrAdd("EnableDenyArea", "false") == "true")
{
var denyAreas = SystemSettings.GetOrAdd("DenyArea", "").Split(',', ',');
foreach (var item in ips.Split(','))
{
var pos = GetIPLocation(item);
return pos.Contains(denyAreas) || denyAreas.Intersect(pos.Split("|")).Any();
}
}
return false;
}
private static readonly DbSearcher Searcher = new DbSearcher(Path.Combine(AppContext.BaseDirectory + "App_Data", "ip2region.db"));
public static string GetIPLocation(this IPAddress ip) => GetIPLocation(ip.MapToIPv4().ToString());
public static string GetIPLocation(this string ips)
{
return ips.Split(',').Select(s => Searcher.MemorySearch(IPAddress.Parse(s).MapToIPv4().ToString()).Region).Join(" , ");
}
///
/// 类型映射
///
///
///
///
public static T Mapper(this object source) where T : class => Startup.ServiceProvider.GetRequiredService().Map(source);
///
/// 发送邮件
///
/// 标题
/// 内容
/// 收件人
public static void SendMail(string title, string content, string tos)
{
#if !DEBUG
new Email()
{
EnableSsl = true,
Body = content,
SmtpServer = EmailConfig.Smtp,
Username = EmailConfig.SendFrom,
Password = EmailConfig.EmailPwd,
SmtpPort = SystemSettings["SmtpPort"].ToInt32(),
Subject = title,
Tos = tos
}.Send();
#endif
}
///
/// 是否是机器人访问
///
///
///
public static bool IsRobot(this HttpRequest req)
{
return req.Headers[HeaderNames.UserAgent].ToString().Contains(new[]
{
"DNSPod",
"Baidu",
"spider",
"Python",
"bot"
});
}
///
/// 清理html的img标签的除src之外的其他属性
///
///
///
public static string ClearImgAttributes(this string html)
{
var doc = new HtmlDocument();
doc.LoadHtml(html);
var nodes = doc.DocumentNode.Descendants("img");
foreach (var node in nodes)
{
string src = "";
if (node.Attributes.Contains("data-original"))
{
src = node.Attributes["data-original"].Value;
}
if (node.Attributes.Contains("src"))
{
src = node.Attributes["src"].Value;
}
node.Attributes.RemoveAll();
node.Attributes.Add("src", src);
}
return doc.DocumentNode.OuterHtml;
}
///
/// 将html的img标签的src属性名替换成data-original
///
///
///
///
public static string ReplaceImgAttribute(this string html, string title)
{
var doc = new HtmlDocument();
doc.LoadHtml(html);
var nodes = doc.DocumentNode.Descendants("img");
foreach (var node in nodes)
{
if (node.Attributes.Contains("src"))
{
string src = node.Attributes["src"].Value;
node.Attributes.Remove("src");
node.Attributes.Add("data-original", src);
node.Attributes.Add("alt", SystemSettings["Title"]);
node.Attributes.Add("title", title);
}
}
return doc.DocumentNode.OuterHtml;
}
///
/// 获取文章摘要
///
///
/// 截取长度
/// 摘要最少字数
///
public static string GetSummary(this string html, int length = 150, int min = 10)
{
var doc = new HtmlDocument();
doc.LoadHtml(html);
var summary = doc.DocumentNode.Descendants("p").FirstOrDefault(n => n.InnerText.Length > min)?.InnerText ?? "没有摘要";
if (summary.Length > 150)
{
return summary.Substring(0, length) + "...";
}
return summary;
}
}
}