添加项目文件。

This commit is contained in:
cmn
2025-11-27 16:58:03 +08:00
parent c5adc0a415
commit ee1bb22e95
23 changed files with 2447 additions and 0 deletions

View File

@@ -0,0 +1,241 @@

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Net;
using System.Threading.Tasks;
using TelegramService.Bl;
using TelegramService.Entity;
using TelegramService.Help;
namespace TelegramServiceV6.Bl
{
public class CnblogsBl
{
/// <summary>
/// 发送 消息
/// </summary>
private async void SendTextMessage(string title, string author, string authorUrl, string time, string preview, string url)
{
try
{
string sHtml = "\r\n主 题:<b>" + title + "</b>\n";
sHtml += "作 者:<a href=\"" + authorUrl + "\">" + author + "</a>\n";
sHtml += "时 间:<b>" + time + "</b>\n";
sHtml += "预 览:<b>" + preview + "</b>\n";
sHtml += "链 接:<a href=\"" + url + "\">" + url + "</a>\n";
JObject oObj = new JObject();
oObj.Add("chat_id", "-1001341062469");
oObj.Add("text", sHtml);
oObj.Add("parse_mode", "HTML");
//是否显示url 预览
oObj.Add("disable_web_page_preview", "TRUE");
SendMessageBl.SendWx("https://api.telegram.org/bot1879430057:AAHtwdwHLH0a7cNjTPBQsI92ivoKZI6P-5A/sendMessage", oObj.ToString());
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[CnblogsBl.SendTextMessage] " + ex.Message);
}
}
/// <summary>
/// 发送微信
/// </summary>
/// <param name="title"></param>
/// <param name="author"></param>
/// <param name="authorUrl"></param>
/// <param name="time"></param>
/// <param name="preview"></param>
/// <param name="url"></param>
private void SendWeixin(string title, string author, string authorUrl, string time, string preview, string url)
{
string sHtml = "主 题:" + title + "\n";
sHtml += "作 者:<a href=\"" + authorUrl + "\">" + author + "</a>\n";
sHtml += "时 间:" + time + "\n";
sHtml += "预 览:" + preview + "\n";
sHtml += "链 接:<a href=\"" + url + "\">" + url + "</a>\n";
JObject oObj = new JObject();
oObj.Add("text", sHtml);
SendMessageBl.SendWx("https://111.230.99.204/weixin/api/send_text", oObj.ToString());
}
/// <summary>
/// 获取博客内容
/// </summary>
public async Task GetCnblogsHtml()
{
try
{
if (DateTime.Now.Hour < 6)
{
EntrustHelper.STCB("show", "[CnblogsBl.GetCnblogsHtml] 晚上0-6点不执行!");
return;
}
EntrustHelper.STCB("show", "[CnblogsBl.GetCnblogsHtml] 开始执行!");
string shtml =await GetHtml();
if (shtml.IsNullOrWhiteSpace())
{
EntrustHelper.STCB("show", "[CnblogsBl.GetCnblogsHtml] 获取不到数据!");
return;
}
List<HtmlTag> listHtmlTag = HtmlTag.FindTagByAttr(shtml, "div", "id", "post_list");
List<HtmlTag> listObj = null;
if (listHtmlTag.Count > 0)
{
listHtmlTag = listHtmlTag[0].FindTag("article");
}
string stitle = "";
string sauthor = "";
string sauthorUrl = "";
string stime = "";
string spreview = "";
string surl = "";
int iCount = listHtmlTag.Count;
for (int i = 1; i <= listHtmlTag.Count; i++)
{
try
{
listObj = listHtmlTag[iCount - i].FindTagByAttr("a", "class", "post-item-title");
stitle = listObj[0].InnerText;
surl = listObj[0].GetAttribute("href");
listObj = listHtmlTag[iCount - i].FindTagByAttr("p", "class", "post-item-summary");
spreview = listObj[0].InnerText.Trim();
listObj = listHtmlTag[iCount - i].FindTagByAttr("a", "class", "post-item-author");
sauthor = listObj[0].InnerText.Trim();
sauthorUrl = listObj[0].GetAttribute("href");
listObj = listHtmlTag[iCount - i].FindTagByAttr("span", "class", "post-meta-item");
stime = listObj[0].FindTag("span")[0].InnerHTML;
if (!IsExistUrl(surl))
{
//写入数据库
SetCnblogsDB(stitle, sauthor, sauthorUrl, stime, spreview, surl);
//发送TG消息
SendTextMessage(stitle, sauthor, sauthorUrl, stime, spreview, surl);
//发送微信
SendWeixin(stitle, sauthor, sauthorUrl, stime, spreview, surl);
}
else
{
continue;
}
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[CnblogsBl.GetCnblogsHtml] " + ex.Message);
}
}
listHtmlTag.Clear();
listObj.Clear();
EntrustHelper.STCB("show", "[CnblogsBl.GetCnblogsHtml] 执行结束!");
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[CnblogsBl.GetCnblogsHtml] " + ex.Message);
}
finally
{
EntrustHelper.STCB("InitTimer", Appsettings.Conf.Interval);
}
}
/// <summary>
/// 判断是否存在 true=存在 false=不存在
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private bool IsExistUrl(string url)
{
try
{
int iCount = 0;
iCount = Db.dbConnection.Queryable<cnblogsList>().Where(it => it.url == url).Count();
if (iCount == 1)
{
return true;
}
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[CnblogsBl.IsExistUrl] " + ex.Message);
}
return false;
}
/// <summary>
/// 写入 数据库
/// </summary>
/// <param name="title"></param>
/// <param name="author"></param>
/// <param name="authorUrl"></param>
/// <param name="time"></param>
/// <param name="preview"></param>
/// <param name="url"></param>
/// <returns></returns>
private int SetCnblogsDB(string title, string author, string authorUrl, string time, string preview, string url)
{
string sSql = "";
int iCount = 0;
cnblogsList encnblogsList = new cnblogsList();
encnblogsList.url = url;
encnblogsList.title = title;
encnblogsList.preview = preview;
encnblogsList.author = author;
encnblogsList.authorUrl = authorUrl;
encnblogsList.time = time;
encnblogsList.addTime = DateTime.Now;
iCount = Db.dbConnection.Insertable(encnblogsList).ExecuteCommand();
return iCount;
}
/// <summary>
/// 获取html
/// </summary>
/// <returns></returns>
private async Task<string> GetHtml()
{
try
{
HttpResult httpResult = null;
string html = "";
for (int i = 0; i < 5; i++)
{
httpResult =await HttpHelper.GetAsync("https://www.cnblogs.com/");
if (httpResult.StatusCode == 200)
{
if (httpResult.Html.IndexOfStr("id=\"post_list\""))
{
return httpResult.Html;
}
}
}
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[CnblogsBl.GetHtml] " + ex.Message);
}
return null;
}
}
}

View File

