1 Star 7 Fork 2

Sunday / GitHubWikiTool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Form1.cs 15.26 KB
一键复制 编辑 原始数据 按行查看 历史
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.Web;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Dictionary<string, string> cssDictionary;
const string xpathStr = "//a[contains(@href,'/wiki/')]";//获取右侧导航a标签(只包含路径/wiki/)
const string wikiDefaultPage = "1首页wiki.html";
private const string jinduFormat = "进度 {0}/{1}";
//https://www.cnblogs.com/mingjiatang/p/5079632.html winform ui异步
private delegate void UpdateUIDelegate(int num, int jdCount);
public delegate void AccomplishTask(string pathDiv, List<PageInfo> pageInfoList,int stepCount);//声明一个在完成任务时通知主线程的委托
public AccomplishTask TaskCallBack;
private void UpdateUI(int step, int stepCount)
{
if (this.InvokeRequired)//跨线程访问
{
UpdateUIDelegate updateCallback = new UpdateUIDelegate(UpdateUI);
this.Invoke(updateCallback,new object[]{ step , stepCount });
}
else
{
this.progressBar1.Value += step;
this.lb_jd.Text = string.Format(jinduFormat, this.progressBar1.Value, stepCount);
}
}
private void button1_Click(object sender, EventArgs e)
{
//ReplaceGithubUrl(); MessageBox.Show("更新git url完毕"); return; //测试代码
if (txb_url.Text.Trim().Length == 0)
{
MessageBox.Show("请填写Github wiki地址");
return;
}
else if (!txb_url.Text.ContainsByIgnoreCase("https://github.com") || !txb_url.Text.ContainsByIgnoreCase("/wiki"))
{
MessageBox.Show("Github wiki地址不正确。url必须含有wiki");
return;
}
cssDictionary = new Dictionary<string, string>();
try
{
var homeHtml = DownLoadFileBllcs.HttpGET(txb_url.Text);
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(homeHtml);
HtmlNodeCollection pageNode = doc.DocumentNode.SelectNodes(xpathStr);
List<PageInfo> pageInfoList = new List<PageInfo>();
string gitName = StringHelper.GetBetweenStr(txb_url.Text, "github.com/", "/wiki").Split('/')[1];
string pathDiv = txb_path.Text + "\\" + gitName;
int stepCount = 0;//进度值
if (pageNode != null)
{
TaskCallBack += Accomplish;//绑定完成任务要调用的委托
stepCount = pageNode.Count + 1;//还有一步是更新下载的文件
this.progressBar1.Maximum = stepCount;
this.progressBar1.Value = 0;
Thread thread = new Thread(new ThreadStart(() => DownLoadWiki(pageNode, pageInfoList, pathDiv, stepCount))) { IsBackground = true };
thread.Start();
}
else
{
MessageBox.Show("没有下载Wiki");
}
//UpdateUI(1, stepCount);
}
catch (Exception exception)
{
MessageBox.Show("异常:" + exception.Message + System.Environment.NewLine + exception.StackTrace);
}
}
private void DownLoadWiki(HtmlNodeCollection pageNode, List<PageInfo> pageInfoList, string pathDiv,int stepCount)
{
PageInfo tempPage;
string requestUrl;
string html;
string href;
for (var index = 0; index < pageNode.Count; index++)
{
var pn = pageNode[index];
href = pn.Attributes["href"]?.Value;
if (!string.IsNullOrEmpty(href))
{
tempPage = new PageInfo();
tempPage.url = href;
requestUrl =
"https://github.com" +
href.Replace("https://github.com", string.Empty); //补全 github.com开头
tempPage.link = GetLinkByUrl(href);
tempPage.Text = pn.InnerText;
if (tempPage.link.Length > 0 && !tempPage.link.Contains("/") &&
pageInfoList.All(p => p.link != tempPage.link))
{
pageInfoList.Add(tempPage);
html = DownLoadFileBllcs.HttpGET(requestUrl);
DownLoadFileBllcs.SyncHtmlByUrl(html, pathDiv,
HttpUtility.UrlDecode(tempPage.link) + ".html");
}
}
UpdateUI(1,stepCount);
}
//任务完成时通知主线程作出相应的处理
TaskCallBack(pathDiv,pageInfoList,stepCount);
}
//完成任务时需要调用
private void Accomplish(string pathDiv, List<PageInfo> pageInfoList,int stepCount)
{
//还可以进行其他的一些完任务完成之后的逻辑处理
//首页位置 读取下载
string html = DownLoadFileBllcs.HttpGET(txb_url.Text.Trim());
DownLoadFileBllcs.SyncHtmlByUrl(html, pathDiv, wikiDefaultPage);
if (pageInfoList.Count > 0)
{
//MessageBox.Show("只下载成功!待完善a标签");return;//测试代码
ReplaceGithubUrl();
//添加 大屏字体调优css.7z
string zip = "\\大屏字体调优css.7z";
string css7z = System.AppDomain.CurrentDomain.BaseDirectory + zip;
if (File.Exists(css7z)) //必须判断要复制的文件是否存在
{
File.Copy(css7z, pathDiv + "\\css" + zip, true); //三个参数分别是源文件路径,存储路径,若存储路径有相同文件是否替换
}
//压缩
// string zipPath = pathDiv + ".zip";
// bool boolResult = ZipHelper.ZipDirectory(pathDiv, zipPath);
//删除文件
//DownLoadFileBllcs.DeleteDir(pathDiv);
//下载
// if (boolResult)//压缩成功并下载
// {
// MessageBox.Show("压缩成功!");
// }
// else
// {
// MessageBox.Show("压缩失败!");
// }
}
UpdateUI(1, stepCount);
MessageBox.Show("下载成功!");
}
/// <summary>
/// 获取短链接
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private string GetLinkByUrl(string url)
{
if (url.Contains("#"))
{ //github.com/wiki/abc#id
return StringHelper.GetBetweenStr(url, "/wiki/", "#");
}
if (url.Contains("?"))
{ //github.com/wiki/abc?id
return StringHelper.GetBetweenStr(url, "/wiki/", "?");
}
int indexNum = url.IndexOf("/wiki/") + "/wiki/".Length;
return url.Substring(indexNum);
}
/// <summary>
/// 替换github链接标签
/// </summary>
private void ReplaceLinkStr(string filePath)
{
string html = TxtHelper.ReadTxt(filePath);
if (string.IsNullOrEmpty(html)) return;
StringBuilder sbHtml = new StringBuilder(html);
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
HtmlNodeCollection pageNode = doc.DocumentNode.SelectNodes("//a[@href]");
/*
链接 7种样式 :https://github.com/dotnetcore/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C
https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0#2%E6%89%B9%E9%87%8F%E6%8F%92%E5%85%A5
/dotnetcore/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C
如果项目名称也是wiki(暂不支持) /dotnetcore/wiki/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C
/dotnetcore/FreeSql/wiki 首页
aop 短链接
#aop 短链接
*/
if (pageNode != null && pageNode.Count > 0)
{
string href;
string str1;//被替换后的字符串
string lastUrl;// /后面最后的url(/dotnetcore/FreeSql/wiki/aop 为aop )
foreach (var pn in pageNode)
{
href = pn.Attributes["href"].Value;
if (href.IndexOf('.') == 0 || href == wikiDefaultPage) continue;
if (href.Contains("wiki"))//带wiki
{
lastUrl = href.Split('/').Last();
if (lastUrl.ToLower() == "wiki") // /dotnetcore/FreeSql/wiki 首页
{
sbHtml.Replace("\"" + href + "\"", "'" + wikiDefaultPage + "'");
sbHtml.Replace("'" + href + "'", "'" + wikiDefaultPage + "'");
}
else
{
str1 = href.Substring(href.IndexOf("/wiki/") + "/wiki/".Length);
if (str1.Contains("?"))//同时有?和# 情况
{
string[] tempStrs = str1.Split('?');
str1 = tempStrs[0] + ".html?" + tempStrs[1];
}
else
{
if (str1.Contains("#"))
{
string[] tempStrs = str1.Split('#');
str1 = tempStrs[0] + ".html#" + tempStrs[1];
}
else
{
str1 = str1 + ".html";
}
}
sbHtml.Replace(href, str1);
}
}
else if (!href.Contains("/") && !href.Contains("."))//短链接
{
if (href.Contains("?"))//同时有?和# 情况
{
sbHtml.Replace("\"" + href + "\"", "'" + href.Replace("?", ".html?") + "'");
sbHtml.Replace("'" + href + "'", "'" + href.Replace("?", ".html?") + "'");
}
else
{
if (href.Contains("#"))
{
sbHtml.Replace("\"" + href + "\"", "'" + href.Replace("#", ".html#") + "'");
sbHtml.Replace("'" + href + "'", "'" + href.Replace("#", ".html#") + "'");
}
else
{
sbHtml.Replace("\"" + href + "\"", "'" + href + ".html'");
sbHtml.Replace("'" + href + "'", "'" + href + ".html'");
}
}
}
}
}
//删除github的css 文件,添加本地css
StringBuilder newHtml = new StringBuilder(sbHtml.ToString());
HtmlAgilityPack.HtmlDocument doc2 = new HtmlAgilityPack.HtmlDocument();
doc2.LoadHtml(sbHtml.ToString());
var cssNode = doc2.DocumentNode.SelectNodes("//link[contains(@href,'css')]");//获取所有的css引用
if (cssNode != null)
{
foreach (var pn in cssNode)
{
newHtml.Replace(pn.OuterHtml.Replace(">", " />"), GetCSSCode(pn));
}
}
TxtHelper.WriteTxt(filePath, newHtml.ToString());
}
private string GetCSSCode(HtmlNode hn)
{
var key = hn.Attributes["href"].Value;
if (!cssDictionary.ContainsKey(key))
{
string gitName = StringHelper.GetBetweenStr(txb_url.Text, "github.com/", "/wiki").Split('/')[1];
cssDictionary[key] = (cssDictionary.Count + 1).ToString();
DownLoadFileBllcs.FileDownLoad(key, txb_path.Text + "\\" + gitName + "\\css\\" + cssDictionary[key] + ".css");
}
return "<link href='css/" + cssDictionary[key] + ".css' rel='stylesheet' type='text/css'/>";
}
/// <summary>
/// 批量替换github url成本地标签。删除外部css引用
/// </summary>
private void ReplaceGithubUrl()
{
//读取页面
DirectoryInfo adminDir = new DirectoryInfo(txb_path.Text);
var dirList = adminDir.GetDirectories().OrderBy(p => p.Name);
IEnumerable<FileInfo> htmlList;
foreach (var dir in dirList)
{
htmlList = dir.EnumerateFiles("*.html").OrderBy(p => p.Name);
foreach (var html in htmlList)
{
//ddl.Items.Add(dir.Name + "/" + html.Name, dir.Name + "/" + html.Name);
ReplaceLinkStr(txb_path.Text + "\\" + dir.Name + "\\" + html.Name);
}
}
}
private void button3_Click(object sender, EventArgs e)
{
MD2Html htmlForm = new MD2Html();
this.Hide();
htmlForm.ShowDialog();
this.Show();
}
private void button2_Click(object sender, EventArgs e)
{
DownImagesForm htmlForm = new DownImagesForm();
this.Hide();
htmlForm.ShowDialog();
this.Show();
}
}
/// <summary>
/// 目录列表
/// </summary>
public class PageInfo
{
/// <summary>
/// url: /dotnetcore/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C 等
/// </summary>
public string url { get; set; }
/// <summary>
/// 短链接 : %E9%AA%9A%E6%93%8D%E4%BD%9C
/// </summary>
public string link { get; set; }
/// <summary>
/// 显示文本 : 安装
/// </summary>
public string Text { get; set; }
}
}
/*todo
wiki 有效地址判断(只下载wiki链接)
链接重复的问题
链接中文转实体的问题,也会导致重复的问题
链接替换为本地链接的问题(根据a标签原html替换?)
批量请求地址
样式的问题(2个css文件)
Xpath表达式提示文章显示
//a[contains(@href,'https://github.com/2881099/FreeSql/wiki')]
*/
C#
1
https://gitee.com/sundayisblue/GitHubWikiTool.git
git@gitee.com:sundayisblue/GitHubWikiTool.git
sundayisblue
GitHubWikiTool
GitHubWikiTool
master

搜索帮助