Skip to content

Commit 85cf314

Browse files
authored
Merge pull request #33 from Adam-Color/Develop
merge for 1.8.3
2 parents a16d822 + fd6094e commit 85cf314

17 files changed

Lines changed: 76 additions & 187 deletions

README.md

Lines changed: 2 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
![version](https://img.shields.io/badge/Version-1.8.2-white.svg)
1+
![version](https://img.shields.io/badge/Version-1.8.3-white.svg)
22
![license](https://img.shields.io/badge/License-GPL%20v3-blue.svg)
33
![python](https://img.shields.io/badge/Python-3.13-green.svg)
44

@@ -19,7 +19,7 @@ To install, follow the instructions for your platform found here:
1919

2020
* Add integrations with professional applications
2121
* Detach the GIL for windows version
22-
* Add a better way to filter out non-GUI apps on macOS
22+
* Find a better way to filter out non-GUI apps
2323
* Full linux support with packages
2424

2525
NOTE: GIL is detached for the macOS build; use Python 3.13.7t
@@ -52,71 +52,6 @@ AppUsageGUI is a cross-platform desktop application built with Python and Tkinte
5252

5353
The application follows a Model-View-Controller (MVC) architecture with separate logic and GUI components.
5454

55-
## Project and Session Structure
56-
57-
AppUsageGUI organizes your time tracking data using a hierarchical project-based structure. This allows you to group related sessions together and manage your time tracking more effectively.
58-
59-
### Data Organization
60-
61-
```
62-
AppUsageGUI/
63-
├── Sessions/ # Standalone sessions (No Project)
64-
│ ├── session1.dat
65-
│ ├── session1.hash
66-
│ ├── session2.dat
67-
│ └── session2.hash
68-
├── Projects/ # Project-organized sessions
69-
│ ├── Web Development/ # Custom project
70-
│ │ ├── frontend_work.dat
71-
│ │ ├── frontend_work.hash
72-
│ │ ├── backend_api.dat
73-
│ │ └── backend_api.hash
74-
│ ├── Design Projects/ # Another custom project
75-
│ │ ├── logo_design.dat
76-
│ │ ├── logo_design.hash
77-
│ │ └── ui_mockup.dat
78-
│ └── projects_metadata.json # Project information and metadata
79-
└── User/
80-
├── config.dat # User configuration
81-
└── apps.dat # Tracked applications list
82-
```
83-
84-
### Project Structure Diagram
85-
86-
```mermaid
87-
graph TD
88-
A[AppUsageGUI Application] --> B[Sessions Directory]
89-
A --> C[Projects Directory]
90-
91-
B --> B1[Session 1]
92-
B --> B2[Session 2]
93-
B --> B3[Session N...]
94-
95-
C --> D[Web Development]
96-
C --> E[Design Projects]
97-
C --> F[Other Projects...]
98-
99-
D --> D1[Frontend Work]
100-
D --> D2[Backend API]
101-
D --> D3[Database Design]
102-
103-
E --> E1[Logo Design]
104-
E --> E2[UI Mockup]
105-
E --> E3[Brand Guidelines]
106-
107-
B1 --> B1A[session1.dat]
108-
B1 --> B1B[session1.hash]
109-
110-
D1 --> D1A[frontend_work.dat]
111-
D1 --> D1B[frontend_work.hash]
112-
113-
style A fill:#e1f5fe
114-
style B fill:#fff3e0
115-
style C fill:#f3e5f5
116-
style D fill:#e8f5e8
117-
style E fill:#fce4ec
118-
```
119-
12055
### Key Concepts
12156

12257
- **Projects**: Top-level containers that group related sessions together, stored in the `Projects/` directory
@@ -126,23 +61,6 @@ graph TD
12661
- **Session Files**: Each session consists of a `.dat` file (data) and `.hash` file (integrity check)
12762
- **Metadata**: Project information is stored in `projects_metadata.json` including creation dates and session counts
12863

129-
### Session Data Structure
130-
131-
Each session file contains comprehensive tracking information:
132-
133-
```python
134-
{
135-
'app_name': 'Visual Studio Code', # Application being tracked
136-
'time_spent': 7200.5, # Total time in seconds
137-
'session_version': '2.0.0', # App version when created
138-
'config': {...}, # Tracking configuration
139-
'time_captures': [...], # Detailed time capture data
140-
'project_name': 'Web Development', # Project this session belongs to
141-
'created_date': '2024-01-15T10:30:00', # When session was created
142-
'last_modified': '2024-01-15T12:30:00' # Last modification time
143-
}
144-
```
145-
14664
## Features
14765

14866
- **Project Management**: Organize sessions into projects for organization and management
@@ -177,57 +95,3 @@ The application now uses a streamlined workflow where users select their project
17795
### Continuing Existing Sessions
17896
- **Main Menu** → "Continue previous session" → Navigate through projects to find and resume sessions
17997
- Sessions can be continued across application restarts with full state preservation
180-
181-
## Code Structure
182-
183-
### Core Application Files
184-
185-
- **`src/main.py`** - Application entry point that initializes the Tkinter root window, applies dark mode theming, sets up the application icon, and launches the splash screen
186-
- **`src/_version.py`** - Contains the application version number
187-
- **`src/_path.py`** - Handles resource path resolution for bundled applications
188-
189-
### Core Logic (`src/core/`)
190-
191-
#### Main Controllers
192-
- **`gui_root.py`** - Main GUI controller that manages the application's window system, initializes all screens, and handles navigation between different windows
193-
- **`logic_root.py`** - Central logic controller that coordinates all tracking components (AppTracker, TimeTracker, FileHandler, ProjectHandler, MouseTracker)
194-
195-
#### Logic Components (`src/core/logic/`)
196-
- **`app_tracker.py`** - Monitors running processes using psutil, filters GUI applications from background processes, and maintains lists of available applications for tracking
197-
- **`time_tracker.py`** - Implements precise time tracking with pause/resume functionality, runs in a separate thread for accuracy, and captures timing data for analysis
198-
- **`file_handler.py`** - Manages session data persistence, handles file I/O operations with pickle serialization, and implements data integrity checking using hash verification
199-
- **`project_handler.py`** - Manages project creation, deletion, and organization, handles project metadata and session counts
200-
- **`user_trackers.py`** - Contains additional tracking modules like MouseTracker for user activity monitoring and ResolveProjectTracker for specific application integration
201-
202-
#### User Interface (`src/core/screens/`)
203-
- **`main_window.py`** - Main menu screen providing options to start new sessions, manage projects, continue previous sessions, or configure settings
204-
- **`projects_window.py`** - Project management interface for viewing, creating, and deleting projects with session counts and total time
205-
- **`create_project_window.py`** - Project creation dialog with name validation and project setup
206-
- **`project_sessions_window.py`** - Project-specific session management interface for viewing and managing sessions within a project
207-
- **`create_session_window.py`** - Session creation dialog with project selection, name validation, and session setup
208-
- **`select_app_window.py`** - Application selection interface with search functionality and real-time app list updates
209-
- **`tracker_window.py`** - Active tracking display showing elapsed time, pause/resume controls, and stop functionality
210-
- **`sessions_window.py`** - Global session management interface for loading, analyzing, and deleting saved sessions across all projects
211-
- **`save_window.py`** - Session saving interface with data confirmation
212-
- **`session_total_window.py`** - Session summary display showing total tracked time and statistics
213-
- **`tracker_settings_window.py`** - Configuration interface for custom tracking rules and application filtering
214-
- **`splash_screen.py`** - Application startup splash screen with loading animation
215-
216-
#### Utilities (`src/core/utils/`)
217-
- **`file_utils.py`** - File system operations, directory management, session file handling, project directory management, and data integrity functions
218-
- **`time_utils.py`** - Time formatting utilities for displaying elapsed time in human-readable format
219-
- **`logic_utils.py`** - Threading utilities and decorators for running functions in separate threads
220-
- **`tk_utils.py`** - Tkinter-specific utilities including window centering and dark mode detection
221-
222-
### Resources (`src/core/resources/`)
223-
- **`icon.ico`** / **`icon.icns`** - Application icons for Windows and macOS respectively
224-
- **`icon-resources/`** - Source files for application icons
225-
226-
### Development and Build Files
227-
- **`setup.py`** - Python package configuration and installation setup
228-
- **`build.py`** - Build script for creating distributable packages
229-
- **`requirements.txt`** - Python dependencies list
230-
- **`pytest.ini`** - Testing configuration
231-
- **`tests/`** - Unit tests for application components including project management and session creation workflows
232-
233-

dev/macos_installer.sh

100644100755
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/bin/bash
22
# This script is used to create the installer for the macOS version of the application
3-
app_version='1.8.2'
3+
app_version='1.8.3'
44

5-
mv dist/AppUsageGUI.app dist/AppUsageGUI/
5+
plutil -replace CFBundleShortVersionString -string ${app_version} ../dist/AppUsageGUI.app/Contents/Info.plist
66

7-
create-dmg --volicon src/core/resources/icon.icns --volname AppUsageGUIsetup --window-pos 200 190 --window-size 800 400 --app-drop-link 600 185 --eula LICENSE.txt dist/AppUsageGUI_v${app_version}_macOS_arm64_setup.dmg dist/
7+
mv ../dist/AppUsageGUI.app ../dist/AppUsageGUI/
8+
9+
create-dmg --volicon ../src/core/resources/icon.icns --volname AppUsageGUIsetup --window-pos 200 190 --window-size 800 400 --app-drop-link 600 185 --eula ../LICENSE.txt ../dist/AppUsageGUI_v${app_version}_macOS_arm64_setup.dmg ../dist/

dev/windows_installer.iss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
33

44
#define MyAppName "AppUsageGUI"
5-
#define MyAppVersion "1.8.2"
5+
#define MyAppVersion "1.8.3"
66
#define MyAppPublisher "Adam Blair-Smith"
77
#define MyAppURL "https://github.com/Adam-Color/AppUsageGUI"
88
#define MyAppExeName "AppUsageGUI.exe"
9-
#define MyInstallerName "AppUsageGUI_v1.8.2_WINDOWS_setup"
9+
#define MyInstallerName "AppUsageGUI_v1.8.3_WINDOWS_setup"
1010

1111
[Setup]
1212
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.

docs/install_macos.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ Note: only arm-based systems are currently supported.
99
* if asked to replace another folder, agree to do so
1010

1111
## Running on macOS:
12-
>[!warning]
13-
>Due to Apple's restrictions when it comes to open source applications such as ours, workarounds are needed to get AppUsageGUI to run on macOS.
1412

1513
If you encounter the error message saying the app was not opened or was damaged, click "done" or "cancel", then enter this in your terminal:
1614
```shell
1715
xattr -dr com.apple.quarantine /Applications/AppUsageGUI/AppUsageGUI.app
1816
```
19-
If you mistakingly hit 'move to trash' or 'delete', repeat installation steps.
17+
If you mistakingly hit "move to trash" or "delete", repeat installation steps.
2018

2119
If you continue to get error messsages, go into your security settings and allow AppUsageGUI to run on your device

src/_logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def setup_logging():
3939
root_logger.addHandler(rotating_handler)
4040
root_logger.addHandler(console_handler)
4141

42-
cleanup_old_logs(logs_dir, backup_count=5)
42+
cleanup_old_logs(logs_dir, backup_count=20)
4343

4444
# quiet some libraries
4545
logging.getLogger("urllib3").setLevel(logging.WARNING)

src/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.8.2"
1+
__version__ = "1.8.3"

src/core/gui_root.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from _version import __version__ as version
99
from _path import resource_path
1010
from _logging import get_current_log_file
11-
from core.utils.tk_utils import center_relative_to_parent, center
11+
from core.utils.tk_utils import center_relative_to_parent
1212
from core.utils.app_utils import new_updates, update
1313

1414
from .screens.main_window import MainWindow
@@ -71,17 +71,15 @@ def __init__(self, parent):
7171
self.selected_project = None
7272
self.init_screens()
7373
self.show_frame("MainWindow")
74-
75-
center(self.parent, -13, -15)
76-
74+
7775
self.parent.protocol("WM_DELETE_WINDOW", self.on_close)
7876

7977
def setup_options(self):
8078
"""Configure Options (About, License, etc.). Uses a Tk Menu for cross-platform behaviour.
8179
On macOS we also register the platform hooks so items appear in the native App menu."""
8280

8381
if self.parent.tk.call("tk", "windowingsystem") == "aqua":
84-
self.parent.createcommand("tk::mac::ShowAbout", self.show_about)
82+
self.parent.createcommand("tk::mac::standardAboutPanel", self.show_about)
8583
self.parent.createcommand("tk::mac::ShowPreferences", self.show_license)
8684
self.parent.createcommand("tk::mac::Quit", self.on_close)
8785
menubar = tk.Menu(self.parent)
@@ -107,7 +105,7 @@ def fallback_buttons():
107105
# Map standard mac menu actions to our callbacks
108106
# "tk::mac::ShowAbout" -> About
109107
# "tk::mac::ShowPreferences" -> Preferences (we map to License here)
110-
self.parent.createcommand("tk::mac::ShowAbout", self.show_about)
108+
self.parent.createcommand("tk::mac::standardAboutPanel", self.show_about)
111109
self.parent.createcommand("tk::mac::ShowPreferences", self.show_license)
112110
except Exception:
113111
# If anything goes wrong, fall back to having the menu (it's already set above)
@@ -195,7 +193,7 @@ def update_and_check(self, _=None):
195193
messagebox.showinfo("Update", "No new updates available.")
196194

197195
def show_logs(self, _=None):
198-
"""Display live-updating logs in a scrollable window with fixed footer buttons."""
196+
"""Display logs in a scrollable window with fixed footer buttons."""
199197
# Prevent duplicate windows
200198
if hasattr(self, "log_window") and self.log_window and self.log_window.winfo_exists():
201199
self.log_window.lift()
@@ -426,4 +424,4 @@ def on_close(self):
426424
self.logic.mouse_tracker.stop()
427425

428426
# Destroy the root window
429-
self.parent.destroy()
427+
self.parent.destroy()

src/core/logic/app_tracker.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
App Tracking logic class. Used for app tracking, filtering, and listing.
3+
"""
4+
15
import threading
26
import os
37
import psutil # type: ignore
@@ -64,7 +68,7 @@ def _fetch_app_names(self):
6468
apps.append(app_name)
6569
seen_names.append(app_name)
6670
if app_name == self.selected_app:
67-
#print(f"Selected app found: {app_name}") # Debugging line
71+
logger.debug(f"Seleced App found: {app_name}")
6872
break
6973
#print(app_name) # Debugging line to help optimize
7074
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
@@ -176,9 +180,9 @@ def _has_gui(self, process_id):
176180
for app in apps:
177181
if app.processIdentifier() == process_id:
178182
return True
179-
if app.processIdentifier() is None:
180-
# Handle the case where the process is not found
181-
return True
183+
elif app.processIdentifier() is None:
184+
# Handle the case where the process is not found
185+
return True
182186
return False
183187
except Exception as e:
184188
logger.error(f"GUI check error: {e}")

src/core/logic/file_handler.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(self, parent, logic_controller):
3232
self.continuing_session = False
3333
self.continuing_tracker = False
3434
self.corrupt_sessions = []
35+
self.session_names = []
3536

3637
def save_session_data(self, data):
3738
"""Special function to save and hash session data"""
@@ -100,6 +101,7 @@ def load_session_data(self, filename, project_name=None):
100101
self.current_project = saved_project # Set to saved project
101102
else:
102103
self.current_project = None # No project
104+
self.session_names.append(self.file_name)
103105
else:
104106
self.corrupt_sessions.append((filename, "Hash mismatch"))
105107
self.data = None
@@ -144,6 +146,9 @@ def set_file_name(self, file_name):
144146
def get_file_name(self):
145147
return self.file_name
146148

149+
def get_session_names(self):
150+
return self.session_names
151+
147152
def set_continuing_session(self, continuation=bool):
148153
self.continuing_session = continuation
149154
if continuation:
@@ -245,4 +250,4 @@ def move_session_to_project(self, session_name, current_project, target_project)
245250

246251
except Exception as e:
247252
logger.error(f"Error moving session {session_name}: {e}")
248-
return False
253+
return False

src/core/logic/user_trackers.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,3 @@ def is_pausing(self):
8888
def is_enabled(self):
8989
return self.enabled
9090

91-
class ResolveProjectTracker:
92-
"""Tracks if the user is in a specified DaVinci Resolve project or not"""
93-
def __init__(self, parent, logic_controller):
94-
self.parent = parent
95-
self.logic = logic_controller
96-
self.paused = False
97-
self.project_name = None
98-
self.project_open = False
99-
self.stop_event = threading.Event() # Used to stop the thread gracefully
100-
try:
101-
self.enabled = read_file(config_file())["resolve_tracker_enabled"]
102-
except FileNotFoundError or KeyError: #! KeyError for dev
103-
self.enabled = False # Default value
104-
self.update_thread = threading.Thread(target=self._update_project_status)

0 commit comments

Comments
 (0)