import asyncio import subprocess from typing import List from sqlalchemy.orm import Session from app.database import Server, WolLog from app.models.schemas import WolLogCreate from app.services.logging_service import LoggingService import logging logger = logging.getLogger(__name__) class WolService: @staticmethod async def send_wol_packet(mac_address: str) -> bool: try: result = subprocess.run( ["wakeonlan", mac_address], capture_output=True, text=True, timeout=10 ) return result.returncode == 0 except subprocess.TimeoutExpired: logger.error(f"WOL timeout for MAC: {mac_address}") return False except Exception as e: logger.error(f"WOL error for MAC {mac_address}: {str(e)}") return False @staticmethod async def ping_server(ip_address: str) -> bool: try: result = subprocess.run( ["ping", "-c", "1", "-W", "3", ip_address], capture_output=True, text=True, timeout=5 ) return result.returncode == 0 except subprocess.TimeoutExpired: return False except Exception as e: logger.error(f"Ping error for IP {ip_address}: {str(e)}") return False @staticmethod async def wake_server(db: Session, server_id: int) -> bool: server = db.query(Server).filter(Server.id == server_id).first() if not server: return False success = await WolService.send_wol_packet(server.mac_address) # Log to both WolLog (backward compatibility) and ActionLog (new unified system) log_entry = WolLog( server_id=server_id, action="wake", success=success, message=f"WOL packet sent to {server.mac_address}" if success else "Failed to send WOL packet" ) db.add(log_entry) # Log to unified action log LoggingService.log_wol_action( db=db, server_id=server_id, server_name=server.name, success=success, message=f"WOL packet {'sent successfully' if success else 'failed'} to {server.name} ({server.mac_address})" ) return success @staticmethod async def check_all_servers_status(db: Session) -> None: servers = db.query(Server).all() tasks = [] for server in servers: tasks.append(WolService.ping_server(server.ip_address)) results = await asyncio.gather(*tasks) from datetime import datetime for server, is_online in zip(servers, results): server.is_online = is_online server.last_ping = datetime.utcnow() db.commit()