From 9cc1d2003446308b87e7e8c2427b20400bf69cc5 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 18 Dec 2024 16:02:24 +0100 Subject: [PATCH] Minor improvements to events connection handling. --- src/templates/_base.tmpl | 41 +++++++++++++++++++++------------------- src/ytplom/http.py | 8 ++++++-- src/ytplom/primitives.py | 4 +++- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/templates/_base.tmpl b/src/templates/_base.tmpl index 0350ced..53ed389 100644 --- a/src/templates/_base.tmpl +++ b/src/templates/_base.tmpl @@ -7,13 +7,13 @@ const RETRY_INTERVAL_S = 5; const PING_INTERVAL_S = 1; -const PATH_EVENTS = '/{{page_names.events}}'; -const PATH_EVENTS_PING = '/{{page_names.events_ping}}'; -const PATH_PLAYER = '/{{page_names.player}}'; -const PATH_PLAYLIST = '/{{page_names.playlist}}'; -const PATH_PREFIX_FILE = '/{{page_names.file}}/'; +const PATH_EVENTS = "/{{page_names.events}}"; +const PATH_EVENTS_PING = "/{{page_names.events_ping}}"; +const PATH_PLAYER = "/{{page_names.player}}"; +const PATH_PLAYLIST = "/{{page_names.playlist}}"; +const PATH_PREFIX_FILE = "/{{page_names.file}}/"; var event_handlers = []; -var events_params = ''; +var events_params = ""; var client_id = null; setInterval(function() {if (client_id) { send_to({client_id: [client_id]}, PATH_EVENTS_PING); }}, @@ -29,23 +29,26 @@ function connect_events() { for (let i = 0; i < event_handlers.length; i++) { event_handlers[i](data); }} events_stream.onerror = function(error) { + client_id = null; const while_connecting = events_stream.readyState == events_stream.CONNECTING; console.log(`Error on ${PATH_EVENTS} connection:`, error); events_stream.close(); if (while_connecting) { - console.log('Error seemed connection-related, trying reconnect.'); + console.log("Error seemed connection-related, trying reconnect."); setTimeout(connect_events, RETRY_INTERVAL_S * 1000); } else { - console.log('Error does not seem connection-related, therefore aborting.'); }}} + console.log("Error does not seem connection-related, therefore aborting."); }}} -async function send_to(data, target) { - console.log(`Trying to send to ${target}:`, data); +async function send_to(data, target, verbose=false) { + if (verbose) { console.log(`Trying to send to ${target}:`, data); } try { const response = await fetch(target, { - method: 'POST', - headers: {'Content-Type': 'application/json'}, + method: "POST", + headers: {"Content-Type": "application/json"}, body: JSON.stringify(data) }); - console.log('Got response:', response); } + if (200 != response.status) { + console.log(`Got unexpected response on sending to ${target}:`, response); } + else if (verbose) { console.log("Got response:", response); }} catch(error) { console.log(`Error on sending to ${target}:`, error); }} @@ -53,13 +56,13 @@ function player_command(command) { send_to({command: [command]}, PATH_PLAYER); } event_handlers.push(function(data) { // update player state - for (const [id, text] of [['playing_tags', data.title_tags ? `(tags: ${data.title_tags})` : ''], - ['a_playing', data.title], - ['player_state', data.running ? (data.paused ? 'paused' : 'playing') : 'stopped'], - ['btn_pause', data.paused ? 'resume' : 'pause'], - ['btn_stop', data.running ? 'stop' : 'play']]) { + for (const [id, text] of [["playing_tags", data.title_tags ? `(tags: ${data.title_tags})` : ""], + ["a_playing", data.title], + ["player_state", data.running ? (data.paused ? "paused" : "playing") : "stopped"], + ["btn_pause", data.paused ? "resume" : "pause"], + ["btn_stop", data.running ? "stop" : "play"]]) { document.getElementById(id).textContent = text; } - document.getElementById('a_playing').href = data.title_digest ? `${PATH_PREFIX_FILE}${data.title_digest}` : PATH_PLAYLIST ; }) + document.getElementById("a_playing").href = data.title_digest ? `${PATH_PREFIX_FILE}${data.title_digest}` : PATH_PLAYLIST ; }) {% block script %} {% endblock %} diff --git a/src/ytplom/http.py b/src/ytplom/http.py index 1ef79b4..d283c3d 100644 --- a/src/ytplom/http.py +++ b/src/ytplom/http.py @@ -147,8 +147,11 @@ class _TaskHandler(BaseHTTPRequestHandler): self._receive_events_ping(postvars.first_for('client_id')) def _receive_events_ping(self, client_id: str) -> None: - self.server.event_pings[client_id] = time() - self._send_http('OK', code=200) + if client_id not in self.server.event_pings: + self._send_http('unknown client ID', code=400) + else: + self.server.event_pings[client_id] = time() + self._send_http('OK') def _receive_player_command(self, postvars: _ReqMap) -> None: command = postvars.first_for('command') @@ -379,6 +382,7 @@ class _TaskHandler(BaseHTTPRequestHandler): ('Cache-Control', 'no-cache'), ('Connection', 'keep-alive')]) client_id = str(uuid4()) + self.server.event_pings[client_id] = time() playing: Optional[VideoFile] = None last_sent = '' init_msg = {'your_id': client_id} diff --git a/src/ytplom/primitives.py b/src/ytplom/primitives.py index 50de4ea..bb1ac3e 100644 --- a/src/ytplom/primitives.py +++ b/src/ytplom/primitives.py @@ -1,4 +1,6 @@ -"""Basic depended-ons not depending on anything else.""" +"""Basic depended-ons not depending on any other, i.e. this should always be + importable without creating import loops. +""" from pathlib import Path -- 2.30.2