|
| 1 | +from sqlalchemy.orm.session import Session |
| 2 | +from typing import Dict, List, Optional, Tuple, Union |
| 3 | +from enum import Enum |
| 4 | +from app.database.models import ( |
| 5 | + AudioTracks, |
| 6 | + User, |
| 7 | + UserAudioTracks, |
| 8 | + UserSettings, |
| 9 | +) |
| 10 | + |
| 11 | + |
| 12 | +DEFAULT_MUSIC = ["GASTRONOMICA.mp3"] |
| 13 | +DEFAULT_MUSIC_VOL = 0.5 |
| 14 | +DEFAULT_SFX = "click_1.wav" |
| 15 | +DEFAULT_SFX_VOL = 0.5 |
| 16 | + |
| 17 | + |
| 18 | +class SoundKind(Enum): |
| 19 | + SONG = 1 |
| 20 | + SFX = 0 |
| 21 | + |
| 22 | + |
| 23 | +class Sound: |
| 24 | + def __init__(self, sound_kind, name, src): |
| 25 | + self.sound_kind = sound_kind |
| 26 | + self.name = name |
| 27 | + self.src = src |
| 28 | + |
| 29 | + |
| 30 | +def init_audio_tracks(session: Session, sounds: List[Sound]): |
| 31 | + """This function fills the AudioTracks table |
| 32 | +
|
| 33 | + Args: |
| 34 | + session (Session): the database |
| 35 | + sounds (List[Sound]): list of sounds |
| 36 | + """ |
| 37 | + for sound in sounds: |
| 38 | + add_sound(session, sound) |
| 39 | + |
| 40 | + |
| 41 | +def add_sound(session: Session, sound: Sound): |
| 42 | + """Adds a new audio track to AudioTracks table. |
| 43 | +
|
| 44 | + Args: |
| 45 | + session (Session): the databse. |
| 46 | + sound (Sound): song or sfx. |
| 47 | + """ |
| 48 | + res = session.query(AudioTracks).filter_by(title=sound.name).first() |
| 49 | + if not res: |
| 50 | + track = AudioTracks(title=sound.name, is_music=sound.sound_kind.value) |
| 51 | + session.add(track) |
| 52 | + session.commit() |
| 53 | + |
| 54 | + |
| 55 | +def get_tracks( |
| 56 | + session: Session, |
| 57 | + user_id: int, |
| 58 | +) -> Tuple[List[str], Optional[str]]: |
| 59 | + """Retrieves audio selections from the database, |
| 60 | + for both music and sound effects. |
| 61 | +
|
| 62 | + Args: |
| 63 | + session (Session): the database. |
| 64 | + user_id (int): current users' id. |
| 65 | +
|
| 66 | + Returns: |
| 67 | + Tuple[Optional[List[str]], Optional[str]]: |
| 68 | + returns the playlist of music tracks, as well as sound effect choice. |
| 69 | + """ |
| 70 | + playlist = [] |
| 71 | + |
| 72 | + chosen_track_ids = session.query(UserAudioTracks.track_id).filter_by( |
| 73 | + user_id=user_id, |
| 74 | + ) |
| 75 | + |
| 76 | + tracks = ( |
| 77 | + session.query(AudioTracks) |
| 78 | + .filter(AudioTracks.id.in_(chosen_track_ids)) |
| 79 | + .filter_by(is_music=1) |
| 80 | + ) |
| 81 | + |
| 82 | + sfx = ( |
| 83 | + session.query(AudioTracks) |
| 84 | + .filter(AudioTracks.id.in_(chosen_track_ids)) |
| 85 | + .filter_by(is_music=0) |
| 86 | + .first() |
| 87 | + ) |
| 88 | + |
| 89 | + for track in tracks: |
| 90 | + playlist.append(track.title + ".mp3") |
| 91 | + sfx_choice = sfx.title + ".wav" if sfx else None |
| 92 | + |
| 93 | + return playlist, sfx_choice |
| 94 | + |
| 95 | + |
| 96 | +def get_audio_settings( |
| 97 | + session: Session, |
| 98 | + user_id: int, |
| 99 | +) -> Tuple[Optional[List[str]], Optional[int], Optional[str], Optional[int]]: |
| 100 | + """Retrieves audio settings from the database. |
| 101 | +
|
| 102 | + Args: |
| 103 | + session (Session): [description] |
| 104 | + user_id (int, optional): [description]. Defaults to 1. |
| 105 | +
|
| 106 | + Returns: |
| 107 | + Tuple[str, Optional[List[str]], Optional[int], |
| 108 | + str, Optional[str], Optional[int]]: the audio settings. |
| 109 | + """ |
| 110 | + music_on, music_vol, sfx_on, sfx_vol = None, None, None, None |
| 111 | + playlist, sfx_choice = get_tracks(session, user_id) |
| 112 | + audio_settings = ( |
| 113 | + session.query(UserSettings).filter_by(user_id=user_id).first() |
| 114 | + ) |
| 115 | + if audio_settings: |
| 116 | + music_on = audio_settings.music_on |
| 117 | + music_vol = audio_settings.music_vol |
| 118 | + sfx_on = audio_settings.sfx_on |
| 119 | + sfx_vol = audio_settings.sfx_vol |
| 120 | + |
| 121 | + return music_on, playlist, music_vol, sfx_on, sfx_choice, sfx_vol |
| 122 | + |
| 123 | + |
| 124 | +def handle_vol( |
| 125 | + is_audio_on: bool, |
| 126 | + vol: Optional[int], |
| 127 | +) -> Optional[int]: |
| 128 | + """Helper function that normalizes the volume and returns it, |
| 129 | + if audio is on. |
| 130 | +
|
| 131 | + Args: |
| 132 | + is_audio_on (bool): True if the user chose to enable, False otherwise. |
| 133 | + vol (Optional[int]): a number in the range (0, 1), |
| 134 | + indicating the volume. |
| 135 | + example: 0.4 means 40% of the tracks' volume. |
| 136 | +
|
| 137 | + Returns: |
| 138 | + Optional[int]: returns the normalized volume, or None if audio |
| 139 | + is disabled. |
| 140 | + """ |
| 141 | + if is_audio_on: |
| 142 | + vol /= 100 |
| 143 | + |
| 144 | + return vol |
| 145 | + |
| 146 | + |
| 147 | +# Functions for saving users' choices in the db. |
| 148 | + |
| 149 | + |
| 150 | +def save_audio_settings( |
| 151 | + session: Session, |
| 152 | + music_choices: Optional[List[str]], |
| 153 | + sfx_choice: Optional[str], |
| 154 | + user_choices: Dict[str, Union[str, int]], |
| 155 | + user: User, |
| 156 | +): |
| 157 | + """Save audio settings in the db. |
| 158 | +
|
| 159 | + Args: |
| 160 | + session (Session): the database |
| 161 | + music_choices (Optional[List[str]]): a list of music tracks |
| 162 | + if music is enabled, None otherwise. |
| 163 | + sfx_choice (Optional[str]): choice for sound effect. |
| 164 | + user_choices (Dict[str, Union[str, int]]): |
| 165 | + including music_on, music_vol, sfx_on, sfx_vol |
| 166 | + user (User): current user |
| 167 | + """ |
| 168 | + handle_audio_settings(session, user.user_id, user_choices) |
| 169 | + handle_user_audio_tracks(session, user.user_id, music_choices, sfx_choice) |
| 170 | + |
| 171 | + |
| 172 | +def handle_audio_settings( |
| 173 | + session: Session, |
| 174 | + user_id: int, |
| 175 | + user_choices: Dict[str, Union[str, int]], |
| 176 | +): |
| 177 | + """Insert or update a new record into UserSettings table. |
| 178 | + The table stores the following information: |
| 179 | + music on, music_vol, sfx on, sfx_vol. |
| 180 | +
|
| 181 | + Args: |
| 182 | + session (Session): the database |
| 183 | + user_id (int): current users' id. |
| 184 | + user_choices (Dict[str, Union[str, int]]): |
| 185 | + including music_on, music_vol, sfx_on, sfx_vol |
| 186 | + """ |
| 187 | + audio_settings = ( |
| 188 | + session.query(UserSettings).filter_by(user_id=user_id).first() |
| 189 | + ) |
| 190 | + if not audio_settings: |
| 191 | + audio_settings = UserSettings(user_id=user_id, **user_choices) |
| 192 | + session.add(audio_settings) |
| 193 | + |
| 194 | + else: |
| 195 | + session.query(UserSettings).filter_by( |
| 196 | + user_id=audio_settings.user_id, |
| 197 | + ).update(user_choices) |
| 198 | + |
| 199 | + session.commit() |
| 200 | + |
| 201 | + |
| 202 | +def handle_user_audio_tracks( |
| 203 | + session: Session, |
| 204 | + user_id: int, |
| 205 | + music_choices: Optional[List[str]], |
| 206 | + sfx_choice: Optional[str], |
| 207 | +): |
| 208 | + """[summary] |
| 209 | +
|
| 210 | + Args: |
| 211 | + session (Session): the database. |
| 212 | + user_id (int): current users' id. |
| 213 | + music_choices (Optional[List[str]]): |
| 214 | + a list of music tracks if music is enabled, None otherwise. |
| 215 | + sfx_choice (Optional[str]): choice for sound effect. |
| 216 | + """ |
| 217 | + user_audio_tracks = session.query(UserAudioTracks).filter_by( |
| 218 | + user_id=user_id, |
| 219 | + ) |
| 220 | + if user_audio_tracks: |
| 221 | + for record in user_audio_tracks: |
| 222 | + session.delete(record) |
| 223 | + session.commit() |
| 224 | + |
| 225 | + if music_choices: |
| 226 | + for track in music_choices: |
| 227 | + create_new_user_audio_record(session, track, user_id) |
| 228 | + if sfx_choice: |
| 229 | + create_new_user_audio_record(session, sfx_choice, user_id) |
| 230 | + |
| 231 | + |
| 232 | +def create_new_user_audio_record(session: Session, choice, user_id: int): |
| 233 | + """Creates a new UserAudioTracks record. |
| 234 | + This is the table that connects users and audio_tracks tables. |
| 235 | +
|
| 236 | + Args: |
| 237 | + session (Session): the database. |
| 238 | + choice ([type]): title of music track or sound effect. |
| 239 | + user_id (int): current users' id. |
| 240 | + """ |
| 241 | + choice = choice.split(".", maxsplit=1)[0] |
| 242 | + track = session.query(AudioTracks).filter_by(title=choice).first() |
| 243 | + track_id = track.id |
| 244 | + record = UserAudioTracks(user_id=user_id, track_id=track_id) |
| 245 | + session.add(record) |
| 246 | + session.commit() |
0 commit comments