@@ -0,0 +1,158 @@
using Newtonsoft.Json.Linq;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using TelegramService.Help;
using TelegramService.Entity;
using TelegramService.Help;
using System.Threading.Tasks;
namespace TelegramServiceV6.Bl
{
public class FundBl
{
/// <summary>
/// 发送微信
/// </summary>
/// <param name="title"></param>
/// <param name="author"></param>
/// <param name="authorUrl"></param>
/// <param name="time"></param>
/// <param name="preview"></param>
/// <param name="url"></param>
public static void SendWeixinFund()
{
SendWeixinFundEastmoney();
}
/// <summary>
/// 发送微信 http://fund.eastmoney.com/ 天天基金
/// </summary>
/// <param name="title"></param>
/// <param name="author"></param>
/// <param name="authorUrl"></param>
/// <param name="time"></param>
/// <param name="preview"></param>
/// <param name="url"></param>
public static async Task SendWeixinFundEastmoney()
{
try
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] 开始发送基金");
string code = string.Join(",", Appsettings.Conf.Fund);
Dictionary<string, string> form = new Dictionary<string, string>();
form.Add("fcodes", code);
Dictionary<string, string> header = new Dictionary<string, string>();
header.Add("Origin", "https://favor.fund.eastmoney.com");
header.Add("Referer", "https://favor.fund.eastmoney.com/");
HttpResult httpResult = null;
string html = "";
for (int i = 0; i < 6; i++)
{
try
{
httpResult = await HttpHelper.PostFormAsync("https://api.fund.eastmoney.com/favor/GetFundsInfo?", form, header);
if (httpResult.StatusCode == 200)
{
html = httpResult.Html;
break;
}
}
catch (Exception)
{
}
}
if (html.IsNull())
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] 开始发送基金,请求失败");
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] "+html);
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] 开始发送基金,请求失败");
return;
}
JObject jsdata = JObject.Parse(html);
if (jsdata["ErrCode"].ToString() != "0")
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney1] "+jsdata.ToString());
return;
}
StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder();
sb1.Append("---------------------------------\n");
int index = 0;
foreach (var data in jsdata["Data"]["KFS"])
{
if (!code.Contains(data["FCODE"].ToString()))
{
continue;
}
if (data["RZDF"].ToDouble() >= 0)
{
if (sb.Length > 0) sb.Append("---------------------------------\n");
sb.Append(data["FSRQ"] + " (" + data["FCODE"].ToString() + ")\n");
sb.Append(data["SHORTNAME"] + "\n");
sb.Append(data["RZDF"] + "\n");
}
else
{
sb1.Append("---------------------------------\n");
sb1.Append(data["FSRQ"] + " (" + data["FCODE"].ToString() + ")\n");
sb1.Append(data["SHORTNAME"] + "\n");
sb1.Append(data["RZDF"] + "\n");
}
index++;
}
for (int i = 0; i < 2; i++)
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] 请求微信api接口");
httpResult=await HttpHelper.GetAsync("https://111.230.99.204/weixin/api/msgyq?id=CaiMengNan&text=" + sb.ToString() + sb1.ToString());
if (httpResult.StatusCode==200 && httpResult.Html.IndexOfStr("\"errmsg\":\"ok\""))
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] 发送基金成功");
return;
}
}
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] "+ex.Message);
}
finally
{
try
{
DateTime now = DateTime.Now;
DateTime next22 = new DateTime(now.Year, now.Month, now.Day, 22, 0, 0);
// 如果现在已经过了今天的 22:00则计算明天的 22:00
if (now >= next22)
{
next22 = next22.AddDays(1);
}
double millisecondsUntilNext22 = (next22 - now).TotalMilliseconds;
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] 等待下次执行");
EntrustHelper.STCB("sendWeixinFund", millisecondsUntilNext22);
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[FundBl.SendWeixinFundEastmoney] " + ex.Message);
}
}
}
}
}

View File

