Skip to content

Feature/audio #132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 74 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
fd2f4dc
feat: add Audio Settings with music and sfx options, as well as play …
subscorp Jan 26, 2021
167a892
feat: add Audio Settings with music and sfx options
subscorp Jan 26, 2021
5f34b9d
feat: add Audio Settings with music and sfx options. Also fixed flake…
subscorp Jan 26, 2021
8beb4e7
fix: fixed another flake8 issue.
subscorp Jan 26, 2021
5bba1e0
fix: fixed yet another flake8 issue.
subscorp Jan 26, 2021
37b29bf
fix: fixed yet another flake8 issue.
subscorp Jan 26, 2021
dda4135
fix: fixed yet another flake8 issue.
subscorp Jan 26, 2021
7477b64
fix: trying to fix an import issue.
subscorp Jan 26, 2021
390635e
fix: trying to fix an import issue.
subscorp Jan 26, 2021
dfe6c16
fix: trying to fix an import issue.
subscorp Jan 26, 2021
8f01632
fix: trying to fix an import issue.
subscorp Jan 26, 2021
06ffcdf
fix: trying to fix an import issue.
subscorp Jan 26, 2021
eb68c99
fix: trying to fix an import issue.
subscorp Jan 26, 2021
dbff1c5
fix: fixed issues, now audio is playing correctly
subscorp Jan 30, 2021
004af9a
fix: fixed conflicts with current build
subscorp Jan 30, 2021
4a78a95
fix: fixed flake8 issue
subscorp Jan 30, 2021
dadb59e
fix: fixed import issue
subscorp Jan 30, 2021
e1f59d4
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
subscorp Jan 30, 2021
875a284
fix: fix tests issue
subscorp Jan 30, 2021
fbb6ee8
fix: trying to fix tests issue in github
subscorp Jan 31, 2021
ad49966
fix: trying to fix tests issue in github
subscorp Jan 31, 2021
b326978
fix: fixed issues according to comments
subscorp Feb 2, 2021
ca5ee80
fix: fixed conflicts
subscorp Feb 2, 2021
f77e20c
fix: fixed flake8 issue
subscorp Feb 2, 2021
0a2f4bb
fix: fixed weird license issue
subscorp Feb 2, 2021
ae06831
fix: fixed weird license issue
subscorp Feb 2, 2021
7c36d8d
fix: fixed issues according to comments
subscorp Feb 3, 2021
6d32135
fix: fixed conflicts
subscorp Feb 3, 2021
e843e15
fix: fixed flake8 issue
subscorp Feb 3, 2021
8ff369b
fix: fixed issues according to comments
subscorp Feb 3, 2021
6b429bc
Merge branch 'develop' into feature/audio
yammesicka Feb 5, 2021
8a68ff5
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
subscorp Feb 7, 2021
4c7bc41
Merge branch 'feature/audio' of https://github.com/subscorp/calendar …
subscorp Feb 7, 2021
a672eb6
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
subscorp Feb 7, 2021
b8a9d45
Apply automatic translateable string changes
subscorp Feb 7, 2021
074fec0
fix: fixed most of the issues according to comments
subscorp Feb 8, 2021
66ef95e
Apply automatic translateable string changes
subscorp Feb 8, 2021
f908549
fix: removed printing to the console
subscorp Feb 8, 2021
ce6a4e0
Merge branch 'feature/audio' of https://github.com/subscorp/calendar …
subscorp Feb 8, 2021
7519a1d
Apply automatic translateable string changes
subscorp Feb 8, 2021
586d166
fix: fixed another issue according to comment
subscorp Feb 8, 2021
04c924d
Merge branch 'feature/audio' of https://github.com/subscorp/calendar …
subscorp Feb 8, 2021
56f0e19
Apply automatic translateable string changes
subscorp Feb 8, 2021
f3be888
Delete app/locales directory
yammesicka Feb 8, 2021
041ac53
fix: fixed some more issues
subscorp Feb 11, 2021
aaea153
Merge branch 'feature/audio' of https://github.com/subscorp/calendar …
subscorp Feb 11, 2021
70facd7
fix: solved conflicts
subscorp Feb 11, 2021
ec7826f
fix: fixed issue with locales
subscorp Feb 11, 2021
93d7345
fix: fixed pytest issue
subscorp Feb 11, 2021
e95573a
fix: fixed flake8 issue
subscorp Feb 11, 2021
e7f4063
fix: fixed two issues according to comments
subscorp Feb 11, 2021
e519c09
fix: fixed issues according to comments
subscorp Feb 17, 2021
876c2fd
fix: fixed conflicts
subscorp Feb 17, 2021
3ef3e77
fix: fixed flake8 issues
subscorp Feb 17, 2021
b9d9c33
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
subscorp Feb 17, 2021
bae9b24
fix: fixed pytest issue
subscorp Feb 17, 2021
f422717
fix: bug fix in UserSettings
subscorp Feb 17, 2021
25452d6
fix: fixed conflicts
subscorp Feb 18, 2021
35c80c5
fix: fixed requirements issue
subscorp Feb 18, 2021
d68298b
fix: fixed issues according to comments
subscorp Feb 18, 2021
c6be5db
fix: fixed conflicts
subscorp Feb 18, 2021
a7f776b
fix: a small fix
subscorp Feb 18, 2021
6dde2ad
fix: a tiny improvement
subscorp Feb 18, 2021
0cd965e
update: user login according to the new system
subscorp Feb 19, 2021
a24d746
fix: a small fix
subscorp Feb 19, 2021
4f83e5f
fix: fixed flake8 error
subscorp Feb 19, 2021
a71a189
fix: hopefully final fix
subscorp Feb 19, 2021
def9206
fix: hopefully final fix
subscorp Feb 19, 2021
61b4adc
fix: solved conflicts
subscorp Feb 21, 2021
7d61df3
update: moved some of the code to internals
subscorp Feb 21, 2021
2ab9bd3
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
subscorp Feb 21, 2021
e6da028
fix: fixed issues according to comments
subscorp Feb 21, 2021
0bac502
fix: tiny fix
subscorp Feb 21, 2021
c9f9e1c
fix: fixed issue according to comment
subscorp Feb 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions app/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,36 @@ def __repr__(self):
return f"<Invitation " f"({self.event.owner}" f"to {self.recipient})>"


