Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 41 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,75 @@ As a programmer, I often found myself getting so engrossed in coding that I woul

## Installation

### Option 1 (Recommended): Install via APT (Ubuntu/Debian/Mint)
### Option 1: Install via Pip (Universal Linux)

1. **Add the Repository Key:**
This method works on any Linux distribution (Arch, Fedora, Debian, etc.).

1. **Install System Dependencies:**
You will need `dbus` and `python3` installed.
* **Debian/Ubuntu:** `sudo apt install dbus python3-pip libdbus-1-dev libglib2.0-dev`
* **Fedora:** `sudo dnf install dbus python3-pip dbus-devel glib2-devel`
* **Arch:** `sudo pacman -S dbus python-pip`

2. **Clone and Install:**
```bash
git clone https://github.com/prathampt/programmingHabits
cd programmingHabits
pip install .
```

3. **Run:**
```bash
programming-habits
```

### Option 2: Install via APT (Ubuntu/Debian/Mint)

1. **Make sure you have dependencies:**
```bash
sudo apt install dbus
```

2. **Add the Repository Key:**
```bash
curl -fsSL https://prathampt.github.io/programmingHabits/KEY.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/programminghabits.gpg
```

2. **Add the Repository:**
3. **Add the Repository:**
```bash
echo "deb [signed-by=/etc/apt/trusted.gpg.d/programminghabits.gpg] https://prathampt.github.io/programmingHabits/ /" | sudo tee /etc/apt/sources.list.d/programminghabits.list
```

3. **Install:**
4. **Install:**
```bash
sudo apt update
sudo apt install programminghabits
```

### Option 2: Build from Source
If you want to contribute or build it manually:
### Option 3: Build from Source (For Developers)

1. **Make sure you have dependencies:**
```bash
sudo apt install dbus
```

1. **Clone the Repository**:
2. **Clone the Repository**:
```bash
git clone https://github.com/prathampt/programmingHabits
cd programmingHabits
```

2. **Install Dependencies** (Using `uv` is recommended):
3. **Install Dependencies** (Using `uv` is recommended):
```bash
uv sync
```

3. **Run in Dev Mode**:
4. **Run in Dev Mode**:
```bash
uv run python -m programminghabits.main
```

4. **Compile to .deb**:
5. **Compile to .deb (Debian/Ubuntu only)**:
Run the included build script to generate a standalone Debian package using PyInstaller:
```bash
chmod +x build_deb.sh
Expand Down
6 changes: 4 additions & 2 deletions programminghabits/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sys
import os
os.environ["QT_QPA_PLATFORMTHEME"] = "gtk3"

from dbus.mainloop.glib import DBusGMainLoop
from PyQt6.QtWidgets import QApplication, QSystemTrayIcon, QMenu
Expand Down Expand Up @@ -106,6 +105,9 @@ def open_settings(self):
def run_logic(self):
sys.exit(self.app.exec())

if __name__ == "__main__":
def main():
controller = AppController()
controller.run_logic()

if __name__ == "__main__":
main()
89 changes: 48 additions & 41 deletions programminghabits/ui_overlay.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import random
import subprocess
import shutil
import dbus
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QFrame, QGraphicsDropShadowEffect
from PyQt6.QtCore import Qt, QTimer, QUrl
Expand Down Expand Up @@ -78,44 +79,45 @@ def get_system_accent_color(self):
Trying multiple approaches
Returns a Hex string.
"""
try:
# Try modern GNOME accent-color (Ubuntu 22.04+)
output = subprocess.check_output(
["gsettings", "get", "org.gnome.desktop.interface", "accent-color"],
stderr=subprocess.DEVNULL
).decode("utf-8").strip().strip("'")

colors = {
'green': '#26a269', # Ubuntu Yaru Green
'orange': '#e95420', # Ubuntu Classic
'blue': '#3584e4', # Adwaita
'teal': '#21a6cb',
'purple': '#9141ac',
'red': '#e01b24',
'yellow': '#f5c211',
'bark': '#787c72',
'pink': '#d56199',
'slate': '#5e5c64'
}
if output in colors:
return colors[output]

except Exception:
pass

# Fallback: Try to guess based on GTK Theme Name
try:
theme = subprocess.check_output(
["gsettings", "get", "org.gnome.desktop.interface", "gtk-theme"],
stderr=subprocess.DEVNULL
).decode("utf-8").strip().strip("'")

if "Yaru" in theme and "dark" not in theme and "blue" not in theme:
return "#e95420" # Standard Yaru is often Orange
if "Mint" in theme:
return "#92b752" # Mint Green
except Exception:
pass
if shutil.which("gsettings"):
try:
# Try modern GNOME accent-color (Ubuntu 22.04+)
output = subprocess.check_output(
["gsettings", "get", "org.gnome.desktop.interface", "accent-color"],
stderr=subprocess.DEVNULL
).decode("utf-8").strip().strip("'")

colors = {
'green': '#26a269', # Ubuntu Yaru Green
'orange': '#e95420', # Ubuntu Classic
'blue': '#3584e4', # Adwaita
'teal': '#21a6cb',
'purple': '#9141ac',
'red': '#e01b24',
'yellow': '#f5c211',
'bark': '#787c72',
'pink': '#d56199',
'slate': '#5e5c64'
}
if output in colors:
return colors[output]

except Exception:
pass

# Fallback: Try to guess based on GTK Theme Name
try:
theme = subprocess.check_output(
["gsettings", "get", "org.gnome.desktop.interface", "gtk-theme"],
stderr=subprocess.DEVNULL
).decode("utf-8").strip().strip("'")

if "Yaru" in theme and "dark" not in theme and "blue" not in theme:
return "#e95420" # Standard Yaru is often Orange
if "Mint" in theme:
return "#92b752" # Mint Green
except Exception:
pass

# Qt Highlight (System Theme Plugin)
qt_color = self.palette().color(QPalette.ColorRole.Highlight).name()
Expand All @@ -142,9 +144,14 @@ def play_sound(self):
self.effect.setSource(QUrl.fromLocalFile(self.sound_path))
self.effect.setVolume(0.5)
self.effect.play()
# Above method can fail
try: subprocess.Popen(["paplay", self.sound_path], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
except: pass
# Above method can fail, fallback to system players
try:
subprocess.Popen(["paplay", self.sound_path], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
except Exception:
try:
subprocess.Popen(["aplay", self.sound_path], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
except Exception:
pass

def format_time(self, s): return f"{divmod(s, 60)[0]:02d}:{divmod(s, 60)[1]:02d}"

Expand Down
10 changes: 10 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "programming-habits"
version = "1.0.0"
Expand All @@ -9,3 +13,9 @@ dependencies = [
"pyinstaller>=6.16.0",
"pyqt6>=6.10.0",
]

[project.scripts]
programming-habits = "programminghabits.main:main"

[tool.setuptools.package-data]
programminghabits = ["assets/*"]