Publish curated Unraid-AppOps-Gateway source from 034c9f844d2455850ba37b31379b7edaa786583e
This commit is contained in:
1 parent
c61fbfd87f
commit
1a54836efc
101 files changed
+4973
-1298
No files matched your search
@@ -1,17 +1,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from datetime import UTC, datetime
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from collections.abc import Callable
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from datetime import UTC, datetime
|
||||
from threading import Lock
|
||||
from time import monotonic
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy import func
|
||||
from sqlmodel import Session, select
|
||||
from sqlmodel import Session, col, select
|
||||
|
||||
from ..connectors.deluge import DelugeConnector
|
||||
from ..connectors.plex import PlexConnector
|
||||
@@ -26,7 +26,6 @@ from .audit_logger import log_event
|
||||
from .job_runner import complete_job, create_job, set_job_progress, start_job
|
||||
from .policy_engine import evaluate_policy
|
||||
|
||||
|
||||
CONNECTOR_IDS = ('sonarr', 'prowlarr', 'deluge', 'plex', 'tautulli', 'widefrog')
|
||||
BLOCKED_ACTION_TOKENS = ('delete', 'remove', 'kill_session', 'terminate', 'empty_trash', 'download_database', 'download_config')
|
||||
SNAPSHOT_CACHE_TTL_SECONDS = 15.0
|
||||
@@ -232,6 +231,16 @@ def _ui_status(connector_status: str, warning: bool = False, critical: bool = Fa
|
||||
return 'healthy'
|
||||
|
||||
|
||||
def _flow_edge_status(source_health: dict[str, Any], target_health: dict[str, Any], *, warning: bool = False) -> str:
|
||||
statuses = [str(health.get('status') or ('connected' if health.get('success') else 'unknown')).lower() for health in (source_health, target_health)]
|
||||
known_statuses = {'connected', 'ok', 'healthy', 'auth_failed', 'unreachable', 'error'}
|
||||
if any(status not in known_statuses for status in statuses):
|
||||
return 'unknown'
|
||||
if any(status in {'auth_failed', 'unreachable', 'error'} for status in statuses):
|
||||
return 'broken'
|
||||
return 'warning' if warning else 'healthy'
|
||||
|
||||
|
||||
def _policy_action(session: Session, *, label: str, action_id: str, target: str, source: str = 'manual') -> dict[str, Any]:
|
||||
policy = evaluate_policy(session=session, action=action_id, target=target, source=source)
|
||||
return {
|
||||
@@ -389,10 +398,10 @@ def flow(session: Session) -> dict[str, Any]:
|
||||
{'id': 'tautulli', 'label': 'Tautulli', 'type': 'analytics', 'status': _ui_status(connectors['tautulli']['status']), 'metrics': {'streams': _int(data['tautulliStreams'].get('activeStreams')), 'plays': _int(data['tautulliStats'].get('totalPlays'))}, 'actions': []},
|
||||
]
|
||||
edges = [
|
||||
{'from': 'sonarr', 'to': 'prowlarr', 'status': 'broken' if connectors['prowlarr']['status'] in {'missing_config', 'error'} else 'healthy', 'label': 'indexer sync'},
|
||||
{'from': 'prowlarr', 'to': 'deluge', 'status': 'warning' if counts['failingIndexers'] else 'healthy', 'label': 'release search'},
|
||||
{'from': 'widefrog', 'to': 'plex', 'status': 'warning' if counts['failedWidefrogJobs'] else 'healthy', 'label': 'media processing'},
|
||||
{'from': 'plex', 'to': 'tautulli', 'status': 'broken' if connectors['tautulli']['status'] == 'missing_config' else 'healthy', 'label': 'playback analytics'},
|
||||
{'from': 'sonarr', 'to': 'prowlarr', 'status': _flow_edge_status(data['sonarrHealth'], data['prowlarrHealth']), 'label': 'indexer sync'},
|
||||
{'from': 'prowlarr', 'to': 'deluge', 'status': _flow_edge_status(data['prowlarrHealth'], data['delugeHealth'], warning=counts['failingIndexers'] > 0), 'label': 'release search'},
|
||||
{'from': 'widefrog', 'to': 'plex', 'status': _flow_edge_status(data['widefrogHealth'], data['plexHealth'], warning=counts['failedWidefrogJobs'] > 0), 'label': 'media processing'},
|
||||
{'from': 'plex', 'to': 'tautulli', 'status': _flow_edge_status(data['plexHealth'], data['tautulliHealth']), 'label': 'playback analytics'},
|
||||
]
|
||||
return {'success': True, 'nodes': nodes, 'edges': edges, 'lastUpdated': _now()}
|
||||
|
||||
@@ -450,7 +459,7 @@ def _configure_action(connector: str) -> dict[str, Any]:
|
||||
|
||||
|
||||
def _needs_review_issues(session: Session) -> list[dict[str, Any]]:
|
||||
apps = session.exec(select(App).where(App.needs_review == True)).all() # noqa: E712
|
||||
apps = session.exec(select(App).where(col(App.needs_review).is_(True))).all()
|
||||
result: list[dict[str, Any]] = []
|
||||
for app in apps:
|
||||
if (app.category or '').lower() not in {'media', 'downloads'}:
|
||||
|
||||
Reference in new issue
Block a user