You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

382 lines
20 KiB

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Tiobon.PublishHelper
{
public partial class Form_UpgradeLog : Form
{
#region 初始化
public Form_UpgradeLog()
{
InitializeComponent();
this.webBrowser_Upgrade.ScriptErrorsSuppressed = true;
this.webBrowser_Upgrade.DocumentCompleted += WebBrowser_Upgrade_DocumentCompleted;
this.webBrowser_Upgrade.StatusTextChanged += WebBrowser_Upgrade_StatusTextChanged;
this.webBrowser_Upgrade.NewWindow += WebBrowser_Upgrade_NewWindow;
}
private void WebBrowser_Upgrade_NewWindow(object sender, CancelEventArgs e)
{
e.Cancel = true;
try
{
this.webBrowser_Upgrade.Navigate(this.webBrowser_Upgrade.Document.ActiveElement.GetAttribute("href"));
}
catch { }
}
private void WebBrowser_Upgrade_StatusTextChanged(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(webBrowser_Upgrade.StatusText))
return;
this.tssl_status.Text = webBrowser_Upgrade.StatusText;
}
public static Dictionary<string, string> ParseQueryString(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentNullException("url");
}
var uri = new Uri(url);
if (string.IsNullOrWhiteSpace(uri.Query))
{
return new Dictionary<string, string>();
}
//1.去除第一个前导?字符
var dic = uri.Query.Substring(1)
//2.通过&划分各个参数
.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
//3.通过=划分参数key和value,且保证只分割第一个=字符
.Select(param => param.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))
//4.通过相同的参数key进行分组
.GroupBy(part => part[0], part => part.Length > 1 ? part[1] : string.Empty)
//5.将相同key的value以,拼接
.ToDictionary(group => group.Key, group => string.Join(",", group));
return dic;
}
private void WebBrowser_Upgrade_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//if (webBrowser_Upgrade.DocumentTitle == "登录-TAPD")
//{
// foreach (HtmlElement element in webBrowser_Upgrade.Document.Links)
// {
// if (element != null && !string.IsNullOrEmpty(element.OuterHtml) && element.OuterHtml.Contains("wx-login-btn"))
// {
// element.InvokeMember("click");
// return;
// }
// }
//}
//else
{
var ver = string.Empty;
StringBuilder sb = new StringBuilder();
foreach (HtmlElement element in webBrowser_Upgrade.Document.All)
{
try
{
var content = element.InnerHtml;
if (string.IsNullOrEmpty(ver) && !string.IsNullOrEmpty(content) && content.Contains("<span class=\"inner-name\">"))
{
int verStart = content.IndexOf("<span class=\"inner-name\">");
string verContent = content.Substring(verStart + 25);
ver = verContent.Substring(0, verContent.IndexOf("<"));
sb.AppendLine($"## {ver}");
sb.AppendLine();
sb.AppendLine($"`{DateTime.Now:yyyy-MM-dd}`");
sb.AppendLine();
}
if (string.IsNullOrEmpty(ver) && !string.IsNullOrEmpty(content) && content.Contains("<span class=\"j-iteration-detail__name iteration-detail__name\"><a title=\""))
{
int verStart = content.IndexOf("<span class=\"j-iteration-detail__name iteration-detail__name\"><a title=\"");
string verContent = content.Substring(verStart + 72);
ver = verContent.Substring(0, verContent.IndexOf("\""));
sb.AppendLine($"## {ver}");
sb.AppendLine();
sb.AppendLine($"`{DateTime.Now:yyyy-MM-dd}`");
sb.AppendLine();
}
int sumEnd = 0;
while (!string.IsNullOrEmpty(content))
{
if (content.Trim().StartsWith("</table>"))
content = content.Substring(9);
if (content.IndexOf("<TABLE") > -1 && webBrowser_Upgrade.Document.Url.ToString().Contains("releases/get_story_list/"))
{
int start = content.IndexOf("<TABLE");
int end = content.IndexOf("</TABLE>");
if (start >= 0 && end >= 0)
{
var str = content.Trim().Substring(start, end - start + 8);
Regex reg = new Regex(@"(?is)<a[^>]*?href=(['""\s]?)(?<href>[^'""\s]*)\1[^>]*?>");
MatchCollection match = reg.Matches(str);
foreach (Match m in match)
{
string mValue = m.Value;
int start1 = mValue.IndexOf("title=");
int end1 = mValue.IndexOf("class=\"j-story-title-link");
if (start1 >= 0 && end1 >= 0)
{
var name = mValue.Trim().Substring(start1, end1);
name = name.Replace("title=", null);
name = name.Replace("class=\"j-story-title-link ", null);
name = name.Replace("nameco", null);
string url = m.Groups["href"].Value;
if (url.Length > 7)
{
start1 = url.IndexOf("href=\"");
end1 = url.IndexOf("?url_cache_key");
url = url.Substring(0, end1);
Uri uri = new Uri(url);
string id = uri.Segments[uri.Segments.Length - 1];
id = id.Substring(id.Length - 7);
//sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} ({url})");
sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} [#{id}]({url})");
sb.AppendLine();
}
//Response.Write(m.Groups["href"].Value + "<br/>");
}
}
sumEnd += end;
content = element.InnerHtml.Substring(sumEnd + 8);
}
else
{
break;
}
}
else if (content.IndexOf("<TBODY id=bugs-list-tbody>") > -1 && webBrowser_Upgrade.Document.Url.ToString().Contains("releases/release_tab_bugs_list"))
{
int start = content.IndexOf("<TBODY id=bugs-list-tbody>");
int end = content.IndexOf("</TBODY>");
if (start >= 0 && end >= 0)
{
var str = content.Trim().Substring(start, end - start + 8);
//Regex reg = new Regex("<TR.*?>(.*?)</TR>");
Regex reg = new Regex("<TR.*?>[\\s\\S]*?</TR>");
MatchCollection match = reg.Matches(str);
foreach (Match m in match)
{
string mValue = m.Value;
Regex reg1 = new Regex("<TD data-editable=\"text\".*?>[\\s\\S]*?</TD>");
MatchCollection match1 = reg1.Matches(mValue);
foreach (Match m1 in match1)
{
string m1Value = m.Value;
var name = "";
int start1 = m1Value.IndexOf("growing-title-inner>");
int end1 = m1Value.IndexOf("data-editable-field=\"version_report\"");
if (start1 >= 0 && end1 >= 0)
{
name = m1Value.Trim().Substring(start1, end1);
name = name.Replace("growing-title-inner>", null);
name = name.Replace("data-editable-field=\"version_report\"", null);
}
reg = new Regex(@"(?is)<a[^>]*?href=(['""\s]?)(?<href>[^'""\s]*)\1[^>]*?>");
match = reg.Matches(name);
foreach (Match m2 in match)
{
start1 = m2.Value.IndexOf("<A title=");
end1 = m2.Value.IndexOf("class=editable-value");
if (start1 >= 0 && end1 >= 0)
{
name = m2.Value.Trim().Substring(start1, end1);
name = name.Replace("<A title=", null);
name = name.Replace("class=editable-value", null);
start1 = m2.Value.IndexOf("href=\"");
end1 = m2.Value.IndexOf("&amp;url_cache_key=");
if (start1 >= 0 && end1 >= 0)
{
string url = m2.Value.Substring(start1, end1 - start1);
url = url.Replace("href=\"", null);
url = url.Replace("target=\"\"", null);
Uri uri = new Uri(url);
string queryString = uri.Query;
string id = queryString.Replace("?bug_id=", null);
id = id.Substring(id.Length - 7);
//sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} ({url})");
sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} [#{id}]({url})");
sb.AppendLine();
}
}
}
// start1 = m1Value.IndexOf("href=\"http");
//end1 = m1Value.IndexOf("target=");
//if (start1 >= 0 && end1 >= 0)
//{
// url = m1Value.Trim().Substring(start1, end1);
// url = name.Replace("\"", null);
// url = name.Replace("\"", null);
//}
}
}
//Regex reg = new Regex(@"(?is)<a[^>]*?href=(['""\s]?)(?<href>[^'""\s]*)\1[^>]*?>[^'""\s]*</a>");
reg = new Regex(@"(?is)<a[^>]*?href=(['""\s]?)(?<href>[^'""\s]*)\1[^>]*?>");
match = reg.Matches(str);
foreach (Match m in match)
{
string mValue = m.Value;
int start1 = mValue.IndexOf("data-editable-value=");
int end1 = mValue.IndexOf("data-editable-field=");
if (start1 >= 0 && end1 >= 0)
{
var name = mValue.Trim().Substring(start1, end1);
name = name.Replace("\"", null);
name = name.Replace("\"", null);
string url = m.Groups["href"].Value;
if (url.Length > 7)
{
//string id = url.Substring(url.Length - 7);
sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} ({url})");
//sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} [#{id}]({url})");
sb.AppendLine();
}
//Response.Write(m.Groups["href"].Value + "<br/>");
}
}
sumEnd += end;
content = element.InnerHtml.Substring(sumEnd + 8);
}
else
{
break;
}
}
else
{
int start = content.IndexOf("<table");
int end = content.IndexOf("</table>");
if (start >= 0 && end >= 0)
{
var str = content.Trim().Substring(start, end - start + 8);
string[] empties = str.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < empties.Length; ++i)
{
if (!empties[i].Trim().StartsWith("<a title=\"") || !empties[i].Contains("editable"))
continue;
string[] datas = empties[i].Contains("bugs") ? empties[i].Split(new string[] { "\"", "&" }, StringSplitOptions.RemoveEmptyEntries) : empties[i].Split(new string[] { "\"", "&", "?" }, StringSplitOptions.RemoveEmptyEntries);
string url = datas.ToList().Where(d => d.StartsWith("https://www.tapd.cn/")).FirstOrDefault();
if (string.IsNullOrEmpty(url) || (!url.Contains("stories/view") && !url.Contains("bugs/view")))
{
continue;
}
string name = datas[1].Trim();
string id = url.Substring(url.Length - 7);
sb.AppendLine($"- :{(url.Contains("bugs") ? "bug" : "sparkles")}: {name} [#{id}]({url})");
sb.AppendLine();
}
sumEnd += end;
content = element.InnerHtml.Substring(sumEnd + 8);
}
else
{
break;
}
}
}
if (sb.Length > 0)
{
this.txt_content.Text = sb.ToString();
return;
}
}
catch (Exception ex) { }
}
}
}
#endregion
#region 拷贝与刷新
private void ll_Copy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (string.IsNullOrEmpty(this.txt_content.Text))
return;
try
{
Clipboard.SetDataObject(this.txt_content.Text, true);
}
catch
{
}
}
private void ll_Refresh_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.webBrowser_Upgrade.Refresh();
}
#endregion
#region 清除IE缓存
private enum ShowCommands : int
{
SW_HIDE = 0,
SW_SHOWNORMAL = 1,
SW_NORMAL = 1,
SW_SHOWMINIMIZED = 2,
SW_SHOWMAXIMIZED = 3,
SW_MAXIMIZE = 3,
SW_SHOWNOACTIVATE = 4,
SW_SHOW = 5,
SW_MINIMIZE = 6,
SW_SHOWMINNOACTIVE = 7,
SW_SHOWNA = 8,
SW_RESTORE = 9,
SW_SHOWDEFAULT = 10,
SW_FORCEMINIMIZE = 11,
SW_MAX = 11
}
[DllImport("shell32.dll")]
private static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, ShowCommands nShowCmd);
private void ll_Clear_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
ShellExecute(IntPtr.Zero, "open", "rundll32.exe", " InetCpl.cpl,ClearMyTracksByProcess 255", "", ShowCommands.SW_HIDE);
}
#endregion
bool b_autorefresh = false;
private void cb_Refresh_CheckedChanged(object sender, EventArgs e)
{
b_autorefresh = true;
}
}
}