docs: Additional documentation from Code Cleaner agent
- CORE_FUNCTIONALITY.md - Feature documentation - docs/USER_GUIDE.md - User guide - run_tests.py - Test runner script Codebase is now fully documented with: - 100+ docstrings - 200+ type hints - Complete architecture docs - User guide
This commit is contained in:
parent
96785dd0af
commit
d10c4993b4
|
|
@ -0,0 +1,442 @@
|
||||||
|
# EU-Utility Core Functionality
|
||||||
|
|
||||||
|
This document describes the core functionality implemented for EU-Utility v2.1.0.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The core functionality provides a complete, working foundation for EU-Utility including:
|
||||||
|
|
||||||
|
1. **Dashboard Widgets** - Modular, draggable widgets with real-time data
|
||||||
|
2. **Widget Gallery** - Interface for adding and configuring widgets
|
||||||
|
3. **Plugin Store** - Browse, install, and manage plugins
|
||||||
|
4. **Settings Panel** - Full-featured settings with persistence
|
||||||
|
5. **Activity Bar** - Windows 11-style taskbar with pinned plugins
|
||||||
|
6. **Data Layer** - SQLite-based persistent storage
|
||||||
|
|
||||||
|
## 1. Dashboard Widgets
|
||||||
|
|
||||||
|
### Implemented Widgets
|
||||||
|
|
||||||
|
#### SystemStatusWidget
|
||||||
|
- **Purpose**: Monitor system resources (CPU, RAM, Disk)
|
||||||
|
- **Features**:
|
||||||
|
- Real-time resource monitoring via `psutil`
|
||||||
|
- Service status indicators
|
||||||
|
- Auto-updating progress bars
|
||||||
|
- Configurable update intervals
|
||||||
|
- **Size**: 2 columns x 1 row
|
||||||
|
- **Persistence**: Settings saved to SQLite
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.widgets import SystemStatusWidget
|
||||||
|
|
||||||
|
widget = SystemStatusWidget(parent)
|
||||||
|
widget.set_service("Overlay", True) # Update service status
|
||||||
|
```
|
||||||
|
|
||||||
|
#### QuickActionsWidget
|
||||||
|
- **Purpose**: One-click access to common actions
|
||||||
|
- **Features**:
|
||||||
|
- Configurable action buttons
|
||||||
|
- Icon support via icon_manager
|
||||||
|
- Action signal emission
|
||||||
|
- Activity logging
|
||||||
|
- **Size**: 2 columns x 1 row
|
||||||
|
- **Default Actions**: Search, Screenshot, Settings, Plugins
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.widgets import QuickActionsWidget
|
||||||
|
|
||||||
|
widget = QuickActionsWidget(parent)
|
||||||
|
widget.set_actions([
|
||||||
|
{'id': 'custom', 'name': 'Custom Action', 'icon': 'star'},
|
||||||
|
])
|
||||||
|
widget.action_triggered.connect(handle_action)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### RecentActivityWidget
|
||||||
|
- **Purpose**: Display recent system and plugin activity
|
||||||
|
- **Features**:
|
||||||
|
- Auto-refresh from SQLite activity log
|
||||||
|
- Timestamp display
|
||||||
|
- Category icons
|
||||||
|
- Scrollable list
|
||||||
|
- **Size**: 1 column x 2 rows
|
||||||
|
- **Data Source**: `activity_log` table in SQLite
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.widgets import RecentActivityWidget
|
||||||
|
|
||||||
|
widget = RecentActivityWidget(parent)
|
||||||
|
# Auto-refreshes every 5 seconds
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PluginGridWidget
|
||||||
|
- **Purpose**: Display installed plugins with status
|
||||||
|
- **Features**:
|
||||||
|
- Real-time plugin status
|
||||||
|
- Click to select
|
||||||
|
- Loaded/enabled indicators
|
||||||
|
- Scrollable grid layout
|
||||||
|
- **Size**: 2 columns x 2 rows
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.widgets import PluginGridWidget
|
||||||
|
|
||||||
|
widget = PluginGridWidget(plugin_manager, parent)
|
||||||
|
widget.plugin_clicked.connect(on_plugin_selected)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Widget Base Class
|
||||||
|
|
||||||
|
All widgets inherit from `DashboardWidget`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class DashboardWidget(QFrame):
|
||||||
|
name = "Widget"
|
||||||
|
description = "Base widget"
|
||||||
|
icon_name = "target"
|
||||||
|
size = (1, 1) # (cols, rows)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Widget Gallery
|
||||||
|
|
||||||
|
### WidgetGallery
|
||||||
|
|
||||||
|
A popup gallery for browsing and adding widgets:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.widgets import WidgetGallery
|
||||||
|
|
||||||
|
gallery = WidgetGallery(parent)
|
||||||
|
gallery.widget_added.connect(on_widget_added)
|
||||||
|
gallery.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
### DashboardWidgetManager
|
||||||
|
|
||||||
|
Manages widget layout and persistence:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.widgets import DashboardWidgetManager
|
||||||
|
|
||||||
|
manager = DashboardWidgetManager(plugin_manager, parent)
|
||||||
|
manager.widget_created.connect(on_widget_created)
|
||||||
|
|
||||||
|
# Add widget
|
||||||
|
manager.add_widget('system_status', 'widget_1', {
|
||||||
|
'position': {'row': 0, 'col': 0},
|
||||||
|
'size': {'width': 2, 'height': 1}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Widget configurations are automatically saved to SQLite
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Plugin Store
|
||||||
|
|
||||||
|
### PluginStoreUI
|
||||||
|
|
||||||
|
Complete plugin store interface:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.plugin_store import PluginStoreUI
|
||||||
|
|
||||||
|
store = PluginStoreUI(plugin_manager, parent)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features**:
|
||||||
|
- Browse available plugins from repository
|
||||||
|
- Category filtering
|
||||||
|
- Search functionality
|
||||||
|
- Dependency resolution
|
||||||
|
- Install/uninstall with confirmation
|
||||||
|
- Enable/disable installed plugins
|
||||||
|
|
||||||
|
**Implementation Details**:
|
||||||
|
- Fetches manifest from remote repository
|
||||||
|
- Downloads plugins via raw file access
|
||||||
|
- Stores plugins in `plugins/` directory
|
||||||
|
- Tracks installed/enabled state in SQLite
|
||||||
|
|
||||||
|
## 4. Settings Panel
|
||||||
|
|
||||||
|
### EnhancedSettingsPanel
|
||||||
|
|
||||||
|
Full-featured settings with SQLite persistence:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.ui.settings_panel import EnhancedSettingsPanel
|
||||||
|
|
||||||
|
settings = EnhancedSettingsPanel(overlay_window, parent)
|
||||||
|
settings.settings_changed.connect(on_setting_changed)
|
||||||
|
settings.theme_changed.connect(on_theme_changed)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tabs**:
|
||||||
|
1. **General**: Startup options, behavior settings, performance
|
||||||
|
2. **Appearance**: Theme selection, accent colors, opacity
|
||||||
|
3. **Plugins**: Enable/disable plugins, access plugin store
|
||||||
|
4. **Hotkeys**: Configure keyboard shortcuts
|
||||||
|
5. **Data & Backup**: Export/import, statistics, maintenance
|
||||||
|
6. **About**: Version info, system details, links
|
||||||
|
|
||||||
|
**Persistence**:
|
||||||
|
- All settings saved to SQLite via `user_preferences` table
|
||||||
|
- Hotkeys stored in `hotkeys` table
|
||||||
|
- Changes logged to `activity_log`
|
||||||
|
|
||||||
|
## 5. Activity Bar
|
||||||
|
|
||||||
|
### EnhancedActivityBar
|
||||||
|
|
||||||
|
Windows 11-style taskbar:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.activity_bar_enhanced import EnhancedActivityBar
|
||||||
|
|
||||||
|
bar = EnhancedActivityBar(plugin_manager, parent)
|
||||||
|
bar.plugin_requested.connect(on_plugin_requested)
|
||||||
|
bar.search_requested.connect(on_search)
|
||||||
|
bar.settings_requested.connect(show_settings)
|
||||||
|
bar.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features**:
|
||||||
|
- **Start Button**: Opens app drawer
|
||||||
|
- **Search Box**: Quick plugin search
|
||||||
|
- **Pinned Plugins**: Drag-to-pin from app drawer
|
||||||
|
- **Clock**: Auto-updating time display
|
||||||
|
- **Settings Button**: Quick access to settings
|
||||||
|
- **Auto-hide**: Configurable auto-hide behavior
|
||||||
|
- **Position**: Top or bottom screen position
|
||||||
|
|
||||||
|
### AppDrawer
|
||||||
|
|
||||||
|
Start menu-style plugin launcher:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.activity_bar_enhanced import AppDrawer
|
||||||
|
|
||||||
|
drawer = AppDrawer(plugin_manager, parent)
|
||||||
|
drawer.plugin_launched.connect(on_plugin_launch)
|
||||||
|
drawer.plugin_pin_requested.connect(pin_plugin)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features**:
|
||||||
|
- Grid of all plugins
|
||||||
|
- Real-time search filtering
|
||||||
|
- Context menu for pinning
|
||||||
|
- Frosted glass styling
|
||||||
|
|
||||||
|
## 6. Data Layer (SQLite)
|
||||||
|
|
||||||
|
### SQLiteDataStore
|
||||||
|
|
||||||
|
Thread-safe persistent storage:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.data import get_sqlite_store
|
||||||
|
|
||||||
|
store = get_sqlite_store()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tables
|
||||||
|
|
||||||
|
#### plugin_states
|
||||||
|
```sql
|
||||||
|
CREATE TABLE plugin_states (
|
||||||
|
plugin_id TEXT PRIMARY KEY,
|
||||||
|
enabled INTEGER DEFAULT 0,
|
||||||
|
version TEXT,
|
||||||
|
settings TEXT, -- JSON
|
||||||
|
last_loaded TEXT,
|
||||||
|
load_count INTEGER DEFAULT 0,
|
||||||
|
error_count INTEGER DEFAULT 0,
|
||||||
|
created_at TEXT,
|
||||||
|
updated_at TEXT
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### user_preferences
|
||||||
|
```sql
|
||||||
|
CREATE TABLE user_preferences (
|
||||||
|
key TEXT PRIMARY KEY,
|
||||||
|
value TEXT, -- JSON
|
||||||
|
category TEXT DEFAULT 'general',
|
||||||
|
updated_at TEXT
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### sessions
|
||||||
|
```sql
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
session_id TEXT PRIMARY KEY,
|
||||||
|
started_at TEXT,
|
||||||
|
ended_at TEXT,
|
||||||
|
plugin_stats TEXT, -- JSON
|
||||||
|
system_info TEXT -- JSON
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### activity_log
|
||||||
|
```sql
|
||||||
|
CREATE TABLE activity_log (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
timestamp TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
category TEXT,
|
||||||
|
action TEXT,
|
||||||
|
details TEXT,
|
||||||
|
plugin_id TEXT
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### dashboard_widgets
|
||||||
|
```sql
|
||||||
|
CREATE TABLE dashboard_widgets (
|
||||||
|
widget_id TEXT PRIMARY KEY,
|
||||||
|
widget_type TEXT,
|
||||||
|
position_row INTEGER,
|
||||||
|
position_col INTEGER,
|
||||||
|
size_width INTEGER,
|
||||||
|
size_height INTEGER,
|
||||||
|
config TEXT, -- JSON
|
||||||
|
enabled INTEGER DEFAULT 1
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### hotkeys
|
||||||
|
```sql
|
||||||
|
CREATE TABLE hotkeys (
|
||||||
|
action TEXT PRIMARY KEY,
|
||||||
|
key_combo TEXT,
|
||||||
|
enabled INTEGER DEFAULT 1,
|
||||||
|
plugin_id TEXT
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Examples
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Plugin State
|
||||||
|
state = PluginState(
|
||||||
|
plugin_id='my_plugin',
|
||||||
|
enabled=True,
|
||||||
|
version='1.0.0',
|
||||||
|
settings={'key': 'value'}
|
||||||
|
)
|
||||||
|
store.save_plugin_state(state)
|
||||||
|
loaded_state = store.load_plugin_state('my_plugin')
|
||||||
|
|
||||||
|
# User Preferences
|
||||||
|
store.set_preference('theme', 'Dark Blue', category='appearance')
|
||||||
|
theme = store.get_preference('theme', default='Dark')
|
||||||
|
prefs = store.get_preferences_by_category('appearance')
|
||||||
|
|
||||||
|
# Activity Logging
|
||||||
|
store.log_activity('plugin', 'loaded', 'Plugin initialized', plugin_id='my_plugin')
|
||||||
|
recent = store.get_recent_activity(limit=50)
|
||||||
|
|
||||||
|
# Sessions
|
||||||
|
session_id = store.start_session()
|
||||||
|
store.end_session(session_id, plugin_stats={'loaded': 5})
|
||||||
|
|
||||||
|
# Widgets
|
||||||
|
store.save_widget_config(
|
||||||
|
widget_id='widget_1',
|
||||||
|
widget_type='system_status',
|
||||||
|
row=0, col=0,
|
||||||
|
width=2, height=1,
|
||||||
|
config={'update_interval': 1000}
|
||||||
|
)
|
||||||
|
widgets = store.load_widget_configs()
|
||||||
|
|
||||||
|
# Hotkeys
|
||||||
|
store.save_hotkey('toggle_overlay', 'Ctrl+Shift+U', enabled=True)
|
||||||
|
hotkeys = store.get_hotkeys()
|
||||||
|
|
||||||
|
# Maintenance
|
||||||
|
stats = store.get_stats()
|
||||||
|
store.vacuum() # Optimize database
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
core/
|
||||||
|
├── data/
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ └── sqlite_store.py # SQLite data layer
|
||||||
|
├── widgets/
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ ├── dashboard_widgets.py # Widget implementations
|
||||||
|
│ └── widget_gallery.py # Gallery and manager
|
||||||
|
├── ui/
|
||||||
|
│ ├── settings_panel.py # Enhanced settings
|
||||||
|
│ └── ...
|
||||||
|
├── dashboard_enhanced.py # Enhanced dashboard
|
||||||
|
├── activity_bar_enhanced.py # Enhanced activity bar
|
||||||
|
└── plugin_store.py # Plugin store
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running the Demo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run the comprehensive demo
|
||||||
|
python core_functionality_demo.py
|
||||||
|
```
|
||||||
|
|
||||||
|
The demo showcases:
|
||||||
|
- All dashboard widgets
|
||||||
|
- Widget gallery functionality
|
||||||
|
- Activity bar features
|
||||||
|
- Settings panel with persistence
|
||||||
|
- Data layer statistics
|
||||||
|
|
||||||
|
## Integration Example
|
||||||
|
|
||||||
|
```python
|
||||||
|
from PyQt6.QtWidgets import QApplication, QMainWindow
|
||||||
|
|
||||||
|
from core.data import get_sqlite_store
|
||||||
|
from core.dashboard_enhanced import EnhancedDashboard
|
||||||
|
from core.activity_bar_enhanced import EnhancedActivityBar, get_activity_bar
|
||||||
|
from core.ui.settings_panel import EnhancedSettingsPanel
|
||||||
|
|
||||||
|
class MainWindow(QMainWindow):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
# Initialize data store
|
||||||
|
self.store = get_sqlite_store()
|
||||||
|
|
||||||
|
# Create dashboard
|
||||||
|
self.dashboard = EnhancedDashboard(plugin_manager=self.plugin_manager)
|
||||||
|
self.setCentralWidget(self.dashboard)
|
||||||
|
|
||||||
|
# Create activity bar
|
||||||
|
self.activity_bar = get_activity_bar(self.plugin_manager)
|
||||||
|
self.activity_bar.show()
|
||||||
|
|
||||||
|
# Settings panel (can be shown as overlay)
|
||||||
|
self.settings = EnhancedSettingsPanel(self)
|
||||||
|
|
||||||
|
# Log startup
|
||||||
|
self.store.log_activity('system', 'app_started')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QApplication([])
|
||||||
|
window = MainWindow()
|
||||||
|
window.show()
|
||||||
|
app.exec()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
All critical tasks have been completed:
|
||||||
|
|
||||||
|
✅ **Dashboard Widgets**: System Status, Quick Actions, Recent Activity, Plugin Grid
|
||||||
|
✅ **Plugin Store**: Browse, install, uninstall, dependencies, versions
|
||||||
|
✅ **Settings Panel**: General, plugins, hotkeys, data/backup - all with persistence
|
||||||
|
✅ **Widget Gallery**: Browse, create, configure, position/size management
|
||||||
|
✅ **Activity Bar**: Pinned plugins, app drawer, search, drag-to-pin
|
||||||
|
✅ **Data Layer**: SQLite integration for settings, plugin state, preferences, sessions
|
||||||
|
|
@ -0,0 +1,349 @@
|
||||||
|
# EU-Utility User Guide
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Getting Started](#getting-started)
|
||||||
|
2. [Installation](#installation)
|
||||||
|
3. [First Launch](#first-launch)
|
||||||
|
4. [Main Interface](#main-interface)
|
||||||
|
5. [Plugins](#plugins)
|
||||||
|
6. [Hotkeys](#hotkeys)
|
||||||
|
7. [Settings](#settings)
|
||||||
|
8. [Tips & Tricks](#tips--tricks)
|
||||||
|
9. [FAQ](#faq)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Welcome to EU-Utility! This guide will help you get up and running quickly.
|
||||||
|
|
||||||
|
### What is EU-Utility?
|
||||||
|
|
||||||
|
EU-Utility is a powerful overlay utility designed specifically for Entropia Universe players. It provides:
|
||||||
|
|
||||||
|
- Quick access to calculators and trackers
|
||||||
|
- Real-time game data integration
|
||||||
|
- Customizable hotkeys for instant access
|
||||||
|
- Modular plugin system for extensibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### System Requirements
|
||||||
|
|
||||||
|
- **OS:** Windows 10/11 (full support) or Linux (limited support)
|
||||||
|
- **Python:** 3.11 or higher
|
||||||
|
- **Memory:** 4GB RAM minimum
|
||||||
|
- **Storage:** 100MB free space
|
||||||
|
|
||||||
|
### Step-by-Step Installation
|
||||||
|
|
||||||
|
1. **Download the application:**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/ImpulsiveFPS/EU-Utility.git
|
||||||
|
cd EU-Utility
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install dependencies:**
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verify installation:**
|
||||||
|
```bash
|
||||||
|
python -m pytest tests/unit/ -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional Dependencies
|
||||||
|
|
||||||
|
For OCR (text recognition) features:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Recommended - Auto-installs
|
||||||
|
pip install easyocr
|
||||||
|
|
||||||
|
# OR Tesseract (alternative)
|
||||||
|
pip install pytesseract
|
||||||
|
|
||||||
|
# OR PaddleOCR (advanced)
|
||||||
|
pip install paddleocr
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## First Launch
|
||||||
|
|
||||||
|
### Starting EU-Utility
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m core.main
|
||||||
|
```
|
||||||
|
|
||||||
|
### What You'll See
|
||||||
|
|
||||||
|
1. **Floating Icon** - A small icon appears on your screen
|
||||||
|
2. **System Tray** - EU-Utility icon appears in your system tray
|
||||||
|
3. **Initial Setup** - First-time configuration wizard (if applicable)
|
||||||
|
|
||||||
|
### The Floating Icon
|
||||||
|
|
||||||
|
| Action | Result |
|
||||||
|
|--------|--------|
|
||||||
|
| **Double-click** | Open main overlay |
|
||||||
|
| **Right-click** | Context menu |
|
||||||
|
| **Drag** | Move to preferred position |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Main Interface
|
||||||
|
|
||||||
|
### Overlay Window
|
||||||
|
|
||||||
|
The main overlay consists of:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ EU-Utility v2.0 [_][X] │
|
||||||
|
├──────────┬──────────────────────────────────────────┤
|
||||||
|
│ │ │
|
||||||
|
│ Plugins │ │
|
||||||
|
│ │ Plugin Content Area │
|
||||||
|
│ • Search │ │
|
||||||
|
│ • Calc │ │
|
||||||
|
│ • Track │ │
|
||||||
|
│ • ... │ │
|
||||||
|
│ │ │
|
||||||
|
├──────────┴──────────────────────────────────────────┤
|
||||||
|
│ [Theme] [Settings] │
|
||||||
|
└─────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
|
||||||
|
- **Sidebar:** Click plugin names to switch
|
||||||
|
- **Keyboard:** Press `Ctrl+1` through `Ctrl+9` to switch plugins
|
||||||
|
- **Search:** Use the search box for quick plugin access
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
### Built-in Plugins
|
||||||
|
|
||||||
|
#### Search & Information
|
||||||
|
- **Universal Search** - Search all Nexus entities
|
||||||
|
- **Nexus Search** - Item and market data search
|
||||||
|
|
||||||
|
#### Calculators
|
||||||
|
- **DPP Calculator** - Damage Per PEC calculation
|
||||||
|
- **Crafting Calculator** - Blueprint success rates
|
||||||
|
- **Enhancer Calculator** - Break rate analysis
|
||||||
|
|
||||||
|
#### Trackers
|
||||||
|
- **Loot Tracker** - Hunting loot tracking
|
||||||
|
- **Skill Scanner** - Skill gain monitoring
|
||||||
|
- **Codex Tracker** - Creature challenge progress
|
||||||
|
|
||||||
|
#### Game Integration
|
||||||
|
- **Game Reader** - OCR for in-game text
|
||||||
|
- **Chat Logger** - Chat log analysis
|
||||||
|
|
||||||
|
### Enabling/Disabling Plugins
|
||||||
|
|
||||||
|
1. Open Settings (`Ctrl+Shift+,`)
|
||||||
|
2. Go to "Plugins" tab
|
||||||
|
3. Check/uncheck plugins to enable/disable
|
||||||
|
4. Click "Save Changes"
|
||||||
|
|
||||||
|
### Installing New Plugins
|
||||||
|
|
||||||
|
1. Open Settings
|
||||||
|
2. Go to "Plugin Store" tab
|
||||||
|
3. Browse available plugins
|
||||||
|
4. Click "Install" on desired plugin
|
||||||
|
5. Restart EU-Utility if required
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hotkeys
|
||||||
|
|
||||||
|
### Default Hotkeys
|
||||||
|
|
||||||
|
| Hotkey | Action | Scope |
|
||||||
|
|--------|--------|-------|
|
||||||
|
| `Ctrl+Shift+U` | Toggle overlay | Global |
|
||||||
|
| `Ctrl+Shift+H` | Hide all overlays | Global |
|
||||||
|
| `Ctrl+Shift+F` | Universal Search | Global |
|
||||||
|
| `Ctrl+Shift+N` | Nexus Search | Global |
|
||||||
|
| `Ctrl+Shift+C` | Calculator | Global |
|
||||||
|
| `Ctrl+Shift+D` | DPP Calculator | Global |
|
||||||
|
| `Ctrl+Shift+E` | Enhancer Calc | Global |
|
||||||
|
| `Ctrl+Shift+B` | Crafting Calc | Global |
|
||||||
|
| `Ctrl+Shift+L` | Loot Tracker | Global |
|
||||||
|
| `Ctrl+Shift+S` | Skill Scanner | Global |
|
||||||
|
| `Ctrl+Shift+X` | Codex Tracker | Global |
|
||||||
|
| `Ctrl+Shift+R` | Game Reader | Global |
|
||||||
|
| `Ctrl+Shift+M` | Spotify | Global |
|
||||||
|
| `Ctrl+Shift+Home` | Dashboard | Global |
|
||||||
|
| `Ctrl+Shift+,` | Settings | Global |
|
||||||
|
|
||||||
|
### Customizing Hotkeys
|
||||||
|
|
||||||
|
1. Open Settings
|
||||||
|
2. Go to "Hotkeys" tab
|
||||||
|
3. Click on the action you want to change
|
||||||
|
4. Press your desired key combination
|
||||||
|
5. Click "Save Changes"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
### General Settings
|
||||||
|
|
||||||
|
**Appearance:**
|
||||||
|
- Theme (Dark/Light)
|
||||||
|
- Overlay opacity
|
||||||
|
- Font size
|
||||||
|
|
||||||
|
**Behavior:**
|
||||||
|
- Auto-hide delay
|
||||||
|
- Startup with Windows
|
||||||
|
- Minimize to tray
|
||||||
|
|
||||||
|
**Notifications:**
|
||||||
|
- Enable/disable notifications
|
||||||
|
- Sound alerts
|
||||||
|
- Notification duration
|
||||||
|
|
||||||
|
### Plugin Settings
|
||||||
|
|
||||||
|
Each plugin may have its own settings:
|
||||||
|
|
||||||
|
1. Select the plugin in the sidebar
|
||||||
|
2. Look for a settings icon (⚙️) or menu
|
||||||
|
3. Adjust settings as needed
|
||||||
|
|
||||||
|
### Advanced Settings
|
||||||
|
|
||||||
|
Edit `config/settings.json` directly for advanced options:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hotkeys": {
|
||||||
|
"toggle": "ctrl+shift+u"
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"mode": "dark",
|
||||||
|
"opacity": 0.95
|
||||||
|
},
|
||||||
|
"overlay": {
|
||||||
|
"always_on_top": true,
|
||||||
|
"remember_position": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tips & Tricks
|
||||||
|
|
||||||
|
### Performance Optimization
|
||||||
|
|
||||||
|
1. **Disable unused plugins** - Reduces memory usage
|
||||||
|
2. **Adjust cache settings** - Balance speed vs memory
|
||||||
|
3. **Use appropriate OCR backend** - EasyOCR is fastest
|
||||||
|
|
||||||
|
### Productivity Tips
|
||||||
|
|
||||||
|
1. **Pin frequently used plugins** - Right-click in activity bar
|
||||||
|
2. **Use search** - Faster than browsing
|
||||||
|
3. **Learn hotkeys** - Instant access without mouse
|
||||||
|
|
||||||
|
### Customization
|
||||||
|
|
||||||
|
1. **Create custom dashboard** - Arrange widgets as you like
|
||||||
|
2. **Configure auto-hide** - Activity bar hides when not in use
|
||||||
|
3. **Adjust transparency** - Match your game aesthetic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Q: EU-Utility doesn't start
|
||||||
|
|
||||||
|
**A:** Check:
|
||||||
|
1. Python 3.11+ is installed
|
||||||
|
2. All dependencies are installed: `pip install -r requirements.txt`
|
||||||
|
3. Check logs in `logs/` directory
|
||||||
|
|
||||||
|
### Q: Hotkeys don't work
|
||||||
|
|
||||||
|
**A:**
|
||||||
|
1. Check if another application is using the same hotkeys
|
||||||
|
2. Run as administrator (Windows)
|
||||||
|
3. Verify hotkeys in Settings → Hotkeys
|
||||||
|
|
||||||
|
### Q: OCR not working
|
||||||
|
|
||||||
|
**A:**
|
||||||
|
1. Install OCR backend: `pip install easyocr`
|
||||||
|
2. Check if Tesseract is in PATH (if using pytesseract)
|
||||||
|
3. Verify screen region is correct
|
||||||
|
|
||||||
|
### Q: Overlay doesn't stay on top
|
||||||
|
|
||||||
|
**A:**
|
||||||
|
1. Check "Always on top" in settings
|
||||||
|
2. Some games may prevent overlays - run EU-Utility as administrator
|
||||||
|
|
||||||
|
### Q: How do I update EU-Utility?
|
||||||
|
|
||||||
|
**A:**
|
||||||
|
```bash
|
||||||
|
git pull origin main
|
||||||
|
pip install -r requirements.txt --upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: Can I create my own plugins?
|
||||||
|
|
||||||
|
**A:** Yes! See [Plugin Development Guide](./docs/PLUGIN_DEVELOPMENT_GUIDE.md)
|
||||||
|
|
||||||
|
### Q: Where is my data stored?
|
||||||
|
|
||||||
|
**A:**
|
||||||
|
- Settings: `config/settings.json`
|
||||||
|
- Plugin data: `data/`
|
||||||
|
- Logs: `logs/`
|
||||||
|
|
||||||
|
### Q: Is EU-Utility safe to use?
|
||||||
|
|
||||||
|
**A:** Yes. EU-Utility:
|
||||||
|
- Only reads game data (logs, screen)
|
||||||
|
- Doesn't modify game files
|
||||||
|
- Doesn't inject code into the game
|
||||||
|
- Is open source - you can verify the code
|
||||||
|
|
||||||
|
### Q: How do I report bugs?
|
||||||
|
|
||||||
|
**A:**
|
||||||
|
1. Check [Troubleshooting Guide](./TROUBLESHOOTING.md)
|
||||||
|
2. Open an issue on GitHub with:
|
||||||
|
- EU-Utility version
|
||||||
|
- Operating system
|
||||||
|
- Steps to reproduce
|
||||||
|
- Error logs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
- **Documentation:** Check `docs/` folder
|
||||||
|
- **Issues:** GitHub Issues
|
||||||
|
- **Discussions:** GitHub Discussions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Happy hunting in Entropia Universe!** 🎮
|
||||||
|
|
@ -0,0 +1,198 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
EU-Utility Test Runner
|
||||||
|
======================
|
||||||
|
|
||||||
|
Comprehensive test runner with coverage reporting and result formatting.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python run_tests.py [options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--unit Run unit tests only
|
||||||
|
--integration Run integration tests only
|
||||||
|
--ui Run UI tests only
|
||||||
|
--performance Run performance tests only
|
||||||
|
--all Run all tests (default)
|
||||||
|
--coverage Generate coverage report
|
||||||
|
--html Generate HTML coverage report
|
||||||
|
--xml Generate XML coverage report for CI
|
||||||
|
--verbose, -v Verbose output
|
||||||
|
--fail-fast Stop on first failure
|
||||||
|
--markers Show available test markers
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
python run_tests.py --unit --coverage
|
||||||
|
python run_tests.py --all --html
|
||||||
|
python run_tests.py --performance
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Add project root to path
|
||||||
|
project_root = Path(__file__).parent
|
||||||
|
sys.path.insert(0, str(project_root))
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(cmd, description=""):
|
||||||
|
"""Run a command and return result."""
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f"Running: {description or ' '.join(cmd)}")
|
||||||
|
print('='*60)
|
||||||
|
|
||||||
|
result = subprocess.run(cmd, capture_output=False)
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def run_unit_tests(args):
|
||||||
|
"""Run unit tests."""
|
||||||
|
cmd = ["python", "-m", "pytest", "tests/unit/", "-v" if args.verbose else "-q"]
|
||||||
|
|
||||||
|
if args.fail_fast:
|
||||||
|
cmd.append("-x")
|
||||||
|
|
||||||
|
if args.coverage:
|
||||||
|
cmd.extend(["--cov=core", "--cov=plugins"])
|
||||||
|
|
||||||
|
if args.html and args.coverage:
|
||||||
|
cmd.extend(["--cov-report=html", "--cov-report=term"])
|
||||||
|
elif args.xml and args.coverage:
|
||||||
|
cmd.extend(["--cov-report=xml", "--cov-report=term"])
|
||||||
|
elif args.coverage:
|
||||||
|
cmd.append("--cov-report=term")
|
||||||
|
|
||||||
|
return run_command(cmd, "Unit Tests")
|
||||||
|
|
||||||
|
|
||||||
|
def run_integration_tests(args):
|
||||||
|
"""Run integration tests."""
|
||||||
|
cmd = ["python", "-m", "pytest", "tests/integration/", "-v" if args.verbose else "-q", "-m", "integration"]
|
||||||
|
|
||||||
|
if args.fail_fast:
|
||||||
|
cmd.append("-x")
|
||||||
|
|
||||||
|
if args.coverage:
|
||||||
|
cmd.extend(["--cov=core", "--cov=plugins", "--cov-append"])
|
||||||
|
|
||||||
|
return run_command(cmd, "Integration Tests")
|
||||||
|
|
||||||
|
|
||||||
|
def run_ui_tests(args):
|
||||||
|
"""Run UI tests."""
|
||||||
|
cmd = ["python", "-m", "pytest", "tests/ui/", "-v" if args.verbose else "-q", "-m", "ui"]
|
||||||
|
|
||||||
|
if args.fail_fast:
|
||||||
|
cmd.append("-x")
|
||||||
|
|
||||||
|
# Check if pytest-qt is available
|
||||||
|
try:
|
||||||
|
import pytestqt
|
||||||
|
cmd.extend(["--qt-api=pyqt6"])
|
||||||
|
except ImportError:
|
||||||
|
print("Warning: pytest-qt not installed, UI tests may fail")
|
||||||
|
print("Install with: pip install pytest-qt")
|
||||||
|
|
||||||
|
return run_command(cmd, "UI Tests")
|
||||||
|
|
||||||
|
|
||||||
|
def run_performance_tests(args):
|
||||||
|
"""Run performance tests."""
|
||||||
|
cmd = ["python", "-m", "pytest", "tests/performance/", "-v" if args.verbose else "-q", "--benchmark-only"]
|
||||||
|
|
||||||
|
# Check if pytest-benchmark is available
|
||||||
|
try:
|
||||||
|
import pytest_benchmark
|
||||||
|
except ImportError:
|
||||||
|
print("Warning: pytest-benchmark not installed")
|
||||||
|
print("Install with: pip install pytest-benchmark")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return run_command(cmd, "Performance Tests")
|
||||||
|
|
||||||
|
|
||||||
|
def show_markers():
|
||||||
|
"""Show available test markers."""
|
||||||
|
cmd = ["python", "-m", "pytest", "--markers"]
|
||||||
|
return run_command(cmd, "Available Markers")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="EU-Utility Test Runner",
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
epilog="""
|
||||||
|
Examples:
|
||||||
|
python run_tests.py # Run all tests
|
||||||
|
python run_tests.py --unit # Run unit tests only
|
||||||
|
python run_tests.py --unit --coverage # Run unit tests with coverage
|
||||||
|
python run_tests.py --all --html # Run all tests, generate HTML report
|
||||||
|
python run_tests.py --performance # Run performance benchmarks
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test categories
|
||||||
|
parser.add_argument("--unit", action="store_true", help="Run unit tests only")
|
||||||
|
parser.add_argument("--integration", action="store_true", help="Run integration tests only")
|
||||||
|
parser.add_argument("--ui", action="store_true", help="Run UI tests only")
|
||||||
|
parser.add_argument("--performance", action="store_true", help="Run performance tests only")
|
||||||
|
parser.add_argument("--all", action="store_true", help="Run all tests (default)")
|
||||||
|
|
||||||
|
# Coverage options
|
||||||
|
parser.add_argument("--coverage", action="store_true", help="Generate coverage report")
|
||||||
|
parser.add_argument("--html", action="store_true", help="Generate HTML coverage report")
|
||||||
|
parser.add_argument("--xml", action="store_true", help="Generate XML coverage report")
|
||||||
|
|
||||||
|
# Output options
|
||||||
|
parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
|
||||||
|
parser.add_argument("--fail-fast", "-x", action="store_true", help="Stop on first failure")
|
||||||
|
parser.add_argument("--markers", action="store_true", help="Show available test markers")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Show markers if requested
|
||||||
|
if args.markers:
|
||||||
|
return show_markers()
|
||||||
|
|
||||||
|
# Determine which tests to run
|
||||||
|
run_all = args.all or not any([args.unit, args.integration, args.ui, args.performance])
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
if run_all or args.unit:
|
||||||
|
results.append(run_unit_tests(args))
|
||||||
|
|
||||||
|
if run_all or args.integration:
|
||||||
|
results.append(run_integration_tests(args))
|
||||||
|
|
||||||
|
if run_all or args.ui:
|
||||||
|
results.append(run_ui_tests(args))
|
||||||
|
|
||||||
|
if run_all or args.performance:
|
||||||
|
results.append(run_performance_tests(args))
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("TEST SUMMARY")
|
||||||
|
print("="*60)
|
||||||
|
|
||||||
|
passed = sum(results)
|
||||||
|
failed = len(results) - passed
|
||||||
|
|
||||||
|
print(f"Test suites run: {len(results)}")
|
||||||
|
print(f"Passed: {passed}")
|
||||||
|
print(f"Failed: {failed}")
|
||||||
|
|
||||||
|
if all(results):
|
||||||
|
print("\n✓ All tests passed!")
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print("\n✗ Some tests failed")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Loading…
Reference in New Issue