Skip to content

Commit

Permalink
refactor: 🔧 Removed ability to fetch profile picture from media servers
Browse files Browse the repository at this point in the history
  • Loading branch information
JamsRepos committed May 2, 2024
1 parent f1f94e1 commit e3ab547
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 202 deletions.
15 changes: 1 addition & 14 deletions apps/wizarr-backend/wizarr_backend/api/routes/users_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from flask_restx import Namespace, Resource
from json import loads, dumps

from helpers.universal import global_sync_users_to_media_server, global_delete_user_from_media_server, global_get_user_profile_picture
from helpers.universal import global_sync_users_to_media_server, global_delete_user_from_media_server
from app.models.database.users import Users

from app.extensions import cache
Expand Down Expand Up @@ -40,19 +40,6 @@ def delete(self, user_id):
return global_delete_user_from_media_server(user_id), 200


@api.route("/<string:user_id>/profile-picture")
class UsersProfilePictureAPI(Resource):

method_decorators = [jwt_required()]

@cache.cached(timeout=3600)
@api.doc(description="Get a user profile picture")
@api.response(500, "Internal server error")
def get(self, user_id):
picture = global_get_user_profile_picture(user_id)
return send_file(picture, mimetype="image/jpeg")


@api.route("/scan")
class UsersScanAPI(Resource):

