Skip to content

Build Windows Activity Tracker with Python

    Build Windows Activity Tracker with Python Complete guide for windows 10/11

    Last Updated on: 22nd November 2025, 06:12 pm

    Introduction to Activity Tracking

    Activity tracking software represents a fascinating intersection of system programming, user interface analysis, and data analytics. The Windows Activity Tracker is a Python application that monitors and records virtually every aspect of user interaction with a Windows 10/11 computer system.

    This isn’t just a simple keylogger or basic activity monitor, it’s a sophisticated system that captures keyboard inputs, mouse interactions, window changes, file operations, and even clipboard activities with remarkable detail.

    For students learning programming, this script serves as an excellent case study in several important areas:

    • System-level programming with Windows APIs
    • Multi-threading and real-time data processing
    • Database management with SQLite
    • Object-oriented design patterns
    • Error handling in production-grade software
    • Data analysis and reporting generation

    The tracker operates by leveraging multiple Windows-specific APIs and libraries to capture low-level system events, then processes and stores this information in both human-readable and database formats for later analysis.

    Note: This article is for only general information and use this ethically.

    Complete Code: https://drive.google.com/file/d/1W8vlXYwohqh-Lk-_RtMRifndvbIsdxEa/view?usp=drive_link

    Import Analysis & Dependencies

    Let’s break down each import statement and understand its purpose in the application:

    import os
    import time
    import sqlite3
    import threading
    import psutil
    import ctypes
    from ctypes import wintypes
    from datetime import datetime
    from collections import defaultdict, deque
    from typing import Optional, Dict, Any, List, Tuple
    import shutil
    import tempfile
    import win32clipboard  # pip install pywin32
    import win32con
    import win32gui
    import win32process
    import re

    Core Python Imports

    import os – Provides operating system interface functionality. In this script, it’s used for:

    • Getting current working directory: os.getcwd()
    • File path operations: os.path.join(), os.path.basename(), os.path.dirname()
    • Environment variable access: os.environ.get()

    import time – Handles time-related operations including:

    • Adding delays: time.sleep(3)
    • Interval-based checking in loops
    • Timestamp calculations

    import sqlite3 – Database management for storing all tracked activities:

    • Creates and manages SQLite database connections
    • Executes SQL queries to insert and retrieve activity data
    • Handles database schema creation and migrations

    import threading – Enables concurrent execution through threads:

    • Runs multiple monitoring tasks simultaneously
    • Prevents blocking operations in the main thread
    • Manages thread lifecycle with threading.Thread and threading.Event

    import psutil – Process and system utilities:

    • Retrieves process information: psutil.Process(pid.value)
    • Gets executable paths and process names
    • Provides system monitoring capabilities

    Windows-Specific Imports

    import ctypes & from ctypes import wintypes – Python’s foreign function library for calling C functions:

    • Accesses Windows API functions directly
    • Defines Windows-specific data types
    • Enables low-level system interaction

    import win32clipboard, win32con, win32gui, win32process – Part of pywin32 package for Windows integration:

    • win32clipboard: Monitors clipboard content changes
    • win32con: Provides Windows constants (like CF_HDROP)
    • win32gui: Handles window management and GUI interactions
    • win32process: Accesses process-related information

    Data Structure Imports

    from collections import defaultdict, deque – Specialized container datatypes:

    • defaultdict: Creates dictionaries with default values for missing keys
    • deque: Double-ended queue for efficient appends and pops from both ends

    from typing import Optional, Dict, Any, List, Tuple – Type hints for better code documentation and IDE support:

    • Improves code readability
    • Helps with static analysis
    • Makes the code more maintainable

    Optional Import Handling

    try:
        from pynput import keyboard, mouse  # type: ignore
        PYNPUT_AVAILABLE = True
    except Exception:
        PYNPUT_AVAILABLE = False

    This try-except block demonstrates robust error handling for optional dependencies. The pynput library provides more reliable input monitoring but isn’t always available. The script gracefully falls back to alternative methods if pynput isn’t installed.

    Virtual Key Mapping System

    The script includes comprehensive virtual key code mapping to translate raw keyboard scan codes into human-readable key names:

    # Map some virtual-key codes for fallback (not exhaustive but practical)
    VK_CODE_ALPHA = {i: chr(i) for i in range(0x41, 0x5B)}  # A-Z
    VK_CODE_NUM = {i: str(i - 0x30) for i in range(0x30, 0x3A)}  # 0-9
    
    VK_SPECIAL = {
        0x20: "Space", 0x0D: "Enter", 0x08: "Backspace", 0x09: "Tab",
        0x1B: "Esc", 0x10: "Shift", 0x11: "Ctrl", 0x12: "Alt",
        # ... and many more special keys
    }

    Understanding Virtual Key Codes

    Virtual Key Codes are numeric constants that represent physical keys on the keyboard, regardless of keyboard layout or language settings. For example:

    • 0x41 represents the ‘A’ key
    • 0x20 represents the Spacebar
    • 0x0D represents the Enter key

    The mapping dictionaries serve as translation tables that convert these numeric codes into meaningful string representations that users can understand.

    Mouse Button Mapping

    VK_LBUTTON = 0x01
    VK_RBUTTON = 0x02
    VK_MBUTTON = 0x04
    VK_XBUTTON1 = 0x05
    VK_XBUTTON2 = 0x06

    These constants represent mouse button virtual key codes, allowing the script to detect and differentiate between left, right, middle, and extended mouse button clicks.

    Dictionary Merging

    VK_MAP = {**VK_CODE_ALPHA, **VK_CODE_NUM}
    VK_MAP.update(VK_SPECIAL)
    VK_MAP.update({
        VK_LBUTTON: "Left Click",
        VK_RBUTTON: "Right Click", 
        # ... mouse buttons
    })

    This demonstrates dictionary unpacking and multiple update operations to create a comprehensive key mapping dictionary that includes alphabetic keys, numeric keys, special keys, and mouse buttons.

    Core Class Architecture

    The main tracking functionality is encapsulated in the UltraActivityTracker class, which demonstrates excellent object-oriented design principles:

    Class Initialization

    class UltraActivityTracker:
        def __init__(self):
            # Files & paths
            self.current_dir = os.getcwd()
            current_date = datetime.now().strftime("%Y-%m-%d")
            self.db_path = os.path.join(self.current_dir, f"activity_{current_date}.db")
            self.log_file = os.path.join(self.current_dir, f"activity_log_{current_date}.txt")
            # ... more file paths
    
            # State management
            self.is_tracking = False
            self.keyboard_listener = None
            self.mouse_listener = None
            self.threads: List[threading.Thread] = []
            self.stop_event = threading.Event()
    
            # Statistics tracking
            self.key_count = 0
            self.shortcut_count = 0
            self.mouse_click_count = 0
            self.file_operations_count = 0
            # ... more statistics

    Key Initialization Components

    File Management:

    • Creates date-stamped filenames for logs, databases, and reports
    • Uses os.path.join() for cross-platform path compatibility
    • Organizes output files systematically

    State Management:

    • is_tracking: Boolean flag to control monitoring state
    • stop_event: Threading event for graceful shutdown
    • Listener objects for keyboard and mouse monitoring

    Data Structures:

    • defaultdict for application usage statistics
    • deque objects for maintaining activity history with fixed sizes
    • Multiple dictionaries for configuration and mapping

    Application Categorization System

    self.app_categories = {
        'Browsers': ['chrome.exe', 'firefox.exe', 'msedge.exe', 'opera.exe', 'brave.exe'],
        'Code Editors': ['code.exe', 'pycharm.exe', 'notepad++.exe', 'sublime_text.exe', 'vim.exe'],
        'Office Suite': ['winword.exe', 'excel.exe', 'powerpnt.exe', 'outlook.exe', 'onenote.exe'],
        # ... more categories
    }

    This categorization system allows the tracker to intelligently classify applications and provide more meaningful activity analysis. Each category has specific process names associated with it, enabling the system to determine whether a user is coding, browsing, working with office documents, etc.

    Shortcut Key Mapping

    self.shortcut_keys = {
        'ctrl+c': 'Copy', 'ctrl+x': 'Cut', 'ctrl+v': 'Paste', 'ctrl+z': 'Undo',
        'ctrl+y': 'Redo', 'ctrl+a': 'Select All', 'ctrl+s': 'Save', 'ctrl+p': 'Print',
        # ... many more shortcuts
    }

    This dictionary maps keyboard shortcut combinations to their common actions, allowing the tracker to recognize and log meaningful user actions rather than just random key presses.

    Database & Logging System

    Database Schema Setup

    The setup_database() method creates a sophisticated SQLite database with multiple tables for different types of activities:

    def setup_database(self):
        """Initialize SQLite database with advanced schema including mouse and file operations"""
        try:
            conn = sqlite3.connect(self.db_path, timeout=10)
            cursor = conn.cursor()
    
            # Create mouse_activities table
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS mouse_activities (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT NOT NULL,
                    window_title TEXT,
                    process_name TEXT,
                    button TEXT,
                    action TEXT,
                    x_position INTEGER,
                    y_position INTEGER,
                    context TEXT,
                    target_file TEXT,
                    target_path TEXT
                )
            ''')
    
            # Create file_operations table
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS file_operations (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT NOT NULL,
                    operation_type TEXT,
                    source_path TEXT,
                    destination_path TEXT,
                    file_name TEXT,
                    file_size INTEGER,
                    application TEXT,
                    window_title TEXT,
                    success BOOLEAN,
                    details TEXT
                )
            ''')
            # ... more tables

    Database Table Purposes

    mouse_activities – Stores detailed mouse interaction data:

    • Click coordinates (x_position, y_position)
    • Button pressed and action type
    • Context and target file information
    • Timestamp for temporal analysis

    file_operations – Tracks file management activities:

    • Operation type (copy, cut, paste, delete, rename)
    • Source and destination paths
    • File names and sizes
    • Application context

    keyboard_activities – Records keyboard inputs:

    • Individual key presses and shortcuts
    • Application context
    • Timestamp and key type classification

    app_sessions – Tracks application usage sessions:

    • Start and end times
    • Duration calculations
    • Activity metrics per application

    Logging System

    The script implements a dual logging system that writes to both the console and log files:

    def _log_console(self, message: str, prefix: str = "πŸ“"):
        ts = datetime.now().strftime("%H:%M:%S")
        line = f"{prefix} [{ts}] {message}"
        print(line)
        try:
            with open(self.log_file, 'a', encoding='utf-8') as f:
                f.write(line + "\n")
        except Exception:
            pass

    Key Features of the Logging System:

    • Emoji prefixes for visual categorization
    • Timestamp inclusion for chronological tracking
    • Error resilience with try-except blocks
    • Dual output to both console and file
    • Unicode support for special characters

    Database Migration Support

    The script includes robust migration logic that checks for existing tables and adds missing columns:

    cursor.execute("PRAGMA table_info(mouse_activities)")
    columns = [column[1] for column in cursor.fetchall()]
    
    if 'target_file' not in columns:
        cursor.execute("ALTER TABLE mouse_activities ADD COLUMN target_file TEXT")

    This ensures that the database schema can evolve over time without losing existing data, demonstrating forward-thinking design for long-term application maintenance.

    Window & Process Tracking

    Active Window Detection

    The get_active_window_info() method is crucial for understanding user context:

    def get_active_window_info(self) -> Optional[Dict[str, Any]]:
        """Get info about the currently active (foreground) window with enhanced details"""
        try:
            hwnd = user32.GetForegroundWindow()
            if not hwnd:
                return None
    
            pid = wintypes.DWORD()
            user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
    
            length = user32.GetWindowTextLengthW(hwnd)
            buff = ctypes.create_unicode_buffer(length + 1)
            user32.GetWindowTextW(hwnd, buff, length + 1)
            window_title = buff.value or ""
    
            # Process details
            process_name = "Unknown"
            process_path = "Unknown"
            try:
                proc = psutil.Process(pid.value)
                process_name = proc.name()
                process_path = proc.exe()
            except Exception:
                pass
    
            category = self.categorize_application(process_name)
            # ... return comprehensive window info

    Technical Breakdown of Window Detection

    user32.GetForegroundWindow() – Windows API call that returns a handle to the currently active window

    • Returns HWND (Handle to a Window)
    • Returns None if no window is active

    user32.GetWindowThreadProcessId() – Retrieves the process ID that created the window

    • Takes window handle and pointer to DWORD variable
    • Fills the DWORD with the process ID

    user32.GetWindowTextLengthW() & user32.GetWindowTextW() – Get the window title text

    • First gets the length, then allocates a buffer
    • Retrieves the actual text into the buffer

    psutil.Process() – Gets detailed process information from the process ID

    • Process name, executable path, and other details
    • Wrapped in try-except for error handling

    Smart Window Title Parsing

    The extract_current_location_and_file_from_window() method demonstrates advanced text parsing:

    def extract_current_location_and_file_from_window(self, window_title: str, process_name: str) -> Tuple[str, str]:
        """Extract current folder location and active file from window title"""
        try:
            current_file = "Unknown"
            current_location = window_title
    
            if process_name.lower() == 'explorer.exe':
                # Remove " - File Explorer" suffix
                if ' - File Explorer' in window_title:
                    content = window_title.replace(' - File Explorer', '')
                    if '\\' in content:
                        current_file = os.path.basename(content)
                        current_location = os.path.dirname(content)
                    else:
                        current_file = content
                        current_location = content
            # ... handle other application types

    This method uses pattern recognition and string manipulation to extract meaningful information from window titles, transforming raw text like "C:\Projects\README.md - Notepad++" into structured data:

    • current_file: “README.md”
    • current_location: “C:\Projects”

    Application Categorization Logic

    def categorize_application(self, process_name: Optional[str]) -> str:
        if not process_name:
            return "Other"
        pname = process_name.lower()
        for category, apps in self.app_categories.items():
            if pname in (a.lower() for a in apps):
                return category
        return "Other"

    This method demonstrates efficient dictionary searching and case normalization to classify applications into predefined categories, enabling meaningful activity analysis and reporting.

    Enhanced Mouse Tracking

    Comprehensive Mouse Event Handling

    The mouse tracking system goes beyond simple click counting to provide contextual understanding of user interactions:

    def handle_mouse_click(self, button: str, pressed: bool, x: int = 0, y: int = 0):
        """Handle mouse click events with enhanced context detection"""
        try:
            window_info = self.get_active_window_info() or {'process_name': 'Unknown', 'window_title': '', 'category': 'Other', 'current_location': 'Unknown', 'current_file': 'Unknown'}
    
            if pressed:
                self.mouse_click_count += 1
                proc = window_info.get('process_name', 'Unknown')
                self.app_usage[proc]['clicks'] += 1
    
                # Determine click context with file information
                context, target_file, target_path = self.detect_click_context_with_files(window_info, button, x, y)
    
                # Store context for file operations
                if button == "right" or button == "left":
                    self.last_right_click_context = {
                        'context': context,
                        'target_file': target_file,
                        'target_path': target_path,
                        'window_info': window_info,
                        'timestamp': datetime.now()
                    }
                    self.last_selected_file = target_file
    
                # Log mouse activity with file details
                self.log_mouse_activity(window_info, button, "click", x, y, context, target_file, target_path)

    Context-Aware Click Detection

    The detect_click_context_with_files() method provides intelligent context detection:

    def detect_click_context_with_files(self, window_info: Dict[str, Any], button: str, x: int, y: int) -> Tuple[str, str, str]:
        """Detect the context of a mouse click with file information"""
        try:
            process_name = window_info.get('process_name', '').lower()
            current_location = window_info.get('current_location', 'Unknown Location')
            current_file = window_info.get('current_file', 'Unknown File')
    
            # File Explorer context
            if process_name == 'explorer.exe':
                if current_file != current_location and current_file != "Unknown File":
                    target_file = current_file
                    target_path = current_location
                else:
                    target_file = "Folder Area"
                    target_path = current_location
    
                if button == "right":
                    return "File Context Menu", target_file, target_path
                elif button == "left":
                    return "File Selection", target_file, target_path
            # ... handle other application types

    Mouse Activity Database Logging

    def log_mouse_activity(self, window_info: Dict[str, Any], button: str, action: str, x: int, y: int, 
                          context: str, target_file: str, target_path: str):
        """Save mouse activity to database with file details"""
        try:
            conn = sqlite3.connect(self.db_path, timeout=10)
            cursor = conn.cursor()
            cursor.execute('''
                INSERT INTO mouse_activities 
                (timestamp, window_title, process_name, button, action, x_position, y_position, context, target_file, target_path)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                datetime.now().isoformat(),
                window_info.get('window_title', ''),
                window_info.get('process_name', ''),
                button,
                action,
                x,
                y,
                context,
                target_file,
                target_path
            ))
            conn.commit()
            conn.close()
        except Exception as e:
            self.log_to_file(f"Error saving mouse activity: {e}", "❌", "ERROR")

    This method demonstrates complete error handling and database transaction management, ensuring that mouse activities are reliably recorded even in case of errors.

    File Operations Monitoring

    Advanced Clipboard Monitoring

    The file operations tracking system uses clipboard monitoring to detect copy, cut, and paste operations:

    def monitor_clipboard_for_file_operations(self):
        """Enhanced clipboard monitoring for detailed file operations"""
        self.log_to_file("Advanced clipboard file operation monitor started", "πŸ“‹", "INFO")
    
        while not self.stop_event.is_set() and self.is_tracking:
            try:
                win32clipboard.OpenClipboard()
                try:
                    # Check for file operations in clipboard
                    if win32clipboard.IsClipboardFormatAvailable(win32con.CF_HDROP):
                        files = win32clipboard.GetClipboardData(win32con.CF_HDROP)
                        if files and files != self.last_clipboard_content:
                            self.last_clipboard_content = files
                            self.handle_detailed_file_operation_detection(files)
                finally:
                    win32clipboard.CloseClipboard()
            except Exception as e:
                # Clipboard might be in use by another process
                pass
    
            time.sleep(self.clipboard_check_interval)

    Technical Details of Clipboard Monitoring

    win32clipboard.OpenClipboard() – Opens the clipboard for examination

    • Required before accessing clipboard contents
    • May fail if another process has the clipboard open

    win32clipboard.IsClipboardFormatAvailable(win32con.CF_HDROP) – Checks for file drop format

    • CF_HDROP indicates files are in the clipboard (from copy/cut operations)
    • Returns True if files are available

    win32clipboard.GetClipboardData(win32con.CF_HDROP) – Retrieves the file list

    • Returns a list of file paths
    • Used to detect what files are being copied or moved

    File Operation Detection and Handling

    def handle_detailed_file_operation_detection(self, files):
        """Handle detected file operations with detailed information"""
        try:
            window_info = self.get_active_window_info() or {'process_name': 'Unknown', 'window_title': '', 'current_location': 'Unknown', 'current_file': 'Unknown'}
    
            # Determine operation type based on modifier keys and context
            operation = "copy" if not self.modifier_keys.get('shift') else "cut"
    
            # Get source information from context
            source_path = self.get_source_path_from_context()
            file_names = []
    
            if isinstance(files, (list, tuple)):
                file_names = [os.path.basename(f) for f in files]
                if files:
                    source_path = os.path.dirname(files[0])
            else:
                file_names = [os.path.basename(files)]
                source_path = os.path.dirname(files) if files else source_path
    
            # Store pending operation with detailed info
            self.pending_file_operations[operation] = {
                'files': files,
                'file_names': file_names,
                'source_path': source_path,
                'timestamp': datetime.now(),
                'source_window': window_info
            }

    This method demonstrates intelligent operation deduction by combining clipboard data with modifier key states and window context to determine whether the user is performing a copy or cut operation.

    File Paste Operation Handling

    def handle_file_paste_operation(self):
        """Handle file paste operations with destination tracking"""
        try:
            window_info = self.get_active_window_info() or {'process_name': 'Unknown', 'window_title': '', 'current_location': 'Unknown', 'current_file': 'Unknown'}
            destination_path = window_info.get('current_location', 'Unknown Destination')
    
            # Check for pending operations
            for op_type in ['copy', 'cut']:
                pending_op = self.pending_file_operations.get(op_type)
                if pending_op:
                    # Calculate time since operation was prepared
                    time_since_op = (datetime.now() - pending_op['timestamp']).total_seconds()
    
                    # Only log if paste happened within a reasonable time (30 seconds)
                    if time_since_op < 30:
                        source_path = pending_op.get('source_path', 'Unknown Source')
                        file_names = pending_op.get('file_names', [])
    
                        if file_names:
                            for file_name in file_names:
                                # Log the completed file operation
                                self.log_file_operation(
                                    operation_type=op_type,
                                    source_path=source_path,
                                    destination_path=destination_path,
                                    file_name=file_name,
                                    application=window_info.get('process_name', 'Unknown'),
                                    window_title=window_info.get('window_title', ''),
                                    success=True,
                                    details=f"{op_type.upper()} operation completed"
                                )

    This method shows temporal correlation between copy/cut and paste operations, ensuring that file operations are only logged when they form complete sequences within a reasonable time window.

    Keyboard Activity Tracking

    Comprehensive Key Event Handling

    The keyboard tracking system differentiates between regular keys, modifier keys, and shortcuts:

    def handle_key_event(self, key_name: str, pressed: bool):
        """
        Unified handler for key press/release events.
        key_name: readable key string like 'a', 'Ctrl', 'F5', 'Enter'
        pressed: True for press, False for release
        """
        try:
            # Map modifier name variants to our keys
            kn = key_name.lower()
            if kn in ('ctrl', 'control'):
                self.modifier_keys['ctrl'] = pressed
                return
            if kn in ('alt',):
                self.modifier_keys['alt'] = pressed
                return
            # ... handle other modifiers
    
            # Only handle presses for non-modifier logging
            if not pressed:
                return
    
            window_info = self.get_active_window_info() or {'process_name': 'Unknown', 'window_title': '', 'category': 'Other', 'current_location': 'Unknown', 'current_file': 'Unknown'}
            active_mods = [m for m, v in self.modifier_keys.items() if v]
            key_str = key_name  # friendly string
    
            # Detect if this constitutes a shortcut
            combo = active_mods + [key_str]
            shortcut_action = self.detect_shortcut(combo)
    
            if shortcut_action:
                combo_str = self.normalize_combo(combo)
                self.log_shortcut(combo_str, shortcut_action, window_info)
                self.log_keyboard_activity(window_info, key_str, "shortcut")
            else:
                # Normal key press - track all alphabets and numbers
                if len(key_str) == 1 and key_str.isalnum():
                    self.key_count += 1
                    proc = window_info.get('process_name', 'Unknown')
                    self.app_usage[proc]['keystrokes'] += 1
                    self.keystroke_buffer.append(key_str)

    Shortcut Detection Logic

    def normalize_combo(self, parts: List[str]) -> str:
        """Normalize combo like ['ctrl','shift','a'] -> 'ctrl+shift+a'"""
        lower = [p.lower() for p in parts if p]
        # place modifiers first in an expected order
        order = ['ctrl', 'alt', 'shift', 'win']
        mods = [m for m in order if m in lower]
        others = sorted([p for p in lower if p not in mods])
        combo = '+'.join(mods + others)
        return combo
    
    def detect_shortcut(self, key_combination: List[str]) -> Optional[str]:
        combo = self.normalize_combo(key_combination)
        return self.shortcut_keys.get(combo)

    These methods demonstrate consistent shortcut normalization by:

    1. Converting all keys to lowercase
    2. Sorting modifiers in a standard order
    3. Combining with regular keys
    4. Looking up in the shortcut dictionary

    Keyboard Activity Logging

    def log_keyboard_activity(self, window_info: Dict[str, Any], key_str: str, key_type: str):
        """Persist keyboard press to keyboard_activities table"""
        try:
            is_shortcut = (key_type == "shortcut")
            shortcut_name = None
            if is_shortcut:
                mods = [k for k, v in self.modifier_keys.items() if v]
                shortcut_name = self.detect_shortcut(mods + [key_str]) if mods else None
    
            conn = sqlite3.connect(self.db_path, timeout=10)
            cursor = conn.cursor()
            cursor.execute('''
                INSERT INTO keyboard_activities
                (timestamp, window_title, process_name, keys_pressed, key_type, is_shortcut, shortcut_name, total_keys)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                datetime.now().isoformat(),
                window_info.get('window_title', ''),
                window_info.get('process_name', ''),
                key_str,
                key_type,
                bool(is_shortcut),
                shortcut_name,
                1
            ))
            conn.commit()
            conn.close()
        except Exception as e:
            self.log_to_file(f"Error saving keyboard activity: {e}", "❌", "ERROR")

    This method shows comprehensive data collection for keyboard activities, including context, key type classification, and shortcut recognition.

    Threading & Real-time Monitoring

    Multi-threaded Architecture

    The tracker uses multiple threads to monitor different aspects of system activity simultaneously:

    def start_tracking(self):
        self.is_tracking = True
        self.stop_event.clear()
        # ... reset statistics
    
        # Start keyboard monitoring
        if PYNPUT_AVAILABLE:
            try:
                self.keyboard_listener = keyboard.Listener(on_press=self._pynput_on_press, on_release=self._pynput_on_release)
                self.keyboard_listener.start()
                self._log_console("pynput keyboard listener started", "🎧")
    
                # Start mouse monitoring with pynput
                self.mouse_listener = mouse.Listener(on_click=self._pynput_mouse_on_click)
                self.mouse_listener.start()
                self._log_console("pynput mouse listener started", "πŸ–±οΈ")
            except Exception as e:
                # Fallback to polling method
                self.log_to_file(f"pynput listeners failed, falling back: {e}", "⚠️", "WARNING")
                t_key = threading.Thread(target=self._fallback_key_poller, daemon=True)
                t_key.start()
                self.threads.append(t_key)
    
        # Window tracker
        t_win = threading.Thread(target=self.track_window_changes, daemon=True)
        t_win.start()
        self.threads.append(t_win)
    
        # File operations monitoring
        t_clipboard = threading.Thread(target=self.monitor_clipboard_for_file_operations, daemon=True)
        t_clipboard.start()
        self.threads.append(t_clipboard)
    
        # Periodic reporter
        t_rep = threading.Thread(target=self.generate_periodic_report, daemon=True)
        t_rep.start()
        self.threads.append(t_rep)

    Thread Management Features

    Daemon Threads – All monitoring threads are created as daemon threads:

    • Automatically terminate when main program exits
    • Prevent hanging processes if main thread crashes

    Graceful Shutdown – Uses threading.Event for coordinated stopping:

    self.stop_event = threading.Event()
    
    # In each monitoring thread:
    while not self.stop_event.is_set() and self.is_tracking:
        # monitoring logic

    Fallback Mechanisms – Provides alternative monitoring methods:

    • Prefers pynput for better performance
    • Falls back to GetAsyncKeyState polling if pynput fails
    • Ensures functionality across different environments

    Fallback Polling Implementation

    def _fallback_key_poller(self):
        """
        Poll keys using GetAsyncKeyState. Detect transitions from up->down to simulate key press.
        Runs in its own thread.
        """
        self.log_to_file("Fallback keyboard poller started", "⚠️", "INFO")
        # Prepare a list of vk codes to watch
        vk_codes = list(VK_MAP.keys())
        # also monitor modifier virtual keys explicitly
        vk_codes += [0x10, 0x11, 0x12, 0x5B]  # shift, ctrl, alt, win
    
        prev_states = {vk: False for vk in vk_codes}
    
        while not self.stop_event.is_set() and self.is_tracking:
            try:
                for vk in vk_codes:
                    state = bool(user32.GetAsyncKeyState(vk) & 0x8000)
                    if state and not prev_states[vk]:
                        # Key down event
                        key_name = VK_MAP.get(vk, f"VK_{vk}")
                        self.handle_key_event(key_name, True)
                    elif not state and prev_states[vk]:
                        # Key up event (handle modifier releases)
                        key_name = VK_MAP.get(vk, f"VK_{vk}")
                        self.handle_key_event(key_name, False)
                    prev_states[vk] = state
                time.sleep(0.006)  # small sleep to avoid high CPU; tuned for responsiveness
            except Exception as e:
                self.log_to_file(f"Fallback poller error: {e}", "❌", "ERROR")
                time.sleep(0.05)

    This fallback method demonstrates efficient key state polling by:

    • Monitoring virtual key state transitions
    • Using bitmask operations to check key states
    • Maintaining previous state for change detection
    • Implementing CPU-friendly polling intervals

    Reporting System

    Comprehensive Report Generation

    The tracker generates multiple report formats with detailed analytics:

    def save_report(self):
        try:
            total_time = sum(usage['time'] for usage in self.app_usage.values()) or 1
            current_time = datetime.now()
            tracking_duration = (current_time - self.start_time).total_seconds() / 60  # minutes
    
            with open(self.report_file, 'w', encoding='utf-8') as f:
                f.write("πŸš€ ULTRA ADVANCED ACTIVITY REPORT WITH DETAILED FILE OPERATIONS\n")
                f.write("=" * 80 + "\n")
                f.write(f"Generated: {current_time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"Tracking Duration: {tracking_duration:.1f} minutes\n")
                f.write(f"Total Keystrokes: {self.key_count}\n")
                f.write(f"Total Shortcuts: {self.shortcut_count}\n")
                f.write(f"Total Mouse Clicks: {self.mouse_click_count}\n")
                f.write(f"Total File Operations: {self.file_operations_count}\n")
                f.write(f"Applications Used: {len(self.app_usage)}\n")
                f.write("=" * 80 + "\n\n")
    
                # Productivity calculations
                productive_categories = ['Code Editors', 'Office Suite', 'Development']
                productive_time = sum(usage['time'] for app, usage in self.app_usage.items()
                                      if self.categorize_application(app) in productive_categories)
                f.write(f"Productive Time: {productive_time/60:.1f} minutes ({productive_time/total_time*100:.1f}%)\n")
    
                # Application usage ranking
                f.write("πŸ“± APPLICATION USAGE RANKING:\n")
                f.write("-" * 80 + "\n")
                for i, (app, usage) in enumerate(sorted(self.app_usage.items(), key=lambda x: x[1]['time'], reverse=True), 1):
                    minutes = usage['time'] / 60
                    percent = (usage['time'] / total_time * 100) if total_time > 0 else 0
                    category = self.categorize_application(app)
                    f.write(f"{i:2d}. {app:<25} {category:<20} {minutes:5.1f}m ({percent:5.1f}%) | ")
                    f.write(f"⌨️{usage['keystrokes']:4d} | 🎯{usage['shortcuts']:3d} | πŸ–±οΈ{usage['clicks']:3d} | πŸ“{usage['file_ops']:2d}\n")

    HTML Report Generation

    def save_detailed_html_report(self):
        try:
            total_time = sum(usage['time'] for usage in self.app_usage.values()) or 1
            html_content = f"""<!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" />
      <title>Ultra Advanced Activity Report - {datetime.now().strftime('%Y-%m-%d')}</title>
      <style>
        body {{ font-family: Arial, sans-serif; margin: 20px; background:#f5f5f5 }}
        .container {{ max-width:1200px; margin:0 auto; background:white; padding:20px; border-radius:10px }}
        .header {{ background:#2c3e50; color:white; padding:20px; border-radius:5px }}
        .stats {{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:15px; margin:20px 0 }}
        .stat-card {{ background:#ecf0f1; padding:15px; border-radius:5px; text-align:center }}
        .app-item {{ background:#f8f9fa; margin:5px 0; padding:10px; border-left:4px solid #3498db }}
      </style>
    </head>
    <body>
      <div class="container">
        <div class="header">
          <h1>πŸš€ Ultra Advanced Activity Report</h1>
          <p>Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
        </div>
        <div class="stats">
          <div class="stat-card"><h3>⏰ Tracking Time</h3><p>{(total_time/60):.1f} minutes</p></div>
          <div class="stat-card"><h3>⌨️ Keystrokes</h3><p>{self.key_count}</p></div>
          <div class="stat-card"><h3>🎯 Shortcuts</h3><p>{self.shortcut_count}</p></div>
          <!-- ... more stat cards -->
        </div>
        <!-- ... more report sections -->
      </div>
    </body>
    </html>
    """
            with open(self.detailed_report_file, 'w', encoding='utf-8') as f:
                f.write(html_content)
        except Exception as e:
            self.log_to_file(f"save_detailed_html_report error: {e}", "❌", "ERROR")

    Analytics Features

    Productivity Metrics – Calculates productive vs. non-productive time based on application categories
    Usage Patterns – Shows application usage distribution and patterns
    Activity Correlation – Correlates different types of activities (keystrokes, clicks, shortcuts)
    Temporal Analysis – Provides time-based activity insights

    Complete Usage Overview

    How to Use the Tracker

    The tracker is designed to be easy to use while providing powerful monitoring capabilities:

    def main():
        tracker = UltraActivityTracker()
        print("πŸš€ ULTRA ADVANCED WINDOWS ACTIVITY TRACKER WITH DETAILED FILE OPERATIONS")
        print("=" * 60)
        print("ENHANCED FEATURES:")
        print("β€’ Smart activity detection with clean page titles")
        print("β€’ Detailed mouse click tracking with file names and locations")
        print("β€’ Advanced file operations monitoring (copy, cut, paste, delete)")
        print("β€’ Source and destination path tracking for file operations")
        print("β€’ Enhanced shortcut key tracking with context")
        print("β€’ Keyboard alphabet and number tracking")
        print("β€’ Clipboard monitoring for precise file operation detection")
        print("β€’ Multiple report formats (TXT, HTML) with detailed file info")
        print("=" * 60)
        print("Starting in 3 seconds...")
        time.sleep(3)
    
        try:
            tracker.start_tracking()
            while True:
                # Keep main thread alive; trap KeyboardInterrupt
                time.sleep(1)
        except KeyboardInterrupt:
            tracker.stop_tracking()
            print("\n\nπŸŽ‰ Tracking completed! Files saved:")
            print(f"   πŸ“„ {tracker.log_file}")
            print(f"   πŸ“Š {tracker.report_file}")
            print(f"   🌐 {tracker.detailed_report_file}")
            print(f"   πŸ—ƒοΈ {tracker.db_path}")
            print("\nThank you for using Ultra Activity Tracker! πŸ‘‹")

    Installation and Setup

    Requirements:

    pip install psutil pywin32 pynput

    Key Features in Action:

    1. Automatic Start – Begins monitoring immediately after 3-second countdown
    2. Real-time Feedback – Shows ongoing activities in console with emojis
    3. Graceful Shutdown – Ctrl+C stops tracking and generates final reports
    4. Multiple Outputs – Creates text, HTML, and database files
    5. Date-stamped Files – Organizes outputs by date for long-term tracking

    Output Files Generated

    activity_YYYY-MM-DD.db – SQLite database with complete activity records
    activity_log_YYYY-MM-DD.txt – Detailed chronological log of all activities
    activity_report_YYYY-MM-DD.txt – Formatted summary report
    detailed_report_YYYY-MM-DD.html – Visual HTML report with analytics

    Educational Value

    Learning Opportunities for Students

    This script provides exceptional educational value across multiple programming domains:

    System Programming:

    • Windows API integration and system calls
    • Process and window management
    • Low-level input monitoring
    • Clipboard interaction

    Software Architecture:

    • Object-oriented design patterns
    • Multi-threaded application design
    • Database schema design and management
    • Configuration management

    Data Analysis:

    • Activity pattern recognition
    • Productivity metrics calculation
    • Temporal data analysis
    • Report generation and visualization

    Error Handling and Robustness:

    • Comprehensive exception handling
    • Graceful degradation features
    • Resource management
    • Data persistence reliability

    This activity tracker represents a comprehensive example of modern Python development, combining system programming, data analysis, and user-friendly reporting in a single, cohesive application. It serves as an excellent codebase for students to study, understand, and extend with their own features and improvements.

    Share this post on social!

    Comment on Post

    Your email address will not be published. Required fields are marked *