class UserSettings(Base):
__tablename__ = "user_settings"

id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
music_on = Column(Boolean, default=False, nullable=False)
music_vol = Column(Integer, default=None)
sfx_on = Column(Boolean, default=False, nullable=False)
sfx_vol = Column(Integer, default=None)
primary_cursor = Column(String, default="default", nullable=False)
secondary_cursor = Column(String, default="default", nullable=False)
video_game_releases = Column(Boolean, default=False)


class AudioTracks(Base):
__tablename__ = "audio_tracks"

id = Column(Integer, primary_key=True, index=True)
title = Column(String, nullable=False, unique=True)
is_music = Column(Boolean, nullable=False)


class UserAudioTracks(Base):
__tablename__ = "user_audio_tracks"

id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
track_id = Column(Integer, ForeignKey("audio_tracks.id"))


class OAuthCredentials(Base):
__tablename__ = "oauth_credentials"

Expand Down
2 changes: 1 addition & 1 deletion app/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
MEDIA_PATH = os.path.join(APP_PATH, config.MEDIA_DIRECTORY)
STATIC_PATH = os.path.join(APP_PATH, "static")
TEMPLATES_PATH = os.path.join(APP_PATH, "templates")

SOUNDS_PATH = os.path.join(STATIC_PATH, "tracks")
templates = Jinja2Templates(directory=TEMPLATES_PATH)
templates.env.add_extension('jinja2.ext.i18n')

Expand Down
246 changes: 246 additions & 0 deletions app/internal/audio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
from sqlalchemy.orm.session import Session
from typing import Dict, List, Optional, Tuple, Union
from enum import Enum
from app.database.models import (
AudioTracks,
User,
UserAudioTracks,
UserSettings,
)


DEFAULT_MUSIC = ["GASTRONOMICA.mp3"]
DEFAULT_MUSIC_VOL = 0.5
DEFAULT_SFX = "click_1.wav"
DEFAULT_SFX_VOL = 0.5


class SoundKind(Enum):
SONG = 1
SFX = 0


class Sound:
def __init__(self, sound_kind, name, src):
self.sound_kind = sound_kind
self.name = name
self.src = src