@@ -0,0 +1,55 @@
using NetTaste;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using TelegramService.Help;
namespace TelegramService.Bl
{
public class SendMessageBl
{
public static async Task<bool> SendWx(string url,string msg)
{
HttpResult httpResult;
for (int i = 0; i < 2; i++)
{
httpResult = await HttpHelper.PostJsonAsync(url, msg);
if (httpResult.StatusCode != 200)
{
continue;
}
if (httpResult.Html.IndexOfStr("\"errmsg\":\"ok\""))
{
return true;
}
}
return false;
}
public static async Task<bool> SendTg(string url,string msg)
{
HttpResult httpResult = null;
for (int i = 0; i < 2; i++)
{
httpResult = await HttpHelper.PostJsonAsync(url, msg);
if (httpResult.StatusCode != 200)
{
continue;
}
if (httpResult.Html.IndexOfStr("\"ok\":true,"))
{
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TelegramService.Entity\TelegramService.Entity.csproj" />
<ProjectReference Include="..\TelegramService.Help\TelegramService.Help.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,174 @@

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using TelegramService.Bl;
using TelegramService.Entity;
using TelegramService.Help;
namespace TelegramServiceV6.Bl
{
public class TieBaBl
{
/// <summary>
/// 发送 消息
/// </summary>
private void SendTextMessage(string title, string sType, string stime, string surl)
{
try
{
string sHtml = "\r\n标 题:<b>" + title + "</b>\n";
sHtml += "类 型:<b>" + sType + "</b>\n";
sHtml += "入库时间:<b>" + stime + "</b>\n";
sHtml += "链 接:<a href=\"" + surl + "\">" + surl + "</a>\n";
JObject oObj = new JObject();
oObj.Add("chat_id", "-1001523898048");
oObj.Add("text", sHtml);
oObj.Add("parse_mode", "HTML");
//是否显示url 预览
oObj.Add("disable_web_page_preview", "TRUE");
SendMessageBl.SendTg("https://api.telegram.org/bot1918024418:AAHj_RNtA-XkWbodtzkzaTIxc0XYxBVoQKY/sendMessage", oObj.ToString());
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[TieBaBl.SendTextMessage] " + ex.Message);
}
}
/// <summary>
/// 获取贴吧
/// </summary>
public async void GetTieBaHtml()
{
try
{
EntrustHelper.STCB("show", "[TieBaBl.GetTieBaHtml1] 开始执行!");
HttpResult httpResult = null;
foreach (var tk in Appsettings.Conf.TieBa)
{
string key = tk.ToString();
string encodedUrl = HttpUtility.UrlEncode(key);
string shtml = null;
string tiebaUrl = "https://tieba.baidu.com/mo/m?kw=" + encodedUrl.ToUpper() + "&lm=&pn=0";
for (int i = 0; i < 3; i++)
{
httpResult =await HttpHelper.GetAsync(tiebaUrl);
if (httpResult.StatusCode == 200)
{
shtml = httpResult.Html;
break;
}
}
if (shtml.IsNullOrWhiteSpace())
{
EntrustHelper.STCB("show", "[TieBaBl.GetTieBaHtml2] 获取不到数据!");
return;
}
List<HtmlTag> listHtmlTag = HtmlTag.FindTagByAttr(shtml, "ul", "id", "frslistcontent");
List<HtmlTag> lista = null;
if (listHtmlTag.Count == 0)
{
EntrustHelper.STCB("show", "[TieBaBl.GetTieBaHtml3] 贴吧html匹配不到div!");
return;
}
listHtmlTag = listHtmlTag[0].FindTagByAttr("li", "class", "tl_shadow tl_shadow_new ");
for (int i = 0; i < listHtmlTag.Count; i++)
{
try
{
lista = listHtmlTag[i].FindTag("a");
if (lista.Count == 0)
{
continue;
}
string url = lista[0].GetAttribute("href");
string id = Regex.Match(url, @"(?is)/p/(?<value>.*?)s*\?").Groups["value"].Value;
if (id.IsNull())
{
continue;
}
lista = lista[0].FindTagByAttr("div", "class", "ti_title");
if (lista.Count <= 0)
{
continue;
}
string title = lista[0].InnerText;
if (title.Contains("&#160;"))
{
string[] arr = title.SplitRemoveEmptyEntries("&#160;");
if (arr.Length > 1)
{
title = arr[1];
}
}
tieba tb = new tieba();
tb.id = id;
tb.title = title;
if (tb.title.Length > 149)
{
tb.title = tb.title.Substring(0, 149);
}
tb.key = key;
tb.url = "tieba.baidu.com/p/" + tb.id;
tb.sysaddtime = DateTime.Now;
if (SetTieBaDB(tb) > 0)
{
SendTextMessage(tb.title, tb.key, tb.sysaddtime.ToDateStr(), "https://" + tb.url);
}
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[TieBaBl.GetTieBaHtml4] " + ex.Message);
}
}
listHtmlTag.Clear();
lista.Clear();
Thread.Sleep(5000);
}
EntrustHelper.STCB("show", "[TieBaBl.GetTieBaHtml5] 执行结束!");
}
catch (Exception)
{
}
finally
{
EntrustHelper.STCB("InitTimerTieBa", Appsettings.Conf.IntervalTieBa);
}
}
/// <summary>
/// 写入 数据库
/// </summary>
/// <returns></returns>
private int SetTieBaDB(tieba tb)
{
try
{
var x = Db.dbConnection.Storageable(tb).ToStorage();
x.AsInsertable.ExecuteCommand();//不存在插入
return x.InsertList.Count;
}
catch (Exception ex)
{
EntrustHelper.STCB("show", "[TieBaBl.SetTieBaDB] " + ex.Message);
}
return 0;
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TelegramService.Entity
{
public class Appsettings
{
public static AppsettingsRoot Conf = null;
}
public class LogLevel
{
/// <summary>
///
/// </summary>
public string Default { get; set; }
/// <summary>
///
/// </summary>
public string MicrosoftHostingLifetime { get; set; }
}
public class Logging
{
/// <summary>
///
/// </summary>
public LogLevel LogLevel { get; set; }
}
public class ConnectionStrings
{
/// <summary>
///
/// </summary>
public string DBConnection { get; set; }
}
public class AppsettingsRoot
{
/// <summary>
///
/// </summary>
public Logging Logging { get; set; }
/// <summary>
///
/// </summary>
public ConnectionStrings ConnectionStrings { get; set; }
/// <summary>
///
/// </summary>
public int Interval { get; set; }
/// <summary>
///
/// </summary>
public int IntervalLiYuan { get; set; }
/// <summary>
///
/// </summary>
public int IntervalTieBa { get; set; }
/// <summary>
///
/// </summary>
public List<string> Fund { get; set; }
/// <summary>
///
/// </summary>
public List<string> TieBa { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
namespace TelegramService.Entity
{
public class Db
{
/// <summary>
/// 数据库连接
/// </summary>
public static SqlSugarClient dbConnection
{
get
{
return new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = Appsettings.Conf.ConnectionStrings.DBConnection,//连接符字串
DbType = SqlSugar.DbType.MySql, //数据库类型
IsAutoCloseConnection = true //不设成true要手动close
});
}
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace TelegramService.Entity
{
///<summary>
///
///</summary>
[SugarTable("cnblogsList")]
public partial class cnblogsList
{
public cnblogsList(){
}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey=true)]
public string url {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string title {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string preview {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string author {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string authorUrl {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string time {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public DateTime? addTime {get;set;}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace TelegramService.Entity
{
///<summary>
///
///</summary>
[SugarTable("liYuanList")]
public partial class liYuanList
{
public liYuanList(){
}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey=true)]
public int tid {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string title {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string type {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string author {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public DateTime? time {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string url {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string slug {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public DateTime? addtime {get;set;}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace TelegramService.Entity
{
///<summary>
///贴吧
///</summary>
[SugarTable("tieba")]
public partial class tieba
{
public tieba(){
}
/// <summary>
/// Desc:那个贴吧
/// Default:
/// Nullable:False
/// </summary>
public string key {get;set;}
/// <summary>
/// Desc:url的id
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey=true)]
public string id {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string url {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string title {get;set;}
/// <summary>
/// Desc:
/// Default:CURRENT_TIMESTAMP
/// Nullable:False
/// </summary>
public DateTime sysaddtime {get;set;}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SqlSugarCore" Version="5.1.4.210" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TelegramService.Help
{
public class EntrustHelper
{
public delegate object SetTextcallBack(string action, object obj);
public static SetTextcallBack STCB;
}
}

View File

@@ -0,0 +1,745 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace TelegramService.Help
{
public static class ExtendHelper
{
#region Exception
/// <summary>
/// 获取 错误信息
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string StackTrace(this Exception s, string str = null)
{
StackTrace st = new StackTrace(s, true);
//Get the first stack frame
// StackFrame frame = st.GetFrames().Last();
StackFrame frame = st.GetFrame(0);
StringBuilder sb = new StringBuilder();
sb.Append("\n===================================错误文件==========================================================\r\n");
sb.Append(frame.GetFileName() + "\r\n");
sb.Append("===================================错误类============================================================\r\n");
sb.Append("[" + Path.GetFileNameWithoutExtension(frame.GetFileName()) + "][" + frame.GetMethod().Name + "][" + frame.GetFileLineNumber() + "]" + "\r\n");
sb.Append("===================================错误内容==========================================================\r\n");
sb.Append(s.ToString() + "\r\n");
if (str.IsNotNull())
{
sb.Append("===================================备注==============================================================\r\n");
sb.Append(str + "\r\n");
}
sb.Append("=====================================================================================================\r\n");
return sb.ToString();
}
/// <summary>
/// 获取 位置信息
/// </summary>
/// <returns></returns>
public static string getStackTrace()
{
StackTrace st = new StackTrace(true);
StackFrame frame = st.GetFrame(1);
StringBuilder sb = new StringBuilder();
if (frame != null)
{
sb.Append("[" + Path.GetFileNameWithoutExtension(frame.GetFileName()) + "][" + frame.GetMethod().Name + "][" + frame.GetFileLineNumber() + "]");
}
return sb.ToString();
}
/// <summary>
/// 获取 位置信息
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string StackTrace(this string s)
{
StackTrace st = new StackTrace(true);
StackFrame frame = st.GetFrame(1);
StringBuilder sb = new StringBuilder();
sb.Append(s);
if (frame != null)
{
sb.Append("[" + Path.GetFileNameWithoutExtension(frame.GetFileName()) + "][" + frame.GetMethod().Name + "][" + frame.GetFileLineNumber() + "]");
}
return sb.ToString();
}
#endregion
#region int
/// <summary>
/// 转换指定时间得到对应的时间戳
/// true 则生成13位的时间戳,
/// false 则生成10位的时间戳,默认为 true
/// </summary>
/// <param name="s"></param>
/// <param name="isLongTime">精度(毫秒)设置 true则生成13位的时间戳精度设置为 false则生成10位的时间戳默认为 true </param>
/// <returns>返回对应的时间戳</returns>
public static long ToTimeStamp(this DateTime s, bool isLongTime = true)
{
var ts = s.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return isLongTime ? Convert.ToInt64(ts.TotalMilliseconds) : Convert.ToInt64(ts.TotalSeconds);
}
/// <summary>
/// 取整 有小数进1
/// </summary>
/// <param name="d"></param>
/// <param name="decimals"></param>
/// <returns></returns>
public static int ToInteger(this double d)
{
return Math.Ceiling(d).ToInt32();
}
/// <summary>
/// 转换为int
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static int ToInt32(this string s)
{
return Convert.ToInt32(s);
}
/// <summary>
/// 转换为Double
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static double ToDouble(this string s)
{
return Convert.ToDouble(s);
}
/// <summary>
/// 转换为int
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static int ToInt32(this object s)
{
return Convert.ToInt32(s);
}
#endregion
#region bool
/// <summary>
/// 判断是否 包含 字符串 true 包含 false 不包含
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IndexOfStr(this string[] s, string sStr)
{
foreach (var item in s)
{
if (item.IndexOf(sStr) > -1)
{
return true;
}
}
return false;
}
/// <summary>
/// 判断是否 存在 字符串 true 存在 false 不存在
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IndexToStr(this string[] s, string sStr)
{
foreach (var item in s)
{
if (item == sStr)
{
return true;
}
}
return false;
}
/// <summary>
/// 判断 为空
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IsNull(this string s)
{
return string.IsNullOrWhiteSpace(s);
}
/// <summary>
/// 判断 为空
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IsNullOrWhiteSpace(this string s)
{
return string.IsNullOrWhiteSpace(s);
}
/// <summary>
/// 判断 不为空
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IsNotNull(this string s)
{
return !string.IsNullOrWhiteSpace(s);
}
/// <summary>
/// 判断 不为空
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IsNotNullOrNotWhiteSpace(this string s)
{
return !string.IsNullOrWhiteSpace(s);
}
/// <summary>
/// 判断是否 包含 字符串 true 包含 false 不包含
/// </summary>
/// <param name="s"></param>
/// <param name="sStr"></param>
/// <returns></returns>
public static bool IndexOfStr(this string s, string sStr)
{
if (s.IndexOf(sStr) > -1)
{
return true;
}
return false;
}
/// <summary>
/// 判断是否 包含 字符串 true 包含 false 不包含 或关系
/// </summary>
/// <param name="s"></param>
/// <param name="sStr"></param>
/// <returns></returns>
public static bool IndexOfStrOr(this string s, params string[] sArrStr)
{
for (int i = 0; i < sArrStr.Length; i++)
{
if (s.IndexOf(sArrStr[i]) > -1)
{
return true;
}
}
return false;
}
/// <summary>
/// 判断是否 包含 字符串 true 包含 false 不包含 和关系
/// </summary>
/// <param name="s"></param>
/// <param name="sStr"></param>
/// <returns></returns>
public static bool IndexOfStrAnd(this string s, params string[] sArrStr)
{
for (int i = 0; i < sArrStr.Length; i++)
{
if (s.IndexOf(sArrStr[i]) == -1)
{
return false;
}
}
return true;
}
/// <summary>
/// 判断是否 包含 字符串 true 包含 false 不包含 和关系
/// </summary>
/// <param name="s"></param>
/// <param name="sArrStr"></param>
/// <returns></returns>
public static bool And(this string s, params string[] sArrStr)
{
for (int i = 0; i < sArrStr.Length; i++)
{
if (!s.Contains(sArrStr[i]))
{
return false;
}
}
return true;
}
/// <summary>
/// 判断是否 包含 字符串 true 包含 false 不包含 和关系
/// </summary>
/// <param name="s"></param>
/// <param name="sArrStr"></param>
/// <returns></returns>
public static bool Or(this string s, params string[] sArrStr)
{
for (int i = 0; i < sArrStr.Length; i++)
{
if (s.Contains(sArrStr[i]))
{
return true;
}
}
return false;
}
#endregion
#region DateTime
/// <summary>
/// 字符串转换为 时间
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static DateTime ToDateTime(this object s)
{
return Convert.ToDateTime(s);
}
/// <summary>
/// 字符串转换为 时间
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static DateTime ToDateTime(this string s)
{
return Convert.ToDateTime(s);
}
/// <summary>
/// 时间戳转为C#格式时间
/// </summary>
/// <param name="timeStamp"></param>
/// <returns></returns>
public static DateTime ToDateTimeByStamp(this string timeStamp)
{
DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long lTime;
if (timeStamp.Length.Equals(10))//判断是10位
{
lTime = long.Parse(timeStamp + "0000000");
}
else
{
lTime = long.Parse(timeStamp + "0000");//13位
}
TimeSpan toNow = new TimeSpan(lTime);
DateTime daTime = dtStart.Add(toNow);
return daTime;
}
#endregion
#region double
/// <summary>
/// 带小数点数字匹配
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static double MatchingNumber(this string s)
{
string s1 = Regex.Replace(s, @"[^\d.\d]", "");
if (s1.IsNotNull())
{
return s1.ToDouble();
}
return 0;
}
/// <summary>
/// 保留小数点 不四舍五入
/// </summary>
/// <param name="d"></param>
/// <param name="decimals"></param>
/// <returns></returns>
public static double NotRound(this double d, int decimals)
{
if (decimals == 0)
{
return (int)d;
}
string sStr = "1";
for (int i = 0; i < decimals; i++)
{
sStr += "0";
}
decimals = Convert.ToInt32(sStr);
return Math.Floor(d * decimals) / decimals;
}
/// <summary>
/// 实现数据的四舍五入法
/// </summary>
/// <param name="v">要进行处理的数据</param>
/// <param name="x">保留的小数位数</param>
/// <returns>四舍五入后的结果</returns>
public static double Round(this double v, int x)
{
bool isNegative = false;
//如果是负数
if (v < 0)
{
isNegative = true;
v = -v;
}
int IValue = 1;
for (int i = 1; i <= x; i++)
{
IValue = IValue * 10;
}
double Int = Math.Round(v * IValue + 0.5, 0);
v = Int / IValue;
if (isNegative)
{
v = -v;
}
return v;
}
/// <summary>
/// 获取百分比 iCount=总数
/// </summary>
/// <param name="d"></param>
/// <param name="iCount"></param>
/// <returns></returns>
public static double getProportion(this double d, double iCount)
{
try
{
double dc = Math.Round((d / iCount) * 100, 2);
if (double.IsNaN(dc))
{
return 0;
}
return dc;
}
catch (Exception)
{
}
return 0;
}
/// <summary>
/// 获取百分比 iCount=总数
/// </summary>
/// <param name="d"></param>
/// <param name="iCount"></param>
/// <returns></returns>
public static double getProportion(this int d, double iCount)
{
try
{
double dc = Math.Round((d / iCount) * 100, 2);
if (double.IsNaN(dc))
{
return 0;
}
return dc;
}
catch (Exception)
{
}
return 0;
}
/// <summary>
/// 转换为 double
/// </summary>
/// <param name="d"></param>
/// <param name="decimals"></param>
/// <returns></returns>
public static double ToDouble(this object d)
{
return Convert.ToDouble(d);
}
#endregion
#region string
/// <summary>
/// url 编码
/// </summary>
/// <param name="s"></param>
/// <param name="e"></param>
/// <returns></returns>
public static string ToUrlEncode(this object s, Encoding e = null)
{
return ToUrlEncode(s.ToString(), e);
}
/// <summary>
/// url 编码
/// </summary>
/// <param name="s"></param>
/// <param name="e"></param>
/// <returns></returns>
public static string ToUrlEncode(this string s, Encoding e = null)
{
if (e == null) e = Encoding.UTF8;
return System.Web.HttpUtility.UrlEncode(s, e);
}
/// <summary>
/// 数字 千位分隔符
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ToThousandsSeparator(this double s)
{
return s.ToString("N0");
}
/// <summary>
/// 数字 千位分隔符
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ToThousandsSeparator(this int s)
{
return s.ToString("N0");
}
/// <summary>
/// 将c# DateTime时间格式转换为Unix时间戳格式 13位
/// </summary>
/// <param name="time">时间</param>
/// <returns>long</returns>
public static string ToTimeStamp13(this System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
long t = (time.Ticks - startTime.Ticks) / 10000; //除10000调整为13位
return t.ToString();
}
/// <summary>
/// 将c# DateTime时间格式转换为Unix时间戳格式 10位
/// </summary>
/// <param name="time">时间</param>
/// <returns>long</returns>
public static string ToTimeStamp10(this System.DateTime time)
{
DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
int timeStamp = Convert.ToInt32((time - dateStart).TotalSeconds);
return timeStamp.ToString(); ;
}
/// <summary>
/// 截取字符串 过滤空格
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string[] SplitRemoveEmptyEntries(this string s, params string[] arr)
{
try
{
if (string.IsNullOrWhiteSpace(s))
{
return new string[] { };
}
return s.Split(arr, StringSplitOptions.RemoveEmptyEntries);
}
catch (Exception)
{
return new string[] { };
}
}
/// <summary>
/// 过滤sql 特殊符号
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ReplaceSQLChar(this string str)
{
if (str == String.Empty)
return String.Empty;
str = str.Replace("'", "");
str = str.Replace("<", "");
str = str.Replace(">", "");
str = str.Replace("@", "");
str = str.Replace("=", "");
str = str.Replace("+", "");
str = str.Replace("*", "");
str = str.Replace("&", "");
str = str.Replace("#", "");
str = str.Replace("%", "");
str = str.Replace("$", "");
//删除与数据库相关的词
str = Regex.Replace(str, "select", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "insert", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "delete from", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "count", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "drop table", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "truncate", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "asc", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "mid", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "char", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "xp_cmdshell", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "exec master", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "net localgroup administrators", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "and", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "net user", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "or", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "net", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "-", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "delete", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "drop", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "script", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "update", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "and", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "chr", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "master", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "truncate", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "declare", "", RegexOptions.IgnoreCase);
str = Regex.Replace(str, "mid", "", RegexOptions.IgnoreCase);
return str;
}
/// <summary>
/// 将DateTime 格式转换为 yyyy-MM-dd HH:mm:ss
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToDateStr(this DateTime d)
{
return d.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 将DateTime 格式转换为 yyyy-MM-dd HH:mm:ss
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToDateStr(this DateTime? d)
{
return Convert.ToDateTime(d).ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// Md5 加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string GetMD5Hash(this string str)
{
using (MD5 mi = MD5.Create())
{
byte[] buffer = Encoding.Default.GetBytes(str);
//开始加密
byte[] newBuffer = mi.ComputeHash(buffer);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < newBuffer.Length; i++)
{
sb.Append(newBuffer[i].ToString("x2"));
}
return sb.ToString();
}
}
#endregion
#region T
/// <summary>
/// 对象拷贝
/// </summary>
/// <param name="obj">被复制对象</param>
/// <returns>新对象</returns>
public static T CopyOjbect<T>(T obj)
{
Object targetDeepCopyObj = null;
if ((T)obj == null)
{
return (T)targetDeepCopyObj;
}
Type targetType = obj.GetType();
//值类型
if (targetType.IsValueType == true)
{
targetDeepCopyObj = obj;
}
//引用类型
else
{
targetDeepCopyObj = System.Activator.CreateInstance(targetType); //创建引用对象
System.Reflection.MemberInfo[] memberCollection = obj.GetType().GetMembers();
foreach (System.Reflection.MemberInfo member in memberCollection)
{
//拷贝字段
if (member.MemberType == System.Reflection.MemberTypes.Field)
{
System.Reflection.FieldInfo field = (System.Reflection.FieldInfo)member;
Object fieldValue = field.GetValue(obj);
if (fieldValue is ICloneable)
{
field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
}
else
{
field.SetValue(targetDeepCopyObj, CopyOjbect(fieldValue));
}
}//拷贝属性
else if (member.MemberType == System.Reflection.MemberTypes.Property)
{
System.Reflection.PropertyInfo myProperty = (System.Reflection.PropertyInfo)member;
MethodInfo info = myProperty.GetSetMethod(false);
if (info != null)
{
try
{
object propertyValue = myProperty.GetValue(obj, null);
if (propertyValue is ICloneable)
{
myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
}
else
{
myProperty.SetValue(targetDeepCopyObj, CopyOjbect(propertyValue), null);
}
}
catch (System.Exception ex)
{
}
}
}
}
}
return (T)targetDeepCopyObj;
}
#endregion
}
}

View File

@@ -0,0 +1,226 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace TelegramService.Help
{
public class HtmlTag
{
private String m_Name;
private String m_BeginTag;
private String m_InnerHTML;
private Hashtable m_Attributes = new Hashtable();
static Regex attrReg = new Regex(@"([a-zA-Z1-9_-]+)\s*=\s*(\x27|\x22)([^\x27\x22]*)(\x27|\x22)", RegexOptions.IgnoreCase);
private HtmlTag(string name, string beginTag, string innerHTML)
{
m_Name = name;
m_BeginTag = beginTag;
m_InnerHTML = innerHTML;
MatchCollection matchs = attrReg.Matches(beginTag);
foreach (Match match in matchs)
{
m_Attributes[match.Groups[1].Value.ToUpper()] = match.Groups[3].Value;
}
}
public string GetBeginTag()
{
return m_BeginTag;
}
public List<HtmlTag> FindTag(String name)
{
return FindTag(m_InnerHTML, name, String.Format(@"<{0}(\s[^<>]*|)>", name));
}
public List<HtmlTag> FindImgTag()
{
return FindTag(m_InnerHTML, "img", @"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>");
}
public List<HtmlTag> FindTag(String name, String format)
{
return FindTag(m_InnerHTML, name, format);
}
public List<HtmlTag> FindTagByAttr(String tagName, String attrName, String attrValue)
{
return FindTagByAttr(m_InnerHTML, tagName, attrName, attrValue);
}
public String TagName
{
get { return m_Name; }
}
public String InnerHTML
{
get { return m_InnerHTML; }
}
public String InnerText
{
get { return checkStr(m_InnerHTML); }
}
public String GetAttribute(string name)
{
return m_Attributes[name.ToUpper()] as String;
}
public String FindDate
{
get
{
Match m = Regex.Match(InnerText, @"(?<date>((1[6-9]|[2-3]\d)\d{2})-(\d{1,2})-(\d{1,2}))");
if (m.Groups.Count > 0)
{
return m.Groups["date"].Value;
}
else
{
return null;
}
}
}
public static string checkStr2(string html)
{
html = html.Replace("<br>", "$br$");
html = html.Replace("<br/>", "$br/$");
System.Text.RegularExpressions.Regex regex1 = new System.Text.RegularExpressions.Regex(@"<script[\s\S]+</script *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@" href *= *[\s\S]*script *:", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex3 = new System.Text.RegularExpressions.Regex(@" no[\s\S]*=", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex4 = new System.Text.RegularExpressions.Regex(@"<iframe[\s\S]+</iframe *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex5 = new System.Text.RegularExpressions.Regex(@"<frameset[\s\S]+</frameset *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex6 = new System.Text.RegularExpressions.Regex(@"\<img[^\>]+\>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex7 = new System.Text.RegularExpressions.Regex(@"</p>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex8 = new System.Text.RegularExpressions.Regex(@"<p>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex9 = new System.Text.RegularExpressions.Regex(@"<[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
html = regex1.Replace(html, ""); //过滤<script></script>标记
html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性
html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件
html = regex4.Replace(html, ""); //过滤iframe
html = regex5.Replace(html, ""); //过滤frameset
html = regex6.Replace(html, ""); //过滤frameset
// html = regex7.Replace(html, ""); //过滤frameset
// html = regex8.Replace(html, ""); //过滤frameset
html = regex9.Replace(html, "");
html = html.Replace(" ", "");
html = html.Replace("</strong>", "");
html = html.Replace("<strong>", "");
html = html.Replace("$br$", "<br>");
html = html.Replace("$br/$", "<br/>");
return html;
}
public static string checkStr(string html)
{
if (string.IsNullOrEmpty(html))
{
return html;
}
System.Text.RegularExpressions.Regex regex1 = new System.Text.RegularExpressions.Regex(@"<script[\s\S]+</script *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@" href *= *[\s\S]*script *:", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex3 = new System.Text.RegularExpressions.Regex(@" no[\s\S]*=", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex4 = new System.Text.RegularExpressions.Regex(@"<iframe[\s\S]+</iframe *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex5 = new System.Text.RegularExpressions.Regex(@"<frameset[\s\S]+</frameset *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex6 = new System.Text.RegularExpressions.Regex(@"\<img[^\>]+\>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex7 = new System.Text.RegularExpressions.Regex(@"</p>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex8 = new System.Text.RegularExpressions.Regex(@"<p>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex9 = new System.Text.RegularExpressions.Regex(@"<[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
html = regex1.Replace(html, ""); //过滤<script></script>标记
html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性
html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件
html = regex4.Replace(html, ""); //过滤iframe
html = regex5.Replace(html, ""); //过滤frameset
html = regex6.Replace(html, ""); //过滤frameset
html = regex7.Replace(html, ""); //过滤frameset
html = regex8.Replace(html, ""); //过滤frameset
html = regex9.Replace(html, "");
html = html.Replace(" ", "");
html = html.Replace("</strong>", "");
html = html.Replace("<strong>", "");
html = html.Replace("&nbsp;", " ");
return html;
}
public static string HtmlToText(string str)
{
string m_outstr = str;
m_outstr = new Regex(@"(?m)<script[^>]*>(\w|\W)*?</script[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
m_outstr = new Regex(@"(?m)<style[^>]*>(\w|\W)*?</style[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
m_outstr = new Regex(@"(?m)<select[^>]*>(\w|\W)*?</select[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
//m_outstr = new Regex(@"(?m)<a[^>]*>(\w|\W)*?</a[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
Regex objReg = new System.Text.RegularExpressions.Regex("(<[^>]+?>)|&nbsp;", RegexOptions.Multiline | RegexOptions.IgnoreCase);
m_outstr = objReg.Replace(m_outstr, "");
Regex objReg2 = new System.Text.RegularExpressions.Regex("(\\s)+", RegexOptions.Multiline | RegexOptions.IgnoreCase);
m_outstr = objReg2.Replace(m_outstr, " ");
return m_outstr;
}
/// <summary>
/// 在文本html的文本查找标志名为tagName,并且属性attrName的值为attrValue的所有标志
/// 例如FindTagByAttr(html, "div", "class", "demo")
/// 返回所有class为demo的div标志
/// </summary>
public static List<HtmlTag> FindTagByAttr(String html, String tagName, String attrName, String attrValue)
{
String format = String.Format(@"<{0}\s[^<>]*{1}\s*=\s*(\x27|\x22){2}(\x27|\x22)[^<>]*>", tagName, attrName, attrValue);
return FindTag(html, tagName, format);
}
public static List<HtmlTag> FindTag(String html, String name, String format)
{
Regex reg = new Regex(format, RegexOptions.IgnoreCase);
Regex tagReg = new Regex(String.Format(@"<(\/|)({0})(\s[^<>]*|)>", name), RegexOptions.IgnoreCase);
List<HtmlTag> tags = new List<HtmlTag>();
int start = 0;
while (true)
{
Match match = reg.Match(html, start);
if (match.Success)
{
start = match.Index + match.Length;
Match tagMatch = null;
int beginTagCount = 1;
while (true)
{
tagMatch = tagReg.Match(html, start);
if (!tagMatch.Success)
{
tagMatch = null;
break;
}
start = tagMatch.Index + tagMatch.Length;
if (tagMatch.Groups[1].Value == "/") beginTagCount--;
else beginTagCount++;
if (beginTagCount == 0) break;
}
if (tagMatch != null)
{
HtmlTag tag = new HtmlTag(name, match.Value, html.Substring(match.Index + match.Length, tagMatch.Index - match.Index - match.Length));
tags.Add(tag);
}
else
{
break;
}
}
else
{
break;
}
}
return tags;
}
}
}

View File

@@ -0,0 +1,244 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
public static class HttpHelper
{
private static readonly HttpClient DefaultClient;
private static readonly HttpResult HttpResult;
static HttpHelper()
{
var handler = CreateBestHandler();
TrySetPooledConnectionLifetime(handler, TimeSpan.FromMinutes(2));
DefaultClient = new HttpClient(handler, disposeHandler: false)
{
Timeout = Timeout.InfiniteTimeSpan
};
HttpResult = new HttpResult();
}
private static HttpClient CreateProxyClient(string proxy)
{
var (address, isHttpsProxy) = ParseProxyScheme(proxy);
var handler = CreateBestHandler();
TrySetPooledConnectionLifetime(handler, TimeSpan.FromMinutes(2));
handler.Proxy = new WebProxy(address)
{
// 关键两行!解决 95% 的 HTTPS 代理报错
UseDefaultCredentials = false,
BypassProxyOnLocal = false
};
// 如果是 https:// 开头的代理(极少数 socks5 也可能用这个格式),强制走 CONNECT
if (isHttpsProxy)
{
// .NET 6+ 推荐方式(安全又快)
handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
}
handler.UseProxy = true;
return new HttpClient(handler, disposeHandler: true)
{
Timeout = Timeout.InfiniteTimeSpan
};
}
private static HttpClientHandler CreateBestHandler()
{
return new HttpClientHandler
{
UseCookies = false,
AutomaticDecompression = DecompressionMethods.All,
AllowAutoRedirect = true,
// 下面这行是终极救命稻草(解决代理返回 407 需要认证的坑)
Proxy = null, // 先留空,后面再设
UseProxy = false,
// 防止某些代理服务器返回奇怪的证书
ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => true
};
}
// 智能解析代理地址,支持以下所有格式:
// http://1.2.3.4:8888
// https://1.2.3.4:8888
// 1.2.3.4:8888
// user:pass@1.2.3.4:8888
private static (Uri address, bool isHttpsProxy) ParseProxyScheme(string proxy)
{
proxy = proxy.Trim();
var uri = proxy.Contains("://")
? new Uri(proxy)
: new Uri("http://" + proxy);
// 带用户名密码的代理
if (!string.IsNullOrEmpty(uri.UserInfo))
{
var parts = uri.UserInfo.Split(new[] { ':' }, 2);
var credential = new NetworkCredential(parts[0], parts.Length > 1 ? parts[1] : "");
// 注意:这里不能直接设 DefaultProxyCredentials会全局污染
// 我们改在下面用更安全的方式处理
}
bool isHttps = uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase);
var address = new Uri($"{(isHttps ? "http" : uri.Scheme)}://{uri.Host}:{uri.Port}");
return (address, isHttps);
}
public static async Task<HttpResult> SendAsync(
string url,
HttpMethod method,
Dictionary<string, string>? headers = null,
Dictionary<string, string>? cookies = null,
HttpContent? content = null,
int timeoutSeconds = 30,
string? proxy = null,
CancellationToken cancellationToken = default)
{
var client = string.IsNullOrWhiteSpace(proxy)
? DefaultClient
: CreateProxyClient(proxy);
var shouldDispose = !string.IsNullOrWhiteSpace(proxy);
// 处理带账号密码的代理(终极写法)
if (!string.IsNullOrWhiteSpace(proxy) && proxy.Contains("@"))
{
var uri = new Uri(proxy.Contains("://") ? proxy : "http://" + proxy);
if (!string.IsNullOrEmpty(uri.UserInfo))
{
var parts = uri.UserInfo.Split(new[] { ':' }, 2);
var credential = new NetworkCredential(parts[0], parts.Length > 1 ? parts[1] : "");
// 关键:每个 HttpClientHandler 单独设置凭据,不污染全局
if (client.DefaultRequestHeaders.ProxyAuthorization == null)
{
var handler = (HttpClientHandler)client.GetType()
.GetProperty("Handler", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
?.GetValue(client)!;
if (handler?.Proxy != null)
{
handler.Proxy.Credentials = credential;
}
}
}
}
try
{
using var request = new HttpRequestMessage(method, url);
if (content != null) request.Content = content;
if (headers != null)
{
foreach (var h in headers)
{
if (IsContentHeader(h.Key))
request.Content?.Headers.TryAddWithoutValidation(h.Key, h.Value);
else
request.Headers.TryAddWithoutValidation(h.Key, h.Value);
}
}
if (cookies is { Count: > 0 })
{
request.Headers.TryAddWithoutValidation("Cookie", string.Join("; ", cookies.Select(c => $"{c.Key}={c.Value}")));
}
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds));
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
if (!response.IsSuccessStatusCode)
{
var err = await response.Content.ReadAsStringAsync(cts.Token);
HttpResult.StatusCode = (int)response.StatusCode;
HttpResult.Html = $"请求失败 {(int)response.StatusCode} {response.ReasonPhrase}\n{err}".Trim();
return HttpResult;
}
var bytes = await response.Content.ReadAsByteArrayAsync(cts.Token);
var charset = response.Content.Headers.ContentType?.CharSet;
if (!string.IsNullOrEmpty(charset) && !charset.Equals("utf-8", StringComparison.OrdinalIgnoreCase))
{
try {
HttpResult.StatusCode = (int)response.StatusCode;
HttpResult.Html = Encoding.GetEncoding(charset).GetString(bytes);
return HttpResult;
} catch { }
}
HttpResult.StatusCode = (int)response.StatusCode;
HttpResult.Html = Encoding.UTF8.GetString(bytes);
return HttpResult;
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
HttpResult.StatusCode = 500;
HttpResult.Html = $"请求超时({timeoutSeconds}s";
return HttpResult;
}
finally
{
if (shouldDispose) client.Dispose();
}
}
// 你的三个快捷方法完全不变
public static Task<HttpResult> GetAsync(string url, Dictionary<string, string>? headers = null,
Dictionary<string, string>? cookies = null, int timeoutSeconds = 30, string? proxy = null) =>
SendAsync(url, HttpMethod.Get, headers, cookies, null, timeoutSeconds, proxy);
public static Task<HttpResult> PostFormAsync(string url, Dictionary<string, string> form,
Dictionary<string, string>? headers = null, Dictionary<string, string>? cookies = null,
int timeoutSeconds = 30, string? proxy = null)
{
var content = new FormUrlEncodedContent(form);
return SendAsync(url, HttpMethod.Post, headers, cookies, content, timeoutSeconds, proxy);
}
public static Task<HttpResult> PostJsonAsync(string url, string json,
Dictionary<string, string>? headers = null, Dictionary<string, string>? cookies = null,
int timeoutSeconds = 30, string? proxy = null)
{
var content = new StringContent(json, Encoding.UTF8, "application/json");
headers ??= new();
headers["Content-Type"] = "application/json; charset=utf-8";
return SendAsync(url, HttpMethod.Post, headers, cookies, content, timeoutSeconds, proxy);
}
private static bool IsContentHeader(string name) =>
name.StartsWith("Content-", StringComparison.OrdinalIgnoreCase);
private static void TrySetPooledConnectionLifetime(HttpClientHandler handler, TimeSpan lifetime)
{
try
{
var prop = handler.GetType().GetProperty("PooledConnectionLifetime");
prop?.SetValue(handler, lifetime);
}
catch { }
}
}
public class HttpResult
{
public int StatusCode { get; set; }
public string Html { get; set; }
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

6
TelegramService.slnx Normal file
View File

@@ -0,0 +1,6 @@
<Solution>
<Project Path="TelegramService.Bl/TelegramService.Bl.csproj" />
<Project Path="TelegramService.Entity/TelegramService.Entity.csproj" />
<Project Path="TelegramService.Help/TelegramService.Help.csproj" />
<Project Path="TelegramService/TelegramService.csproj" />
</Solution>

View File

@@ -0,0 +1,16 @@
using System.Runtime.InteropServices;
namespace TelegramService
{
public class Program
{
public static void Main(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
var host = builder.Build();
host.Run();
}
}
}

View File

@@ -0,0 +1,12 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"TelegramService": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-TelegramService-a097e3f5-17e6-4c41-b5ba-b8e0e160be6e</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TelegramService.Bl\TelegramService.Bl.csproj" />
<ProjectReference Include="..\TelegramService.Entity\TelegramService.Entity.csproj" />
<ProjectReference Include="..\TelegramService.Help\TelegramService.Help.csproj" />
</ItemGroup>
</Project>

175
TelegramService/Worker.cs Normal file
View File

@@ -0,0 +1,175 @@
using Newtonsoft.Json;
using System.Net;
using System.Net.Security;
using System.Text;
using TelegramService.Entity;
using TelegramService.Help;
using TelegramServiceV6.Bl;
namespace TelegramService
{
public class Worker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "log"))
{
Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "log");
}
// <20><><EFBFBD><EFBFBD> 192.168.1.80 <20><><EFBFBD><EFBFBD> SSL <20><>֤
ServicePointManager.ServerCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
{
// sender <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HttpWebRequest
if (sender is HttpWebRequest req)
{
if (req.Address.Host == "111.230.99.204")
return true; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>֤<EFBFBD>߼<EFBFBD>
return sslPolicyErrors == SslPolicyErrors.None;
};
EntrustHelper.STCB = Controller;
Appsettings.Conf = JsonConvert.DeserializeObject<AppsettingsRoot>(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "/appsettings.json"));
await Task.Run(() =>
{
InitTimer(10);
InitTimerTieBa(10);
InitFund(10);
});
}
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
///<2F><><EFBFBD>ر<EFBFBD><D8B1><EFBFBD>
/// </summary>
/// <param name="interval"></param>
private void InitFund(double interval)
{
try
{
System.Timers.Timer timer = new System.Timers.Timer(interval);
//<2F><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>һ<EFBFBD>Σ<EFBFBD>false<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱִ<D6B1><D6B4>(true)
timer.AutoReset = false;
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>ִ<EFBFBD><D6B4>System.Timers.Timer.Elapsed<65>¼<EFBFBD>
timer.Enabled = true;
//<2F><><EFBFBD><EFBFBD>Elapsed<65>¼<EFBFBD>
timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) =>
{
FundBl.SendWeixinFund();
});
}
catch (Exception ex)
{
Controller("show", ex.StackTrace);
}
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>԰
/// <summary>
///<2F><><EFBFBD>ر<EFBFBD><D8B1><EFBFBD>
/// </summary>
/// <param name="interval"></param>
private void InitTimer(double interval)
{
try
{
System.Timers.Timer timer = new System.Timers.Timer(interval);
//<2F><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>һ<EFBFBD>Σ<EFBFBD>false<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱִ<D6B1><D6B4>(true)
timer.AutoReset = false;
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>ִ<EFBFBD><D6B4>System.Timers.Timer.Elapsed<65>¼<EFBFBD>
timer.Enabled = true;
//<2F><><EFBFBD><EFBFBD>Elapsed<65>¼<EFBFBD>
timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) =>
{
CnblogsBl cnblogsBl = new CnblogsBl();
cnblogsBl.GetCnblogsHtml();
});
}
catch (Exception ex)
{
Controller("show", ex.StackTrace);
}
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
///<2F><>԰
/// </summary>
/// <param name="interval"></param>
private void InitTimerTieBa(double interval)
{
try
{
System.Timers.Timer timer = new System.Timers.Timer(interval);
//<2F><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>һ<EFBFBD>Σ<EFBFBD>false<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱִ<D6B1><D6B4>(true)
timer.AutoReset = false;
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>ִ<EFBFBD><D6B4>System.Timers.Timer.Elapsed<65>¼<EFBFBD>
timer.Enabled = true;
//<2F><><EFBFBD><EFBFBD>Elapsed<65>¼<EFBFBD>
timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) =>
{
TieBaBl tb = new TieBaBl();
tb.GetTieBaHtml();
});
}
catch (Exception ex)
{
Controller("show", ex.StackTrace);
}
}
#endregion
#region ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
private static object _lockObj = new object();
/// <summary>
/// <20><><EFBFBD><EFBFBD> ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD>״̬
/// </summary>
/// <param name="text"></param>
delegate object SetController(string type, object errorMessage);
public object Controller(string type, object errorMessage)
{
if (type.Equals("show"))
{
try
{
lock (_lockObj)
{
File.AppendAllText(System.AppDomain.CurrentDomain.BaseDirectory + "log/Log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", "[" + DateTime.Now.ToString() + "]:" + errorMessage + "\r\n", Encoding.UTF8);
}
}
catch (Exception)
{
}
}
else if (type.Equals("InitTimer"))
{
InitTimer(Convert.ToDouble(errorMessage) * 60000);
}
else if (type.Equals("InitTimerTieBa"))
{
InitTimerTieBa(Convert.ToDouble(errorMessage) * 60000);
}
else if (type.Equals("sendWeixinFund"))
{
InitFund(Convert.ToDouble(errorMessage));
}
return null;
}
#endregion
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@@ -0,0 +1,16 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"DBConnection": ""
},
"Interval": 3,
"IntervalLiYuan": 3,
"IntervalTieBa": 3,
"Fund": [ "009271", "160213", "018043", "016452" ],
"TieBa": [ "广东联通", "广东移动" ]
}