refactor: Fix __init__.py - remove duplicates, add lazy loading for Qt deps
This commit is contained in:
parent
b2ec4e2f0f
commit
6f3b6f6781
|
|
@ -0,0 +1,533 @@
|
||||||
|
# EU-Utility Architecture
|
||||||
|
|
||||||
|
> System architecture, component design, and data flow documentation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System Overview
|
||||||
|
|
||||||
|
EU-Utility is built on a **modular plugin architecture** with clear separation of concerns. The system is organized into three main layers:
|
||||||
|
|
||||||
|
1. **Core Layer** - Foundation services and APIs
|
||||||
|
2. **Plugin Layer** - Extensible functionality modules
|
||||||
|
3. **UI Layer** - User interface components and overlays
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ UI Layer │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
|
||||||
|
│ │ Overlay │ │ Widgets │ │ Activity Bar │ │
|
||||||
|
│ │ Window │ │ (Draggable)│ │ (Taskbar + App Drawer) │ │
|
||||||
|
│ └──────┬──────┘ └──────┬──────┘ └───────────┬─────────────┘ │
|
||||||
|
└─────────┼────────────────┼─────────────────────┼────────────────┘
|
||||||
|
│ │ │
|
||||||
|
└────────────────┴──────────┬──────────┘
|
||||||
|
│
|
||||||
|
┌─────────────────────────────────────┼─────────────────────────────┐
|
||||||
|
│ Plugin Layer │ │
|
||||||
|
│ ┌──────────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
|
||||||
|
│ │ │ Search │ │ Calculator│ │ Tracker │ │ Scanner │ │
|
||||||
|
│ │ │ Plugins │ │ Plugins │ │ Plugins │ │ Plugins │ │
|
||||||
|
│ │ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
|
||||||
|
│ │ │ │ │ │ │
|
||||||
|
│ │ └─────────────┴──────┬──────┴─────────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌────────┴────────┐ │
|
||||||
|
│ │ │ BasePlugin API │ │
|
||||||
|
│ │ │ (Base Class) │ │
|
||||||
|
│ │ └────────┬────────┘ │
|
||||||
|
│ └─────────────────────────────┼─────────────────────────────────┘
|
||||||
|
└────────────────────────────────┼─────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌────────────────────────────────┼─────────────────────────────────┐
|
||||||
|
│ Core Layer│ │
|
||||||
|
│ ┌─────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ │ ┌──────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ │ Three-Tier API System │ │
|
||||||
|
│ │ ├───────────────┬───────────────┬───────────────────────┤ │
|
||||||
|
│ │ │ PluginAPI │ WidgetAPI │ ExternalAPI │ │
|
||||||
|
│ │ │ (Services) │ (Overlays) │ (REST/Webhooks) │ │
|
||||||
|
│ │ └───────┬───────┴───────┬───────┴───────────┬───────────┘ │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ │ ┌───────┴───────┐ ┌─────┴─────┐ ┌───────────┴──────────┐ │
|
||||||
|
│ │ │ Core Services │ │ Event │ │ Data Layer │ │
|
||||||
|
│ │ │ │ │ Bus │ │ │ │
|
||||||
|
│ │ │ • Window Mgr │ │ (Pub/Sub) │ │ • SQLite Store │ │
|
||||||
|
│ │ │ • OCR Service │ │ │ │ • Settings │ │
|
||||||
|
│ │ │ • Screenshot │ │ │ │ • Plugin States │ │
|
||||||
|
│ │ │ • Log Reader │ │ │ │ • Activity Log │ │
|
||||||
|
│ │ │ • Nexus API │ │ │ │ │ │
|
||||||
|
│ │ │ • HTTP Client │ │ │ │ │ │
|
||||||
|
│ │ │ • Audio │ │ │ │ │ │
|
||||||
|
│ │ └───────────────┘ └───────────┘ └──────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ │ ┌──────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ │ Plugin Manager │ │
|
||||||
|
│ │ │ (Discovery, Loading, Lifecycle, Dependencies) │ │
|
||||||
|
│ │ └──────────────────────────────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ └────────────────────────────────────────────────────────────────┘
|
||||||
|
└────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Core Layer
|
||||||
|
|
||||||
|
### Three-Tier API System
|
||||||
|
|
||||||
|
The Core provides a unified API organized into three tiers:
|
||||||
|
|
||||||
|
#### 1. PluginAPI
|
||||||
|
Primary interface for plugin developers to access core services.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.api import get_api
|
||||||
|
|
||||||
|
api = get_api()
|
||||||
|
|
||||||
|
# Window Management
|
||||||
|
window = api.get_eu_window()
|
||||||
|
is_focused = api.is_eu_focused()
|
||||||
|
|
||||||
|
# OCR
|
||||||
|
if api.ocr_available():
|
||||||
|
text = api.recognize_text(region=(100, 100, 200, 50))
|
||||||
|
|
||||||
|
# Data Storage
|
||||||
|
api.set_data("key", value)
|
||||||
|
value = api.get_data("key", default)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Available Services:**
|
||||||
|
- `LogReader` - Read and monitor Entropia Universe chat logs
|
||||||
|
- `WindowManager` - Detect and interact with EU window
|
||||||
|
- `OCRService` - Screen text recognition (EasyOCR/Tesseract/PaddleOCR)
|
||||||
|
- `Screenshot` - Screen capture with multiple backends
|
||||||
|
- `NexusAPI` - Entropia Nexus item database integration
|
||||||
|
- `HTTPClient` - Cached web requests with rate limiting
|
||||||
|
- `Audio` - Sound playback and volume control
|
||||||
|
- `Clipboard` - Cross-platform copy/paste
|
||||||
|
- `Notifications` - Desktop toast notifications
|
||||||
|
- `EventBus` - Pub/sub event system
|
||||||
|
- `DataStore` - Persistent key-value storage
|
||||||
|
- `TaskManager` - Background task execution
|
||||||
|
|
||||||
|
#### 2. WidgetAPI
|
||||||
|
Manages overlay widgets - floating UI components.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.api import get_widget_api
|
||||||
|
|
||||||
|
widget_api = get_widget_api()
|
||||||
|
|
||||||
|
# Create widget
|
||||||
|
widget = widget_api.create_widget(
|
||||||
|
name="loot_tracker",
|
||||||
|
title="Loot Tracker",
|
||||||
|
size=(400, 300)
|
||||||
|
)
|
||||||
|
|
||||||
|
widget.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Draggable overlay widgets
|
||||||
|
- Size and position persistence
|
||||||
|
- Opacity control
|
||||||
|
- Lock/unlock positioning
|
||||||
|
- Layout helpers (grid, cascade)
|
||||||
|
|
||||||
|
#### 3. ExternalAPI
|
||||||
|
Provides REST endpoints and webhook support for third-party integrations.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from core.api import get_external_api
|
||||||
|
|
||||||
|
ext = get_external_api()
|
||||||
|
ext.start_server(port=8080)
|
||||||
|
|
||||||
|
# Register endpoint
|
||||||
|
@ext.endpoint("stats", methods=["GET"])
|
||||||
|
def get_stats():
|
||||||
|
return {"kills": 100, "loot": "50 PED"}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- REST API server with CORS
|
||||||
|
- Incoming/outgoing webhooks
|
||||||
|
- HMAC authentication
|
||||||
|
- IPC (Inter-Process Communication)
|
||||||
|
- Server-Sent Events (SSE)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugin Layer
|
||||||
|
|
||||||
|
### Plugin Architecture
|
||||||
|
|
||||||
|
All plugins inherit from `BasePlugin` and implement a standard interface:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ BasePlugin (Abstract) │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ Metadata: name, version, author, etc. │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ initialize() → Setup plugin │
|
||||||
|
│ get_ui() → Return QWidget │
|
||||||
|
│ on_show() → Overlay visible │
|
||||||
|
│ on_hide() → Overlay hidden │
|
||||||
|
│ on_hotkey() → Hotkey pressed │
|
||||||
|
│ shutdown() → Cleanup resources │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ Helper Methods: │
|
||||||
|
│ • OCR capture │
|
||||||
|
│ • Screenshot │
|
||||||
|
│ • Log reading │
|
||||||
|
│ • Data storage │
|
||||||
|
│ • Event publishing/subscribing │
|
||||||
|
│ • Nexus API access │
|
||||||
|
│ • Background tasks │
|
||||||
|
│ • Notifications │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌───────────┼───────────┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||||
|
│ Search │ │ Tracker │ │Utility │
|
||||||
|
│ Plugins │ │ Plugins │ │ Plugins │
|
||||||
|
└─────────┘ └─────────┘ └─────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plugin Categories
|
||||||
|
|
||||||
|
| Category | Purpose | Examples |
|
||||||
|
|----------|---------|----------|
|
||||||
|
| **Search** | Data lookup | Universal Search, Nexus Search, TP Runner |
|
||||||
|
| **Trackers** | Progress monitoring | Loot, Skills, Codex, Missions, Globals |
|
||||||
|
| **Calculators** | Game math | DPP, Crafting, Enhancer, Markup |
|
||||||
|
| **Scanners** | OCR-based tools | Game Reader, Skill Scanner |
|
||||||
|
| **Integration** | External services | Spotify Controller, Chat Logger |
|
||||||
|
| **System** | Core functionality | Dashboard, Settings, Plugin Store |
|
||||||
|
|
||||||
|
### Plugin Lifecycle
|
||||||
|
|
||||||
|
```
|
||||||
|
Discovery
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────┐
|
||||||
|
│ Import │
|
||||||
|
└────┬─────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────┐ No ┌──────────┐
|
||||||
|
│ Enabled? │───────────▶│ Skip │
|
||||||
|
└────┬─────┘ └──────────┘
|
||||||
|
│ Yes
|
||||||
|
▼
|
||||||
|
┌──────────┐
|
||||||
|
│ Load │
|
||||||
|
│ Module │
|
||||||
|
└────┬─────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────┐ Error ┌──────────┐
|
||||||
|
│Initialize│───────────▶│ Disable │
|
||||||
|
└────┬─────┘ └──────────┘
|
||||||
|
│ Success
|
||||||
|
▼
|
||||||
|
┌──────────┐
|
||||||
|
│ Running │◀───────┐
|
||||||
|
└────┬─────┘ │
|
||||||
|
│ │
|
||||||
|
▼ │
|
||||||
|
┌──────────┐ │
|
||||||
|
│ Hotkey │ │
|
||||||
|
│ Pressed │────────┘
|
||||||
|
└──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────┐
|
||||||
|
│ Shutdown │
|
||||||
|
└──────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Event System
|
||||||
|
|
||||||
|
### Event Bus Architecture
|
||||||
|
|
||||||
|
The Event Bus provides typed, filterable pub/sub communication:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ Event Bus │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ Publisher ─────┐ │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌─────────────────────────┐ │
|
||||||
|
│ │ Event Router │ │
|
||||||
|
│ │ (Type + Filter Match) │ │
|
||||||
|
│ └────────────┬────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌───────────┼───────────┐ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌──────┐ ┌──────┐ ┌──────┐ │
|
||||||
|
│ │ Sub │ │ Sub │ │ Sub │ │
|
||||||
|
│ │ #1 │ │ #2 │ │ #3 │ │
|
||||||
|
│ └──────┘ └──────┘ └──────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ Plugin A Plugin B Plugin C │
|
||||||
|
│ │
|
||||||
|
│ ┌────────────────────────────────────────────┐ │
|
||||||
|
│ │ Event Types: │ │
|
||||||
|
│ │ • SkillGainEvent │ │
|
||||||
|
│ │ • LootEvent │ │
|
||||||
|
│ │ • DamageEvent │ │
|
||||||
|
│ │ • GlobalEvent │ │
|
||||||
|
│ │ • ChatEvent │ │
|
||||||
|
│ │ • EconomyEvent │ │
|
||||||
|
│ │ • SystemEvent │ │
|
||||||
|
│ └────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Event Flow Example
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Plugin A publishes loot event
|
||||||
|
from core.event_bus import LootEvent
|
||||||
|
|
||||||
|
self.publish_typed(LootEvent(
|
||||||
|
mob_name="Daikiba",
|
||||||
|
items=[{"name": "Animal Oil", "value": 0.05}],
|
||||||
|
total_tt_value=0.05
|
||||||
|
))
|
||||||
|
|
||||||
|
# Plugin B subscribes with filter
|
||||||
|
self.subscribe_typed(
|
||||||
|
LootEvent,
|
||||||
|
on_loot,
|
||||||
|
mob_types=["Daikiba", "Atrox"] # Filter
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
### Data Layer Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ Data Layer │
|
||||||
|
├─────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────┐ │
|
||||||
|
│ │ SQLite Data Store │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌─────────────┐ ┌─────────────┐ │ │
|
||||||
|
│ │ │user_prefs │ │plugin_states│ │ │
|
||||||
|
│ │ ├─────────────┤ ├─────────────┤ │ │
|
||||||
|
│ │ │• settings │ │• enabled │ │ │
|
||||||
|
│ │ │• hotkeys │ │• version │ │ │
|
||||||
|
│ │ │• theme │ │• settings │ │ │
|
||||||
|
│ │ └─────────────┘ └─────────────┘ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌─────────────┐ ┌─────────────┐ │ │
|
||||||
|
│ │ │sessions │ │activity_log │ │ │
|
||||||
|
│ │ ├─────────────┤ ├─────────────┤ │ │
|
||||||
|
│ │ │• start_time │ │• timestamp │ │ │
|
||||||
|
│ │ │• end_time │ │• category │ │ │
|
||||||
|
│ │ │• stats │ │• action │ │ │
|
||||||
|
│ │ └─────────────┘ └─────────────┘ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌─────────────┐ ┌─────────────┐ │ │
|
||||||
|
│ │ │dashboard │ │hotkeys │ │ │
|
||||||
|
│ │ │_widgets │ │ │ │ │
|
||||||
|
│ │ ├─────────────┤ ├─────────────┤ │ │
|
||||||
|
│ │ │• position │ │• key_combo │ │ │
|
||||||
|
│ │ │• size │ │• action │ │ │
|
||||||
|
│ │ │• config │ │• plugin_id │ │ │
|
||||||
|
│ │ └─────────────┘ └─────────────┘ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ └─────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Data Access Pattern │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ Plugin ──▶ API ──▶ SQLiteStore ──▶ SQLite DB │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ All data is JSON-serialized for flexibility │ │
|
||||||
|
│ └─────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UI Architecture
|
||||||
|
|
||||||
|
### Overlay System
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Desktop │
|
||||||
|
│ ┌─────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Main Overlay Window │ │
|
||||||
|
│ │ ┌─────────────────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Plugin Tab Bar │ │ │
|
||||||
|
│ │ │ [Dash][Search][Calc][Track][...] │ │ │
|
||||||
|
│ │ └─────────────────────────────────────────────┘ │ │
|
||||||
|
│ │ ┌─────────┬──────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Plugin │ │ │ │
|
||||||
|
│ │ │ List │ Active Plugin Content │ │ │
|
||||||
|
│ │ │ │ │ │ │
|
||||||
|
│ │ │ • Search│ ┌──────────────────────┐ │ │ │
|
||||||
|
│ │ │ • Calc │ │ │ │ │ │
|
||||||
|
│ │ │ • Track │ │ Plugin UI Here │ │ │ │
|
||||||
|
│ │ │ • ... │ │ │ │ │ │
|
||||||
|
│ │ │ │ └──────────────────────┘ │ │ │
|
||||||
|
│ │ └─────────┴──────────────────────────────────┘ │ │
|
||||||
|
│ │ ┌─────────────────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Quick Actions Bar │ │ │
|
||||||
|
│ │ └─────────────────────────────────────────────┘ │ │
|
||||||
|
│ └─────────────────────────────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌─────────────────┼─────────────────┐ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ Floating │ │ Widget │ │ Activity │ │
|
||||||
|
│ │ Icon │ │ (Loot) │ │ Bar │ │
|
||||||
|
│ │ (Draggable)│ │ (Draggable)│ │(Bottom/Top) │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component Hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
QApplication
|
||||||
|
└── EUUtilityApp
|
||||||
|
├── MainOverlayWindow
|
||||||
|
│ ├── PluginTabBar
|
||||||
|
│ ├── PluginSidebar
|
||||||
|
│ ├── PluginContentArea
|
||||||
|
│ └── QuickActionsBar
|
||||||
|
├── FloatingIcon (always on top)
|
||||||
|
├── ActivityBar (optional, bottom/top)
|
||||||
|
│ ├── StartButton (opens AppDrawer)
|
||||||
|
│ ├── PinnedPlugins
|
||||||
|
│ ├── SearchBox
|
||||||
|
│ └── Clock/Settings
|
||||||
|
├── WidgetOverlay
|
||||||
|
│ └── Individual Widgets
|
||||||
|
└── TrayIcon
|
||||||
|
└── ContextMenu
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Architecture
|
||||||
|
|
||||||
|
### Data Protection
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ Security Layer │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────┐ │
|
||||||
|
│ │ Input Sanitization │ │
|
||||||
|
│ │ • Path traversal protection │ │
|
||||||
|
│ │ • SQL injection prevention │ │
|
||||||
|
│ │ • XSS protection │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────┐ │
|
||||||
|
│ │ Data Encryption │ │
|
||||||
|
│ │ • AES-256 for sensitive data │ │
|
||||||
|
│ │ • Secure key storage │ │
|
||||||
|
│ │ • Encrypted settings │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────┐ │
|
||||||
|
│ │ File Operations │ │
|
||||||
|
│ │ • Atomic writes (temp files) │ │
|
||||||
|
│ │ • Proper file permissions │ │
|
||||||
|
│ │ • Safe temp file handling │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────┐ │
|
||||||
|
│ │ Plugin Isolation │ │
|
||||||
|
│ │ • Try/except around plugin ops │ │
|
||||||
|
│ │ • Separate error handling │ │
|
||||||
|
│ │ • Resource cleanup on crash │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Optimizations
|
||||||
|
|
||||||
|
### Caching Strategy
|
||||||
|
|
||||||
|
| Layer | Cache Type | TTL | Purpose |
|
||||||
|
|-------|------------|-----|---------|
|
||||||
|
| HTTP Client | Response cache | Configurable | API responses |
|
||||||
|
| Nexus API | Item data | 5 minutes | Item/market data |
|
||||||
|
| Icon Manager | Loaded icons | Session | UI performance |
|
||||||
|
| Plugin Manager | Loaded plugins | Session | Startup time |
|
||||||
|
| Settings | Config values | Session | Fast access |
|
||||||
|
|
||||||
|
### Resource Management
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Lazy initialization pattern
|
||||||
|
class ExpensiveService:
|
||||||
|
def __init__(self):
|
||||||
|
self._initialized = False
|
||||||
|
self._resource = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource(self):
|
||||||
|
if not self._initialized:
|
||||||
|
self._resource = self._create_expensive_resource()
|
||||||
|
self._initialized = True
|
||||||
|
return self._resource
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technology Stack
|
||||||
|
|
||||||
|
| Component | Technology |
|
||||||
|
|-----------|------------|
|
||||||
|
| **Language** | Python 3.11+ |
|
||||||
|
| **UI Framework** | PyQt6 |
|
||||||
|
| **Database** | SQLite |
|
||||||
|
| **HTTP Client** | `requests` with caching |
|
||||||
|
| **OCR** | EasyOCR / Tesseract / PaddleOCR |
|
||||||
|
| **Screenshot** | PIL / MSS / Win32 (Windows) |
|
||||||
|
| **Audio** | pygame.mixer / simpleaudio |
|
||||||
|
| **Task Queue** | ThreadPoolExecutor |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [API Reference](./API.md) - Complete API documentation
|
||||||
|
- [Plugin Development](./docs/PLUGIN_DEVELOPMENT.md) - Creating plugins
|
||||||
|
- [Contributing](./CONTRIBUTING.md) - Contribution guidelines
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
# EU-Utility - MANIFEST.in
|
||||||
|
# Controls what files are included in the source distribution (sdist)
|
||||||
|
# https://packaging.python.org/en/latest/guides/using-manifest-in/
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# INCLUDE PATTERNS
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Core package files
|
||||||
|
recursive-include core *.py
|
||||||
|
recursive-include core *.json *.yaml *.yml
|
||||||
|
recursive-include core *.css *.qss *.ui
|
||||||
|
recursive-include core *.png *.jpg *.jpeg *.gif *.ico *.svg
|
||||||
|
|
||||||
|
# Plugin files
|
||||||
|
recursive-include plugins *.py
|
||||||
|
recursive-include plugins *.json *.yaml *.yml
|
||||||
|
recursive-include plugins *.css *.qss *.ui
|
||||||
|
recursive-include plugins/assets *.png *.jpg *.jpeg *.gif *.ico *.svg *.ttf *.woff *.woff2
|
||||||
|
recursive-include plugins/templates *.html *.txt *.md
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
recursive-include docs *.md *.rst *.txt
|
||||||
|
recursive-include docs *.png *.jpg *.jpeg *.gif *.svg
|
||||||
|
include README.md
|
||||||
|
include CONTRIBUTING.md
|
||||||
|
include CHANGELOG.md
|
||||||
|
include SECURITY_AUDIT_REPORT.md
|
||||||
|
include LICENSE
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
include requirements.txt
|
||||||
|
include requirements-dev.txt
|
||||||
|
include pytest.ini
|
||||||
|
|
||||||
|
# Build and packaging
|
||||||
|
include setup.py
|
||||||
|
include pyproject.toml
|
||||||
|
include MANIFEST.in
|
||||||
|
include Makefile
|
||||||
|
|
||||||
|
# GitHub templates and workflows
|
||||||
|
recursive-include .github *.md *.yml *.yaml
|
||||||
|
|
||||||
|
# Assets
|
||||||
|
recursive-include assets *.png *.jpg *.jpeg *.gif *.ico *.svg
|
||||||
|
recursive-include benchmarks *.py *.md
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# EXCLUDE PATTERNS
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Test files (excluded from distribution)
|
||||||
|
recursive-exclude tests *
|
||||||
|
recursive-exclude * test_*.py *_test.py
|
||||||
|
recursive-exclude * __pycache__
|
||||||
|
recursive-exclude * *.py[co]
|
||||||
|
recursive-exclude * *.so
|
||||||
|
recursive-exclude * .pytest_cache
|
||||||
|
recursive-exclude * .coverage
|
||||||
|
recursive-exclude * coverage.xml
|
||||||
|
recursive-exclude * htmlcov
|
||||||
|
|
||||||
|
# Development environment
|
||||||
|
recursive-exclude * .venv
|
||||||
|
recursive-exclude * venv
|
||||||
|
recursive-exclude * env
|
||||||
|
recursive-exclude * .env
|
||||||
|
recursive-exclude * .env.*
|
||||||
|
|
||||||
|
# Version control
|
||||||
|
recursive-exclude * .git
|
||||||
|
recursive-exclude * .gitignore
|
||||||
|
recursive-exclude * .gitattributes
|
||||||
|
|
||||||
|
# IDE and editor files
|
||||||
|
recursive-exclude * .vscode
|
||||||
|
recursive-exclude * .idea
|
||||||
|
recursive-exclude * *.swp
|
||||||
|
recursive-exclude * *.swo
|
||||||
|
recursive-exclude * *~
|
||||||
|
recursive-exclude * .DS_Store
|
||||||
|
recursive-exclude * Thumbs.db
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
recursive-exclude * build
|
||||||
|
recursive-exclude * dist
|
||||||
|
recursive-exclude * *.egg-info
|
||||||
|
recursive-exclude * .eggs
|
||||||
|
|
||||||
|
# CI/CD (excluded - these are for development only)
|
||||||
|
recursive-exclude .github/workflows *
|
||||||
|
|
||||||
|
# Temporary and cache files
|
||||||
|
recursive-exclude * .tox
|
||||||
|
recursive-exclude * .mypy_cache
|
||||||
|
recursive-exclude * .hypothesis
|
||||||
|
recursive-exclude * .ruff_cache
|
||||||
|
recursive-exclude * *.log
|
||||||
|
recursive-exclude * logs/*.log
|
||||||
|
recursive-exclude * *.db
|
||||||
|
recursive-exclude * *.sqlite
|
||||||
|
recursive-exclude * *.sqlite3
|
||||||
|
|
||||||
|
# Security and sensitive files (never include these)
|
||||||
|
exclude .env
|
||||||
|
exclude .env.local
|
||||||
|
exclude .env.production
|
||||||
|
exclude secrets.json
|
||||||
|
exclude credentials.json
|
||||||
|
exclude *secret*
|
||||||
|
exclude *password*
|
||||||
|
exclude *credential*
|
||||||
|
exclude *_key*
|
||||||
|
exclude private_*
|
||||||
|
|
||||||
|
# Debug and vulnerable files (exclude from distribution)
|
||||||
|
recursive-exclude * *_vulnerable.py
|
||||||
|
recursive-exclude * *_insecure.py
|
||||||
|
recursive-exclude * *_debug.py
|
||||||
|
|
@ -0,0 +1,328 @@
|
||||||
|
# EU-Utility - Modern Python Packaging Configuration
|
||||||
|
# https://github.com/ImpulsiveFPS/EU-Utility
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = [
|
||||||
|
"setuptools>=65.0",
|
||||||
|
"wheel>=0.41.0",
|
||||||
|
"setuptools-scm>=7.0",
|
||||||
|
]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "eu-utility"
|
||||||
|
version = "2.1.0"
|
||||||
|
description = "A versatile Entropia Universe utility suite with a modular plugin system"
|
||||||
|
readme = "README.md"
|
||||||
|
license = {text = "MIT"}
|
||||||
|
authors = [
|
||||||
|
{name = "ImpulsiveFPS", email = "dev@impulsivefps.com"},
|
||||||
|
]
|
||||||
|
maintainers = [
|
||||||
|
{name = "ImpulsiveFPS", email = "dev@impulsivefps.com"},
|
||||||
|
]
|
||||||
|
keywords = [
|
||||||
|
"entropia universe",
|
||||||
|
"game utility",
|
||||||
|
"overlay",
|
||||||
|
"plugin system",
|
||||||
|
"ocr",
|
||||||
|
"tracker",
|
||||||
|
"calculator",
|
||||||
|
"gaming",
|
||||||
|
"mmorpg",
|
||||||
|
]
|
||||||
|
classifiers = [
|
||||||
|
"Development Status :: 4 - Beta",
|
||||||
|
"Intended Audience :: End Users/Desktop",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
"Operating System :: Microsoft :: Windows",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Programming Language :: Python :: 3.12",
|
||||||
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
|
"Topic :: Games/Entertainment",
|
||||||
|
"Topic :: Utilities",
|
||||||
|
"Topic :: Desktop Environment",
|
||||||
|
"Environment :: X11 Applications :: Qt",
|
||||||
|
"Environment :: Win32 (MS Windows)",
|
||||||
|
"Natural Language :: English",
|
||||||
|
]
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
"PyQt6>=6.4.0,<7.0.0",
|
||||||
|
"keyboard>=0.13.5,<1.0.0",
|
||||||
|
"psutil>=5.9.0,<6.0.0",
|
||||||
|
"pyperclip>=1.8.2,<2.0.0",
|
||||||
|
"easyocr>=1.7.0,<2.0.0",
|
||||||
|
"pytesseract>=0.3.10,<1.0.0",
|
||||||
|
"pyautogui>=0.9.54,<1.0.0",
|
||||||
|
"pillow>=10.0.0,<11.0.0",
|
||||||
|
"requests>=2.28.0,<3.0.0",
|
||||||
|
"urllib3>=1.26.0,<3.0.0",
|
||||||
|
"numpy>=1.21.0,<2.0.0",
|
||||||
|
'portalocker>=2.7.0; platform_system=="Windows"',
|
||||||
|
'pywin32>=306; platform_system=="Windows"',
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
spotify = [
|
||||||
|
"spotipy>=2.23.0,<3.0.0",
|
||||||
|
'pycaw>=20230407; platform_system=="Windows"',
|
||||||
|
]
|
||||||
|
discord = [
|
||||||
|
"pypresence>=4.3.0,<5.0.0",
|
||||||
|
]
|
||||||
|
all = [
|
||||||
|
"spotipy>=2.23.0,<3.0.0",
|
||||||
|
'pycaw>=20230407; platform_system=="Windows"',
|
||||||
|
"pypresence>=4.3.0,<5.0.0",
|
||||||
|
]
|
||||||
|
dev = [
|
||||||
|
"pytest>=7.4.0,<8.0.0",
|
||||||
|
"pytest-cov>=4.1.0,<5.0.0",
|
||||||
|
"pytest-mock>=3.11.0,<4.0.0",
|
||||||
|
"pytest-benchmark>=4.0.0,<5.0.0",
|
||||||
|
"pytest-qt>=4.2.0,<5.0.0",
|
||||||
|
"pytest-xvfb>=2.0.0,<3.0.0",
|
||||||
|
"black>=23.0.0,<24.0.0",
|
||||||
|
"flake8>=6.0.0,<7.0.0",
|
||||||
|
"mypy>=1.5.0,<2.0.0",
|
||||||
|
"isort>=5.12.0,<6.0.0",
|
||||||
|
"pydocstyle>=6.3.0,<7.0.0",
|
||||||
|
"bandit>=1.7.5,<2.0.0",
|
||||||
|
"safety>=2.3.0,<3.0.0",
|
||||||
|
"sphinx>=7.0.0,<8.0.0",
|
||||||
|
"sphinx-rtd-theme>=1.3.0,<2.0.0",
|
||||||
|
"myst-parser>=2.0.0,<3.0.0",
|
||||||
|
"build>=0.10.0,<1.0.0",
|
||||||
|
"twine>=4.0.0,<5.0.0",
|
||||||
|
"wheel>=0.41.0,<1.0.0",
|
||||||
|
"pre-commit>=3.4.0,<4.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
eu-utility = "core.main:main"
|
||||||
|
eu-utility-secure = "core.main_optimized:main"
|
||||||
|
|
||||||
|
[project.gui-scripts]
|
||||||
|
eu-utility-gui = "core.main:main"
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Homepage = "https://github.com/ImpulsiveFPS/EU-Utility"
|
||||||
|
Documentation = "https://github.com/ImpulsiveFPS/EU-Utility/tree/main/docs"
|
||||||
|
Repository = "https://github.com/ImpulsiveFPS/EU-Utility.git"
|
||||||
|
"Bug Tracker" = "https://github.com/ImpulsiveFPS/EU-Utility/issues"
|
||||||
|
Changelog = "https://github.com/ImpulsiveFPS/EU-Utility/blob/main/CHANGELOG.md"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# TOOL CONFIGURATIONS
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Black - Code Formatter
|
||||||
|
[tool.black]
|
||||||
|
line-length = 100
|
||||||
|
target-version = ["py311", "py312"]
|
||||||
|
include = '\.pyi?$'
|
||||||
|
extend-exclude = '''
|
||||||
|
/(
|
||||||
|
\.git
|
||||||
|
| \.venv
|
||||||
|
| venv
|
||||||
|
| env
|
||||||
|
| build
|
||||||
|
| dist
|
||||||
|
| __pycache__
|
||||||
|
| \.pytest_cache
|
||||||
|
| htmlcov
|
||||||
|
| \.tox
|
||||||
|
| migrations
|
||||||
|
)/
|
||||||
|
'''
|
||||||
|
skip-string-normalization = false
|
||||||
|
preview = false
|
||||||
|
|
||||||
|
# isort - Import Sorting
|
||||||
|
[tool.isort]
|
||||||
|
profile = "black"
|
||||||
|
line_length = 100
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma = true
|
||||||
|
force_grid_wrap = 0
|
||||||
|
use_parentheses = true
|
||||||
|
ensure_newline_before_comments = true
|
||||||
|
skip = [".git", "__pycache__", "venv", ".venv", "build", "dist"]
|
||||||
|
known_first_party = ["core", "plugins"]
|
||||||
|
known_third_party = ["PyQt6", "pytest"]
|
||||||
|
|
||||||
|
# flake8 - Linting
|
||||||
|
[tool.flake8]
|
||||||
|
max-line-length = 100
|
||||||
|
extend-ignore = [
|
||||||
|
"E203", # Whitespace before ':' (conflicts with black)
|
||||||
|
"E501", # Line too long (handled by black)
|
||||||
|
"W503", # Line break before binary operator (black style)
|
||||||
|
]
|
||||||
|
exclude = [
|
||||||
|
".git",
|
||||||
|
"__pycache__",
|
||||||
|
".venv",
|
||||||
|
"venv",
|
||||||
|
"build",
|
||||||
|
"dist",
|
||||||
|
".pytest_cache",
|
||||||
|
"htmlcov",
|
||||||
|
".tox",
|
||||||
|
"migrations",
|
||||||
|
]
|
||||||
|
per-file-ignores = [
|
||||||
|
"__init__.py:F401,F403",
|
||||||
|
"test_*.py:S101",
|
||||||
|
]
|
||||||
|
max-complexity = 10
|
||||||
|
|
||||||
|
# mypy - Type Checking
|
||||||
|
[tool.mypy]
|
||||||
|
python_version = "3.11"
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unused_configs = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_untyped_decorators = false
|
||||||
|
no_implicit_optional = true
|
||||||
|
warn_redundant_casts = true
|
||||||
|
warn_unused_ignores = true
|
||||||
|
warn_no_return = true
|
||||||
|
warn_unreachable = true
|
||||||
|
strict_equality = true
|
||||||
|
show_error_codes = true
|
||||||
|
show_column_numbers = true
|
||||||
|
show_error_context = true
|
||||||
|
pretty = true
|
||||||
|
|
||||||
|
# Module-specific settings
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
module = [
|
||||||
|
"pytesseract.*",
|
||||||
|
"pyautogui.*",
|
||||||
|
"easyocr.*",
|
||||||
|
"keyboard.*",
|
||||||
|
"psutil.*",
|
||||||
|
"PIL.*",
|
||||||
|
"win32con.*",
|
||||||
|
"win32gui.*",
|
||||||
|
"win32api.*",
|
||||||
|
"portalocker.*",
|
||||||
|
]
|
||||||
|
ignore_missing_imports = true
|
||||||
|
|
||||||
|
# pytest - Testing
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
testpaths = ["tests"]
|
||||||
|
python_files = ["test_*.py"]
|
||||||
|
python_classes = ["Test*"]
|
||||||
|
python_functions = ["test_*"]
|
||||||
|
addopts = [
|
||||||
|
"-v",
|
||||||
|
"--tb=short",
|
||||||
|
"--strict-markers",
|
||||||
|
"--cov=core",
|
||||||
|
"--cov=plugins",
|
||||||
|
"--cov-report=term-missing",
|
||||||
|
"--cov-report=html:htmlcov",
|
||||||
|
"--cov-report=xml:coverage.xml",
|
||||||
|
"--cov-fail-under=80",
|
||||||
|
]
|
||||||
|
markers = [
|
||||||
|
"unit: Unit tests for individual components",
|
||||||
|
"integration: Integration tests for plugin interactions",
|
||||||
|
"ui: UI automation tests",
|
||||||
|
"performance: Performance benchmarks",
|
||||||
|
"slow: Slow tests that may be skipped in CI",
|
||||||
|
"requires_qt: Tests requiring PyQt6",
|
||||||
|
"requires_network: Tests requiring network access",
|
||||||
|
]
|
||||||
|
filterwarnings = [
|
||||||
|
"ignore::DeprecationWarning",
|
||||||
|
"ignore::PendingDeprecationWarning",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Coverage - Code Coverage
|
||||||
|
[tool.coverage.run]
|
||||||
|
source = ["core", "plugins"]
|
||||||
|
branch = true
|
||||||
|
omit = [
|
||||||
|
"*/tests/*",
|
||||||
|
"*/test_*",
|
||||||
|
"*/venv/*",
|
||||||
|
"*/.venv/*",
|
||||||
|
"setup.py",
|
||||||
|
"run_tests.py",
|
||||||
|
"code_review_report.py",
|
||||||
|
"*/benchmarks/*",
|
||||||
|
"*_vulnerable.py",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.coverage.report]
|
||||||
|
exclude_lines = [
|
||||||
|
"pragma: no cover",
|
||||||
|
"def __repr__",
|
||||||
|
"if self.debug:",
|
||||||
|
"if settings.DEBUG",
|
||||||
|
"raise AssertionError",
|
||||||
|
"raise NotImplementedError",
|
||||||
|
"if 0:",
|
||||||
|
"if __name__ == .__main__.:",
|
||||||
|
"class .*\\bProtocol\\):",
|
||||||
|
"@(abc\\.)?abstractmethod",
|
||||||
|
"pass",
|
||||||
|
]
|
||||||
|
fail_under = 80
|
||||||
|
show_missing = true
|
||||||
|
skip_covered = false
|
||||||
|
|
||||||
|
[tool.coverage.html]
|
||||||
|
directory = "htmlcov"
|
||||||
|
|
||||||
|
# Bandit - Security Linter
|
||||||
|
[tool.bandit]
|
||||||
|
exclude_dirs = [
|
||||||
|
"tests",
|
||||||
|
"test",
|
||||||
|
".venv",
|
||||||
|
"venv",
|
||||||
|
"build",
|
||||||
|
"dist",
|
||||||
|
]
|
||||||
|
skips = [
|
||||||
|
"B101", # assert_used (common in Python code)
|
||||||
|
"B311", # random (acceptable for non-cryptographic use)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Pydocstyle - Docstring Conventions
|
||||||
|
[tool.pydocstyle]
|
||||||
|
convention = "google"
|
||||||
|
match = "(?!test_).*\\.py"
|
||||||
|
match_dir = "^(?!tests|\\.venv|venv|build|dist).*"
|
||||||
|
add_ignore = [
|
||||||
|
"D100", # Missing docstring in public module
|
||||||
|
"D104", # Missing docstring in public package
|
||||||
|
"D107", # Missing docstring in __init__
|
||||||
|
]
|
||||||
|
|
||||||
|
# setuptools - Package Discovery
|
||||||
|
[tool.setuptools]
|
||||||
|
packages = ["core", "core.*", "plugins", "plugins.*"]
|
||||||
|
include-package-data = true
|
||||||
|
zip-safe = false
|
||||||
|
|
||||||
|
[tool.setuptools.package-data]
|
||||||
|
core = ["*.json", "*.yaml", "*.yml", "*.css", "*.qss"]
|
||||||
|
plugins = ["*/assets/*", "*/templates/*"]
|
||||||
|
|
||||||
|
[tool.setuptools.exclude-package-data]
|
||||||
|
core = ["tests/*", "*_test.py", "test_*.py"]
|
||||||
|
plugins = ["tests/*", "*_test.py", "test_*.py"]
|
||||||
|
|
@ -7,12 +7,6 @@ addopts =
|
||||||
-v
|
-v
|
||||||
--tb=short
|
--tb=short
|
||||||
--strict-markers
|
--strict-markers
|
||||||
--cov=core
|
|
||||||
--cov=plugins
|
|
||||||
--cov-report=term-missing
|
|
||||||
--cov-report=html:htmlcov
|
|
||||||
--cov-report=xml:coverage.xml
|
|
||||||
--cov-fail-under=80
|
|
||||||
markers =
|
markers =
|
||||||
unit: Unit tests for individual components
|
unit: Unit tests for individual components
|
||||||
integration: Integration tests for plugin interactions
|
integration: Integration tests for plugin interactions
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
EU-Utility - Setup Script
|
||||||
|
|
||||||
|
A versatile Entropia Universe utility suite with a modular plugin system.
|
||||||
|
|
||||||
|
For more information, visit: https://github.com/ImpulsiveFPS/EU-Utility
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Ensure setuptools is available
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
# Project root directory
|
||||||
|
PROJECT_ROOT = Path(__file__).parent.resolve()
|
||||||
|
|
||||||
|
# Read version from core/__init__.py
|
||||||
|
def get_version():
|
||||||
|
"""Extract version from core/__init__.py."""
|
||||||
|
init_file = PROJECT_ROOT / "core" / "__init__.py"
|
||||||
|
with open(init_file, "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
if line.startswith("__version__"):
|
||||||
|
return line.split("=")[1].strip().strip('"\'')
|
||||||
|
raise RuntimeError("Version not found in core/__init__.py")
|
||||||
|
|
||||||
|
# Read long description from README
|
||||||
|
def get_long_description():
|
||||||
|
"""Read README.md for long description."""
|
||||||
|
readme_file = PROJECT_ROOT / "README.md"
|
||||||
|
if readme_file.exists():
|
||||||
|
with open(readme_file, "r", encoding="utf-8") as f:
|
||||||
|
return f.read()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# Runtime dependencies
|
||||||
|
INSTALL_REQUIRES = [
|
||||||
|
# Core GUI Framework
|
||||||
|
"PyQt6>=6.4.0,<7.0.0",
|
||||||
|
|
||||||
|
# System Integration
|
||||||
|
"keyboard>=0.13.5,<1.0.0",
|
||||||
|
"psutil>=5.9.0,<6.0.0",
|
||||||
|
"pyperclip>=1.8.2,<2.0.0",
|
||||||
|
|
||||||
|
# OCR and Image Processing
|
||||||
|
"easyocr>=1.7.0,<2.0.0",
|
||||||
|
"pytesseract>=0.3.10,<1.0.0",
|
||||||
|
"pyautogui>=0.9.54,<1.0.0",
|
||||||
|
"pillow>=10.0.0,<11.0.0",
|
||||||
|
|
||||||
|
# HTTP and Networking
|
||||||
|
"requests>=2.28.0,<3.0.0",
|
||||||
|
"urllib3>=1.26.0,<3.0.0",
|
||||||
|
|
||||||
|
# Data Processing
|
||||||
|
"numpy>=1.21.0,<2.0.0",
|
||||||
|
|
||||||
|
# Windows-specific dependencies (installed only on Windows)
|
||||||
|
'portalocker>=2.7.0; platform_system=="Windows"',
|
||||||
|
'pywin32>=306; platform_system=="Windows"',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Development dependencies
|
||||||
|
DEV_REQUIRES = [
|
||||||
|
# Testing
|
||||||
|
"pytest>=7.4.0,<8.0.0",
|
||||||
|
"pytest-cov>=4.1.0,<5.0.0",
|
||||||
|
"pytest-mock>=3.11.0,<4.0.0",
|
||||||
|
"pytest-benchmark>=4.0.0,<5.0.0",
|
||||||
|
"pytest-qt>=4.2.0,<5.0.0",
|
||||||
|
"pytest-xvfb>=2.0.0,<3.0.0",
|
||||||
|
|
||||||
|
# Code Quality
|
||||||
|
"black>=23.0.0,<24.0.0",
|
||||||
|
"flake8>=6.0.0,<7.0.0",
|
||||||
|
"mypy>=1.5.0,<2.0.0",
|
||||||
|
"isort>=5.12.0,<6.0.0",
|
||||||
|
"pydocstyle>=6.3.0,<7.0.0",
|
||||||
|
|
||||||
|
# Security
|
||||||
|
"bandit>=1.7.5,<2.0.0",
|
||||||
|
"safety>=2.3.0,<3.0.0",
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
"sphinx>=7.0.0,<8.0.0",
|
||||||
|
"sphinx-rtd-theme>=1.3.0,<2.0.0",
|
||||||
|
"myst-parser>=2.0.0,<3.0.0",
|
||||||
|
|
||||||
|
# Build and Packaging
|
||||||
|
"build>=0.10.0,<1.0.0",
|
||||||
|
"twine>=4.0.0,<5.0.0",
|
||||||
|
"wheel>=0.41.0,<1.0.0",
|
||||||
|
|
||||||
|
# Pre-commit hooks
|
||||||
|
"pre-commit>=3.4.0,<4.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Optional plugin dependencies
|
||||||
|
EXTRAS_REQUIRE = {
|
||||||
|
# Advanced media control features
|
||||||
|
"spotify": [
|
||||||
|
"spotipy>=2.23.0,<3.0.0",
|
||||||
|
'pycaw>=20230407; platform_system=="Windows"',
|
||||||
|
],
|
||||||
|
|
||||||
|
# Discord Rich Presence integration
|
||||||
|
"discord": [
|
||||||
|
"pypresence>=4.3.0,<5.0.0",
|
||||||
|
],
|
||||||
|
|
||||||
|
# All optional features
|
||||||
|
"all": [
|
||||||
|
"spotipy>=2.23.0,<3.0.0",
|
||||||
|
'pycaw>=20230407; platform_system=="Windows"',
|
||||||
|
"pypresence>=4.3.0,<5.0.0",
|
||||||
|
],
|
||||||
|
|
||||||
|
# Development extras (includes all dev dependencies)
|
||||||
|
"dev": DEV_REQUIRES,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Package classifiers
|
||||||
|
CLASSIFIERS = [
|
||||||
|
# Development Status
|
||||||
|
"Development Status :: 4 - Beta",
|
||||||
|
|
||||||
|
# Intended Audience
|
||||||
|
"Intended Audience :: End Users/Desktop",
|
||||||
|
"Intended Audience :: Gamers",
|
||||||
|
|
||||||
|
# License
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
|
||||||
|
# Operating System
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
"Operating System :: Microsoft :: Windows",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
|
||||||
|
# Programming Language
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Programming Language :: Python :: 3.12",
|
||||||
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
|
|
||||||
|
# Topic
|
||||||
|
"Topic :: Games/Entertainment",
|
||||||
|
"Topic :: Utilities",
|
||||||
|
"Topic :: Desktop Environment",
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
"Environment :: X11 Applications :: Qt",
|
||||||
|
"Environment :: Win32 (MS Windows)",
|
||||||
|
|
||||||
|
# Natural Language
|
||||||
|
"Natural Language :: English",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Entry points for CLI usage
|
||||||
|
ENTRY_POINTS = {
|
||||||
|
"console_scripts": [
|
||||||
|
"eu-utility=core.main:main",
|
||||||
|
"eu-utility-secure=core.main_optimized:main",
|
||||||
|
],
|
||||||
|
"gui_scripts": [
|
||||||
|
"eu-utility-gui=core.main:main",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Package data to include
|
||||||
|
PACKAGE_DATA = {
|
||||||
|
"core": ["*.json", "*.yaml", "*.yml", "*.css", "*.qss"],
|
||||||
|
"plugins": ["*/assets/*", "*/templates/*"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Execute setup."""
|
||||||
|
setup(
|
||||||
|
# Basic metadata
|
||||||
|
name="eu-utility",
|
||||||
|
version=get_version(),
|
||||||
|
author="ImpulsiveFPS",
|
||||||
|
author_email="dev@impulsivefps.com",
|
||||||
|
maintainer="ImpulsiveFPS",
|
||||||
|
maintainer_email="dev@impulsivefps.com",
|
||||||
|
url="https://github.com/ImpulsiveFPS/EU-Utility",
|
||||||
|
project_urls={
|
||||||
|
"Bug Reports": "https://github.com/ImpulsiveFPS/EU-Utility/issues",
|
||||||
|
"Source": "https://github.com/ImpulsiveFPS/EU-Utility",
|
||||||
|
"Documentation": "https://github.com/ImpulsiveFPS/EU-Utility/tree/main/docs",
|
||||||
|
"Changelog": "https://github.com/ImpulsiveFPS/EU-Utility/blob/main/CHANGELOG.md",
|
||||||
|
},
|
||||||
|
|
||||||
|
# Descriptions
|
||||||
|
description="A versatile Entropia Universe utility suite with a modular plugin system",
|
||||||
|
long_description=get_long_description(),
|
||||||
|
long_description_content_type="text/markdown",
|
||||||
|
keywords=[
|
||||||
|
"entropia universe",
|
||||||
|
"game utility",
|
||||||
|
"overlay",
|
||||||
|
"plugin system",
|
||||||
|
"ocr",
|
||||||
|
"tracker",
|
||||||
|
"calculator",
|
||||||
|
"gaming",
|
||||||
|
"mmorpg",
|
||||||
|
],
|
||||||
|
|
||||||
|
# Classifiers
|
||||||
|
classifiers=CLASSIFIERS,
|
||||||
|
|
||||||
|
# License
|
||||||
|
license="MIT",
|
||||||
|
|
||||||
|
# Python version requirement
|
||||||
|
python_requires=">=3.11",
|
||||||
|
|
||||||
|
# Packages
|
||||||
|
packages=find_packages(
|
||||||
|
include=["core", "core.*", "plugins", "plugins.*"],
|
||||||
|
exclude=["tests", "tests.*", "benchmarks", "benchmarks.*", "docs", "docs.*"],
|
||||||
|
),
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
install_requires=INSTALL_REQUIRES,
|
||||||
|
extras_require=EXTRAS_REQUIRE,
|
||||||
|
|
||||||
|
# Package data
|
||||||
|
include_package_data=True,
|
||||||
|
package_data=PACKAGE_DATA,
|
||||||
|
|
||||||
|
# Entry points
|
||||||
|
entry_points=ENTRY_POINTS,
|
||||||
|
|
||||||
|
# Zip safety
|
||||||
|
zip_safe=False,
|
||||||
|
|
||||||
|
# Platforms
|
||||||
|
platforms=["win32", "win64", "linux"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue