예제 #1
0
        public void SetDailyActivity(DailyActivity newDailyActivity, DateTime now)
        {
            lock (this)
            {
                DailyActivity oldActivity = this.dailyActivity;

                if (oldActivity.CurrentActivityRegion != null)
                {
                    Application.Current.Dispatcher.InvokeAsync(() =>
                    {
                        oldActivity.Update(now);
                    });

                    newDailyActivity.SetCurrentActivity(this.dailyActivity.CurrentActivityRegion.ActivityId, now);
                }

                this.dailyActivity = newDailyActivity;
            }
        }
예제 #2
0
        private void InitializeTodaysActivity()
        {
            var path = GetPathForDate(DateTime.Now);

            if (File.Exists(path))
            {
                try
                {
                    this.TodaysActivity = DailyActivity.Deserialize(path);
                }
                catch (Exception)
                {
                }
            }

            if (this.TodaysActivity == null)
            {
                this.TodaysActivity = new DailyActivity();
            }
        }
예제 #3
0
        public ActivityTracker(Configuration configuration, DailyActivity dailyActivity)
        {
            this.dailyActivity = dailyActivity;

            this.winEventDelegate = new WinEventDelegate(WinEventProc);
            this.winEventHook     = NativeMethods.SetWinEventHook(NativeMethods.EVENT_SYSTEM_FOREGROUND, NativeMethods.EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, this.winEventDelegate, 0, 0, NativeMethods.WINEVENT_OUTOFCONTEXT);

            this.Watchers = new Dictionary <BaseWatcher, WatcherVM>();

            var lockScreenWatcher = new LockScreenWatcher("Lock Screen", ActivityId.Away);

            lockScreenWatcher.PropertyChanged += (object obj, PropertyChangedEventArgs args) => { this.Watchers[(BaseWatcher)obj].Active = ((LockScreenWatcher)obj).CurrentState == LockScreenWatcher.State.Active; };
            this.Watchers.Add(lockScreenWatcher, new WatcherVM(lockScreenWatcher));

            var inputWatcher = new InputWatcher("Idle", ActivityManager.GetActivityFromName("Idle"), 60, 1000);

            inputWatcher.PropertyChanged += (object obj, PropertyChangedEventArgs args) => { this.Watchers[(BaseWatcher)obj].Active = ((InputWatcher)obj).CurrentState == InputWatcher.State.Inactive; };
            this.Watchers.Add(inputWatcher, new WatcherVM(inputWatcher));

            foreach (var watcherConfig in configuration.ProcessFocusWatchers)
            {
                var watcher = new ProcessFocusWatcher(watcherConfig.DisplayName, ActivityManager.GetActivityFromName(watcherConfig.ActivityName), watcherConfig.ProcessName);
                watcher.PropertyChanged += (object obj, PropertyChangedEventArgs args) => { this.Watchers[(BaseWatcher)obj].Active = ((ProcessFocusWatcher)obj).CurrentState == ProcessFocusWatcher.State.Active; };
                this.Watchers.Add(watcher, new WatcherVM(watcher));
            }

            foreach (var watcherConfig in configuration.ProcessActivityWatchers)
            {
                var watcher = new ProcessActivityWatcher(watcherConfig.DisplayName, ActivityManager.GetActivityFromName(watcherConfig.ActivityName), watcherConfig.ProcessName, watcherConfig.CPUUsageThresholdForRunning, watcherConfig.DelayBeforeReturnToInactiveInSeconds, watcherConfig.UpdatePeriodInSeconds);
                watcher.PropertyChanged += (object obj, PropertyChangedEventArgs args) => { this.Watchers[(BaseWatcher)obj].Active = ((ProcessActivityWatcher)obj).CurrentState == ProcessActivityWatcher.State.Running; };
                this.Watchers.Add(watcher, new WatcherVM(watcher));
            }

            foreach (var watcher in this.Watchers)
            {
                watcher.Value.PropertyChanged += watcher_PropertyChanged;
            }

            // Force update the current activity
            watcher_PropertyChanged(null, null);
        }
