public async Task <TimeData> GetTodayTimeDataSummary(PluginDataProject proj) { NowTime nowTime = SoftwareCoUtil.GetNowTime(); List <TimeData> list = GetTimeDataList(); if (proj == null || proj.directory == null || proj.directory.Equals("")) { proj = await PluginData.GetPluginProject(); } if (proj == null || proj.directory == null || proj.directory.Equals("")) { proj = new PluginDataProject("Unnamed", "Untitled"); } if (list != null && list.Count > 0) { foreach (TimeData td in list) { if (td.day.Equals(nowTime.local_day) && td.project.directory.Equals(proj.directory)) { return(td); } } } return(await GetNewTimeDataSummary(proj)); }
public static CommitChangeStats GetCommitsForRange(string rangeType, string projectDir, string email) { if (!SoftwareCoUtil.IsGitProject(projectDir)) { return(new CommitChangeStats()); } NowTime nowTime = SoftwareCoUtil.GetNowTime(); string sinceTime = nowTime.start_of_today.ToString("yyyy-MM-ddTHH:mm:sszzz"); string untilTime = null; if (rangeType == "yesterday") { sinceTime = nowTime.start_of_yesterday_dt.ToString("yyyy-MM-ddTHH:mm:sszzz"); untilTime = nowTime.start_of_today.ToString("yyyy-MM-ddTHH:mm:sszzz"); } else if (rangeType == "thisWeek") { sinceTime = nowTime.start_of_week_dt.ToString("yyyy-MM-ddTHH:mm:sszzz"); } string cmd = "git log --stat --pretty=\"COMMIT:% H,% ct,% cI,% s\" --since=\"" + sinceTime + "\""; if (untilTime != null) { cmd += " --until=\"" + untilTime + "\""; } if (email != null && !email.Equals("")) { cmd += " --author=" + email; } return(GetChangeStats(cmd, projectDir)); }
public static bool IsNewDay() { NowTime nowTime = SoftwareCoUtil.GetNowTime(); string currentDay = FileManager.getItemAsString("currentDay"); return((!nowTime.day.Equals(currentDay)) ? true : false); }
public static NowTime GetNowTime() { NowTime timeParam = new NowTime(); timeParam.day = DateTime.Now.ToString(@"yyyy-MM-dd"); DateTimeOffset offset = DateTimeOffset.Now; // utc now in seconds timeParam.now = offset.ToUnixTimeSeconds(); timeParam.now_dt = DateTime.Now; // set the offset (will be negative before utc and positive after) timeParam.offset_minutes = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes; timeParam.offset_seconds = timeParam.offset_minutes * 60; // local now in seconds timeParam.local_now = Convert.ToInt64(timeParam.now + timeParam.offset_seconds); timeParam.local_day = offset.ToLocalTime().ToString(@"yyyy-MM-dd"); // start and end of day timeParam.start_of_today = StartOfDay(); timeParam.local_start_of_day = Convert.ToInt64(((DateTimeOffset)timeParam.start_of_today).ToUnixTimeSeconds() + timeParam.offset_seconds); timeParam.local_end_of_day = Convert.ToInt64(EndOfDay() + timeParam.offset_seconds); timeParam.utc_end_of_day = EndOfDay(); // yesterday start timeParam.start_of_yesterday_dt = StartOfYesterday(); timeParam.local_start_of_yesterday = Convert.ToInt64(((DateTimeOffset)timeParam.start_of_yesterday_dt).ToUnixTimeSeconds() + timeParam.offset_seconds); // week start timeParam.start_of_week_dt = StartOfWeek(); timeParam.local_start_of_week = Convert.ToInt64(((DateTimeOffset)timeParam.start_of_week_dt).ToUnixTimeSeconds() + timeParam.offset_seconds); return(timeParam); }
public async Task <TimeData> GetNewTimeDataSummary(PluginDataProject project) { NowTime nowTime = SoftwareCoUtil.GetNowTime(); TimeData td = new TimeData(); td.day = nowTime.local_day; td.timestamp = nowTime.utc_end_of_day; td.timestamp_local = nowTime.local_end_of_day; td.project = project; return(td); }
public void SaveTimeDataSummaryToDisk(TimeData timeData) { // don't save it to disk if it's null or the project info is null or empty if (timeData == null || timeData.project == null || timeData.project.directory == null || timeData.project.directory.Equals("")) { return; } string MethodName = "saveTimeDataSummaryToDisk"; NowTime nowTime = SoftwareCoUtil.GetNowTime(); List <TimeData> list = GetTimeDataList(); string projDir = timeData.project.directory; if (list != null && list.Count > 0) { for (int i = list.Count - 1; i >= 0; i--) { TimeData td = list[i]; if (td.project.directory.Equals(timeData.project.directory) && td.day.Equals(timeData.day)) { list.RemoveAt(i); break; } } } list.Add(timeData); JsonArray jsonToSave = BuildJsonObjectFromList(list); string file = GetTimeDataFile(); File.SetAttributes(file, FileAttributes.Normal); try { string content = jsonToSave.ToString(); content = content.Replace("\r\n", string.Empty).Replace("\n", string.Empty).Replace("\r", string.Empty); File.WriteAllText(file, content, System.Text.Encoding.UTF8); } catch (Exception e) { // } finally { } }
public async Task UpdateSessionFromSummaryApiAsync(long currentDayMinutes) { NowTime nowTime = SoftwareCoUtil.GetNowTime(); CodeTimeSummary ctSummary = this.GetCodeTimeSummary(); long diff = ctSummary.activeCodeTimeMinutes < currentDayMinutes ? currentDayMinutes - ctSummary.activeCodeTimeMinutes : 0; PluginDataProject project = await PluginData.GetPluginProject(); TimeData td = null; if (project != null) { td = await GetTodayTimeDataSummary(project); } else { List <TimeData> list = GetTimeDataList(); if (list != null && list.Count > 0) { foreach (TimeData timeData in list) { if (timeData.day.Equals(nowTime.local_day)) { td = timeData; break; } } } } if (td == null) { project = new PluginDataProject("Unnamed", "Untitled"); td = new TimeData(); td.day = nowTime.local_day; td.timestamp_local = nowTime.local_now; td.timestamp = nowTime.now; td.project = project; } long secondsToAdd = diff * 60; td.session_seconds += secondsToAdd; td.editor_seconds += secondsToAdd; SaveTimeDataSummaryToDisk(td); }
public PluginDataFileInfo(string file) { NowTime nowTime = SoftwareCoUtil.GetNowTime(); this.file = file; this.start = nowTime.now; this.local_start = nowTime.local_now; this.add = 0; this.close = 0; this.linesAdded = 0; this.open = 0; this.keystrokes = 0; this.netkeys = 0; this.syntax = ""; this.length = 0; this.end = this.start + 60; this.local_end = this.local_start + 60; }
public PluginData(string projectName, string projectDirectory) { this.type = "Events"; this.pluginId = Constants.PluginId; NowTime nowTime = SoftwareCoUtil.GetNowTime(); start = nowTime.now; local_start = nowTime.local_now; offset = nowTime.offset_minutes; version = SoftwareCoPackage.GetVersion(); os = SoftwareCoPackage.GetOs(); source = new List <PluginDataFileInfo>(); project = GetPluginProjectUsingDir(projectDirectory); cumulative_editor_seconds = 0; elapsed_seconds = 0; cumulative_session_seconds = 0; project_null_error = ""; workspace_name = ""; hostname = ""; }
private void InitializeData() { NowTime nowTime = SoftwareCoUtil.GetNowTime(); this.timestamp = nowTime.now; this.timestamp_local = nowTime.local_now; this.pluginId = Constants.PluginId; this.os = SoftwareCoPackage.GetOs(); this.hostname = SoftwareCoUtil.getHostname(); this.version = SoftwareCoPackage.GetVersion(); if (TimeZone.CurrentTimeZone.DaylightName != null && TimeZone.CurrentTimeZone.DaylightName != TimeZone.CurrentTimeZone.StandardName) { this.timezone = TimeZone.CurrentTimeZone.DaylightName; } else { this.timezone = TimeZone.CurrentTimeZone.StandardName; } }
public CodeTimeSummary GetCodeTimeSummary() { CodeTimeSummary ctSummary = new CodeTimeSummary(); NowTime nowTime = SoftwareCoUtil.GetNowTime(); List <TimeData> list = GetTimeDataList(); if (list != null && list.Count > 0) { foreach (TimeData td in list) { if (td.day.Equals(nowTime.local_day)) { ctSummary.activeCodeTimeMinutes += (td.session_seconds / 60); ctSummary.codeTimeMinutes += (td.editor_seconds / 60); ctSummary.fileTimeMinutes += (td.file_seconds / 60); } } } return(ctSummary); }
public async void PostData() { NowTime nowTime = SoftwareCoUtil.GetNowTime(); DateTime now = DateTime.UtcNow; if (_pluginData != null && _pluginData.source.Count > 0 && _pluginData.keystrokes > 0) { // create the aggregates, end the file times, gather the cumulatives string softwareDataContent = await _pluginData.CompletePayloadAndReturnJsonString(); Logger.Info("Code Time: storing plugin data: " + softwareDataContent); FileManager.AppendPluginData(softwareDataContent); } // update the latestPayloadTimestampEndUtc FileManager.setNumericItem("latestPayloadTimestampEndUtc", nowTime.now); // update the status bar and tree WallclockManager.Instance.DispatchUpdateAsync(); _pluginData = null; }
public TimeGapData GetTimeBetweenLastPayload() { TimeGapData eTimeInfo = new TimeGapData(); long sessionSeconds = 60; long elapsedSeconds = 60; long lastPayloadEnd = FileManager.getItemAsLong("latestPayloadTimestampEndUtc"); if (lastPayloadEnd > 0) { NowTime nowTime = SoftwareCoUtil.GetNowTime(); elapsedSeconds = Math.Max(60, nowTime.now - lastPayloadEnd); long sessionThresholdSeconds = 60 * 15; if (elapsedSeconds > 0 && elapsedSeconds <= sessionThresholdSeconds) { sessionSeconds = elapsedSeconds; } sessionSeconds = Math.Max(60, sessionSeconds); } eTimeInfo.elapsed_seconds = elapsedSeconds; eTimeInfo.session_seconds = sessionSeconds; return(eTimeInfo); }
public async Task GetNewDayCheckerAsync() { if (SoftwareCoUtil.IsNewDay()) { SessionSummaryManager.Instance.ÇlearSessionSummaryData(); // send the offline data SoftwareCoPackage.SendOfflinePluginBatchData(); // clear the last payload in memory FileManager.ClearLastSavedKeystrokeStats(); // send the offline events EventManager.Instance.SendOfflineEvents(); // send the offline TimeData payloads // this will clear the time data summary as well TimeDataManager.Instance.SendTimeDataAsync(); // day does't match. clear the wall clock time, // the session summary, time data summary, // and the file change info summary data ClearWcTime(); // set the current day NowTime nowTime = SoftwareCoUtil.GetNowTime(); _currentDay = nowTime.day; // update the current day FileManager.setItem("currentDay", _currentDay); // update the last payload timestamp FileManager.setNumericItem("latestPayloadTimestampEndUtc", 0); // update the session summary global and averages for the new day Task.Delay(ONE_MINUTE).ContinueWith((task) => { WallclockManager.Instance.UpdateSessionSummaryFromServerAsync(); }); } }
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 SolutionEventOpenedAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (!PLUGIN_READY) { string solutionDir = await GetSolutionDirectory(); if (solutionDir == null || solutionDir.Equals("")) { Task.Delay(3000).ContinueWith((task) => { SolutionEventOpenedAsync(); }); return; } // init the doc event mgr and inject ObjDte docEventMgr = DocEventManager.Instance; DocEventManager.ObjDte = ObjDte; // init the session summary mgr sessionSummaryMgr = SessionSummaryManager.Instance; sessionSummaryMgr.InjectAsyncPackage(this); // init the event manager and inject this EventManager.Instance.InjectAsyncPackage(this); // update the latestPayloadTimestampEndUtc NowTime nowTime = SoftwareCoUtil.GetNowTime(); FileManager.setNumericItem("latestPayloadTimestampEndUtc", nowTime.now); // init the wallclock WallclockManager wallclockMgr = WallclockManager.Instance; wallclockMgr.InjectAsyncPackage(this, ObjDte); // setup event handlers _textDocKeyEvent.AfterKeyPress += docEventMgr.AfterKeyPressedAsync; _docEvents.DocumentOpened += docEventMgr.DocEventsOnDocumentOpenedAsync; _docEvents.DocumentClosing += docEventMgr.DocEventsOnDocumentClosedAsync; _docEvents.DocumentSaved += docEventMgr.DocEventsOnDocumentSaved; _docEvents.DocumentOpening += docEventMgr.DocEventsOnDocumentOpeningAsync; // init the code metrics tree mgr CodeMetricsTreeManager.Instance.InjectAsyncPackage(this); // initialize the menu commands await SoftwareLaunchCommand.InitializeAsync(this); await SoftwareDashboardLaunchCommand.InitializeAsync(this); await SoftwareTopFortyCommand.InitializeAsync(this); await SoftwareLoginCommand.InitializeAsync(this); await SoftwareToggleStatusInfoCommand.InitializeAsync(this); await SoftwareOpenCodeMetricsTreeCommand.InitializeAsync(this); if (_softwareRepoUtil == null) { _softwareRepoUtil = new SoftwareRepoManager(); } // Create an AutoResetEvent to signal the timeout threshold in the // timer callback has been reached. var autoEvent = new AutoResetEvent(false); offlineDataTimer = new System.Threading.Timer( SendOfflineData, null, ONE_MINUTE, ONE_MINUTE * 15); repoCommitsTimer = new System.Threading.Timer( ProcessRepoJobs, autoEvent, ONE_MINUTE * 5, ONE_MINUTE * 20); keystrokeTimer = new System.Threading.Timer( ProcessKeystrokePayload, autoEvent, ONE_MINUTE, ONE_MINUTE); // initialize the status bar before we fetch the summary data InitializeStatusBar(); // make sure the last payload is in memory FileManager.GetLastSavedKeystrokeStats(); // check if we've shown the readme or not bool initializedVisualStudioPlugin = FileManager.getItemAsBool("visualstudio_CtInit"); if (!initializedVisualStudioPlugin) { DashboardManager.Instance.LaunchReadmeFileAsync(); FileManager.setBoolItem("visualstudio_CtInit", true); // launch the tree view CodeMetricsTreeManager.Instance.OpenCodeMetricsPaneAsync(); } Task.Delay(3000).ContinueWith((task) => { EventManager.Instance.CreateCodeTimeEvent("resource", "load", "EditorActivate"); }); string PluginVersion = GetVersion(); Logger.Info(string.Format("Initialized Code Time v{0}", PluginVersion)); PLUGIN_READY = true; } }
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()); }
public void EndFileInfoTime(NowTime nowTime) { this.end = nowTime.now; this.local_end = nowTime.local_now; }