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; } }
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(); } }
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); }
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? } }
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(); }); }
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); }