def init_audio_tracks(session: Session, sounds: List[Sound]):
"""This function fills the AudioTracks table

Args:
session (Session): the database
sounds (List[Sound]): list of sounds
"""
for sound in sounds:
add_sound(session, sound)


def add_sound(session: Session, sound: Sound):
"""Adds a new audio track to AudioTracks table.

Args:
session (Session): the databse.
sound (Sound): song or sfx.
"""
res = session.query(AudioTracks).filter_by(title=sound.name).first()
if not res:
track = AudioTracks(title=sound.name, is_music=sound.sound_kind.value)
session.add(track)
session.commit()


def get_tracks(
session: Session,
user_id: int,
) -> Tuple[List[str], Optional[str]]:
"""Retrieves audio selections from the database,
for both music and sound effects.

Args:
session (Session): the database.
user_id (int): current users' id.

Returns:
Tuple[Optional[List[str]], Optional[str]]:
returns the playlist of music tracks, as well as sound effect choice.
"""
playlist = []

chosen_track_ids = session.query(UserAudioTracks.track_id).filter_by(
user_id=user_id,
)

tracks = (
session.query(AudioTracks)
.filter(AudioTracks.id.in_(chosen_track_ids))
.filter_by(is_music=1)
)

sfx = (
session.query(AudioTracks)
.filter(AudioTracks.id.in_(chosen_track_ids))
.filter_by(is_music=0)
.first()
)

for track in tracks:
playlist.append(track.title + ".mp3")
sfx_choice = sfx.title + ".wav" if sfx else None

return playlist, sfx_choice


def get_audio_settings(
session: Session,
user_id: int,
) -> Tuple[Optional[List[str]], Optional[int], Optional[str], Optional[int]]:
"""Retrieves audio settings from the database.

Args:
session (Session): [description]
user_id (int, optional): [description]. Defaults to 1.

Returns:
Tuple[str, Optional[List[str]], Optional[int],
str, Optional[str], Optional[int]]: the audio settings.
"""
music_on, music_vol, sfx_on, sfx_vol = None, None, None, None
playlist, sfx_choice = get_tracks(session, user_id)
audio_settings = (
session.query(UserSettings).filter_by(user_id=user_id).first()
)
if audio_settings:
music_on = audio_settings.music_on
music_vol = audio_settings.music_vol
sfx_on = audio_settings.sfx_on
sfx_vol = audio_settings.sfx_vol

return music_on, playlist, music_vol, sfx_on, sfx_choice, sfx_vol


def handle_vol(
is_audio_on: bool,
vol: Optional[int],
) -> Optional[int]:
"""Helper function that normalizes the volume and returns it,
if audio is on.

Args:
is_audio_on (bool): True if the user chose to enable, False otherwise.
vol (Optional[int]): a number in the range (0, 1),
indicating the volume.
example: 0.4 means 40% of the tracks' volume.

Returns:
Optional[int]: returns the normalized volume, or None if audio
is disabled.
"""
if is_audio_on:
vol /= 100

return vol


# Functions for saving users' choices in the db.


def save_audio_settings(
session: Session,
music_choices: Optional[List[str]],
sfx_choice: Optional[str],
user_choices: Dict[str, Union[str, int]],
user: User,
):
"""Save audio settings in the db.

Args:
session (Session): the database
music_choices (Optional[List[str]]): a list of music tracks
if music is enabled, None otherwise.
sfx_choice (Optional[str]): choice for sound effect.
user_choices (Dict[str, Union[str, int]]):
including music_on, music_vol, sfx_on, sfx_vol
user (User): current user
"""
handle_audio_settings(session, user.user_id, user_choices)
handle_user_audio_tracks(session, user.user_id, music_choices, sfx_choice)


def handle_audio_settings(
session: Session,
user_id: int,
user_choices: Dict[str, Union[str, int]],
):
"""Insert or update a new record into UserSettings table.
The table stores the following information:
music on, music_vol, sfx on, sfx_vol.

Args:
session (Session): the database
user_id (int): current users' id.
user_choices (Dict[str, Union[str, int]]):
including music_on, music_vol, sfx_on, sfx_vol
"""
audio_settings = (
session.query(UserSettings).filter_by(user_id=user_id).first()
)
if not audio_settings:
audio_settings = UserSettings(user_id=user_id, **user_choices)
session.add(audio_settings)

