private async Task CreateIssue(CodePlexIssue codePlexIssue) { var codePlexIssueUrl = string.Format("http://{0}.codeplex.com/workitem/{1}", _options.CodeplexProject, codePlexIssue.Id); var description = new StringBuilder(); description.AppendFormat("<sub>This issue was imported from [CodePlex]({0})</sub>", codePlexIssueUrl); description.AppendLine(); description.AppendLine(); description.AppendFormat(CultureInfo.InvariantCulture, "**[{0}](https://github.com/{0})** <sup>wrote {1:yyyy-MM-dd} at {1:HH:mm}</sup>", codePlexIssue.ReportedBy, codePlexIssue.Time); description.AppendLine(); description.Append(FormatForGithub(codePlexIssue.Description)); var labels = new List<string>(); if (codePlexIssue.Type == "Feature") { labels.Add("enhancement"); } // if (codePlexIssue.Type == "Issue") // labels.Add("bug"); // if (codePlexIssue.Impact == "Low" || codePlexIssue.Impact == "Medium" || codePlexIssue.Impact == "High") // labels.Add(issue.Impact); var issue = new NewIssue(codePlexIssue.Title) { Body = description.ToString().Trim() }; if (_options.AddCodePlexLabel) { issue.Labels.Add("CodePlex"); } foreach (var label in labels) { if (!string.IsNullOrEmpty(label)) { issue.Labels.Add(label); } } var gitHubIssue = await _gitHubClient.Issue.Create(_options.GitHubOwner, _options.GitHubRepository, issue); var commentsCount = codePlexIssue.Comments.Count; var n = 0; foreach (var comment in codePlexIssue.Comments) { Console.WriteLine("{0} - > Adding Comment {1}/{2} by {3}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), ++n, commentsCount, comment.Author); await CreateComment(gitHubIssue.Number, comment); } if (codePlexIssue.IsClosed()) { await CloseIssue(gitHubIssue); } }
public async Task<CodePlexIssue> GetIssue(int id) { var url = string.Format("http://{0}.codeplex.com/workitem/{1}", _codePlexProject, id); var html = await _httpClient.GetStringAsync(url); HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); var root = doc.DocumentNode; var description = root.SelectSingleNode("//div[@id='descriptionContent']").InnerHtml; var reportedBy = root.SelectSingleNode("//a[@id='ReportedByLink']").InnerText; var title = root.SelectSingleNode("//h1[@id='workItemTitle']").InnerText; var status = root.SelectSingleNode("//a[@id='StatusLink']").InnerText; var type = root.SelectSingleNode("//a[@id='TypeLink']").InnerText; var impact = root.SelectSingleNode("//a[@id='ImpactLink']").InnerText; var release = root.SelectSingleNode("//a[@id='ReleaseLink']").InnerText; var closedReason = root.SelectSingleNode("//a[@id='ReasonClosedLink']").InnerText; var component = root.SelectSingleNode("//a[@id='ComponentLink']").InnerText; var reportedTimeString = root.SelectSingleNode("//span[@id='ReportedOnDateTime']").GetAttributeValue("title", "01/01/1990 00:00:00"); DateTime reportedTime; DateTime.TryParse( reportedTimeString, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal, out reportedTime); var issue = new CodePlexIssue { Description = HtmlToMarkdown(description), ReportedBy = reportedBy, Time = reportedTime }; issue.Id = id; issue.Title = HtmlToMarkdown(title); issue.Status = status; issue.Type = type; issue.Impact = impact; issue.Release = release; issue.ClosedReason = closedReason; issue.Component = component; for (int i = 0; ; i++) { var commentNode = root.SelectSingleNode("//div[@id='CommentContainer" + i + "']"); if (commentNode == null) { break; } HtmlDocument commentDoc = new HtmlDocument(); commentDoc.LoadHtml(commentNode.InnerHtml); var commentRoot = commentDoc.DocumentNode; var author = commentRoot.SelectSingleNode("//a[@id='PostedByLink" + i + "']").InnerText; var timeString = commentRoot.SelectSingleNode("//span[@id='PostedOnDateTime" + i + "']"). GetAttributeValue("title", "01/01/1990 00:00:00"); DateTime time; DateTime.TryParse( timeString, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal, out time); var content = commentRoot.SelectSingleNode("//div[@class='markDownOutput' or @class='markDownOutput ']").InnerHtml; issue.Comments.Add(new CodeplexComment { Content = HtmlToMarkdown(content), Author = author, Time = time }); } if (issue.IsClosed()) { var closedNode = root.SelectSingleNode("//div[@id='ClosedDiv']"); HtmlDocument closedDoc = new HtmlDocument(); closedDoc.LoadHtml(closedNode.InnerHtml); var closedRoot = closedDoc.DocumentNode; var timeString = closedRoot.SelectSingleNode("//span[@id='ClosedOnDateTimeComment']").GetAttributeValue("title", "01/01/1990 00:00:00"); DateTime time; DateTime.TryParse( timeString, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal, out time); var author = closedRoot.SelectSingleNode("//a[@id='ClosedByLink']").InnerText; var content = closedRoot.SelectSingleNode("//div[@class='markDownOutput' or @class='markDownOutput ']").InnerHtml; if (string.IsNullOrEmpty(content)) { content = "Closed."; } issue.Comments.Add(new CodeplexComment { Content = HtmlToMarkdown(content), Author = author, Time = time }); } Console.WriteLine("{0} : {1} ({2} comments)", issue.Id, issue.Title, issue.Comments.Count); return issue; }
public async Task RunFor(CodePlexIssue issue) { await CreateIssue(issue); }