unrealon 1.1.6__py3-none-any.whl → 2.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unrealon-1.1.6.dist-info/licenses → unrealon-2.0.5.dist-info}/LICENSE +1 -1
- unrealon-2.0.5.dist-info/METADATA +491 -0
- unrealon-2.0.5.dist-info/RECORD +128 -0
- {unrealon-1.1.6.dist-info → unrealon-2.0.5.dist-info}/WHEEL +2 -1
- unrealon-2.0.5.dist-info/entry_points.txt +3 -0
- unrealon-2.0.5.dist-info/top_level.txt +3 -0
- unrealon_browser/__init__.py +5 -6
- unrealon_browser/cli/browser_cli.py +18 -9
- unrealon_browser/cli/interactive_mode.py +13 -4
- unrealon_browser/core/browser_manager.py +29 -16
- unrealon_browser/dto/__init__.py +21 -0
- unrealon_browser/dto/bot_detection.py +175 -0
- unrealon_browser/dto/models/config.py +9 -3
- unrealon_browser/managers/__init__.py +1 -1
- unrealon_browser/managers/logger_bridge.py +1 -4
- unrealon_browser/stealth/__init__.py +27 -0
- unrealon_browser/stealth/bypass_techniques.pyc +0 -0
- unrealon_browser/stealth/manager.pyc +0 -0
- unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
- unrealon_browser/stealth/playwright_stealth.pyc +0 -0
- unrealon_browser/stealth/scanner_tester.pyc +0 -0
- unrealon_browser/stealth/undetected_chrome.pyc +0 -0
- unrealon_core/__init__.py +172 -0
- unrealon_core/config/__init__.py +16 -0
- unrealon_core/config/environment.py +151 -0
- unrealon_core/config/urls.py +94 -0
- unrealon_core/enums/__init__.py +24 -0
- unrealon_core/enums/status.py +216 -0
- unrealon_core/enums/types.py +240 -0
- unrealon_core/error_handling/__init__.py +45 -0
- unrealon_core/error_handling/circuit_breaker.py +292 -0
- unrealon_core/error_handling/error_context.py +324 -0
- unrealon_core/error_handling/recovery.py +371 -0
- unrealon_core/error_handling/retry.py +268 -0
- unrealon_core/exceptions/__init__.py +46 -0
- unrealon_core/exceptions/base.py +292 -0
- unrealon_core/exceptions/communication.py +22 -0
- unrealon_core/exceptions/driver.py +11 -0
- unrealon_core/exceptions/proxy.py +11 -0
- unrealon_core/exceptions/task.py +12 -0
- unrealon_core/exceptions/validation.py +17 -0
- unrealon_core/models/__init__.py +79 -0
- unrealon_core/models/arq_context.py +252 -0
- unrealon_core/models/arq_responses.py +125 -0
- unrealon_core/models/base.py +291 -0
- unrealon_core/models/bridge_stats.py +58 -0
- unrealon_core/models/communication.py +39 -0
- unrealon_core/models/connection_stats.py +47 -0
- unrealon_core/models/driver.py +30 -0
- unrealon_core/models/driver_details.py +98 -0
- unrealon_core/models/logging.py +28 -0
- unrealon_core/models/task.py +21 -0
- unrealon_core/models/typed_responses.py +210 -0
- unrealon_core/models/websocket/__init__.py +91 -0
- unrealon_core/models/websocket/base.py +49 -0
- unrealon_core/models/websocket/config.py +200 -0
- unrealon_core/models/websocket/driver.py +215 -0
- unrealon_core/models/websocket/errors.py +138 -0
- unrealon_core/models/websocket/heartbeat.py +100 -0
- unrealon_core/models/websocket/logging.py +261 -0
- unrealon_core/models/websocket/proxy.py +496 -0
- unrealon_core/models/websocket/tasks.py +275 -0
- unrealon_core/models/websocket/utils.py +153 -0
- unrealon_core/models/websocket_session.py +144 -0
- unrealon_core/monitoring/__init__.py +43 -0
- unrealon_core/monitoring/alerts.py +398 -0
- unrealon_core/monitoring/dashboard.py +307 -0
- unrealon_core/monitoring/health_check.py +354 -0
- unrealon_core/monitoring/metrics.py +352 -0
- unrealon_core/utils/__init__.py +11 -0
- unrealon_core/utils/time.py +61 -0
- unrealon_core/version.py +219 -0
- unrealon_driver/__init__.py +90 -51
- unrealon_driver/core_module/__init__.py +34 -0
- unrealon_driver/core_module/base.py +184 -0
- unrealon_driver/core_module/config.py +30 -0
- unrealon_driver/core_module/event_manager.py +127 -0
- unrealon_driver/core_module/protocols.py +98 -0
- unrealon_driver/core_module/registry.py +146 -0
- unrealon_driver/decorators/__init__.py +15 -0
- unrealon_driver/decorators/retry.py +117 -0
- unrealon_driver/decorators/schedule.py +137 -0
- unrealon_driver/decorators/task.py +61 -0
- unrealon_driver/decorators/timing.py +132 -0
- unrealon_driver/driver/__init__.py +20 -0
- unrealon_driver/driver/communication/__init__.py +10 -0
- unrealon_driver/driver/communication/session.py +203 -0
- unrealon_driver/driver/communication/websocket_client.py +205 -0
- unrealon_driver/driver/core/__init__.py +10 -0
- unrealon_driver/driver/core/config.py +175 -0
- unrealon_driver/driver/core/driver.py +221 -0
- unrealon_driver/driver/factory/__init__.py +9 -0
- unrealon_driver/driver/factory/manager_factory.py +130 -0
- unrealon_driver/driver/lifecycle/__init__.py +11 -0
- unrealon_driver/driver/lifecycle/daemon.py +76 -0
- unrealon_driver/driver/lifecycle/initialization.py +97 -0
- unrealon_driver/driver/lifecycle/shutdown.py +48 -0
- unrealon_driver/driver/monitoring/__init__.py +9 -0
- unrealon_driver/driver/monitoring/health.py +63 -0
- unrealon_driver/driver/utilities/__init__.py +10 -0
- unrealon_driver/driver/utilities/logging.py +51 -0
- unrealon_driver/driver/utilities/serialization.py +61 -0
- unrealon_driver/managers/__init__.py +32 -0
- unrealon_driver/managers/base.py +174 -0
- unrealon_driver/managers/browser.py +98 -0
- unrealon_driver/managers/cache.py +116 -0
- unrealon_driver/managers/http.py +107 -0
- unrealon_driver/managers/logger.py +286 -0
- unrealon_driver/managers/proxy.py +99 -0
- unrealon_driver/managers/registry.py +87 -0
- unrealon_driver/managers/threading.py +54 -0
- unrealon_driver/managers/update.py +107 -0
- unrealon_driver/utils/__init__.py +9 -0
- unrealon_driver/utils/time.py +10 -0
- unrealon-1.1.6.dist-info/METADATA +0 -625
- unrealon-1.1.6.dist-info/RECORD +0 -55
- unrealon-1.1.6.dist-info/entry_points.txt +0 -9
- unrealon_browser/managers/stealth.py +0 -388
- unrealon_driver/README.md +0 -0
- unrealon_driver/exceptions.py +0 -33
- unrealon_driver/html_analyzer/__init__.py +0 -32
- unrealon_driver/html_analyzer/cleaner.py +0 -657
- unrealon_driver/html_analyzer/config.py +0 -64
- unrealon_driver/html_analyzer/manager.py +0 -247
- unrealon_driver/html_analyzer/models.py +0 -115
- unrealon_driver/html_analyzer/websocket_analyzer.py +0 -157
- unrealon_driver/models/__init__.py +0 -31
- unrealon_driver/models/websocket.py +0 -98
- unrealon_driver/parser/__init__.py +0 -36
- unrealon_driver/parser/cli_manager.py +0 -142
- unrealon_driver/parser/daemon_manager.py +0 -403
- unrealon_driver/parser/managers/__init__.py +0 -25
- unrealon_driver/parser/managers/config.py +0 -293
- unrealon_driver/parser/managers/error.py +0 -412
- unrealon_driver/parser/managers/result.py +0 -321
- unrealon_driver/parser/parser_manager.py +0 -458
- unrealon_driver/smart_logging/__init__.py +0 -24
- unrealon_driver/smart_logging/models.py +0 -44
- unrealon_driver/smart_logging/smart_logger.py +0 -406
- unrealon_driver/smart_logging/unified_logger.py +0 -525
- unrealon_driver/websocket/__init__.py +0 -31
- unrealon_driver/websocket/client.py +0 -249
- unrealon_driver/websocket/config.py +0 -188
- unrealon_driver/websocket/manager.py +0 -90
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Time utilities for UnrealOn.
|
|
3
|
+
|
|
4
|
+
Provides timezone-aware datetime functions to replace deprecated datetime.utc_now().
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def utc_now() -> datetime:
|
|
12
|
+
"""
|
|
13
|
+
Get current UTC time as timezone-aware datetime.
|
|
14
|
+
|
|
15
|
+
Replacement for deprecated datetime.utc_now().
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
datetime: Current UTC time with timezone info
|
|
19
|
+
"""
|
|
20
|
+
return datetime.now(timezone.utc)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def utc_timestamp() -> str:
|
|
24
|
+
"""
|
|
25
|
+
Get current UTC time as ISO format string.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
str: Current UTC time in ISO format
|
|
29
|
+
"""
|
|
30
|
+
return utc_now().isoformat()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def datetime_to_iso(dt: Optional[datetime]) -> Optional[str]:
|
|
34
|
+
"""
|
|
35
|
+
Convert datetime to ISO format string.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
dt: Datetime to convert (can be None)
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
str or None: ISO format string or None if input was None
|
|
42
|
+
"""
|
|
43
|
+
if dt is None:
|
|
44
|
+
return None
|
|
45
|
+
return dt.isoformat()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def ensure_utc(dt: datetime) -> datetime:
|
|
49
|
+
"""
|
|
50
|
+
Ensure datetime is timezone-aware and in UTC.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
dt: Datetime to convert
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
datetime: UTC timezone-aware datetime
|
|
57
|
+
"""
|
|
58
|
+
if dt.tzinfo is None:
|
|
59
|
+
# Assume naive datetime is UTC
|
|
60
|
+
return dt.replace(tzinfo=timezone.utc)
|
|
61
|
+
return dt.astimezone(timezone.utc)
|
unrealon_core/version.py
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""
|
|
2
|
+
🔄 UnrealOn Version Management
|
|
3
|
+
|
|
4
|
+
Unified version system for all UnrealOn packages.
|
|
5
|
+
This ensures version synchronization between driver, RPC server, and core components.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import tomlkit
|
|
9
|
+
from typing import Dict, Any
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from unrealon_core.utils.time import utc_timestamp
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _get_version_from_pyproject() -> str:
|
|
15
|
+
"""Get version from main pyproject.toml."""
|
|
16
|
+
try:
|
|
17
|
+
# Go up from unrealon-core/src/unrealon_core to project root
|
|
18
|
+
project_root = Path(__file__).parent.parent.parent.parent
|
|
19
|
+
pyproject_path = project_root / "pyproject.toml"
|
|
20
|
+
|
|
21
|
+
if pyproject_path.exists():
|
|
22
|
+
with open(pyproject_path, "r") as f:
|
|
23
|
+
pyproject = tomlkit.parse(f.read())
|
|
24
|
+
|
|
25
|
+
# Try PEP 621 format first
|
|
26
|
+
if "project" in pyproject and "version" in pyproject["project"]:
|
|
27
|
+
return str(pyproject["project"]["version"])
|
|
28
|
+
# Fallback to Poetry format
|
|
29
|
+
elif "tool" in pyproject and "poetry" in pyproject["tool"] and "version" in pyproject["tool"]["poetry"]:
|
|
30
|
+
return str(pyproject["tool"]["poetry"]["version"])
|
|
31
|
+
except Exception:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
# Fallback version if can't read from pyproject.toml
|
|
35
|
+
return "2.0.0"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# 🎯 UNIFIED VERSION - Automatically synced from main pyproject.toml
|
|
39
|
+
__version__ = _get_version_from_pyproject()
|
|
40
|
+
|
|
41
|
+
# 📅 Release Information
|
|
42
|
+
__release_date__ = "2024-12-19"
|
|
43
|
+
__build_number__ = "20241219001"
|
|
44
|
+
|
|
45
|
+
# 🏷️ Version Components
|
|
46
|
+
VERSION_MAJOR = 4
|
|
47
|
+
VERSION_MINOR = 0
|
|
48
|
+
VERSION_PATCH = 0
|
|
49
|
+
VERSION_BUILD = "stable"
|
|
50
|
+
|
|
51
|
+
# 🔧 Package Compatibility Matrix
|
|
52
|
+
COMPATIBILITY_MATRIX = {
|
|
53
|
+
"unrealon_core": __version__,
|
|
54
|
+
"unrealon_rpc": __version__,
|
|
55
|
+
"unrealon_driver": __version__,
|
|
56
|
+
"unrealon_browser": __version__
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# 📊 Version Metadata
|
|
60
|
+
VERSION_INFO = {
|
|
61
|
+
"version": __version__,
|
|
62
|
+
"major": VERSION_MAJOR,
|
|
63
|
+
"minor": VERSION_MINOR,
|
|
64
|
+
"patch": VERSION_PATCH,
|
|
65
|
+
"build": VERSION_BUILD,
|
|
66
|
+
"release_date": __release_date__,
|
|
67
|
+
"build_number": __build_number__,
|
|
68
|
+
"compatibility": COMPATIBILITY_MATRIX
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_version() -> str:
|
|
73
|
+
"""
|
|
74
|
+
Get the current UnrealOn version.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
str: Version string (e.g., "4.0.0")
|
|
78
|
+
"""
|
|
79
|
+
return __version__
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_version_info() -> Dict[str, Any]:
|
|
83
|
+
"""
|
|
84
|
+
Get detailed version information.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Dict[str, Any]: Complete version metadata
|
|
88
|
+
"""
|
|
89
|
+
return VERSION_INFO.copy()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_build_info() -> Dict[str, Any]:
|
|
93
|
+
"""
|
|
94
|
+
Get build information.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Dict[str, Any]: Build metadata
|
|
98
|
+
"""
|
|
99
|
+
return {
|
|
100
|
+
"version": __version__,
|
|
101
|
+
"build_number": __build_number__,
|
|
102
|
+
"release_date": __release_date__,
|
|
103
|
+
"build_type": VERSION_BUILD,
|
|
104
|
+
"timestamp": utc_timestamp()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def is_compatible_version(other_version: str) -> bool:
|
|
109
|
+
"""
|
|
110
|
+
Check if another version is compatible with current version.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
other_version: Version string to check
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
bool: True if versions are compatible
|
|
117
|
+
"""
|
|
118
|
+
try:
|
|
119
|
+
# For now, require exact match for stability
|
|
120
|
+
return other_version == __version__
|
|
121
|
+
except Exception:
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def get_compatibility_status(package_versions: Dict[str, str]) -> Dict[str, Any]:
|
|
126
|
+
"""
|
|
127
|
+
Check compatibility status of multiple packages.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
package_versions: Dict of package names to versions
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Dict[str, Any]: Compatibility report
|
|
134
|
+
"""
|
|
135
|
+
compatible_packages = []
|
|
136
|
+
incompatible_packages = []
|
|
137
|
+
|
|
138
|
+
for package, version in package_versions.items():
|
|
139
|
+
expected_version = COMPATIBILITY_MATRIX.get(package)
|
|
140
|
+
if expected_version and version == expected_version:
|
|
141
|
+
compatible_packages.append(package)
|
|
142
|
+
else:
|
|
143
|
+
incompatible_packages.append({
|
|
144
|
+
"package": package,
|
|
145
|
+
"current": version,
|
|
146
|
+
"expected": expected_version
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
"overall_compatible": len(incompatible_packages) == 0,
|
|
151
|
+
"compatible_packages": compatible_packages,
|
|
152
|
+
"incompatible_packages": incompatible_packages,
|
|
153
|
+
"total_packages": len(package_versions),
|
|
154
|
+
"compatibility_score": len(compatible_packages) / len(package_versions) if package_versions else 1.0
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# 🎯 Convenience functions for specific packages
|
|
159
|
+
def get_core_version() -> str:
|
|
160
|
+
"""Get unrealon_core version."""
|
|
161
|
+
return COMPATIBILITY_MATRIX["unrealon_core"]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def get_rpc_version() -> str:
|
|
165
|
+
"""Get unrealon_rpc version."""
|
|
166
|
+
return COMPATIBILITY_MATRIX["unrealon_rpc"]
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def get_driver_version() -> str:
|
|
170
|
+
"""Get unrealon_driver version."""
|
|
171
|
+
return COMPATIBILITY_MATRIX["unrealon_driver"]
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def get_browser_version() -> str:
|
|
175
|
+
"""Get unrealon_browser version."""
|
|
176
|
+
return COMPATIBILITY_MATRIX["unrealon_browser"]
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# 🔍 Version validation
|
|
180
|
+
def validate_version_format(version: str) -> bool:
|
|
181
|
+
"""
|
|
182
|
+
Validate version string format.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
version: Version string to validate
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
bool: True if format is valid
|
|
189
|
+
"""
|
|
190
|
+
try:
|
|
191
|
+
parts = version.split(".")
|
|
192
|
+
if len(parts) != 3:
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
# Check if all parts are integers
|
|
196
|
+
for part in parts:
|
|
197
|
+
int(part)
|
|
198
|
+
|
|
199
|
+
return True
|
|
200
|
+
except (ValueError, AttributeError):
|
|
201
|
+
return False
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# 📋 Export all version functions
|
|
205
|
+
__all__ = [
|
|
206
|
+
"__version__",
|
|
207
|
+
"VERSION_INFO",
|
|
208
|
+
"COMPATIBILITY_MATRIX",
|
|
209
|
+
"get_version",
|
|
210
|
+
"get_version_info",
|
|
211
|
+
"get_build_info",
|
|
212
|
+
"is_compatible_version",
|
|
213
|
+
"get_compatibility_status",
|
|
214
|
+
"get_core_version",
|
|
215
|
+
"get_rpc_version",
|
|
216
|
+
"get_driver_version",
|
|
217
|
+
"get_browser_version",
|
|
218
|
+
"validate_version_format"
|
|
219
|
+
]
|
unrealon_driver/__init__.py
CHANGED
|
@@ -1,66 +1,105 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
UnrealOn Driver SDK - Refactored
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Clean, simple, powerful API for parser development.
|
|
5
|
+
Simplified architecture with all original functionality.
|
|
6
6
|
|
|
7
7
|
Key Features:
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- 🛡️ Type Safety: Full Pydantic v2 compliance
|
|
8
|
+
- UniversalDriver - Simple unified API
|
|
9
|
+
- All managers integrated cleanly
|
|
10
|
+
- WebSocket communication with RPC
|
|
11
|
+
- Module system for extensibility
|
|
12
|
+
- Clean decorator system
|
|
13
|
+
- No complex inheritance chains
|
|
15
14
|
"""
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
# Version info
|
|
17
|
+
from unrealon_core.version import get_driver_version
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
# Core API - Simple and clean
|
|
20
|
+
from .driver import (
|
|
21
|
+
UniversalDriver,
|
|
22
|
+
DriverConfig,
|
|
23
|
+
DriverMode
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from .driver.communication import (
|
|
27
|
+
DriverSession,
|
|
28
|
+
WebSocketClient
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Managers - Clean resource management
|
|
32
|
+
from .managers import (
|
|
33
|
+
LoggerManager,
|
|
34
|
+
HttpManager,
|
|
35
|
+
BrowserManager,
|
|
36
|
+
CacheManager,
|
|
37
|
+
ProxyManager,
|
|
38
|
+
ThreadManager,
|
|
39
|
+
UpdateManager,
|
|
40
|
+
ManagerRegistry
|
|
41
|
+
)
|
|
23
42
|
|
|
43
|
+
# Module system - Extensible architecture
|
|
44
|
+
from .core_module import (
|
|
45
|
+
BaseModule,
|
|
46
|
+
DriverModule,
|
|
47
|
+
ModuleConfig,
|
|
48
|
+
EventManager,
|
|
49
|
+
ModuleRegistry,
|
|
50
|
+
ModuleStatus,
|
|
51
|
+
EventType,
|
|
52
|
+
HealthStatus
|
|
53
|
+
)
|
|
24
54
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
ConfigManager,
|
|
32
|
-
ParserConfig,
|
|
33
|
-
ResultManager,
|
|
34
|
-
ParseResult,
|
|
35
|
-
ParseMetrics,
|
|
36
|
-
ErrorManager,
|
|
37
|
-
RetryConfig,
|
|
38
|
-
ErrorInfo,
|
|
55
|
+
# Decorators - Clean task management
|
|
56
|
+
from .decorators import (
|
|
57
|
+
task,
|
|
58
|
+
retry,
|
|
59
|
+
schedule,
|
|
60
|
+
timing
|
|
39
61
|
)
|
|
40
|
-
|
|
62
|
+
|
|
63
|
+
__version__ = get_driver_version()
|
|
64
|
+
__author__ = "UnrealOn Team"
|
|
65
|
+
__phase__ = "Phase 3.8: Clean Refactor"
|
|
41
66
|
|
|
42
67
|
__all__ = [
|
|
43
|
-
"__version__",
|
|
44
|
-
# Main Parser Manager
|
|
45
|
-
"ParserManager",
|
|
46
|
-
"ParserManagerConfig",
|
|
47
|
-
"ParserStats",
|
|
48
|
-
"get_parser_manager",
|
|
49
|
-
"quick_parse",
|
|
50
|
-
# Individual Managers
|
|
51
|
-
"ConfigManager",
|
|
52
|
-
"ParserConfig",
|
|
53
|
-
"ResultManager",
|
|
54
|
-
"ParseResult",
|
|
55
|
-
"ParseMetrics",
|
|
56
|
-
"ErrorManager",
|
|
57
|
-
"RetryConfig",
|
|
58
|
-
"ErrorInfo",
|
|
59
|
-
# Exceptions
|
|
60
|
-
"ParserError",
|
|
61
|
-
"BrowserError",
|
|
62
68
|
# Version
|
|
63
69
|
"__version__",
|
|
70
|
+
"__author__",
|
|
71
|
+
"__phase__",
|
|
72
|
+
|
|
73
|
+
# Core API
|
|
74
|
+
"UniversalDriver",
|
|
75
|
+
"DriverConfig",
|
|
76
|
+
"DriverMode",
|
|
77
|
+
"DriverSession",
|
|
78
|
+
"WebSocketClient",
|
|
79
|
+
|
|
80
|
+
# Managers
|
|
81
|
+
"LoggerManager",
|
|
82
|
+
"HttpManager",
|
|
83
|
+
"BrowserManager",
|
|
84
|
+
"CacheManager",
|
|
85
|
+
"ProxyManager",
|
|
86
|
+
"ThreadManager",
|
|
87
|
+
"UpdateManager",
|
|
88
|
+
"ManagerRegistry",
|
|
89
|
+
|
|
90
|
+
# Module system
|
|
91
|
+
"BaseModule",
|
|
92
|
+
"DriverModule",
|
|
93
|
+
"ModuleConfig",
|
|
94
|
+
"EventManager",
|
|
95
|
+
"ModuleRegistry",
|
|
96
|
+
"ModuleStatus",
|
|
97
|
+
"EventType",
|
|
98
|
+
"HealthStatus",
|
|
99
|
+
|
|
100
|
+
# Decorators
|
|
101
|
+
"task",
|
|
102
|
+
"retry",
|
|
103
|
+
"schedule",
|
|
104
|
+
"timing",
|
|
64
105
|
]
|
|
65
|
-
# Convenience aliases for backward compatibility
|
|
66
|
-
Parser = ParserManager
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Clean module system for UnrealOn Driver.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .protocols import (
|
|
6
|
+
BaseModule,
|
|
7
|
+
ModuleStatus,
|
|
8
|
+
EventType,
|
|
9
|
+
HealthStatus,
|
|
10
|
+
ModuleEvent,
|
|
11
|
+
HealthCheckResult
|
|
12
|
+
)
|
|
13
|
+
from .config import ModuleConfig
|
|
14
|
+
from .base import DriverModule
|
|
15
|
+
from .event_manager import EventManager
|
|
16
|
+
from .registry import ModuleRegistry
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
# Protocols and enums
|
|
20
|
+
"BaseModule",
|
|
21
|
+
"ModuleStatus",
|
|
22
|
+
"EventType",
|
|
23
|
+
"HealthStatus",
|
|
24
|
+
"ModuleEvent",
|
|
25
|
+
"HealthCheckResult",
|
|
26
|
+
|
|
27
|
+
# Base classes
|
|
28
|
+
"ModuleConfig",
|
|
29
|
+
"DriverModule",
|
|
30
|
+
|
|
31
|
+
# System components
|
|
32
|
+
"EventManager",
|
|
33
|
+
"ModuleRegistry",
|
|
34
|
+
]
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Clean base module implementation.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from typing import Optional, Dict, Any
|
|
9
|
+
|
|
10
|
+
from .protocols import ModuleStatus, HealthStatus, HealthCheckResult, ModuleEvent, EventType
|
|
11
|
+
from .config import ModuleConfig
|
|
12
|
+
from ..utils.time import utc_now
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DriverModule(ABC):
|
|
18
|
+
"""
|
|
19
|
+
Clean base module implementation.
|
|
20
|
+
|
|
21
|
+
Provides common functionality for all driver modules.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, config: ModuleConfig, driver_id: str):
|
|
25
|
+
self.config = config
|
|
26
|
+
self.driver_id = driver_id
|
|
27
|
+
self.name = config.module_name
|
|
28
|
+
self.status = ModuleStatus.UNINITIALIZED
|
|
29
|
+
self.logger = logging.getLogger(f"{__name__}.{self.name}")
|
|
30
|
+
|
|
31
|
+
# Event system
|
|
32
|
+
self.event_manager: Optional[Any] = None
|
|
33
|
+
|
|
34
|
+
async def initialize(self) -> bool:
|
|
35
|
+
"""Initialize module."""
|
|
36
|
+
if not self.config.enabled:
|
|
37
|
+
self.logger.info(f"Module {self.name} is disabled")
|
|
38
|
+
self.status = ModuleStatus.STOPPED
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
self.status = ModuleStatus.INITIALIZING
|
|
43
|
+
self.logger.info(f"Initializing module: {self.name}")
|
|
44
|
+
|
|
45
|
+
success = await self._initialize()
|
|
46
|
+
|
|
47
|
+
if success:
|
|
48
|
+
self.status = ModuleStatus.INITIALIZED
|
|
49
|
+
self.logger.info(f"Module {self.name} initialized successfully")
|
|
50
|
+
|
|
51
|
+
# Emit event
|
|
52
|
+
await self._emit_event(EventType.MODULE_INITIALIZED)
|
|
53
|
+
else:
|
|
54
|
+
self.status = ModuleStatus.ERROR
|
|
55
|
+
self.logger.error(f"Module {self.name} initialization failed")
|
|
56
|
+
|
|
57
|
+
return success
|
|
58
|
+
|
|
59
|
+
except Exception as e:
|
|
60
|
+
self.status = ModuleStatus.ERROR
|
|
61
|
+
self.logger.error(f"Module {self.name} initialization error: {e}")
|
|
62
|
+
await self._emit_event(EventType.MODULE_ERROR, error=str(e))
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
async def start(self) -> bool:
|
|
66
|
+
"""Start module."""
|
|
67
|
+
if self.status != ModuleStatus.INITIALIZED:
|
|
68
|
+
self.logger.error(f"Cannot start module {self.name} - not initialized")
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
self.status = ModuleStatus.STARTING
|
|
73
|
+
self.logger.info(f"Starting module: {self.name}")
|
|
74
|
+
|
|
75
|
+
success = await self._start()
|
|
76
|
+
|
|
77
|
+
if success:
|
|
78
|
+
self.status = ModuleStatus.RUNNING
|
|
79
|
+
self.logger.info(f"Module {self.name} started successfully")
|
|
80
|
+
|
|
81
|
+
# Emit event
|
|
82
|
+
await self._emit_event(EventType.MODULE_STARTED)
|
|
83
|
+
else:
|
|
84
|
+
self.status = ModuleStatus.ERROR
|
|
85
|
+
self.logger.error(f"Module {self.name} start failed")
|
|
86
|
+
|
|
87
|
+
return success
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
self.status = ModuleStatus.ERROR
|
|
91
|
+
self.logger.error(f"Module {self.name} start error: {e}")
|
|
92
|
+
await self._emit_event(EventType.MODULE_ERROR, error=str(e))
|
|
93
|
+
return False
|
|
94
|
+
|
|
95
|
+
async def stop(self) -> None:
|
|
96
|
+
"""Stop module."""
|
|
97
|
+
try:
|
|
98
|
+
self.status = ModuleStatus.STOPPING
|
|
99
|
+
self.logger.info(f"Stopping module: {self.name}")
|
|
100
|
+
|
|
101
|
+
await self._stop()
|
|
102
|
+
|
|
103
|
+
self.status = ModuleStatus.STOPPED
|
|
104
|
+
self.logger.info(f"Module {self.name} stopped successfully")
|
|
105
|
+
|
|
106
|
+
# Emit event
|
|
107
|
+
await self._emit_event(EventType.MODULE_STOPPED)
|
|
108
|
+
|
|
109
|
+
except Exception as e:
|
|
110
|
+
self.status = ModuleStatus.ERROR
|
|
111
|
+
self.logger.error(f"Module {self.name} stop error: {e}")
|
|
112
|
+
await self._emit_event(EventType.MODULE_ERROR, error=str(e))
|
|
113
|
+
|
|
114
|
+
async def health_check(self) -> HealthCheckResult:
|
|
115
|
+
"""Perform health check."""
|
|
116
|
+
start_time = asyncio.get_event_loop().time()
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
health_data = await self._health_check()
|
|
120
|
+
|
|
121
|
+
response_time = (asyncio.get_event_loop().time() - start_time) * 1000
|
|
122
|
+
|
|
123
|
+
return HealthCheckResult(
|
|
124
|
+
status=HealthStatus.HEALTHY,
|
|
125
|
+
timestamp=utc_now(),
|
|
126
|
+
details=health_data,
|
|
127
|
+
response_time_ms=response_time
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
except Exception as e:
|
|
131
|
+
response_time = (asyncio.get_event_loop().time() - start_time) * 1000
|
|
132
|
+
|
|
133
|
+
return HealthCheckResult(
|
|
134
|
+
status=HealthStatus.UNHEALTHY,
|
|
135
|
+
timestamp=utc_now(),
|
|
136
|
+
error=str(e),
|
|
137
|
+
response_time_ms=response_time
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def set_event_manager(self, event_manager):
|
|
141
|
+
"""Set event manager for event emission."""
|
|
142
|
+
self.event_manager = event_manager
|
|
143
|
+
|
|
144
|
+
async def _emit_event(self, event_type: EventType, data: Optional[Dict[str, Any]] = None, error: Optional[str] = None):
|
|
145
|
+
"""Emit module event."""
|
|
146
|
+
if not self.event_manager:
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
event = ModuleEvent(
|
|
151
|
+
event_type=event_type,
|
|
152
|
+
module_name=self.name,
|
|
153
|
+
timestamp=utc_now(),
|
|
154
|
+
data=data or {},
|
|
155
|
+
error=error
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
await self.event_manager.emit(event)
|
|
159
|
+
|
|
160
|
+
except Exception as e:
|
|
161
|
+
self.logger.error(f"Failed to emit event: {e}")
|
|
162
|
+
|
|
163
|
+
@abstractmethod
|
|
164
|
+
async def _initialize(self) -> bool:
|
|
165
|
+
"""Module-specific initialization."""
|
|
166
|
+
pass
|
|
167
|
+
|
|
168
|
+
@abstractmethod
|
|
169
|
+
async def _start(self) -> bool:
|
|
170
|
+
"""Module-specific start logic."""
|
|
171
|
+
pass
|
|
172
|
+
|
|
173
|
+
@abstractmethod
|
|
174
|
+
async def _stop(self) -> None:
|
|
175
|
+
"""Module-specific stop logic."""
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
async def _health_check(self) -> Dict[str, Any]:
|
|
179
|
+
"""Module-specific health check."""
|
|
180
|
+
return {
|
|
181
|
+
"status": "ok",
|
|
182
|
+
"module": self.name,
|
|
183
|
+
"version": self.config.version
|
|
184
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Clean module configuration.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, Dict, Any
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ModuleConfig(BaseModel):
|
|
10
|
+
"""Base configuration for all modules."""
|
|
11
|
+
|
|
12
|
+
# Module identification
|
|
13
|
+
module_name: str = Field(..., description="Unique module name")
|
|
14
|
+
version: str = Field(default="1.0.0", description="Module version")
|
|
15
|
+
|
|
16
|
+
# Module behavior
|
|
17
|
+
enabled: bool = Field(default=True, description="Whether module is enabled")
|
|
18
|
+
auto_start: bool = Field(default=True, description="Auto-start on driver init")
|
|
19
|
+
|
|
20
|
+
# Performance
|
|
21
|
+
timeout_seconds: float = Field(default=30.0, description="Operation timeout")
|
|
22
|
+
retry_count: int = Field(default=3, description="Retry attempts")
|
|
23
|
+
|
|
24
|
+
# Health checks
|
|
25
|
+
health_check_interval: int = Field(default=60, description="Health check interval")
|
|
26
|
+
|
|
27
|
+
# Custom settings
|
|
28
|
+
custom_settings: Dict[str, Any] = Field(default_factory=dict, description="Module-specific settings")
|
|
29
|
+
|
|
30
|
+
model_config = {"extra": "forbid"}
|