unrealon 2.0.12__tar.gz → 2.0.14__tar.gz
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-2.0.12/unrealon.egg-info → unrealon-2.0.14}/PKG-INFO +1 -1
- {unrealon-2.0.12 → unrealon-2.0.14}/pyproject.toml +1 -1
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/__init__.py +2 -10
- unrealon-2.0.14/unrealon-driver/src/unrealon_driver/utils/__init__.py +10 -0
- unrealon-2.0.14/unrealon-driver/src/unrealon_installer/__init__.py +11 -0
- unrealon-2.0.14/unrealon-driver/src/unrealon_installer/browser_fixes.py +227 -0
- unrealon-2.0.14/unrealon-driver/src/unrealon_installer/core.py +166 -0
- unrealon-2.0.14/unrealon-driver/src/unrealon_installer/platform.py +122 -0
- unrealon-2.0.14/unrealon-driver/src/unrealon_installer/templates.py +60 -0
- {unrealon-2.0.12 → unrealon-2.0.14/unrealon.egg-info}/PKG-INFO +1 -1
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon.egg-info/SOURCES.txt +5 -1
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon.egg-info/top_level.txt +1 -0
- unrealon-2.0.12/unrealon-driver/src/unrealon_driver/utils/__init__.py +0 -18
- unrealon-2.0.12/unrealon-driver/src/unrealon_driver/utils/platform_compatibility.py +0 -205
- {unrealon-2.0.12 → unrealon-2.0.14}/LICENSE +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/MANIFEST.in +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/README.md +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/setup.cfg +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/README.md +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/cli/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/cli/browser_cli.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/cli/cookies_cli.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/cli/interactive_mode.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/cli/main.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/core/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/core/browser_manager.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/bot_detection.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/models/config.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/models/core.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/models/dataclasses.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/models/detection.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/models/enums.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/dto/models/statistics.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/captcha.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/cookies.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/logger_bridge.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/page_wait_manager.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/profile.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/managers/script_manager.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/bypass_techniques.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/manager.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/nodriver_stealth.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/playwright_stealth.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/scanner_tester.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-browser/src/unrealon_browser/stealth/undetected_chrome.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/config/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/config/environment.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/config/urls.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/enums/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/enums/events.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/enums/jobs.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/enums/status.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/enums/types.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/error_handling/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/error_handling/circuit_breaker.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/error_handling/error_context.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/error_handling/recovery.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/error_handling/retry.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/base.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/communication.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/driver.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/proxy.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/task.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/exceptions/validation.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/arq_context.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/arq_responses.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/authentication.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/base.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/bridge_stats.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/communication.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/connection_stats.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/driver.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/driver_details.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/logging.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/task.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/typed_responses.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/base.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/broadcast.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/config.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/driver.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/errors.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/heartbeat.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/logging.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/proxy.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/tasks.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket/utils.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/models/websocket_session.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/monitoring/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/monitoring/alerts.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/monitoring/dashboard.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/monitoring/health_check.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/monitoring/metrics.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/utils/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/utils/time.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-core/src/unrealon_core/version.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/core_module/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/core_module/base.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/core_module/config.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/core_module/event_manager.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/core_module/protocols.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/core_module/registry.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/decorators/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/decorators/retry.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/decorators/schedule.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/decorators/task.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/decorators/timing.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/communication/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/communication/session.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/communication/websocket_client.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/core/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/core/config.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/core/driver.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/factory/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/factory/manager_factory.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/lifecycle/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/lifecycle/daemon.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/lifecycle/initialization.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/lifecycle/shutdown.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/monitoring/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/monitoring/health.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/utilities/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/utilities/logging.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/driver/utilities/serialization.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/__init__.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/base.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/browser.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/cache.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/http.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/logger.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/proxy.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/registry.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/threading.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/managers/update.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon-driver/src/unrealon_driver/utils/time.py +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon.egg-info/dependency_links.txt +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon.egg-info/entry_points.txt +0 -0
- {unrealon-2.0.12 → unrealon-2.0.14}/unrealon.egg-info/requires.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unrealon"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.14"
|
|
8
8
|
description = "Enterprise-grade web scraping platform with AI-powered automation and real-time orchestration capabilities"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "UnrealOn Team", email = "team@unrealon.com"}
|
|
@@ -60,12 +60,8 @@ from .decorators import (
|
|
|
60
60
|
timing
|
|
61
61
|
)
|
|
62
62
|
|
|
63
|
-
# Utilities -
|
|
64
|
-
from .utils import
|
|
65
|
-
PlatformCompatibility,
|
|
66
|
-
ensure_platform_compatibility,
|
|
67
|
-
get_platform_info
|
|
68
|
-
)
|
|
63
|
+
# Utilities - Time utilities only (platform compatibility moved to installer)
|
|
64
|
+
from .utils import time
|
|
69
65
|
|
|
70
66
|
__version__ = get_driver_version()
|
|
71
67
|
__author__ = "UnrealOn Team"
|
|
@@ -108,8 +104,4 @@ __all__ = [
|
|
|
108
104
|
"schedule",
|
|
109
105
|
"timing",
|
|
110
106
|
|
|
111
|
-
# Utilities
|
|
112
|
-
"PlatformCompatibility",
|
|
113
|
-
"ensure_platform_compatibility",
|
|
114
|
-
"get_platform_info",
|
|
115
107
|
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UnrealOn Universal Installer - Clean Edition
|
|
3
|
+
|
|
4
|
+
One function installs everything. Simple and reliable.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .core import install_parser
|
|
8
|
+
from .browser_fixes import fix_browsers, diagnose_browsers, get_browser_status
|
|
9
|
+
|
|
10
|
+
__version__ = "2.0.0"
|
|
11
|
+
__all__ = ["install_parser", "fix_browsers", "diagnose_browsers", "get_browser_status"]
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Browser troubleshooting and fixes for Windows.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import subprocess
|
|
8
|
+
import platform
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, List, Optional
|
|
11
|
+
import shutil
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BrowserFixer:
|
|
15
|
+
"""Windows browser troubleshooting and fixes."""
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.is_windows = platform.system() == "Windows"
|
|
19
|
+
self.playwright_cache = self._get_playwright_cache_path()
|
|
20
|
+
|
|
21
|
+
def _get_playwright_cache_path(self) -> Optional[Path]:
|
|
22
|
+
"""Get Playwright cache directory path."""
|
|
23
|
+
if self.is_windows:
|
|
24
|
+
return Path(os.environ.get("USERPROFILE", "")) / "AppData" / "Local" / "ms-playwright"
|
|
25
|
+
elif platform.system() == "Darwin": # macOS
|
|
26
|
+
return Path.home() / "Library" / "Caches" / "ms-playwright"
|
|
27
|
+
else: # Linux
|
|
28
|
+
return Path.home() / ".cache" / "ms-playwright"
|
|
29
|
+
|
|
30
|
+
def diagnose_browser_issues(self) -> Dict[str, bool]:
|
|
31
|
+
"""Diagnose common browser issues."""
|
|
32
|
+
issues = {}
|
|
33
|
+
|
|
34
|
+
# Check if Playwright is installed
|
|
35
|
+
issues['playwright_installed'] = self._check_playwright_installed()
|
|
36
|
+
|
|
37
|
+
# Check if browsers are installed
|
|
38
|
+
issues['browsers_installed'] = self._check_browsers_installed()
|
|
39
|
+
|
|
40
|
+
# Check cache directory
|
|
41
|
+
issues['cache_exists'] = self._check_cache_directory()
|
|
42
|
+
|
|
43
|
+
# Check if browsers can launch
|
|
44
|
+
issues['browser_launch_test'] = self._test_browser_launch()
|
|
45
|
+
|
|
46
|
+
return issues
|
|
47
|
+
|
|
48
|
+
def _check_playwright_installed(self) -> bool:
|
|
49
|
+
"""Check if Playwright is installed."""
|
|
50
|
+
try:
|
|
51
|
+
subprocess.run([sys.executable, "-c", "import playwright"],
|
|
52
|
+
check=True, capture_output=True)
|
|
53
|
+
return True
|
|
54
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
def _check_browsers_installed(self) -> bool:
|
|
58
|
+
"""Check if Playwright browsers are installed."""
|
|
59
|
+
try:
|
|
60
|
+
result = subprocess.run([sys.executable, "-m", "playwright", "--version"],
|
|
61
|
+
check=True, capture_output=True, text=True)
|
|
62
|
+
return "version" in result.stdout.lower()
|
|
63
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
def _check_cache_directory(self) -> bool:
|
|
67
|
+
"""Check if Playwright cache directory exists."""
|
|
68
|
+
if not self.playwright_cache:
|
|
69
|
+
return False
|
|
70
|
+
return self.playwright_cache.exists()
|
|
71
|
+
|
|
72
|
+
def _test_browser_launch(self) -> bool:
|
|
73
|
+
"""Test if browser can launch (quick test)."""
|
|
74
|
+
try:
|
|
75
|
+
test_code = """
|
|
76
|
+
from playwright.sync_api import sync_playwright
|
|
77
|
+
try:
|
|
78
|
+
with sync_playwright() as p:
|
|
79
|
+
browser = p.chromium.launch(headless=True)
|
|
80
|
+
browser.close()
|
|
81
|
+
print("OK")
|
|
82
|
+
except Exception as e:
|
|
83
|
+
print(f"ERROR: {e}")
|
|
84
|
+
"""
|
|
85
|
+
result = subprocess.run([sys.executable, "-c", test_code],
|
|
86
|
+
capture_output=True, text=True, timeout=30)
|
|
87
|
+
return "OK" in result.stdout
|
|
88
|
+
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
def fix_browser_issues(self, force_reinstall: bool = False) -> bool:
|
|
92
|
+
"""Fix common browser issues."""
|
|
93
|
+
print("🔧 Fixing browser issues...")
|
|
94
|
+
|
|
95
|
+
success = True
|
|
96
|
+
|
|
97
|
+
# Step 1: Clear cache if it exists
|
|
98
|
+
if self._clear_browser_cache():
|
|
99
|
+
print("✅ Browser cache cleared")
|
|
100
|
+
else:
|
|
101
|
+
print("⚠️ Could not clear browser cache")
|
|
102
|
+
|
|
103
|
+
# Step 2: Reinstall Playwright if needed or forced
|
|
104
|
+
if force_reinstall or not self._check_playwright_installed():
|
|
105
|
+
if self._reinstall_playwright():
|
|
106
|
+
print("✅ Playwright reinstalled")
|
|
107
|
+
else:
|
|
108
|
+
print("❌ Failed to reinstall Playwright")
|
|
109
|
+
success = False
|
|
110
|
+
|
|
111
|
+
# Step 3: Install browsers
|
|
112
|
+
if self._install_browsers():
|
|
113
|
+
print("✅ Browsers installed")
|
|
114
|
+
else:
|
|
115
|
+
print("❌ Failed to install browsers")
|
|
116
|
+
success = False
|
|
117
|
+
|
|
118
|
+
# Step 4: Test installation
|
|
119
|
+
if self._test_browser_launch():
|
|
120
|
+
print("✅ Browser test passed")
|
|
121
|
+
else:
|
|
122
|
+
print("❌ Browser test failed")
|
|
123
|
+
success = False
|
|
124
|
+
|
|
125
|
+
return success
|
|
126
|
+
|
|
127
|
+
def _clear_browser_cache(self) -> bool:
|
|
128
|
+
"""Clear Playwright browser cache."""
|
|
129
|
+
try:
|
|
130
|
+
if self.playwright_cache and self.playwright_cache.exists():
|
|
131
|
+
shutil.rmtree(self.playwright_cache, ignore_errors=True)
|
|
132
|
+
print(f"Cleared cache: {self.playwright_cache}")
|
|
133
|
+
return True
|
|
134
|
+
except Exception as e:
|
|
135
|
+
print(f"Cache clear error: {e}")
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
def _reinstall_playwright(self) -> bool:
|
|
139
|
+
"""Reinstall Playwright completely."""
|
|
140
|
+
try:
|
|
141
|
+
# Uninstall
|
|
142
|
+
subprocess.run([sys.executable, "-m", "pip", "uninstall", "-y", "playwright"],
|
|
143
|
+
check=False, capture_output=True)
|
|
144
|
+
|
|
145
|
+
# Clear pip cache
|
|
146
|
+
subprocess.run([sys.executable, "-m", "pip", "cache", "purge"],
|
|
147
|
+
check=False, capture_output=True)
|
|
148
|
+
|
|
149
|
+
# Reinstall
|
|
150
|
+
subprocess.run([sys.executable, "-m", "pip", "install", "playwright"],
|
|
151
|
+
check=True, capture_output=True)
|
|
152
|
+
|
|
153
|
+
return True
|
|
154
|
+
except subprocess.CalledProcessError:
|
|
155
|
+
return False
|
|
156
|
+
|
|
157
|
+
def _install_browsers(self) -> bool:
|
|
158
|
+
"""Install Playwright browsers."""
|
|
159
|
+
try:
|
|
160
|
+
# Install chromium (most stable)
|
|
161
|
+
subprocess.run([sys.executable, "-m", "playwright", "install", "chromium"],
|
|
162
|
+
check=True, capture_output=True)
|
|
163
|
+
|
|
164
|
+
# Try to install firefox too (optional)
|
|
165
|
+
subprocess.run([sys.executable, "-m", "playwright", "install", "firefox"],
|
|
166
|
+
check=False, capture_output=True)
|
|
167
|
+
|
|
168
|
+
return True
|
|
169
|
+
except subprocess.CalledProcessError:
|
|
170
|
+
return False
|
|
171
|
+
|
|
172
|
+
def get_browser_info(self) -> Dict[str, str]:
|
|
173
|
+
"""Get browser installation information."""
|
|
174
|
+
info = {}
|
|
175
|
+
|
|
176
|
+
# Playwright version
|
|
177
|
+
try:
|
|
178
|
+
result = subprocess.run([sys.executable, "-m", "playwright", "--version"],
|
|
179
|
+
capture_output=True, text=True)
|
|
180
|
+
info['playwright_version'] = result.stdout.strip()
|
|
181
|
+
except:
|
|
182
|
+
info['playwright_version'] = "Not installed"
|
|
183
|
+
|
|
184
|
+
# Cache directory
|
|
185
|
+
info['cache_path'] = str(self.playwright_cache) if self.playwright_cache else "Unknown"
|
|
186
|
+
info['cache_exists'] = str(self._check_cache_directory())
|
|
187
|
+
|
|
188
|
+
# Browser test
|
|
189
|
+
info['browser_test'] = "PASS" if self._test_browser_launch() else "FAIL"
|
|
190
|
+
|
|
191
|
+
return info
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def fix_browsers(force_reinstall: bool = False) -> bool:
|
|
195
|
+
"""
|
|
196
|
+
Quick browser fix function.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
force_reinstall: Force complete reinstall
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
True if successful
|
|
203
|
+
"""
|
|
204
|
+
fixer = BrowserFixer()
|
|
205
|
+
return fixer.fix_browser_issues(force_reinstall)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def diagnose_browsers() -> Dict[str, bool]:
|
|
209
|
+
"""
|
|
210
|
+
Quick browser diagnosis.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
Dictionary with diagnosis results
|
|
214
|
+
"""
|
|
215
|
+
fixer = BrowserFixer()
|
|
216
|
+
return fixer.diagnose_browser_issues()
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def get_browser_status() -> Dict[str, str]:
|
|
220
|
+
"""
|
|
221
|
+
Get browser status information.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
Dictionary with browser info
|
|
225
|
+
"""
|
|
226
|
+
fixer = BrowserFixer()
|
|
227
|
+
return fixer.get_browser_info()
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core installer logic. Clean and simple.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import subprocess
|
|
8
|
+
import platform
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, Any
|
|
11
|
+
|
|
12
|
+
from .platform import apply_platform_fixes, check_system_requirements
|
|
13
|
+
from .templates import TemplateEngine
|
|
14
|
+
from .browser_fixes import fix_browsers, diagnose_browsers
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def install_parser(parser_name: str, parser_path: str = ".") -> bool:
|
|
18
|
+
"""
|
|
19
|
+
Install everything for a UnrealOn parser.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
parser_name: Name like "upbit_concurrent"
|
|
23
|
+
parser_path: Path to parser directory
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
True if success, False if failed
|
|
27
|
+
"""
|
|
28
|
+
print(f"🚀 Installing {parser_name}")
|
|
29
|
+
print("=" * 40)
|
|
30
|
+
|
|
31
|
+
parser_dir = Path(parser_path).resolve()
|
|
32
|
+
os.chdir(parser_dir)
|
|
33
|
+
|
|
34
|
+
# 1. Apply platform fixes
|
|
35
|
+
print("🔧 Applying platform fixes...")
|
|
36
|
+
apply_platform_fixes()
|
|
37
|
+
print("✅ Platform fixes applied")
|
|
38
|
+
|
|
39
|
+
# 2. Check system
|
|
40
|
+
print("🔍 Checking system...")
|
|
41
|
+
requirements = check_system_requirements()
|
|
42
|
+
failed = [k for k, v in requirements.items() if not v]
|
|
43
|
+
if failed:
|
|
44
|
+
print(f"❌ Missing: {', '.join(failed)}")
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
print(f"✅ Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
|
|
48
|
+
|
|
49
|
+
# 3. Install dependencies
|
|
50
|
+
if not _install_dependencies():
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
# 4. Install browsers
|
|
54
|
+
if not _install_browsers():
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
# 5. Create batch files (Windows only)
|
|
58
|
+
if platform.system() == "Windows":
|
|
59
|
+
_create_batch_files(parser_name)
|
|
60
|
+
|
|
61
|
+
print(f"\n✅ {parser_name} installed successfully!")
|
|
62
|
+
print("Run: python main.py 5 2")
|
|
63
|
+
if platform.system() == "Windows":
|
|
64
|
+
print("Or: START.bat")
|
|
65
|
+
|
|
66
|
+
return True
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _install_dependencies() -> bool:
|
|
70
|
+
"""Install Python dependencies."""
|
|
71
|
+
print("📦 Installing dependencies...")
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
# Check if requirements.txt exists
|
|
75
|
+
if Path("requirements.txt").exists():
|
|
76
|
+
subprocess.run([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"],
|
|
77
|
+
check=True, capture_output=True)
|
|
78
|
+
else:
|
|
79
|
+
# Fallback to basic packages
|
|
80
|
+
subprocess.run([sys.executable, "-m", "pip", "install", "unrealon", "playwright"],
|
|
81
|
+
check=True, capture_output=True)
|
|
82
|
+
|
|
83
|
+
print("✅ Dependencies installed")
|
|
84
|
+
return True
|
|
85
|
+
except subprocess.CalledProcessError as e:
|
|
86
|
+
print(f"❌ Failed to install dependencies: {e}")
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _install_browsers() -> bool:
|
|
91
|
+
"""Install Playwright browsers with smart fixing."""
|
|
92
|
+
print("🌐 Installing browsers...")
|
|
93
|
+
|
|
94
|
+
# First, diagnose any issues
|
|
95
|
+
issues = diagnose_browsers()
|
|
96
|
+
|
|
97
|
+
# If there are issues, try to fix them
|
|
98
|
+
if not all(issues.values()):
|
|
99
|
+
print("🔧 Detected browser issues, applying fixes...")
|
|
100
|
+
if fix_browsers(force_reinstall=False):
|
|
101
|
+
print("✅ Browser issues fixed")
|
|
102
|
+
return True
|
|
103
|
+
else:
|
|
104
|
+
print("❌ Could not fix browser issues")
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
# If no issues, just install normally
|
|
108
|
+
try:
|
|
109
|
+
subprocess.run([sys.executable, "-m", "playwright", "install", "chromium"],
|
|
110
|
+
check=True, capture_output=True)
|
|
111
|
+
print("✅ Browsers installed")
|
|
112
|
+
return True
|
|
113
|
+
except subprocess.CalledProcessError as e:
|
|
114
|
+
print(f"⚠️ Normal install failed, trying fix: {e}")
|
|
115
|
+
# Try fixing as fallback
|
|
116
|
+
return fix_browsers(force_reinstall=True)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _create_batch_files(parser_name: str):
|
|
120
|
+
"""Create Windows batch files using Jinja2 templates."""
|
|
121
|
+
print("🪟 Creating Windows batch files...")
|
|
122
|
+
|
|
123
|
+
# Detect parser config
|
|
124
|
+
config = _detect_parser_config()
|
|
125
|
+
|
|
126
|
+
# Create template engine
|
|
127
|
+
engine = TemplateEngine()
|
|
128
|
+
|
|
129
|
+
# Generate batch files
|
|
130
|
+
start_content = engine.render_start_bat(parser_name, config)
|
|
131
|
+
Path("START.bat").write_text(start_content, encoding="utf-8")
|
|
132
|
+
|
|
133
|
+
quick_content = engine.render_quick_run_bat(parser_name, config)
|
|
134
|
+
Path("QUICK_RUN.bat").write_text(quick_content, encoding="utf-8")
|
|
135
|
+
|
|
136
|
+
test_content = engine.render_test_bat(parser_name, config)
|
|
137
|
+
Path("TEST.bat").write_text(test_content, encoding="utf-8")
|
|
138
|
+
|
|
139
|
+
print("✅ Created START.bat, QUICK_RUN.bat, TEST.bat")
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _detect_parser_config() -> Dict[str, Any]:
|
|
143
|
+
"""Detect parser configuration from files."""
|
|
144
|
+
config = {
|
|
145
|
+
'browsers_needed': ['chromium'],
|
|
146
|
+
'proxy_support': False,
|
|
147
|
+
'supports_persistent': False
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Check main.py for persistent mode support
|
|
151
|
+
if Path("main.py").exists():
|
|
152
|
+
main_content = Path("main.py").read_text()
|
|
153
|
+
if "--persistent" in main_content:
|
|
154
|
+
config['supports_persistent'] = True
|
|
155
|
+
|
|
156
|
+
# Check for proxy config
|
|
157
|
+
if Path("src/proxy_config.py").exists() or Path("proxy_config.py").exists():
|
|
158
|
+
config['proxy_support'] = True
|
|
159
|
+
|
|
160
|
+
# Check pyproject.toml for browser requirements
|
|
161
|
+
if Path("pyproject.toml").exists():
|
|
162
|
+
toml_content = Path("pyproject.toml").read_text()
|
|
163
|
+
if "firefox" in toml_content.lower():
|
|
164
|
+
config['browsers_needed'].append('firefox')
|
|
165
|
+
|
|
166
|
+
return config
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Platform compatibility fixes. Clean and simple.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import sys
|
|
7
|
+
import platform
|
|
8
|
+
import warnings
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def apply_platform_fixes():
|
|
15
|
+
"""Apply all necessary platform fixes automatically."""
|
|
16
|
+
system = platform.system()
|
|
17
|
+
fixes = []
|
|
18
|
+
|
|
19
|
+
if system == "Windows":
|
|
20
|
+
fixes.extend(_apply_windows_fixes())
|
|
21
|
+
elif system == "Darwin": # macOS
|
|
22
|
+
fixes.extend(_apply_macos_fixes())
|
|
23
|
+
elif system == "Linux":
|
|
24
|
+
fixes.extend(_apply_linux_fixes())
|
|
25
|
+
|
|
26
|
+
if fixes:
|
|
27
|
+
logger.info(f"✅ Applied platform fixes: {', '.join(fixes)}")
|
|
28
|
+
|
|
29
|
+
return fixes
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _apply_windows_fixes():
|
|
33
|
+
"""Windows-specific fixes."""
|
|
34
|
+
fixes = []
|
|
35
|
+
|
|
36
|
+
# Asyncio event loop policy
|
|
37
|
+
if sys.version_info >= (3, 8):
|
|
38
|
+
try:
|
|
39
|
+
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
|
40
|
+
fixes.append("ProactorEventLoop")
|
|
41
|
+
except Exception:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
# Console encoding
|
|
45
|
+
try:
|
|
46
|
+
if hasattr(sys.stdout, 'reconfigure'):
|
|
47
|
+
sys.stdout.reconfigure(encoding='utf-8')
|
|
48
|
+
sys.stderr.reconfigure(encoding='utf-8')
|
|
49
|
+
fixes.append("UTF-8 encoding")
|
|
50
|
+
except Exception:
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
# Suppress warnings
|
|
54
|
+
warnings.filterwarnings("ignore", category=ResourceWarning)
|
|
55
|
+
fixes.append("ResourceWarning suppression")
|
|
56
|
+
|
|
57
|
+
return fixes
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _apply_macos_fixes():
|
|
61
|
+
"""macOS-specific fixes."""
|
|
62
|
+
fixes = []
|
|
63
|
+
|
|
64
|
+
# SSL context fix
|
|
65
|
+
try:
|
|
66
|
+
import ssl
|
|
67
|
+
ssl._create_default_https_context = ssl._create_unverified_context
|
|
68
|
+
fixes.append("SSL context")
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# File descriptor limits
|
|
73
|
+
try:
|
|
74
|
+
import resource
|
|
75
|
+
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
|
|
76
|
+
if soft < 1024:
|
|
77
|
+
resource.setrlimit(resource.RLIMIT_NOFILE, (min(1024, hard), hard))
|
|
78
|
+
fixes.append("File descriptor limit")
|
|
79
|
+
except Exception:
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
return fixes
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _apply_linux_fixes():
|
|
86
|
+
"""Linux-specific fixes."""
|
|
87
|
+
fixes = []
|
|
88
|
+
|
|
89
|
+
# File descriptor limits
|
|
90
|
+
try:
|
|
91
|
+
import resource
|
|
92
|
+
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
|
|
93
|
+
if soft < 2048:
|
|
94
|
+
resource.setrlimit(resource.RLIMIT_NOFILE, (min(2048, hard), hard))
|
|
95
|
+
fixes.append("File descriptor limit")
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
# Headless display
|
|
100
|
+
import os
|
|
101
|
+
if not os.environ.get('DISPLAY'):
|
|
102
|
+
os.environ['DISPLAY'] = ':99'
|
|
103
|
+
fixes.append("Headless display")
|
|
104
|
+
|
|
105
|
+
return fixes
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_platform_info():
|
|
109
|
+
"""Get platform information."""
|
|
110
|
+
return {
|
|
111
|
+
'platform': platform.system(),
|
|
112
|
+
'architecture': platform.architecture()[0],
|
|
113
|
+
'python_version': f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def check_system_requirements():
|
|
118
|
+
"""Check if system meets requirements."""
|
|
119
|
+
return {
|
|
120
|
+
'python_version': sys.version_info >= (3, 9),
|
|
121
|
+
'platform_supported': platform.system() in ['Windows', 'Darwin', 'Linux']
|
|
122
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Jinja2 template engine for batch files.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Dict, Any
|
|
7
|
+
import json
|
|
8
|
+
from jinja2 import Environment, FileSystemLoader
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TemplateEngine:
|
|
12
|
+
"""Jinja2-based template engine for Windows batch files."""
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
# Get batch templates directory
|
|
16
|
+
templates_dir = Path(__file__).parent / "batch_templates"
|
|
17
|
+
|
|
18
|
+
# Create Jinja2 environment
|
|
19
|
+
self.env = Environment(
|
|
20
|
+
loader=FileSystemLoader(str(templates_dir)),
|
|
21
|
+
trim_blocks=True,
|
|
22
|
+
lstrip_blocks=True
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def render_start_bat(self, parser_name: str, config: Dict[str, Any]) -> str:
|
|
26
|
+
"""Render START.bat file."""
|
|
27
|
+
template = self.env.get_template('start.bat.j2')
|
|
28
|
+
|
|
29
|
+
context = {
|
|
30
|
+
'parser_name': parser_name,
|
|
31
|
+
'config': config,
|
|
32
|
+
'config_json': json.dumps(config, indent=None),
|
|
33
|
+
'browsers_list': ', '.join(config.get('browsers_needed', ['chromium'])),
|
|
34
|
+
'has_proxy': config.get('proxy_support', False),
|
|
35
|
+
'has_persistent': config.get('supports_persistent', False)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return template.render(**context)
|
|
39
|
+
|
|
40
|
+
def render_quick_run_bat(self, parser_name: str, config: Dict[str, Any]) -> str:
|
|
41
|
+
"""Render QUICK_RUN.bat file."""
|
|
42
|
+
template = self.env.get_template('quick_run.bat.j2')
|
|
43
|
+
|
|
44
|
+
context = {
|
|
45
|
+
'parser_name': parser_name,
|
|
46
|
+
'config': config
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return template.render(**context)
|
|
50
|
+
|
|
51
|
+
def render_test_bat(self, parser_name: str, config: Dict[str, Any]) -> str:
|
|
52
|
+
"""Render TEST.bat file."""
|
|
53
|
+
template = self.env.get_template('test.bat.j2')
|
|
54
|
+
|
|
55
|
+
context = {
|
|
56
|
+
'parser_name': parser_name,
|
|
57
|
+
'config': config
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return template.render(**context)
|
|
@@ -128,8 +128,12 @@ unrealon-driver/src/unrealon_driver/managers/registry.py
|
|
|
128
128
|
unrealon-driver/src/unrealon_driver/managers/threading.py
|
|
129
129
|
unrealon-driver/src/unrealon_driver/managers/update.py
|
|
130
130
|
unrealon-driver/src/unrealon_driver/utils/__init__.py
|
|
131
|
-
unrealon-driver/src/unrealon_driver/utils/platform_compatibility.py
|
|
132
131
|
unrealon-driver/src/unrealon_driver/utils/time.py
|
|
132
|
+
unrealon-driver/src/unrealon_installer/__init__.py
|
|
133
|
+
unrealon-driver/src/unrealon_installer/browser_fixes.py
|
|
134
|
+
unrealon-driver/src/unrealon_installer/core.py
|
|
135
|
+
unrealon-driver/src/unrealon_installer/platform.py
|
|
136
|
+
unrealon-driver/src/unrealon_installer/templates.py
|
|
133
137
|
unrealon.egg-info/PKG-INFO
|
|
134
138
|
unrealon.egg-info/SOURCES.txt
|
|
135
139
|
unrealon.egg-info/dependency_links.txt
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Utility modules for UnrealOn Driver.
|
|
3
|
-
|
|
4
|
-
Contains cross-platform compatibility and other utility functions.
|
|
5
|
-
"""
|
|
6
|
-
from .time import utc_now
|
|
7
|
-
from .platform_compatibility import (
|
|
8
|
-
PlatformCompatibility,
|
|
9
|
-
ensure_platform_compatibility,
|
|
10
|
-
get_platform_info
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
__all__ = [
|
|
14
|
-
'utc_now',
|
|
15
|
-
'PlatformCompatibility',
|
|
16
|
-
'ensure_platform_compatibility',
|
|
17
|
-
'get_platform_info'
|
|
18
|
-
]
|