else:
session.query(UserSettings).filter_by(
user_id=audio_settings.user_id,
).update(user_choices)

session.commit()


def handle_user_audio_tracks(
session: Session,
user_id: int,
music_choices: Optional[List[str]],
sfx_choice: Optional[str],
):
"""[summary]

Args:
session (Session): the database.
user_id (int): current users' id.
music_choices (Optional[List[str]]):
a list of music tracks if music is enabled, None otherwise.
sfx_choice (Optional[str]): choice for sound effect.
"""
user_audio_tracks = session.query(UserAudioTracks).filter_by(
user_id=user_id,
)
if user_audio_tracks:
for record in user_audio_tracks:
session.delete(record)
session.commit()

if music_choices:
for track in music_choices:
create_new_user_audio_record(session, track, user_id)
if sfx_choice:
create_new_user_audio_record(session, sfx_choice, user_id)


def create_new_user_audio_record(session: Session, choice, user_id: int):
"""Creates a new UserAudioTracks record.
This is the table that connects users and audio_tracks tables.

Args:
session (Session): the database.
choice ([type]): title of music track or sound effect.
user_id (int): current users' id.
"""
choice = choice.split(".", maxsplit=1)[0]
track = session.query(AudioTracks).filter_by(title=choice).first()
track_id = track.id
record = UserAudioTracks(user_id=user_id, track_id=track_id)
session.add(record)
session.commit()
57 changes: 46 additions & 11 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@

from app import config
from app.database import engine, models
from app.dependencies import get_db, logger, MEDIA_PATH, STATIC_PATH, templates
from app.dependencies import (
get_db,
logger,
MEDIA_PATH,
SOUNDS_PATH,
STATIC_PATH,
templates,
)
from app.internal import daily_quotes, json_data_loader
from app.internal.languages import set_ui_language
from app.internal.security.ouath2 import auth_exception_handler
Expand All @@ -17,11 +24,11 @@


def create_tables(engine, psql_environment):
if 'sqlite' in str(engine.url) and psql_environment:
if "sqlite" in str(engine.url) and psql_environment:
raise models.PSQLEnvironmentError(
"You're trying to use PSQL features on SQLite env.\n"
"Please set app.config.PSQL_ENVIRONMENT to False "
"and run the app again."
"and run the app again.",
)
else:
models.Base.metadata.create_all(bind=engine)
Expand All @@ -32,6 +39,7 @@ def create_tables(engine, psql_environment):
app = FastAPI(title="Pylander", docs_url=None)
app.mount("/static", StaticFiles(directory=STATIC_PATH), name="static")
app.mount("/media", StaticFiles(directory=MEDIA_PATH), name="media")
app.mount("/static/tracks", StaticFiles(directory=SOUNDS_PATH), name="sounds")
app.logger = logger

app.add_exception_handler(status.HTTP_401_UNAUTHORIZED, auth_exception_handler)
Expand All @@ -40,10 +48,33 @@ def create_tables(engine, psql_environment):
set_ui_language()

from app.routers import ( # noqa: E402
about_us, agenda, calendar, categories, celebrity, credits,
currency, dayview, email, event, export, four_o_four, friendview,
google_connect, invitation, joke, login, logout, profile,
register, search, telegram, user, weekview, weight, whatsapp,
about_us,
agenda,
audio,
calendar,
categories,
celebrity,
credits,
currency,
dayview,
email,
event,
export,
four_o_four,
friendview,
google_connect,
invitation,
joke,
login,
logout,
profile,
register,
search,
telegram,
user,
weekview,
weight,
whatsapp,
)

json_data_loader.load_to_database(next(get_db()))
Expand All @@ -68,6 +99,7 @@ async def swagger_ui_redirect():
routers_to_include = [
about_us.router,
agenda.router,
audio.router,
calendar.router,
categories.router,
celebrity.router,
Expand Down Expand Up @@ -105,10 +137,13 @@ async def swagger_ui_redirect():
@logger.catch()
async def home(request: Request, db: Session = Depends(get_db)):
quote = daily_quotes.get_quote_of_day(db)
return templates.TemplateResponse("index.html", {
"request": request,
"quote": quote,
})
return templates.TemplateResponse(
"index.html",
{
"request": request,
"quote": quote,
},
)


custom_openapi(app)
Binary file added app/media/new_user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading