feat: Enhance sound favorite management; add WebSocket event broadcasting for favoriting and unfavoriting sounds
This commit is contained in:
@@ -10,6 +10,7 @@ from app.repositories.favorite import FavoriteRepository
|
|||||||
from app.repositories.playlist import PlaylistRepository
|
from app.repositories.playlist import PlaylistRepository
|
||||||
from app.repositories.sound import SoundRepository
|
from app.repositories.sound import SoundRepository
|
||||||
from app.repositories.user import UserRepository
|
from app.repositories.user import UserRepository
|
||||||
|
from app.services.socket import socket_manager
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -55,6 +56,10 @@ class FavoriteService:
|
|||||||
if not sound:
|
if not sound:
|
||||||
raise ValueError(f"Sound with ID {sound_id} not found")
|
raise ValueError(f"Sound with ID {sound_id} not found")
|
||||||
|
|
||||||
|
# Get data for the event immediately after loading
|
||||||
|
sound_name = sound.name
|
||||||
|
user_name = user.name
|
||||||
|
|
||||||
# Check if already favorited
|
# Check if already favorited
|
||||||
existing = await favorite_repo.get_by_user_and_sound(user_id, sound_id)
|
existing = await favorite_repo.get_by_user_and_sound(user_id, sound_id)
|
||||||
if existing:
|
if existing:
|
||||||
@@ -70,7 +75,28 @@ class FavoriteService:
|
|||||||
}
|
}
|
||||||
favorite = await favorite_repo.create(favorite_data)
|
favorite = await favorite_repo.create(favorite_data)
|
||||||
logger.info("User %s favorited sound %s", user_id, sound_id)
|
logger.info("User %s favorited sound %s", user_id, sound_id)
|
||||||
return favorite
|
|
||||||
|
# Get updated favorite count within the same session
|
||||||
|
favorite_count = await favorite_repo.count_sound_favorites(sound_id)
|
||||||
|
|
||||||
|
# Emit sound_favorited event via WebSocket (outside the session)
|
||||||
|
try:
|
||||||
|
event_data = {
|
||||||
|
"sound_id": sound_id,
|
||||||
|
"sound_name": sound_name,
|
||||||
|
"user_id": user_id,
|
||||||
|
"user_name": user_name,
|
||||||
|
"favorite_count": favorite_count,
|
||||||
|
}
|
||||||
|
await socket_manager.broadcast_to_all("sound_favorited", event_data)
|
||||||
|
logger.info("Broadcasted sound_favorited event for sound %s", sound_id)
|
||||||
|
except Exception:
|
||||||
|
logger.exception(
|
||||||
|
"Failed to broadcast sound_favorited event for sound %s",
|
||||||
|
sound_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return favorite
|
||||||
|
|
||||||
async def add_playlist_favorite(self, user_id: int, playlist_id: int) -> Favorite:
|
async def add_playlist_favorite(self, user_id: int, playlist_id: int) -> Favorite:
|
||||||
"""Add a playlist to user's favorites.
|
"""Add a playlist to user's favorites.
|
||||||
@@ -103,7 +129,8 @@ class FavoriteService:
|
|||||||
|
|
||||||
# Check if already favorited
|
# Check if already favorited
|
||||||
existing = await favorite_repo.get_by_user_and_playlist(
|
existing = await favorite_repo.get_by_user_and_playlist(
|
||||||
user_id, playlist_id,
|
user_id,
|
||||||
|
playlist_id,
|
||||||
)
|
)
|
||||||
if existing:
|
if existing:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@@ -138,9 +165,41 @@ class FavoriteService:
|
|||||||
if not favorite:
|
if not favorite:
|
||||||
raise ValueError(f"Sound {sound_id} is not favorited by user {user_id}")
|
raise ValueError(f"Sound {sound_id} is not favorited by user {user_id}")
|
||||||
|
|
||||||
|
# Get user and sound info before deletion for the event
|
||||||
|
user_repo = UserRepository(session)
|
||||||
|
sound_repo = SoundRepository(session)
|
||||||
|
user = await user_repo.get_by_id(user_id)
|
||||||
|
sound = await sound_repo.get_by_id(sound_id)
|
||||||
|
|
||||||
|
# Get data for the event immediately after loading
|
||||||
|
sound_name = sound.name if sound else "Unknown"
|
||||||
|
user_name = user.name if user else "Unknown"
|
||||||
|
|
||||||
await favorite_repo.delete(favorite)
|
await favorite_repo.delete(favorite)
|
||||||
logger.info("User %s removed sound %s from favorites", user_id, sound_id)
|
logger.info("User %s removed sound %s from favorites", user_id, sound_id)
|
||||||
|
|
||||||
|
# Get updated favorite count after deletion within the same session
|
||||||
|
favorite_count = await favorite_repo.count_sound_favorites(sound_id)
|
||||||
|
|
||||||
|
# Emit sound_favorited event via WebSocket (outside the session)
|
||||||
|
try:
|
||||||
|
event_data = {
|
||||||
|
"sound_id": sound_id,
|
||||||
|
"sound_name": sound_name,
|
||||||
|
"user_id": user_id,
|
||||||
|
"user_name": user_name,
|
||||||
|
"favorite_count": favorite_count,
|
||||||
|
}
|
||||||
|
await socket_manager.broadcast_to_all("sound_favorited", event_data)
|
||||||
|
logger.info(
|
||||||
|
"Broadcasted sound_favorited event for sound %s removal", sound_id
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
logger.exception(
|
||||||
|
"Failed to broadcast sound_favorited event for sound %s removal",
|
||||||
|
sound_id,
|
||||||
|
)
|
||||||
|
|
||||||
async def remove_playlist_favorite(self, user_id: int, playlist_id: int) -> None:
|
async def remove_playlist_favorite(self, user_id: int, playlist_id: int) -> None:
|
||||||
"""Remove a playlist from user's favorites.
|
"""Remove a playlist from user's favorites.
|
||||||
|
|
||||||
@@ -156,7 +215,8 @@ class FavoriteService:
|
|||||||
favorite_repo = FavoriteRepository(session)
|
favorite_repo = FavoriteRepository(session)
|
||||||
|
|
||||||
favorite = await favorite_repo.get_by_user_and_playlist(
|
favorite = await favorite_repo.get_by_user_and_playlist(
|
||||||
user_id, playlist_id,
|
user_id,
|
||||||
|
playlist_id,
|
||||||
)
|
)
|
||||||
if not favorite:
|
if not favorite:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@@ -165,7 +225,9 @@ class FavoriteService:
|
|||||||
|
|
||||||
await favorite_repo.delete(favorite)
|
await favorite_repo.delete(favorite)
|
||||||
logger.info(
|
logger.info(
|
||||||
"User %s removed playlist %s from favorites", user_id, playlist_id,
|
"User %s removed playlist %s from favorites",
|
||||||
|
user_id,
|
||||||
|
playlist_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_user_favorites(
|
async def get_user_favorites(
|
||||||
@@ -230,7 +292,9 @@ class FavoriteService:
|
|||||||
async with self.db_session_factory() as session:
|
async with self.db_session_factory() as session:
|
||||||
favorite_repo = FavoriteRepository(session)
|
favorite_repo = FavoriteRepository(session)
|
||||||
return await favorite_repo.get_user_playlist_favorites(
|
return await favorite_repo.get_user_playlist_favorites(
|
||||||
user_id, limit, offset,
|
user_id,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def is_sound_favorited(self, user_id: int, sound_id: int) -> bool:
|
async def is_sound_favorited(self, user_id: int, sound_id: int) -> bool:
|
||||||
|
|||||||
Reference in New Issue
Block a user