-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTools.cs
532 lines (513 loc) · 19.7 KB
/
Tools.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace BilibiliProjects
{
public class Tools
{
public static NovelSource source;
/// <summary>
/// 初始化NovelSource,公共变量
/// </summary>
/// <param name="index">首页下拉框索引</param>
public static string InitSource(int index, bool instead = true)
{
NovelSource source1 = new NovelSource();
source1.ID = index;
switch (index)
{
case 0: //31小说网
source1.Site = "http://m.31xs.com/";
source1.SearchPage = "search.php";
source1.SearchKeyword = "keyword";
break;
case 1: //悠悠书盟
source1.Site = "https://m.uutxt.com/";
source1.SearchPage = "SearchBook.php";
source1.SearchKeyword = "submit=&keyword";
break;
case 2: //棉花糖小说
source1.Site = "http://m.mhtxs.la/";
source1.SearchPage = "search.php";
source1.SearchKeyword = "submit=&searchkey";
break;
case 3: //天域
source1.Site = "http://www.tycqxs.com/";
source1.SearchPage = "search.php";
source1.SearchKeyword = "searchkey";
break;
case 4: //56书库
source1.Site = "http://www.liuxs.la/";
source1.SearchPage = "search.php";
source1.SearchKeyword = "searchkey";
break;
}
if (instead)
source = source1;
return source1.Site;
}
/// <summary>
/// 保存图片
/// </summary>
/// <param name="bmp"></param>
public static void SaveImage(Bitmap bmp)
{
if (bmp == null)
return;
SaveFileDialog save = new SaveFileDialog(); //保存文件对话框
save.InitialDirectory = Directory.GetCurrentDirectory(); //初始目录
save.Filter = "BMP图片|*.bmp";
if (save.ShowDialog() == DialogResult.OK)
{
bmp.Save(save.FileName, ImageFormat.Bmp); //保存
MessageBox.Show("保存完成", "提示");
}
}
/// <summary>
/// 获取所有字体
/// </summary>
/// <returns></returns>
public static List<string> GetFonts()
{
//获取字体
InstalledFontCollection installedFontCollection = new InstalledFontCollection();
FontFamily[] fontFamilies = installedFontCollection.Families;
List<string> fonts = new List<string>();
//转为string数组
foreach (FontFamily family in fontFamilies)
{
if (family.Name.StartsWith("Adobe")|| family.Name.StartsWith("Kozuka")|| family.Name.StartsWith("Bahn")|| family.Name.StartsWith("Franklin"))
continue;
fonts.Add(family.Name);
}
fonts.Reverse();
return fonts;
}
//初始化时创建表
public static void CreateTable()
{
//阅读记录
string sql = "create table bookshelf(novel text,chapter text,webIndex text,site text,date text);";
//章节列表
sql += "create table chapters(novel text,chapter text,webIndex text,site text,filename text,compressed real);";
//关键字黑名单,如果章节中出现这些词,将会替换成空。词语,类型(词语/正则表达式),添加时间
sql += "create table blackWords(words text,insteadWords text,type text,date text);";
//屏蔽关键词的次数记录,以及阅读时间记录
//列的含义:日期,替换词语次数,替换正则表达式次数,实验性功能1,实验性功能2,阅读时长
sql += "create table record(date text,wordCount int,regexCount int,whyReason int,delPS int,readSeconds int);";
//用户配置
sql += "create table settings(key text, value text);";
MySqlite.ExecSql(sql);
}
/// <summary>
/// 取文本中间内容
/// </summary>
/// <param name="str">原文本</param>
/// <param name="leftstr">左边文本</param>
/// <param name="rightstr">右边文本</param>
/// <returns>返回中间文本内容</returns>
public static string GetBetweenText(string str, string leftstr, string rightstr)
{
int i = str.IndexOf(leftstr);
if (i == -1)
return str;
i += leftstr.Length;
int i2 = str.IndexOf(rightstr, i);
string temp;
if (i2 == -1) //取后面所有
temp = str.Substring(i);
else
temp = str.Substring(i, i2 - i);
return temp;
}
/// <summary>
/// 批量取文本中间内容
/// </summary>
/// <param name="str">原文本</param>
/// <param name="leftstr">左边文本</param>
/// <param name="rightstr">右边文本</param>
/// <returns>返回中间文本内容</returns>
public static List<string> GetAllBetweenText(string str, string leftstr, string rightstr, bool deleteHtmlTag = false)
{
List<string> result = new List<string>();
int left = str.IndexOf(leftstr);
if (left == -1) return result;
int right = str.IndexOf(rightstr);
if (right == -1) return result;
while (str.IndexOf(leftstr) > -1)
{
int i = str.IndexOf(leftstr) + leftstr.Length;
int i2 = str.IndexOf(rightstr, i);
if (i2 == -1) break;
string tmp = str.Substring(i, i2 - i).Trim();
if(deleteHtmlTag)
{
tmp = RemoveHtmlTag(tmp);
}
result.Add(tmp);
str = str.Substring(i2 + rightstr.Length);
}
return result;
}
//定义委托方法
public delegate void HTMLGet(WebResponseInfo responseInfo, int requestCode);
//定义事件,触发该事件时,会执行上面的委托方法
public event HTMLGet HTMLGetCompleted;
/// <summary>
/// 获取网页内容,请调用该方法
/// </summary>
/// <param name="url">url</param>
/// <param name="requestCode">请求代码</param>
public void GetHtmlByThread(string url,int requestCode)
{
Thread t = new Thread(new ThreadStart(delegate
{
GetHtml(url, requestCode);
}));
t.IsBackground = true;
t.Start();
}
/// <summary>
/// 获取网页内容(文本形式)
/// </summary>
/// <param name="url">url</param>
/// <returns>网页Stream</returns>
void GetHtml(string url,int requestCode)
{
string responseText;
HttpWebRequest myRequest;
if (!url.StartsWith("http")) url = "http://" + url;
//创建 HttpWebRequest 对象
myRequest = (HttpWebRequest)WebRequest.Create(url);
WebResponseInfo webResponseInfo = new WebResponseInfo();
webResponseInfo.URL = url;
try
{
//取得response
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
webResponseInfo.ResponseCode = myResponse.StatusCode;
webResponseInfo.ResponseHeader = myResponse.Headers;
//取网页流
Stream stream = myResponse.GetResponseStream();
//返回数据的类型
string rType = myResponse.Headers["Content-Type"];
if (rType.Contains("text")) //返回的是文本
{
string encode = myResponse.ContentEncoding.ToLower();//返回文本格式
if (encode.Contains("gzip")) //解压缩gzip
{
using (GZipStream gstream = new GZipStream(stream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(gstream))
{
responseText = reader.ReadToEnd();
}
}
}
else if (encode.Contains("deflate")) //解压缩deflate,该压缩方式已过时
{
using (DeflateStream dstream = new DeflateStream(stream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(dstream, Encoding.UTF8))
{
responseText = reader.ReadToEnd();
}
}
}
else
{
//string encoding = myResponse.CharacterSet; //返回内容的字符集编码
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
responseText = reader.ReadToEnd();
}
}
webResponseInfo.DataType = "text";
webResponseInfo.ResponseText = responseText;
}
else if(rType.Contains("image")) //如果返回的是图像
{
Image img = Image.FromStream(stream);
webResponseInfo.ResponseImage = img;
webResponseInfo.DataType = "image";
//图形格式
string type = rType.Substring(6);
switch(type.ToLower())
{
case "png":
webResponseInfo.ResponseImageType = ImageFormat.Png;
break;
case "jpg":
case "jpeg":
webResponseInfo.ResponseImageType = ImageFormat.Jpeg;
break;
case "gif":
webResponseInfo.ResponseImageType = ImageFormat.Gif;
break;
case "bmp":
webResponseInfo.ResponseImageType = ImageFormat.Bmp;
break;
case "x-icon":
webResponseInfo.ResponseImageType = ImageFormat.Icon;
break;
}
}
HTMLGetCompleted(webResponseInfo, requestCode);
}
catch (Exception ex)
{
webResponseInfo.ErrorMessage = ex.ToString();
HTMLGetCompleted(webResponseInfo, requestCode);
}
}
/// <summary>
/// 将Stream转为String
/// </summary>
/// <param name="stream">网页流</param>
/// <param name="encoding">编码</param>
/// <returns></returns>
public static string streamToString(Stream stream, Encoding encoding)
{
if (encoding == null)
encoding = Encoding.UTF8;
try
{
StreamReader reader = new StreamReader(stream, encoding);
return reader.ReadToEnd();
}
catch (Exception e)
{
return e.ToString(); //转换失败,返回错误信息
}
}
/// <summary>
/// 去掉html标签
/// </summary>
/// <param name="html"></param>
/// <param name="length">需要返回的固定长度,传入0返回所有</param>
/// <returns></returns>
public static string RemoveHtmlTag(string html, int length = 0)
{
string strText = Regex.Replace(html, "<[^>]+>", "");
strText = Regex.Replace(strText, "&[^;]+;", "");
if (length > 0 && strText.Length > length)
return strText.Substring(0, length);
return strText;
}
/// <summary>
/// 判断文本文件的编码
/// </summary>
/// <param name="filename">文件名</param>
/// <returns>编码</returns>
public static Encoding GetFileEncodeType(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
int.TryParse(fs.Length.ToString(), out int i);
byte[] buffer = br.ReadBytes(i);
if (IsUTF8Bytes(buffer) || (buffer[0] == 0xEF && buffer[1] == 0xBB))
{
return Encoding.UTF8;
}
else if (buffer[0] == 0xFE && buffer[1] == 0xFF)
{
return Encoding.BigEndianUnicode;
}
else if (buffer[0] == 0xFF && buffer[1] == 0xFE)
{
return Encoding.Unicode;
}
else
{
return Encoding.Default;
}
}
/// <summary>
/// 判断是否为不带 BOM 的 UTF8 格式
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private static bool IsUTF8Bytes(byte[] data)
{
int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
byte curByte; //当前分析的字节.
for (int i = 0; i < data.Length; i++)
{
curByte = data[i];
if (charByteCounter == 1)
{
if (curByte >= 0x80)
{
//判断当前
while (((curByte <<= 1) & 0x80) != 0)
{
charByteCounter++;
}
//标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
if (charByteCounter == 1 || charByteCounter > 6)
{
return false;
}
}
}
else
{
//若是UTF-8 此时第一位必须为1
if ((curByte & 0xC0) != 0x80)
{
return false;
}
charByteCounter--;
}
}
if (charByteCounter > 1)
{
return false;
}
return true;
}
}
/// <summary>
/// 网络访问的返回信息,包含协议头、重定向地址、状态码、cookie等等
/// </summary>
public class WebResponseInfo
{
public WebResponseInfo() { }
/// <summary>
/// 当前访问的链接
/// </summary>
public string URL;
/// <summary>
/// 返回数据类型 text image
/// </summary>
public string DataType;
/// <summary>
/// 状态码
/// </summary>
public HttpStatusCode ResponseCode;
/// <summary>
/// 返回协议头,包含cookie、重定向链接、数据类型等
/// </summary>
public WebHeaderCollection ResponseHeader;
/// <summary>
/// 网络访问错误时的信息
/// </summary>
public string ErrorMessage;
/// <summary>
/// 返回文本(仅DataType="text"时有效)
/// </summary>
public string ResponseText;
/// <summary>
/// 返回的图像(仅DataType="image"时有效)
/// </summary>
public Image ResponseImage;
/// <summary>
/// 返回的图像格式(仅DataType="image"时有效)
/// </summary>
public ImageFormat ResponseImageType;
}
/// <summary>
/// 小说来源
/// </summary>
public class NovelSource
{
public int ID; //网站索引,就是首页下拉框索引
public string Site; //网站域名
public string SearchPage; //搜索页面名
public string SearchKeyword; //搜索页面提交的关键词key,可以理解为postdata
}
/// <summary>
/// 小说类
/// </summary>
public class Novel
{
public Novel(string name, string author, string new1, string date)
{
this.author = Tools.RemoveHtmlTag(author);
lastDate = date;
indexUrl = Tools.GetBetweenText(name, "href=\"", "\"");
if (name.IndexOf("完本") > -1 || name.IndexOf("连载") > -1 || name.IndexOf("完结") > -1)
{
state = Tools.GetBetweenText(name, "[", "]");
int index = name.LastIndexOf("]");
if (index >= 1)
name = name.Substring(index + 1).Trim();
//去掉“完本”“连载”
this.name = Tools.RemoveHtmlTag(name);
}
else
{
state = "";
this.name = Tools.RemoveHtmlTag(name);
}
if(new1.Contains("href="))
newUrl = Tools.GetBetweenText(new1, "href=\"", "\"");
newChapter = Tools.RemoveHtmlTag(new1);
}
public string name; //书名
public string state; //状态
public string indexUrl; //章节目录链接
public string author; //作者
public string newChapter; //最新章
public string newUrl; //最新章链接
public string lastDate; //最近更新日期
}
/// <summary>
/// 章节类
/// </summary>
public class Chapter
{
public Chapter()
{}
public Chapter(string chapter, string site)
{
this.chapter = chapter;
this.site = site;
}
public Chapter(string novel, string chapter, string site)
{
this.novel = novel;
this.chapter = chapter;
this.site = site;
}
public string novel; //小说名
public string chapter; //章节名
public string site; //地址,不包含域名
public int web; //网站索引,这个是首页下拉框的索引
public string lastDate; //最后阅读时间
public string filename; //保存到本地的文件名
public bool compressed; //保存时是否压缩
}
public class Record
{
public Record() { }
public string date;
public int wordCount;
public int regexCount;
//将“为什么……的原因”改为“……的原因”
public int whyReason;
//删除作者写的PS之类的话
public int delPS;
public int seconds;
public string ReadTime
{
get
{
int hour = seconds / 3600;
int minute = (seconds - hour * 3600) / 60;
int second = seconds % 60;
return hour + "时 " + minute + "分 " + second + "秒";
}
}
}
}