Files
wizarr/app/services/ombi_client.py

209 lines
6.5 KiB
Python

import logging
import requests
from app.models import Connection, Settings, User
from app.services.companions import get_companion_client
__all__ = [
"delete_user",
"delete_user_from_connections",
"get_connection_for_server",
"invite_user_to_connections",
"run_user_importer",
]
def _cfg():
"""Fetch Ombi/Overseerr URL and API key from the DB (legacy fallback)."""
url_row = Settings.query.filter_by(key="overseerr_url").first()
key_row = Settings.query.filter_by(key="ombi_api_key").first()
return (
url_row.value if url_row else None,
key_row.value if key_row else None,
)
def get_connection_for_server(
server_id: int, connection_type: str = "ombi"
) -> Connection | None:
"""Get the connection configuration for a specific media server."""
return Connection.query.filter_by(
media_server_id=server_id, connection_type=connection_type
).first()
def invite_user_to_connections(
username: str, email: str, server_id: int, password: str = ""
) -> list[dict]:
"""
Invite a user to all connected external services for the given media server.
Args:
username: Username of the user to invite
email: Email address of the user
server_id: Media server ID to check for connections
password: Password for the user (optional, defaults to empty string)
Returns:
List of results with connection details and success status
"""
results = []
# Get all connections for this server
connections = Connection.query.filter_by(media_server_id=server_id).all()
for connection in connections:
try:
# Get the appropriate companion client for this connection type
client_class = get_companion_client(connection.connection_type)
client = client_class()
# Use the client to invite the user
result = client.invite_user(username, email, connection, password)
results.append(
{
"connection_name": connection.name,
"connection_type": connection.connection_type,
"status": result["status"],
"message": result["message"],
}
)
except ValueError as exc:
# Unknown connection type
logging.error(
"Unknown connection type %s: %s", connection.connection_type, exc
)
results.append(
{
"connection_name": connection.name,
"connection_type": connection.connection_type,
"status": "error",
"message": f"Unknown connection type: {connection.connection_type}",
}
)
return results
def run_user_importer(name: str):
"""Legacy function - now uses fallback global settings."""
url, key = _cfg()
if not url or not key:
return None
try:
resp = requests.post(
f"{url}/api/v1/Job/{name}UserImporter/",
headers={"ApiKey": key},
timeout=5,
)
logging.info("Ombi importer %s%s", name, resp.status_code)
return resp
except Exception as exc:
logging.error("Ombi importer error: %s", exc)
def run_all_importers():
"""Legacy function - runs importer using global settings."""
run_user_importer("jellyfin") # extend when plex/emby needed
def delete_user_from_connections(internal_token: str) -> list[dict]:
"""
Delete a user from all connected external services.
Args:
internal_token: User's internal token
Returns:
List of results with connection details and success status
"""
results = []
# Get the user
wiz_user = User.query.filter_by(token=internal_token).first()
if not wiz_user:
return [{"status": "error", "message": "User not found"}]
# Get server ID if available
server_id = getattr(wiz_user, "server_id", None)
if not server_id:
# Try to find connections across all servers for this user
connections = Connection.query.all()
else:
# Get connections for user's server
connections = Connection.query.filter_by(media_server_id=server_id).all()
for connection in connections:
try:
# Get the appropriate companion client for this connection type
client_class = get_companion_client(connection.connection_type)
client = client_class()
# Use the client to delete the user
result = client.delete_user(wiz_user.username, connection)
results.append(
{
"connection_name": connection.name,
"connection_type": connection.connection_type,
"status": result["status"],
"message": result["message"],
}
)
except ValueError as exc:
# Unknown connection type
logging.error(
"Unknown connection type %s: %s", connection.connection_type, exc
)
results.append(
{
"connection_name": connection.name,
"connection_type": connection.connection_type,
"status": "error",
"message": f"Unknown connection type: {connection.connection_type}",
}
)
return results
def delete_user(internal_token: str):
"""Legacy function - now uses fallback global settings."""
url, key = _cfg()
if not url or not key:
return None
# 1. Get Ombi user list
try:
users = requests.get(
f"{url}/api/v1/Identity/Users",
headers={"ApiKey": key},
timeout=5,
).json()
except Exception as exc:
logging.error("Ombi list users failed: %s", exc)
return None
# 2. Map our internal token → User → Ombi ID
wiz_user = User.query.filter_by(token=internal_token).first()
if not wiz_user:
return None
ombi_id = next(
(u["id"] for u in users if u.get("userName") == wiz_user.username), None
)
if ombi_id:
try:
resp = requests.delete(
f"{url}/api/v1/Identity/{ombi_id}",
headers={"ApiKey": key},
timeout=5,
)
logging.info("Ombi delete user %s%s", ombi_id, resp.status_code)
return resp
except Exception as exc:
logging.error("Ombi delete user error: %s", exc)
return None