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; } } }