Enabled all Ruff lint rules and resolved findings.
This commit is contained in:
@@ -31,6 +31,9 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
_MARKDOWN_ESCAPE_TABLE = str.maketrans({c: f"\\{c}" for c in r"\*_[]()~`#+-=|{}.!<>&"})
|
||||
_SECONDS_PER_MINUTE = 60
|
||||
_SECONDS_PER_HOUR = 60 * _SECONDS_PER_MINUTE
|
||||
_SECONDS_PER_DAY = 24 * _SECONDS_PER_HOUR
|
||||
|
||||
|
||||
def _sanitize_for_plain_text(text: str) -> str:
|
||||
@@ -67,18 +70,19 @@ def _format_duration(timestamp_str: str, now: datetime) -> str:
|
||||
seconds = int(delta.total_seconds())
|
||||
if seconds < 0:
|
||||
return "unknown duration"
|
||||
if seconds < 60:
|
||||
if seconds < _SECONDS_PER_MINUTE:
|
||||
return f"{seconds} second{'s' if seconds != 1 else ''}"
|
||||
if seconds < 3600:
|
||||
minutes = seconds // 60
|
||||
if seconds < _SECONDS_PER_HOUR:
|
||||
minutes = seconds // _SECONDS_PER_MINUTE
|
||||
return f"{minutes} minute{'s' if minutes != 1 else ''}"
|
||||
if seconds < 86400:
|
||||
hours = seconds // 3600
|
||||
if seconds < _SECONDS_PER_DAY:
|
||||
hours = seconds // _SECONDS_PER_HOUR
|
||||
return f"{hours} hour{'s' if hours != 1 else ''}"
|
||||
days = seconds // 86400
|
||||
return f"{days} day{'s' if days != 1 else ''}"
|
||||
except TypeError, ValueError:
|
||||
return "unknown duration"
|
||||
else:
|
||||
days = seconds // _SECONDS_PER_DAY
|
||||
return f"{days} day{'s' if days != 1 else ''}"
|
||||
|
||||
|
||||
class CommandHandler:
|
||||
|
||||
@@ -66,7 +66,8 @@ class _ResponseTimer:
|
||||
"""Mark the request as successful so the duration is recorded."""
|
||||
self._should_observe = True
|
||||
|
||||
def _finalize(self) -> None:
|
||||
def finalize(self) -> None:
|
||||
"""Record or discard the timing observation when the block exits."""
|
||||
if self._should_observe:
|
||||
self._gauge.labels(domain=self._domain).set(
|
||||
max(time.monotonic() - self._start, 0)
|
||||
@@ -196,7 +197,7 @@ class MetricsService:
|
||||
try:
|
||||
yield timer
|
||||
finally:
|
||||
timer._finalize()
|
||||
timer.finalize()
|
||||
|
||||
def set_build_info(self, version: str) -> None:
|
||||
"""Set the build version info metric.
|
||||
|
||||
@@ -101,7 +101,9 @@ class NotificationService:
|
||||
return
|
||||
|
||||
# Build the notification message
|
||||
body_text = self._format_message(name, title, domain, tags, title_change)
|
||||
body_text = self._format_message(
|
||||
name, title, domain, tags, title_change=title_change
|
||||
)
|
||||
|
||||
# Send notifications to all subscribed rooms in parallel
|
||||
successful, failed = await self._broadcast_to_rooms(domain, body_text)
|
||||
@@ -223,6 +225,7 @@ class NotificationService:
|
||||
title: str,
|
||||
domain: str,
|
||||
tags: Sequence[str],
|
||||
*,
|
||||
title_change: bool,
|
||||
) -> str:
|
||||
"""Format the notification message body.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"""HTTP client for querying Owncast instance APIs."""
|
||||
|
||||
import json
|
||||
from http import HTTPStatus
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import aiohttp
|
||||
@@ -118,7 +119,7 @@ class OwncastClient:
|
||||
url = f"https://{domain}{path}"
|
||||
try:
|
||||
async with self.session.get(url, allow_redirects=False) as response:
|
||||
if response.status != 200:
|
||||
if response.status != HTTPStatus.OK:
|
||||
self.log.warning(
|
||||
"[%s] Response to request on %s was not 200, got %s instead.",
|
||||
domain,
|
||||
@@ -147,7 +148,6 @@ class OwncastClient:
|
||||
path,
|
||||
)
|
||||
return None
|
||||
return result
|
||||
except ValueError as e:
|
||||
self.log.warning(
|
||||
"[%s] Rejecting response to request on %s as could not "
|
||||
@@ -157,6 +157,8 @@ class OwncastClient:
|
||||
e,
|
||||
)
|
||||
return None
|
||||
else:
|
||||
return result
|
||||
except (aiohttp.ClientError, TimeoutError, OSError) as e:
|
||||
self.log.warning("[%s] Error making GET request to %s: %s", domain, path, e)
|
||||
return None
|
||||
@@ -237,8 +239,11 @@ class OwncastClient:
|
||||
connector = self.session.connector
|
||||
if connector is None:
|
||||
return 0
|
||||
idle = sum(len(conns) for conns in connector._conns.values())
|
||||
active = len(connector._acquired)
|
||||
|
||||
# aiohttp does not expose public live pool counts; this metric intentionally
|
||||
# mirrors its internal idle and active connection pools.
|
||||
idle = sum(len(conns) for conns in connector._conns.values()) # noqa: SLF001
|
||||
active = len(connector._acquired) # noqa: SLF001
|
||||
return idle + active
|
||||
|
||||
async def close(self) -> None:
|
||||
|
||||
@@ -33,19 +33,27 @@ _TEMPORARY_OFFLINE_NOTIFICATION_COOLDOWN = 7 * 60
|
||||
|
||||
_CLEANUP_WARNING_THRESHOLD = 83 * 24 * 60
|
||||
_CLEANUP_DELETE_THRESHOLD = 90 * 24 * 60
|
||||
_QUERY_EVERY_MINUTE_FAILURE_LIMIT = 4
|
||||
_QUERY_EVERY_2_MINUTES_FAILURE_LIMIT = 9
|
||||
_QUERY_EVERY_3_MINUTES_FAILURE_LIMIT = 14
|
||||
_QUERY_EVERY_5_MINUTES_FAILURE_LIMIT = 29
|
||||
_QUERY_EVERY_2_MINUTES_INTERVAL = 2
|
||||
_QUERY_EVERY_3_MINUTES_INTERVAL = 3
|
||||
_QUERY_EVERY_5_MINUTES_INTERVAL = 5
|
||||
_QUERY_EVERY_15_MINUTES_INTERVAL = 15
|
||||
|
||||
|
||||
def _should_query_stream(failure_counter: int) -> bool:
|
||||
"""Determine if a stream should be queried based on failure count."""
|
||||
if failure_counter <= 4:
|
||||
if failure_counter <= _QUERY_EVERY_MINUTE_FAILURE_LIMIT:
|
||||
return True
|
||||
if failure_counter <= 9:
|
||||
return failure_counter % 2 == 0
|
||||
if failure_counter <= 14:
|
||||
return failure_counter % 3 == 0
|
||||
if failure_counter <= 29:
|
||||
return failure_counter % 5 == 0
|
||||
return failure_counter % 15 == 0
|
||||
if failure_counter <= _QUERY_EVERY_2_MINUTES_FAILURE_LIMIT:
|
||||
return failure_counter % _QUERY_EVERY_2_MINUTES_INTERVAL == 0
|
||||
if failure_counter <= _QUERY_EVERY_3_MINUTES_FAILURE_LIMIT:
|
||||
return failure_counter % _QUERY_EVERY_3_MINUTES_INTERVAL == 0
|
||||
if failure_counter <= _QUERY_EVERY_5_MINUTES_FAILURE_LIMIT:
|
||||
return failure_counter % _QUERY_EVERY_5_MINUTES_INTERVAL == 0
|
||||
return failure_counter % _QUERY_EVERY_15_MINUTES_INTERVAL == 0
|
||||
|
||||
|
||||
class StreamMonitor:
|
||||
|
||||
Reference in New Issue
Block a user