Expand Down
57 changes: 1 addition & 56 deletions apps/wizarr-backend/wizarr_backend/helpers/emby.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,59 +406,4 @@ def sync_emby_users(server_api_key: Optional[str] = None, server_url: Optional[s
for database_user in database_users:
if str(database_user.token) not in [str(emby_user["Id"]) for emby_user in emby_users]:
database_user.delete_instance()
info(f"User {database_user.username} successfully deleted from database.")



# ANCHOR - Emby Get Profile Picture
def get_emby_profile_picture(user_id: str, max_height: Optional[int] = 150, max_width: Optional[int] = 150, quality: Optional[int] = 30, server_api_key: Optional[str] = None, server_url: Optional[str] = None):
"""Get profile picture from Emby.
:param user_id: ID of the user to get profile picture for
:type user_id: str
:param username: Username for backup profile picture using ui-avatars.com
:type username: str
:param max_height: Maximum height of profile picture
:type max_height: Optional[int] - Default: 150
:param max_width: Maximum width of profile picture
:type max_width: Optional[int] - Default: 150
:param quality: Quality of profile picture
:type quality: Optional[int] - Default: 30
:param server_api_key: Emby API key
:type server_api_key: Optional[str] - If not provided, will get from database.
:param server_url: Emby URL
:type server_url: Optional[str] - If not provided, will get from database.
:return: Emby API response
"""

# Response object
response = None

try:
# Get profile picture from Emby
response = get_emby(api_path=f"/Users/{user_id}/Images/Primary?maxHeight={max_height}&maxWidth={max_width}&quality={quality}", as_json=False, server_api_key=server_api_key, server_url=server_url)
except RequestException:
# Backup profile picture using ui-avatars.com if Emby fails
user = get_user_by_token(user_id, verify=False)
username = f"{user.username}&length=1" if user else "ERROR&length=60&font-size=0.28"
response = get(url=f"https://ui-avatars.com/api/?uppercase=true&background=52b54b&color=fff&name={username}", timeout=30)

# Raise exception if either Emby or ui-avatars.com fails
if response.status_code != 200:
raise RequestException("Failed to get profile picture.")

# Extract image from response
image = response.content

# Convert image bytes to read image
image = BytesIO(image)

# Return profile picture
return image
info(f"User {database_user.username} successfully deleted from database.")
56 changes: 1 addition & 55 deletions apps/wizarr-backend/wizarr_backend/helpers/jellyfin.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,58 +400,4 @@ def sync_jellyfin_users(server_api_key: Optional[str] = None, server_url: Option
for database_user in database_users:
if str(database_user.token) not in [str(jellyfin_user["Id"]) for jellyfin_user in jellyfin_users]:
database_user.delete_instance()
info(f"User {database_user.username} successfully deleted from database.")


# ANCHOR - Jellyfin Get Profile Picture
def get_jellyfin_profile_picture(user_id: str, max_height: Optional[int] = 150, max_width: Optional[int] = 150, quality: Optional[int] = 30, server_api_key: Optional[str] = None, server_url: Optional[str] = None):
"""Get profile picture from Jellyfin.
:param user_id: ID of the user to get profile picture for
:type user_id: str
:param username: Username for backup profile picture using ui-avatars.com
:type username: str
:param max_height: Maximum height of profile picture
:type max_height: Optional[int] - Default: 150
:param max_width: Maximum width of profile picture
:type max_width: Optional[int] - Default: 150
:param quality: Quality of profile picture
:type quality: Optional[int] - Default: 30
:param server_api_key: Jellyfin API key
:type server_api_key: Optional[str] - If not provided, will get from database.
:param server_url: Jellyfin URL
:type server_url: Optional[str] - If not provided, will get from database.
:return: Jellyfin API response
"""

# Response object
response = None

try:
# Get profile picture from Jellyfin
response = get_jellyfin(api_path=f"/Users/{user_id}/Images/Primary?maxHeight={max_height}&maxWidth={max_width}&quality={quality}", as_json=False, server_api_key=server_api_key, server_url=server_url)
except RequestException:
# Backup profile picture using ui-avatars.com if Jellyfin fails
user = get_user_by_token(user_id, verify=False)
username = f"{user.username}&length=1" if user else "ERROR&length=60&font-size=0.28"
response = get(url=f"https://ui-avatars.com/api/?uppercase=true&background=AA5CC3&color=fff&name={username}", timeout=30)

# Raise exception if either Jellyfin or ui-avatars.com fails
if response.status_code != 200:
raise RequestException("Failed to get profile picture.")

# Extract image from response
image = response.content

# Convert image bytes to read image
image = BytesIO(image)

# Return profile picture
return image
info(f"User {database_user.username} successfully deleted from database.")
48 changes: 1 addition & 47 deletions apps/wizarr-backend/wizarr_backend/helpers/plex.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,50 +300,4 @@ def sync_plex_users(server_api_key: Optional[str] = None, server_url: Optional[s
for database_user in database_users:
if str(database_user.token) not in [str(plex_user.id) for plex_user in plex_users]:
database_user.delete_instance()
info(f"User {database_user.username} successfully removed from database")


# ANCHOR - Plex Get Profile Picture
def get_plex_profile_picture(user_id: str, server_api_key: Optional[str] = None, server_url: Optional[str] = None) -> str:
"""Get a Plex user's profile picture
:param user_id: The id of the user
:type user_id: str - [usernames, email, id]
:param server_api_key: The API key of the Plex server
:type server_api_key: Optional[str] - If not provided, will get from database.
:param server_url: The URL of the Plex server
:type server_url: Optional[str] - If not provided, will get from database.
:return: str - The url of the profile picture
"""

# Response object
response = None

# Get the user
user = get_plex_user(user_id=user_id, server_api_key=server_api_key, server_url=server_url)

try:
# Get the profile picture from Plex
url = user.thumb
print(url)
response = get(url=url, timeout=30)
except RequestException:
# Backup profile picture using ui-avatars.com if Plex fails to obtain profile picture
username = f"{user.username}&length=1" if user else "ERROR&length=5&font-size=0.28"
response = get(url=f"https://ui-avatars.com/api/?uppercase=true&background=eaad00&color=fff&name={username}", timeout=30)

# Raise exception if either Jellyfin or ui-avatars.com fails
if response.status_code != 200:
raise RequestException("Failed to get profile picture.")

# Extract image from response
image = response.content

# Convert image bytes to read image
image = BytesIO(image)

# Return profile picture
return image
info(f"User {database_user.username} successfully removed from database")
33 changes: 3 additions & 30 deletions apps/wizarr-backend/wizarr_backend/helpers/universal.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from app.extensions import socketio
from datetime import datetime

from .plex import get_plex_users, get_plex_user, sync_plex_users, delete_plex_user, get_plex_profile_picture, invite_plex_user, accept_plex_invitation
from .jellyfin import get_jellyfin_users, get_jellyfin_user, sync_jellyfin_users, delete_jellyfin_user, get_jellyfin_profile_picture, invite_jellyfin_user
from .emby import get_emby_users, get_emby_user, sync_emby_users, delete_emby_user, get_emby_profile_picture, invite_emby_user
from .plex import get_plex_users, get_plex_user, sync_plex_users, delete_plex_user, invite_plex_user, accept_plex_invitation
from .jellyfin import get_jellyfin_users, get_jellyfin_user, sync_jellyfin_users, delete_jellyfin_user, invite_jellyfin_user
from .emby import get_emby_users, get_emby_user, sync_emby_users, delete_emby_user, invite_emby_user

from .jellyseerr import jellyseerr_import_user, jellyseerr_delete_user
from .overseerr import overseerr_import_user, overseerr_delete_user
Expand Down Expand Up @@ -231,33 +231,6 @@ def global_sync_users_to_media_server() -> dict[str]:
return { "message": "Users synced" }


# ANCHOR - Global Get User Profile Picture
def global_get_user_profile_picture(user_id: str) -> str:
"""Get a user"s profile picture from the media server
:param user_id: The id of the user
:type user_id: str
:return: The url of the user"s profile picture
"""

# Get the server type
server_type = get_server_type()

# Get the user"s profile picture from the media server
if server_type == "plex":
return get_plex_profile_picture(user_id)

if server_type == "jellyfin":
return get_jellyfin_profile_picture(user_id)

if server_type == "emby":
return get_emby_profile_picture(user_id)

# Raise an error if the user"s profile picture is None
raise ValueError("Unable to get user's profile picture")


# ANCHOR - Global Invite User To Media Server
def global_invite_user_to_media_server(**kwargs) -> dict[str]:
"""Invite a user to the media server
Expand Down

0 comments on commit e3ab547

Please sign in to comment.