コード例 #1
0
        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));
        }
コード例 #2
0
        public static bool IsNewDay()
        {
            NowTime nowTime    = SoftwareCoUtil.GetNowTime();
            string  currentDay = FileManager.getItemAsString("currentDay");

            return((!nowTime.day.Equals(currentDay)) ? true : false);
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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
            {
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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;
        }
コード例 #8
0
        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 = "";
        }
コード例 #9
0
        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;
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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;
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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(); });
            }
        }
コード例 #14
0
        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);
            }
        }
コード例 #15
0
        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;
            }
        }
コード例 #16
0
        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());
        }