aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GEMINI.md71
-rw-r--r--Program.cs7
-rw-r--r--README.md7
-rw-r--r--src/WeeklyReport.cs120
4 files changed, 203 insertions, 2 deletions
diff --git a/GEMINI.md b/GEMINI.md
new file mode 100644
index 0000000..d7ea87e
--- /dev/null
+++ b/GEMINI.md
@@ -0,0 +1,71 @@
+# hypr-wellbeing
+
+## Project Overview
+
+`hypr-wellbeing` is a command-line tool for tracking application usage time on Linux, with a specific focus on the Hyprland and niri window managers. It helps users monitor their screen time and promote digital wellbeing by providing detailed statistics on application usage.
+
+## Features
+
+- **Time Tracking:** Monitors the active window and logs the time spent on each application.
+- **Daily Reports:** Displays a summary of daily application usage, including total screen time and a breakdown of time spent on each application.
+- **Data Storage:** Stores usage data in CSV files in the `~/.cache/hyprwatch/daily_data/` directory.
+- **Cross-Desktop Support (Limited):** While primarily designed for Hyprland and niri, it may work on other Wayland-based desktops.
+- **Analysis:** Includes logic for generating weekly reports and sorting data.
+
+## Technology Stack
+
+- **Language:** C#
+- **Framework:** .NET 8
+- **Platform:** Linux
+- **Compilation:** Published as a self-contained AOT (Ahead-Of-Time) compiled application.
+
+## File Structure
+
+```
+/home/swarn/dox/code/hypr-wellbeing/
+├───.gitignore
+├───hypr-wellbeing.csproj
+├───LICENSE
+├───Program.cs
+├───README.md
+├───.assets/
+│ └───show.png
+├───.git/...
+├───bin/
+│ ├───Debug/...
+│ └───Release/...
+├───obj/
+│ ├───Debug/...
+│ └───Release/...
+└───src/
+ ├───Analysis.cs
+ ├───GetWindows.cs
+ ├───GetWindowsv2.cs
+ ├───TimeOperations.cs
+ └───WatchLog.cs
+```
+
+## Usage
+
+### Monitor Mode
+
+To run the application in the background and monitor application usage, use the following command:
+
+```sh
+hypr-wellbeing -d &> /dev/null &
+```
+
+### Show Stats
+
+To display the statistics for the current day, use the following command:
+
+```sh
+hypr-wellbeing --show
+```
+
+## Future Improvements
+
+The following features are planned for future releases:
+
+- Weekly view of application usage
+- Monthly view of application usage
diff --git a/Program.cs b/Program.cs
index d57fe2c..8e4afd1 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,6 +1,7 @@
using System.IO;
using System.Runtime.InteropServices;
using hyprwatch.Logger;
+using hyprwatch.Report.Weekly;
class Program
{
@@ -11,7 +12,7 @@ class Program
string dailyDataDirectory = Path.Combine(hyprwatchDirectory, "daily_data");
Directory.CreateDirectory(dailyDataDirectory);
- if (args.Length == 0 || args[0] != "-d" && args[0] != "--show")
+ if (args.Length == 0 || args[0] != "-d" && args[0] != "--show" && args[0] != "--weekly")
{
Console.WriteLine("Usage: -d || --show");
return;
@@ -75,6 +76,10 @@ class Program
}
}
+ if(args[0] == "--weekly")
+ {
+ WeeklyReport.DisplayWeeklyReport();
+ }
}
}
diff --git a/README.md b/README.md
index a202332..31ef736 100644
--- a/README.md
+++ b/README.md
@@ -28,9 +28,14 @@ hypr-wellbeing -d &> /dev/null &
hypr-wellbeing --show
```
+### Show Weekly Stats
+
+```sh
+hypr-wellbeing --weekly
+```
+
## To-Do
-- [] Weekly view
- [] Monthly view
## Special Thanks
diff --git a/src/WeeklyReport.cs b/src/WeeklyReport.cs
new file mode 100644
index 0000000..9f81510
--- /dev/null
+++ b/src/WeeklyReport.cs
@@ -0,0 +1,120 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Globalization;
+using System.Collections.Generic;
+using hyprwatch.Time;
+
+namespace hyprwatch.Report.Weekly
+{
+ public class WeeklyReport
+ {
+ private static string FormatTime(string time)
+ {
+ var parts = time.Split(':');
+ if (parts.Length == 3)
+ {
+ int hr = int.Parse(parts[0]);
+ int mn = int.Parse(parts[1]);
+ int sec = int.Parse(parts[2]);
+ return $"{hr:D2}:{mn:D2}:{sec:D2}";
+ }
+ return "00:00:00"; // Should not happen with valid data
+ }
+
+ private static int ConvertToSeconds(string time)
+ {
+ var parts = time.Split(':');
+ if (parts.Length == 3)
+ {
+ int hr = int.Parse(parts[0]);
+ int mn = int.Parse(parts[1]);
+ int sec = int.Parse(parts[2]);
+ return hr * 3600 + mn * 60 + sec;
+ }
+ return 0;
+ }
+
+ private static string ConvertFromSeconds(int totalSeconds)
+ {
+ int hr = totalSeconds / 3600;
+ totalSeconds %= 3600;
+ int mn = totalSeconds / 60;
+ int sec = totalSeconds % 60;
+ return $"{hr:D2}:{mn:D2}:{sec:D2}";
+ }
+
+ public static Dictionary<string, int> GetWeeklyReport()
+ {
+ var allData = new Dictionary<string, int>();
+ string path = Environment.GetEnvironmentVariable("HOME") + "/.cache/hyprwatch/daily_data/";
+ var files = Directory.GetFiles(path, "*.csv");
+
+ DateTime today = DateTime.Today;
+ int daysUntilMonday = (int)today.DayOfWeek - (int)DayOfWeek.Monday;
+ if (daysUntilMonday < 0) daysUntilMonday += 7;
+ DateTime startOfWeek = today.AddDays(-daysUntilMonday);
+
+ foreach (var file in files)
+ {
+ string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
+ if (DateTime.TryParse(fileNameWithoutExtension, out DateTime fileDate))
+ {
+ if (fileDate >= startOfWeek && fileDate < startOfWeek.AddDays(7))
+ {
+ var report = new Dictionary<string, string>();
+ var rawData = File.ReadAllLines(file);
+ foreach (var line in rawData)
+ {
+ var splitData = line.Split('\t');
+ if (splitData.Length >= 2)
+ {
+ report[splitData[1].Trim()] = splitData[0];
+ }
+ }
+
+ foreach (var kvp in report)
+ {
+ if (!allData.ContainsKey(kvp.Key))
+ {
+ allData[kvp.Key] = 0;
+ }
+ allData[kvp.Key] += ConvertToSeconds(FormatTime(kvp.Value));
+ }
+ }
+ }
+ }
+
+ return allData;
+ }
+
+ public static void DisplayWeeklyReport()
+ {
+ string green = "\x1b[0;32m";
+ string yellow = "\x1b[1;33m";
+ string red = "\x1b[0;31m";
+ string blue = "\x1b[0;34m";
+ string reset = "\x1b[0m";
+
+ var weeklyData = GetWeeklyReport();
+
+ var sortedData = from entry in weeklyData orderby entry.Value descending select entry;
+
+ int totalSeconds = weeklyData.Values.Sum();
+ string totalTime = ConvertFromSeconds(totalSeconds);
+
+ Console.WriteLine(" ");
+ Console.WriteLine($"This Week's Screen Usage\t{totalTime}");
+ Console.WriteLine($"{red}{new string('-', 60)}{reset}");
+ Console.WriteLine($"{yellow}{"App".PadRight(30)}{"Time".PadLeft(30)}{reset}");
+ Console.WriteLine($"{red}{new string('-', 60)}{reset}");
+
+ foreach (var entry in sortedData)
+ {
+ string key = entry.Key.Length > 30 ? entry.Key.Substring(0, 27) + "..." : entry.Key;
+ string time = ConvertFromSeconds(entry.Value);
+ Console.WriteLine($"{blue}{key.PadRight(30)}{reset}{green}{time.PadLeft(30)}{reset}");
+ }
+ }
+ }
+}