public PluginDataProject(String nameVal, String directoryVal) { name = nameVal; directory = directoryVal; // get the identifier RepoResourceInfo resourceInfo = GitUtilManager.GetResourceInfo(directoryVal, false); if (resourceInfo != null && resourceInfo.identifier != null) { identifier = resourceInfo.identifier; } }
/** * Get the latest repo commit **/ public async Task <RepoCommit> GetLatestCommitAsync(string projectDir) { try { if (!SoftwareCoUtil.IsGitProject(projectDir)) { return(null); } RepoResourceInfo info = GitUtilManager.GetResourceInfo(projectDir, false); if (info != null && info.identifier != null) { string identifier = info.identifier; if (identifier != null && !identifier.Equals("")) { string tag = info.tag; string branch = info.branch; string qryString = "?identifier=" + identifier; qryString += "&tag=" + tag; qryString += "&branch=" + branch; HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync( HttpMethod.Get, "/commits/latest?" + qryString, null); if (SoftwareHttpManager.IsOk(response)) { // get the json data string responseBody = await response.Content.ReadAsStringAsync(); IDictionary <string, object> jsonObj = (IDictionary <string, object>)SimpleJson.DeserializeObject(responseBody, new Dictionary <string, object>()); jsonObj.TryGetValue("commitId", out object commitIdObj); string commitId = (commitIdObj == null) ? "" : Convert.ToString(commitIdObj); jsonObj.TryGetValue("message", out object messageObj); string message = (messageObj == null) ? "" : Convert.ToString(messageObj); jsonObj.TryGetValue("message", out object timestampObj); long timestamp = (timestampObj == null) ? 0L : Convert.ToInt64(timestampObj); RepoCommit repoCommit = new RepoCommit(commitId, message, timestamp); return(repoCommit); } } } } catch (Exception ex) { Logger.Error("GetLatestCommitAsync ,error: " + ex.Message, ex); } return(null); }
public List <RepoMember> GetRepoUsers(string projectDir) { if (!SoftwareCoUtil.IsGitProject(projectDir)) { return(new List <RepoMember>()); } RepoResourceInfo info = GitUtilManager.GetResourceInfo(projectDir, true); if (info != null && info.Members != null) { return(info.Members); } return(new List <RepoMember>()); }
public async Task ProcessRepoMembers(string projectDir) { if (!SoftwareCoUtil.IsGitProject(projectDir)) { return; } RepoResourceInfo info = GitUtilManager.GetResourceInfo(projectDir, true); if (info != null && info.Members.Count > 0) { string jsonContent = SimpleJson.SerializeObject(info); // send the members HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync( HttpMethod.Post, "/repo/members", jsonContent); if (!SoftwareHttpManager.IsOk(response)) { Logger.Error(response.ToString()); } } }
public async Task RebuildContributorMetricsAsync() { string dir = DocEventManager._solutionDirectory; if ((dir == null || dir.Equals("")) && SoftwareCoPackage.PLUGIN_READY) { dir = await DocEventManager.GetSolutionDirectory(); } RepoResourceInfo resourceInfo = GitUtilManager.GetResourceInfo(dir, true); // clear the children ContributorsMetricsPanel.Children.Clear(); if (resourceInfo != null && resourceInfo.identifier != null) { StackPanel identifierPanel = BuildClickLabel("IdentifierPanel", "github.png", resourceInfo.identifier, RepoIdentifierClickHandler); ContributorsMetricsPanel.Children.Add(identifierPanel); // build the repo contributors // } // < TreeView x: Name = "TopCodeTimeFiles" Background = "Transparent" BorderBrush = "Transparent" Width = "auto" Height = "auto" ScrollViewer.VerticalScrollBarVisibility = "Auto" ScrollViewer.HorizontalScrollBarVisibility = "Disabled" > // < TreeView.Resources > // < SolidColorBrush x: Key = "{x:Static SystemColors.HighlightBrushKey}" // Color = "Transparent" /> // < SolidColorBrush x: Key = "{x:Static SystemColors.HighlightTextBrushKey}" // Color = "Transparent" /> // < SolidColorBrush x: Key = "{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" // Color = "Transparent" /> // < SolidColorBrush x: Key = "{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" // Color = "Transparent" /> // </ TreeView.Resources > // </ TreeView > }
public async Task DisplayProjectContributorSummaryDashboard() { string file = FileManager.GetContributorDashboardFile(); StringBuilder sb = new StringBuilder(); // fetch the git stats string projectDir = DocEventManager._solutionDirectory; RepoResourceInfo resourceInfo = GitUtilManager.GetResourceInfo(projectDir, false); string identifier = resourceInfo != null && resourceInfo.identifier != null ? resourceInfo.identifier : "Untitled"; NowTime nowTime = SoftwareCoUtil.GetNowTime(); string email = GitUtilManager.GetUsersEmail(projectDir); CommitChangeStats usersTodaysCommits = GitUtilManager.GetTodaysCommits(projectDir, email); CommitChangeStats contribTodaysCommits = GitUtilManager.GetTodaysCommits(projectDir, null); CommitChangeStats usersYesterdaysCommits = GitUtilManager.GetYesterdayCommits(projectDir, email); CommitChangeStats contribYesterdaysCommits = GitUtilManager.GetYesterdayCommits(projectDir, null); CommitChangeStats usersThisWeeksCommits = GitUtilManager.GetThisWeeksCommits(projectDir, email); CommitChangeStats contribThisWeeksCommits = GitUtilManager.GetThisWeeksCommits(projectDir, null); string lastUpdatedStr = DateTime.Now.ToString("dddd, MMM d h:mm tt"); sb.Append(getTableHeader("PROJECT SUMMARY", " (Last updated on " + lastUpdatedStr + ")", true)); sb.Append("\n\n Project: ").Append(identifier).Append("\n\n"); // TODAY String projectDate = DateTime.Now.ToString("MMM d, yyyy"); sb.Append(getRightAlignedTableHeader("Today (" + projectDate + ")")); sb.Append(getColumnHeaders(new List <string>() { "Metric", "You", "All Contributors" })); sb.Append(getRowNumberData("Commits", usersTodaysCommits.commitCount, contribTodaysCommits.commitCount)); sb.Append(getRowNumberData("Files changed", usersTodaysCommits.fileCount, contribTodaysCommits.fileCount)); sb.Append(getRowNumberData("Insertions", usersTodaysCommits.insertions, contribTodaysCommits.insertions)); sb.Append(getRowNumberData("Deletions", usersTodaysCommits.deletions, contribTodaysCommits.deletions)); sb.Append("\n"); // YESTERDAY String yesterday = nowTime.start_of_yesterday_dt.ToString("MMM d, yyyy"); sb.Append(getRightAlignedTableHeader("Yesterday (" + yesterday + ")")); sb.Append(getColumnHeaders(new List <string>() { "Metric", "You", "All Contributors" })); sb.Append(getRowNumberData("Commits", usersYesterdaysCommits.commitCount, contribYesterdaysCommits.commitCount)); sb.Append(getRowNumberData("Files changed", usersYesterdaysCommits.fileCount, contribYesterdaysCommits.fileCount)); sb.Append(getRowNumberData("Insertions", usersYesterdaysCommits.insertions, contribYesterdaysCommits.insertions)); sb.Append(getRowNumberData("Deletions", usersYesterdaysCommits.deletions, contribYesterdaysCommits.deletions)); sb.Append("\n"); // THIS WEEK String startOfWeek = nowTime.start_of_week_dt.ToString("MMM d, yyyy"); sb.Append(getRightAlignedTableHeader("This week (" + startOfWeek + " to " + projectDate + ")")); sb.Append(getColumnHeaders(new List <string>() { "Metric", "You", "All Contributors" })); sb.Append(getRowNumberData("Commits", usersThisWeeksCommits.commitCount, contribThisWeeksCommits.commitCount)); sb.Append(getRowNumberData("Files changed", usersThisWeeksCommits.fileCount, contribThisWeeksCommits.fileCount)); sb.Append(getRowNumberData("Insertions", usersThisWeeksCommits.insertions, contribThisWeeksCommits.insertions)); sb.Append(getRowNumberData("Deletions", usersThisWeeksCommits.deletions, contribThisWeeksCommits.deletions)); sb.Append("\n"); if (File.Exists(file)) { File.SetAttributes(file, FileAttributes.Normal); } try { File.WriteAllText(file, sb.ToString(), System.Text.Encoding.UTF8); } catch (Exception e) { } try { if (File.Exists(file)) { SoftwareCoPackage.ObjDte.ItemOperations.OpenFile(file); } } catch (Exception ex) { Logger.Error("LaunchCodeTimeDashboardAsync, error : " + ex.Message, ex); } }
public async void GetHistoricalCommitsAsync(string projectDir) { try { if (!SoftwareCoUtil.IsGitProject(projectDir)) { return; } RepoResourceInfo info = GitUtilManager.GetResourceInfo(projectDir, false); if (info != null && info.identifier != null) { string identifier = info.identifier; if (identifier != null && !identifier.Equals("")) { string tag = info.tag; string branch = info.branch; string email = info.email; RepoCommit latestCommit = null; latestCommit = await this.GetLatestCommitAsync(projectDir); string sinceOption = ""; if (latestCommit != null) { sinceOption = " --since=" + latestCommit.timestamp; } else { sinceOption = " --max-count=100"; } string cmd = "git log --stat --pretty=COMMIT:%H,%ct,%cI,%s --author=" + email + "" + sinceOption; string gitCommitData = SoftwareCoUtil.RunCommand(cmd, projectDir); if (gitCommitData != null && !gitCommitData.Equals("")) { string[] lines = gitCommitData.Split( new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); RepoCommit currentRepoCommit = null; List <RepoCommit> repoCommits = new List <RepoCommit>(); if (lines != null && lines.Length > 0) { for (int i = 0; i < lines.Length; i++) { string line = lines[i].Trim(); if (line.Length > 0) { bool hasPipe = line.IndexOf("|") != -1 ? true : false; bool isBin = line.ToLower().IndexOf("bin") != -1 ? true : false; if (line.IndexOf("COMMIT:") == 0) { line = line.Substring("COMMIT:".Length); if (currentRepoCommit != null) { repoCommits.Add(currentRepoCommit); } string[] commitInfos = line.Split(','); if (commitInfos != null && commitInfos.Length > 0) { string commitId = commitInfos[0].Trim(); // go to the next line if we've already processed this commitId if (latestCommit != null && commitId.Equals(latestCommit.commitId)) { currentRepoCommit = null; continue; } // get the other attributes now long timestamp = Convert.ToInt64(commitInfos[1].Trim()); string date = commitInfos[2].Trim(); string message = commitInfos[3].Trim(); currentRepoCommit = new RepoCommit(commitId, message, timestamp); currentRepoCommit.date = date; RepoCommitChanges changesObj = new RepoCommitChanges(0, 0); currentRepoCommit.changes.Add("__sftwTotal__", changesObj); } } else if (currentRepoCommit != null && hasPipe && !isBin) { // get the file and changes // i.e. somefile.cs | 20 +++++++++--------- line = string.Join(" ", line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); string[] lineInfos = line.Split('|'); if (lineInfos != null && lineInfos.Length > 1) { string file = lineInfos[0].Trim(); string[] metricInfos = lineInfos[1].Trim().Split(' '); if (metricInfos != null && metricInfos.Length > 1) { string addAndDeletes = metricInfos[1].Trim(); int len = addAndDeletes.Length; int lastPlusIdx = addAndDeletes.LastIndexOf('+'); int insertions = 0; int deletions = 0; if (lastPlusIdx != -1) { insertions = lastPlusIdx + 1; deletions = len - insertions; } else if (len > 0) { // all deletions deletions = len; } if (!currentRepoCommit.changes.ContainsKey(file)) { RepoCommitChanges changesObj = new RepoCommitChanges(insertions, deletions); currentRepoCommit.changes.Add(file, changesObj); } else { RepoCommitChanges fileCommitChanges; currentRepoCommit.changes.TryGetValue(file, out fileCommitChanges); if (fileCommitChanges != null) { fileCommitChanges.deletions += deletions; fileCommitChanges.insertions += insertions; } } RepoCommitChanges totalRepoCommit; currentRepoCommit.changes.TryGetValue("__sftwTotal__", out totalRepoCommit); if (totalRepoCommit != null) { totalRepoCommit.deletions += deletions; totalRepoCommit.insertions += insertions; } } } } } } } if (currentRepoCommit != null) { repoCommits.Add(currentRepoCommit); } if (repoCommits != null && repoCommits.Count > 0) { // batch 10 at a time int batch_size = 10; List <RepoCommit> batch = new List <RepoCommit>(); for (int i = 0; i < repoCommits.Count; i++) { batch.Add(repoCommits[i]); if (i > 0 && i % batch_size == 0) { // send this batch. RepoCommitData commitData = new RepoCommitData(identifier, tag, branch, batch); string jsonContent = commitData.GetAsJson(); // SimpleJson.SerializeObject(commitData); // send the members HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync( HttpMethod.Post, "/commits", jsonContent); if (SoftwareHttpManager.IsOk(response)) { Logger.Info(response.ToString()); } else { Logger.Error(response.ToString()); } } } if (batch.Count > 0) { RepoCommitData commitData = new RepoCommitData(identifier, tag, branch, batch); string jsonContent = commitData.GetAsJson(); // SimpleJson.SerializeObject(commitData); // send the members HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync( HttpMethod.Post, "/commits", jsonContent); if (SoftwareHttpManager.IsOk(response)) { Logger.Info(response.ToString()); } else if (response != null) { Logger.Error("Unable to complete commit request, status: " + response.StatusCode); } } } } } } } catch (Exception ex) { Logger.Error("GetHistoricalCommitsAsync ,error: " + ex.Message, ex); } }
public async Task RebuildGitMetricsAsync() { string dir = DocEventManager._solutionDirectory; if ((dir == null || dir.Equals("")) && SoftwareCoPackage.PLUGIN_READY) { dir = await DocEventManager.GetSolutionDirectory(); } // if (dir == null || dir.Equals("")) // { // Uncommitted.Visibility = Visibility.Hidden; // CommittedToday.Visibility = Visibility.Hidden; // return; // } else // { // Uncommitted.Visibility = Visibility.Visible; // CommittedToday.Visibility = Visibility.Visible; // } string name = ""; try { FileInfo fi = new FileInfo(dir); name = fi.Name; } catch (Exception e) { // } CommitChangeStats uncommited = GitUtilManager.GetUncommitedChanges(dir); string uncommittedInsertions = "Insertion(s): " + uncommited.insertions; string uncommittedDeletions = "Deletion(s): " + uncommited.deletions; if (Uncommitted.HasItems) { // update TreeViewItem parentItem = await GetParent(Uncommitted, "uncommitted"); UpdateNodeValue(parentItem, "uncommittedinsertions", uncommittedInsertions, "insertion.png"); UpdateNodeValue(parentItem, "uncommitteddeletions", uncommittedDeletions, "deletion.png"); } else { List <TreeViewItem> uncommitedChilren = new List <TreeViewItem>(); uncommitedChilren.Add(BuildMetricNode("uncommittedinsertions", uncommittedInsertions, "insertion.png")); uncommitedChilren.Add(BuildMetricNode("uncommitteddeletions", uncommittedDeletions, "deletion.png")); TreeViewItem uncommittedParent = BuildMetricNodes("uncommitted", "Open changes", uncommitedChilren); Uncommitted.Items.Add(uncommittedParent); } string email = GitUtilManager.GetUsersEmail(dir); CommitChangeStats todaysStats = GitUtilManager.GetTodaysCommits(dir, email); string committedInsertions = "Insertion(s): " + todaysStats.insertions; string committedDeletions = "Deletion(s): " + todaysStats.deletions; string committedCount = "Commit(s): " + todaysStats.commitCount; string committedFilecount = "Files changed: " + todaysStats.fileCount; if (CommittedToday.HasItems) { // update TreeViewItem parentItem = await GetParent(CommittedToday, "committed"); UpdateNodeValue(parentItem, "committedinsertions", committedInsertions, "insertion.png"); UpdateNodeValue(parentItem, "committeddeletions", committedDeletions, "deletion.png"); UpdateNodeValue(parentItem, "committedcount", committedCount, "commit.png"); UpdateNodeValue(parentItem, "committedfilecount", committedFilecount, "files.png"); } else { List <TreeViewItem> committedChilren = new List <TreeViewItem>(); committedChilren.Add(BuildMetricNode("committedinsertions", committedInsertions, "insertion.png")); committedChilren.Add(BuildMetricNode("committeddeletions", committedDeletions, "deletion.png")); committedChilren.Add(BuildMetricNode("committedcount", committedCount, "commit.png")); committedChilren.Add(BuildMetricNode("committedfilecount", committedFilecount, "files.png")); TreeViewItem committedParent = BuildMetricNodes("committed", "Committed today", committedChilren); CommittedToday.Items.Add(committedParent); } }
public async Task <string> CompletePayloadAndReturnJsonString() { RepoResourceInfo resourceInfo = null; // make sure we have a valid project and identifier if possible if (this.project == null || this.project.directory == null || this.project.directory.Equals("Untitled")) { // try to get a valid project string projectDir = await DocEventManager.GetSolutionDirectory(); if (projectDir != null && !projectDir.Equals("")) { FileInfo fi = new FileInfo(projectDir); project = new PluginDataProject(fi.Name, projectDir); resourceInfo = GitUtilManager.GetResourceInfo(projectDir, false); } } else { resourceInfo = GitUtilManager.GetResourceInfo(this.project.directory, false); } if (resourceInfo != null && resourceInfo.identifier != null && !resourceInfo.identifier.Equals("")) { project.identifier = resourceInfo.identifier; } SessionSummaryManager summaryMgr = SessionSummaryManager.Instance; TimeGapData eTimeInfo = summaryMgr.GetTimeBetweenLastPayload(); NowTime nowTime = SoftwareCoUtil.GetNowTime(); this.end = nowTime.now; this.local_end = nowTime.local_now; // get the TimeData for this project dir await ValidateAndUpdateCumulativeDataAsync(eTimeInfo.session_seconds); this.elapsed_seconds = eTimeInfo.elapsed_seconds; // make sure all of the end times are set foreach (PluginDataFileInfo pdFileInfo in this.source) { pdFileInfo.EndFileInfoTime(nowTime); } double offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes; this.offset = Math.Abs((int)offset); if (TimeZone.CurrentTimeZone.DaylightName != null && TimeZone.CurrentTimeZone.DaylightName != TimeZone.CurrentTimeZone.StandardName) { this.timezone = TimeZone.CurrentTimeZone.DaylightName; } else { this.timezone = TimeZone.CurrentTimeZone.StandardName; } // update the file metrics used in the tree List <FileInfoSummary> fileInfoList = this.GetSourceFileInfoList(); KeystrokeAggregates aggregates = new KeystrokeAggregates(); aggregates.directory = this.project.directory; foreach (FileInfoSummary fileInfo in fileInfoList) { aggregates.Aggregate(fileInfo); FileChangeInfo fileChangeInfo = FileChangeInfoDataManager.Instance.GetFileChangeInfo(fileInfo.fsPath); if (fileChangeInfo == null) { // create a new entry fileChangeInfo = new FileChangeInfo(); } fileChangeInfo.UpdateFromFileInfo(fileInfo); FileChangeInfoDataManager.Instance.SaveFileChangeInfoDataSummaryToDisk(fileChangeInfo); } // increment the session summary minutes and other metrics summaryMgr.IncrementSessionSummaryData(aggregates, eTimeInfo); // create the json payload JsonObject jsonObj = new JsonObject(); jsonObj.Add("start", this.start); jsonObj.Add("local_start", this.local_start); jsonObj.Add("pluginId", this.pluginId); jsonObj.Add("type", this.type); jsonObj.Add("keystrokes", this.keystrokes); jsonObj.Add("project", this.project.GetAsJson()); jsonObj.Add("timezone", this.timezone); jsonObj.Add("offset", this.offset); jsonObj.Add("version", this.version); jsonObj.Add("os", this.os); jsonObj.Add("end", this.end); jsonObj.Add("local_end", this.local_end); jsonObj.Add("cumulative_editor_seconds", this.cumulative_editor_seconds); jsonObj.Add("cumulative_session_seconds", this.cumulative_session_seconds); jsonObj.Add("elapsed_seconds", this.elapsed_seconds); jsonObj.Add("workspace_name", this.workspace_name); jsonObj.Add("hostname", this.hostname); jsonObj.Add("project_null_error", this.project_null_error); // get the source as json jsonObj.Add("source", BuildSourceJson()); return(jsonObj.ToString()); }