python.video_converter_v3/app/main_server.py

132 lines
4.7 KiB
Python
Executable file

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())
await self.send_websocket(self.obj_path.queue_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"))
await self.send_websocket(self.obj_path.queue_path_to_dict())
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['websocket_port'])
logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['websocket_port']}")
await server.wait_closed()
# WebServer --------------------------------------------------------------------------------------------------------
# noinspection PyUnusedLocal
@staticmethod
async def handle_index(request):
return web.FileResponse("./client/index.html")
# noinspection PyUnusedLocal
async def handle_ip(self, request):
url = self.yaml["extern_websocket_url"]
port = self.yaml["websocket_port"]
websocket_https = self.yaml["websocket_https"]
return web.json_response({"extern_websocket_url": url, "websocket_port": port, "websocket_https": websocket_https})
# noinspection PyUnusedLocal
@staticmethod
async def handle_stat(request):
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", self.yaml["webserver_port"])
await site.start()
logging.info(f"HTTP Server läuft auf Port {self.yaml["webserver_port"]}")
# 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}")