Skip to content

Commit 925e449

Browse files
authored
Merge branch 'develop' into feature/weekly-tasks
2 parents f7cbce6 + 190a274 commit 925e449

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1297
-322
lines changed

app/config.py.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ from starlette.templating import Jinja2Templates
77

88

99
class Settings(BaseSettings):
10-
app_name: str = "PyLander"
10+
app_name: str = "PyLendar"
1111
bot_api: str = "BOT_API"
1212
webhook_url: str = "WEBHOOK_URL"
1313

app/database/models.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ class Event(Base):
9898
end = Column(DateTime, nullable=False)
9999
content = Column(String)
100100
location = Column(String, nullable=True)
101+
vc_link = Column(String, nullable=True)
101102
is_google_event = Column(Boolean, default=False)
102-
vc_link = Column(String)
103103
color = Column(String, nullable=True)
104104
all_day = Column(Boolean, default=False)
105105
invitees = Column(String)
@@ -223,6 +223,36 @@ def __repr__(self):
223223
return f"<Invitation " f"({self.event.owner}" f"to {self.recipient})>"
224224

225225

226+
class UserSettings(Base):
227+
__tablename__ = "user_settings"
228+
229+
id = Column(Integer, primary_key=True, index=True)
230+
user_id = Column(Integer, ForeignKey("users.id"))
231+
music_on = Column(Boolean, default=False, nullable=False)
232+
music_vol = Column(Integer, default=None)
233+
sfx_on = Column(Boolean, default=False, nullable=False)
234+
sfx_vol = Column(Integer, default=None)
235+
primary_cursor = Column(String, default="default", nullable=False)
236+
secondary_cursor = Column(String, default="default", nullable=False)
237+
video_game_releases = Column(Boolean, default=False)
238+
239+
240+
class AudioTracks(Base):
241+
__tablename__ = "audio_tracks"
242+
243+
id = Column(Integer, primary_key=True, index=True)
244+
title = Column(String, nullable=False, unique=True)
245+
is_music = Column(Boolean, nullable=False)
246+
247+
248+
class UserAudioTracks(Base):
249+
__tablename__ = "user_audio_tracks"
250+
251+
id = Column(Integer, primary_key=True, index=True)
252+
user_id = Column(Integer, ForeignKey("users.id"))
253+
track_id = Column(Integer, ForeignKey("audio_tracks.id"))
254+
255+
226256
class OAuthCredentials(Base):
227257
__tablename__ = "oauth_credentials"
228258

app/dependencies.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
MEDIA_PATH = os.path.join(APP_PATH, config.MEDIA_DIRECTORY)
1414
STATIC_PATH = os.path.join(APP_PATH, "static")
1515
TEMPLATES_PATH = os.path.join(APP_PATH, "templates")
16-
16+
SOUNDS_PATH = os.path.join(STATIC_PATH, "tracks")
1717
templates = Jinja2Templates(directory=TEMPLATES_PATH)
1818
templates.env.add_extension('jinja2.ext.i18n')
1919

app/internal/audio.py

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
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

Comments
 (0)