mirror of
https://github.com/wizarrrr/wizarr.git
synced 2026-07-31 07:17:10 -04:00
209 lines
6.5 KiB
Python
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
|