This is one in a series of articles about Time Tortoise, a Universal Windows Platform app for planning and tracking your work schedule. For more on the development of this app and the ideas behind it, see my Time Tortoise category page.
This week’s task: an initial implementation of the Daily Summary File.
The DailySummary class is responsible for generating and writing the contents of the daily summary text file. It needs to know these things:
- How often the file should be written.
- How to retrieve the raw data that will be formatted in the file.
- How to write a text file to disk.
This week’s code updates support those requirements.
Here’s the high-level design:
MainViewModel contains an instance of
DailySummary, and exposes a
WriteDailySummary method. Other parts of the system call that method when they want to update the daily summary file.
The DailySummary class itself is part of the ViewModel project. It depends on Repository, which is part of Model. Think of the daily summary text file as a type of view, with the DailySummary class as the supporting view model.
Repository and IRepository
The Time Tortoise GUI shows a list of time segments for a selected activity, optionally filtered to a date range. For the daily summary, we want time segments filtered to the current day, but we want them for all activities, not just one. Rather than iterate through all activities, it’s more efficient to retrieve the required time segments in a single request. Entity Framework makes that easy. Here’s the Repository query:
return _context.TimeSegments. Where(t => t.StartTime >= startTime.Value && t.EndTime <= endTime.Value).ToList();
Settings, ISettings, and SettingsUtility
WriteDailySummary method uses a new setting,
DailySummaryUpdateIntervalSeconds, to determine how often to update the summary file. If fewer seconds than specified have elapsed since the last update, then a call to
WriteDailySummary has no effect.
With the Time Tortoise settings infrastructure, the following steps are used to add a new setting:
- Add an accessor with the appropriate name to the
ISettingsinterface and the
- Set a default value for the setting in the
- Add a section to
settings.txtwith the new setting name, its value, and a comment explaining the purpose of the setting.
I also made a change to
SettingsUtility this week: the settings path is exposed as a public property, to make it easy for other classes (like DailySummary) to write files to the same location.
As explained in Time Tortoise: Timers, the view must own the main timer event in a UWP solution. To ensure that the daily summary file is updated periodically while the timer is running, the MainPage view calls
Main.WriteDailySummary on each timer tick. But the file doesn’t actually get written on each tick, since
WriteDailySummary checks the update interval setting first. It only gets updated as often as that setting specifies.
In addition to writing the file periodically while the timer is running, I also want to write it when the user starts and stops the timer. And there are other times (e.g., when the user edits a time segment) where it also makes sense to write the file. It’s easy enough to add more calls to
WriteDailySummary to cover those cases.
Writing Text Files
Once all of the source data is available, the DailySummary class can write the file to disk. As explained in Time Tortoise: Reading and Writing Text Files in UWP Apps, UWP has some rules about file I/O and similar operations. However, it turns out that those rules aren’t enforced when a UWP app calls a method in a .NET Standard library from a UWP view. In that scenario, the
File.WriteAllText method works as you would expect. So after building the summary file in memory (in a
StringBuilder), I write it to disk by calling
File.WriteAllText with the full path and the string representation of the file contents.
(Image credit: Kim Alaniz)