예제 #4
0
        private void Save(DailyActivity dailyActivity)
        {
            var path = GetPathForDate(dailyActivity.StartTime.Date);

            try
            {
                dailyActivity.Serialize(path);
            }
            catch (InvalidOperationException e)
            {
                // Ignore these, as we will just try to save again in a minute or so
                // TODO: if we detect multiple failures in a row, message the user?
                if (!(e.InnerException is IOException))
                {
                    throw e;
                }
            }
            catch (IOException)
            {
                // Ignore these, as we will just try to save again in a minute or so
                // TODO: if we detect multiple failures in a row, message the user?
            }
        }
예제 #5
0
        private void SetDateRange(DateTime start, DateTime end)
        {
            start = start.Date;
            end   = end.Date.AddDays(1).AddTicks(-1);
            var now = DateTime.Now;

            if (end.Date > now.Date)
            {
                end = now.Date.AddDays(1).AddTicks(-1);
            }

            if (start > end)
            {
                start = end;
            }


            if (this.StartTime == start && this.EndTime == end)
            {
                return;
            }

            this.StartTime = start.Date;
            this.EndTime   = end.Date.AddDays(1).AddTicks(-1);

            List <DailyActivity> dailyActivities = new List <DailyActivity>();

            // Don't include today in the list of things to load because we already have it loaded
            var endDate = this.EndTime;

            if (endDate.Date == now.Date)
            {
                endDate = endDate.AddDays(-1);
            }
            for (var currentDate = this.StartTime.Date; currentDate <= endDate; currentDate = currentDate.AddDays(1))
            {
                var path = GetPathForDate(currentDate);
                if (File.Exists(path))
                {
                    try
                    {
                        dailyActivities.Add(DailyActivity.Deserialize(path));
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            // Add today's data if needed
            if (this.EndTime.Date == now.Date)
            {
                dailyActivities.Add(this.TodaysActivity);
            }

            this.aggragateDailyActivity.SetDailyActivities(dailyActivities);

            this.Dispatcher.Invoke(() =>
            {
                UpdateLayout();
                AutoFitTimeline();
            });
        }
예제 #6
0
        public MainWindow()
        {
            /*
             * this.configuration = new Configuration();
             *
             * // Focus based watchers
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Surfing", Color = Colors.Cyan });
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "RemoteDesktop", Color = Colors.Green });
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Email", Color = Colors.Blue });
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Chat", Color = Colors.Beige });
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Programming", Color = Colors.Yellow });
             *
             * // Idle
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Idle", Color = Colors.Pink });
             *
             * // Activity based watchers
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Loading", Color = Colors.Orange });
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Linking", Color = Colors.Aquamarine });
             * this.configuration.Activities.Add(new Configuration.ActivityConfig() { Name = "Compiling", Color = Colors.Purple });
             *
             * this.configuration.ProcessFocusWatchers.Add(new Configuration.ProcessFocusWatcherConfig("Outlook", "Email", "outlook", 0.5));
             * this.configuration.ProcessFocusWatchers.Add(new Configuration.ProcessFocusWatcherConfig("Skype", "Chat", "lync", 0.5));
             * this.configuration.ProcessFocusWatchers.Add(new Configuration.ProcessFocusWatcherConfig("Remote Desktop", "RemoteDesktop", "mstsc", 0.5));
             * this.configuration.ProcessFocusWatchers.Add(new Configuration.ProcessFocusWatcherConfig("Internet Explorer", "Surfing", "iexplore", 0.5));
             * this.configuration.ProcessFocusWatchers.Add(new Configuration.ProcessFocusWatcherConfig("Chrome", "Surfing", "chrome", 0.5));
             * this.configuration.ProcessFocusWatchers.Add(new Configuration.ProcessFocusWatcherConfig("Visual Studio", "Programming", "devenv", 0.5));
             *
             * this.configuration.ProcessActivityWatchers.Add(new Configuration.ProcessActivityWatcherConfig("Compiler", "Compiling", "cl", 0.02, 0, 0.5));
             * this.configuration.ProcessActivityWatchers.Add(new Configuration.ProcessActivityWatcherConfig("Linker", "Linking", "link", 0.02, 0, 0.5));
             *
             * var jsonConfiguration = JsonConvert.SerializeObject(this.configuration, Formatting.Indented);
             * File.WriteAllText(@"E:\defaultConfiguration.json", jsonConfiguration);
             */

            var configurationPath = Path.Combine(GetAppDataPath(), "configuration.json");

            if (!File.Exists(configurationPath))
            {
                var defaultConfigurationpath = "defaultConfiguration.json";
                File.Copy(defaultConfigurationpath, configurationPath);
            }

            this.configuration = JsonConvert.DeserializeObject <Configuration>(File.ReadAllText(configurationPath));

            ActivityManager.Initialize(this.configuration);

            InitializeTodaysActivity();
            this.ActivityTracker = new ActivityTracker(this.configuration, this.TodaysActivity);

            var startDate = DateTime.Now.Date;

            SetDateRange(startDate, startDate.AddDays(1).AddTicks(-1));

            this.DataContext      = this;
            this.SelectedActivity = new DailyActivityVM(this.aggragateDailyActivity);

            InitializeComponent();

            // Queue up an extra auto fit once we have rendered once
            this.Dispatcher.BeginInvoke(new Action(() => { AutoFitTimeline(); }), DispatcherPriority.Render, null);

            this.updateTask = Task.Run(async() =>
            {
                while (!this.cancellationTokenSource.Token.IsCancellationRequested)
                {
                    lock (this)
                    {
                        DateTime now = DateTime.Now;

                        if (now.Date != this.TodaysActivity.StartTime.Date)
                        {
                            bool updateDateRangeStart = this.StartTime.Date == this.TodaysActivity.StartTime.Date;
                            bool updateDateRangeEnd   = this.EndTime.Date == this.TodaysActivity.EndTime.Date;

                            // Get the end of the day time
                            var currentDaysActivity = this.TodaysActivity;
                            var endOfDay            = this.TodaysActivity.StartTime.Date.AddDays(1);

                            // Create a new days activity, setting it should update the current activity to the end of the day.
                            this.TodaysActivity = new DailyActivity(endOfDay);
                            this.ActivityTracker.SetDailyActivity(this.TodaysActivity, endOfDay);
                            Save(currentDaysActivity);
                            this.ActivityTracker.Update(now);

                            if (updateDateRangeStart || updateDateRangeEnd)
                            {
                                // Current range includes today, so increment
                                var newStart = updateDateRangeStart ? this.StartTime.Date.AddDays(1) : this.StartTime;
                                var newEnd   = updateDateRangeEnd ? this.EndTime.Date.AddDays(1) : this.EndTime;
                                SetDateRange(newStart, newEnd);
                            }
                        }
                        else
                        {
                            this.ActivityTracker.Update(now);
                        }
                    }

                    try
                    {
                        await Task.Delay(200, this.cancellationTokenSource.Token);
                    }
                    catch (TaskCanceledException)
                    {
                    }
                }
            }, this.cancellationTokenSource.Token);

            this.saveTask = Task.Run(async() =>
            {
                while (!this.cancellationTokenSource.Token.IsCancellationRequested)
                {
                    lock (this)
                    {
                        Save(this.TodaysActivity);
                    }

                    try
                    {
                        await Task.Delay(60 * 1000, this.cancellationTokenSource.Token);
                    }
                    catch (TaskCanceledException)
                    {
                    }
                }
            }, this.cancellationTokenSource.Token);
        }