mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-09-17 14:42:18 +02:00
180 lines
5.5 KiB
Python
180 lines
5.5 KiB
Python
# ============================================================================
|
|
# FILE 3: streaming_providers/base/ui/console_notification_adapter.py
|
|
# ============================================================================
|
|
"""
|
|
Console notification adapter for non-Kodi environments
|
|
Displays remote login information as simple text output
|
|
"""
|
|
|
|
import time
|
|
from typing import Optional
|
|
|
|
from ..utils.logger import logger
|
|
from .notification_interface import NotificationInterface, NotificationResult
|
|
|
|
|
|
class ConsoleNotificationAdapter(NotificationInterface):
|
|
"""
|
|
Console-based notification adapter
|
|
|
|
Displays remote login information as text output
|
|
Suitable for:
|
|
- Standalone script execution
|
|
- Headless environments
|
|
- Development/testing
|
|
- CI/CD pipelines
|
|
"""
|
|
|
|
def __init__(self, provider_name: str = "Service",
|
|
success_message: Optional[str] = None,
|
|
failure_template: Optional[str] = None):
|
|
"""
|
|
Initialize console notification adapter
|
|
|
|
Args:
|
|
provider_name: Name of the provider (e.g., "MagentaTV")
|
|
success_message: Custom success message (optional)
|
|
failure_template: Template for failure messages (optional)
|
|
"""
|
|
super().__init__()
|
|
self._start_time = None
|
|
self._expires_in = 0
|
|
self._last_update = 0
|
|
|
|
# Provider-specific configuration
|
|
self.provider_name = provider_name
|
|
self.success_message = success_message or f"{provider_name} login successful!"
|
|
self.failure_template = failure_template or f"{provider_name} login failed: {{}}"
|
|
|
|
@property
|
|
def supports_qr_display(self) -> bool:
|
|
"""Console cannot display QR codes"""
|
|
return False
|
|
|
|
@property
|
|
def supports_countdown(self) -> bool:
|
|
"""Console supports text-based countdown"""
|
|
return True
|
|
|
|
@property
|
|
def is_blocking(self) -> bool:
|
|
"""Console output is non-blocking"""
|
|
return False
|
|
|
|
def show_remote_login(
|
|
self, login_code: str, qr_target_url: str, expires_in: int, interval: int = 10
|
|
) -> NotificationResult:
|
|
"""
|
|
Show remote login information in console
|
|
|
|
Args:
|
|
login_code: Short login code
|
|
qr_target_url: The URL to encode in QR (displayed to user)
|
|
expires_in: Expiration time in seconds
|
|
interval: Update interval
|
|
|
|
Returns:
|
|
NotificationResult.CONTINUE (always, as console can't cancel)
|
|
"""
|
|
self._is_active = True
|
|
self._start_time = time.time()
|
|
self._expires_in = expires_in
|
|
self._last_update = 0
|
|
|
|
# Print header
|
|
print("\n" + "=" * 70)
|
|
print(f" {self.provider_name} - REMOTE LOGIN REQUIRED")
|
|
print("=" * 70)
|
|
print()
|
|
|
|
# Print instructions
|
|
print(f"Please authenticate using your mobile device for {self.provider_name}:")
|
|
print()
|
|
print(f" Option 1: Scan QR Code")
|
|
print(f" Visit this URL on your mobile device:")
|
|
print(f" {qr_target_url}")
|
|
print()
|
|
print(f" Option 2: Manual Entry")
|
|
print(f" Login Code: {login_code}")
|
|
print()
|
|
print(f" This code expires in {expires_in} seconds")
|
|
print()
|
|
print("=" * 70)
|
|
print()
|
|
|
|
logger.info(f"Remote login started for {self.provider_name}: code={login_code}, expires_in={expires_in}s")
|
|
logger.info(f"QR target URL: {qr_target_url}")
|
|
|
|
return NotificationResult.CONTINUE
|
|
|
|
def update_countdown(self, remaining_seconds: int) -> bool:
|
|
"""
|
|
Update countdown in console
|
|
|
|
Only prints updates at reasonable intervals to avoid spam
|
|
|
|
Args:
|
|
remaining_seconds: Seconds remaining
|
|
|
|
Returns:
|
|
bool: Always True (console can't be cancelled by user)
|
|
"""
|
|
if not self._is_active:
|
|
return True
|
|
|
|
# Print milestone updates (every 30 seconds, or at key intervals)
|
|
if remaining_seconds <= 0:
|
|
print(f"⏰ {self.provider_name} remote login expired")
|
|
return True
|
|
|
|
# Print at: 240s, 180s, 120s, 60s, 30s, 10s
|
|
milestones = [240, 180, 120, 60, 30, 10]
|
|
|
|
if remaining_seconds in milestones or remaining_seconds <= 10:
|
|
minutes = remaining_seconds // 60
|
|
seconds = remaining_seconds % 60
|
|
|
|
if minutes > 0:
|
|
time_str = f"{minutes}m {seconds}s"
|
|
else:
|
|
time_str = f"{seconds}s"
|
|
|
|
print(f"⏳ {self.provider_name}: Waiting for authentication... {time_str} remaining")
|
|
|
|
return True
|
|
|
|
def close(self, success: bool = False, message: Optional[str] = None):
|
|
"""
|
|
Close console notification
|
|
|
|
Args:
|
|
success: Whether authentication succeeded
|
|
message: Optional message
|
|
"""
|
|
if not self._is_active:
|
|
return
|
|
|
|
self._is_active = False
|
|
|
|
print()
|
|
print("=" * 70)
|
|
|
|
if success:
|
|
print(f"✓ {self.success_message}")
|
|
elif message:
|
|
failure_msg = self.failure_template.format(message)
|
|
print(f"✗ {failure_msg}")
|
|
else:
|
|
print(f"✗ {self.failure_template.format('unknown error')}")
|
|
|
|
print("=" * 70)
|
|
print()
|
|
|
|
def is_cancelled(self) -> bool:
|
|
"""
|
|
Check if cancelled (always False for console)
|
|
|
|
Returns:
|
|
bool: Always False (console can't be cancelled interactively)
|
|
"""
|
|
return False |