python.video_converter_v3/app/main_server.py

136 lines
4.7 KiB
Python

import asyncio
import websockets
import json
import logging
from asyncio import CancelledError
from websockets import InvalidUpgrade, ConnectionClosed, ConnectionClosedError
from aiohttp import web
from app.class_settings import Settings
from app.class_file_path import Path
from app.class_file_convert import Convert
from app.class_media_file_stat import Stat
var_convert_active = False
class Server:
def __init__(self):
self.websocket = None
self.clients = set()
obj_settings = Settings()
obj_settings.set_logging()
self.yaml = obj_settings.yaml
self.obj_path = Path(self.yaml)
self.obj_convert = Convert(self, self.yaml, self.obj_path)
async def send_websocket(self, message):
message_json = json.dumps(message)
for client in self.clients.copy():
try:
await client.send(message_json)
except websockets.exceptions.ConnectionClosed:
self.clients.remove(client)
async def handle_client(self, websocket):
self.websocket = websocket
global var_convert_active
if websocket not in self.clients:
self.clients.add(websocket)
await self.send_websocket(self.obj_path.active_path_to_dict())
try:
async for message in websocket:
data = json.loads(message)
if data.get("data_path"):
self.obj_path.receive_paths(data.get("data_path"))
if var_convert_active == False and self.yaml['autostart']:
await self.obj_convert.snake_waiting()
var_convert_active = True
else:
self.obj_convert.snake_update()
elif data.get("data_command"):
pass
elif data.get("data_message"):
logging.info(f"Server hat Empfangen: {data.get('data_message')}")
except (ConnectionClosedError, ConnectionClosed):
logging.warning("Client Verbindung geschlossen")
except InvalidUpgrade:
logging.warning("Ungültiger Websocket Upgrade versuch")
except Exception as e:
logging.error(f"Unerwarteter Fehler {e}")
finally:
self.clients.discard(websocket)
@staticmethod
def set_var_convert_active(value: bool):
global var_convert_active
var_convert_active = value
async def server_websocket(self):
server = await websockets.serve(self.handle_client, self.yaml['server_ip'], self.yaml['server_port'])
logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['server_port']}")
await server.wait_closed()
# WebServer --------------------------------------------------------------------------------------------------------
@staticmethod
async def handle_index(request):
query = request.rel_url.query
if "debug" in query:
logging.info("Debug-Modus aktiv beim Seitenaufruf")
return web.FileResponse("./client/index.html")
async def handle_ip(self, request):
query = request.rel_url.query
if "debug" in query:
logging.info("Debug-Modus aktiv beim Seitenaufruf")
ip = self.yaml.get("server_ip", "localhost")
port = self.yaml.get("server_port", 8000)
return web.json_response({"server_ip": ip, "server_port": port})
@staticmethod
async def handle_stat(request):
query = request.rel_url.query
if "debug" in query:
logging.info("Debug-Modus aktiv beim Seitenaufruf")
obj_stat = Stat()
return web.json_response(obj_stat.read_stat())
async def server_http(self):
app = web.Application()
app.router.add_get("/", self.handle_index)
app.router.add_get("/api/ip", self.handle_ip)
app.router.add_get("/api/stats", self.handle_stat)
app.router.add_static("/client/", path="./client", name="client")
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, "0.0.0.0", 8080)
await site.start()
logging.info("HTTP Server läuft auf Port 8080")
# Start Server -----------------------------------------------------------------------------------------------------
async def start_server(self):
try:
await asyncio.gather(
self.server_websocket(),
self.server_http()
)
except CancelledError:
logging.warning("Server wurde durch Keyboard Interrupt gestoppt.")
except Exception as e:
logging.error(f"Unerwarteter Fehler beim Starten des Servers {e}")