commit c9f1da022013341c980f1c72698622fa432ace53
parent 8ea129818792f985f643b7291f6ab1fd2427eea4
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Fri, 15 Nov 2024 19:17:35 -0800
Specify if song wasn't found or API error occurred
Diffstat:
4 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/songs2slides/core.py b/songs2slides/core.py
@@ -26,6 +26,10 @@ class SongData:
artist: str
lyrics: str
+class SongNotFound(Exception):
+ """Raised when the API cannot find the lyrics to a song"""
+ pass
+
def filter_lyrics(lyrics: str):
"""
Filter raw lyrics to remove text enclosed in brackets or parenthesis
@@ -75,7 +79,7 @@ def get_song_data(title: str, artist:str):
# Get API URL
url = os.getenv('API_URL')
if url is None:
- raise Exception()
+ raise Exception('Bad API_URL')
url = url.replace('{title}', title, 1)
url = url.replace('{artist}', artist, 1)
@@ -84,14 +88,20 @@ def get_song_data(title: str, artist:str):
headers = { 'Authorization': auth } if auth else {}
# Query API
- data = requests.get(url, headers=headers).json()
+ res = requests.get(url, headers=headers)
+ if res.status_code != requests.codes.ok:
+ if res.status_code == 404:
+ raise SongNotFound()
+ else:
+ res.raise_for_status()
+ data = res.json()
# Parse response
if 'lyrics' in data.keys():
return SongData(data['title'], data['artist'],
filter_lyrics(data['lyrics']))
else:
- raise Exception()
+ raise Exception('API returned invalid lyric data')
def parse_song_lyrics(lyrics: str, lines_per_slide: int):
"""
diff --git a/songs2slides/routes.py b/songs2slides/routes.py
@@ -59,19 +59,24 @@ def create_step_2():
songs = parse_form(request.form)
# Get lyrics
+ api_error = True # Whether an API error occured for all requests
for i in range(len(songs)):
try:
songs[i] = core.get_song_data(songs[i].title, songs[i].artist)
+ api_error = False
slides = core.parse_song_lyrics(songs[i].lyrics, 4)
songs[i].lyrics = '\n\n'.join(slides)
- except:
+ except core.SongNotFound:
+ api_error = False
+ except Exception as e:
pass
# Count missing songs
missing = sum([1 for x in songs if x.lyrics == None])
# Return song data
- return render_template('create-step-2.html', songs=songs, missing=missing)
+ return render_template('create-step-2.html', songs=songs, missing=missing,
+ api_error=api_error)
@bp.get('/create/step-3/')
def create_step_3_get():
diff --git a/songs2slides/templates/create-step-2.html b/songs2slides/templates/create-step-2.html
@@ -20,6 +20,7 @@
</p>
<p id="missing-message" {% if missing == 0 %} hidden {% endif %}>
+ {% if api_error %} Our lyric API is currently down. {% endif %}
Lyrics must be entered manually for
<span id="missing-count">{{ missing }}</span> song(s).
</p>
diff --git a/tests/test_routes.py b/tests/test_routes.py
@@ -34,8 +34,8 @@ def test_get_lyrics_basic(client, mocker):
core.parse_song_lyrics.assert_has_calls([
mocker.call('L1', 4), mocker.call('L2', 4)
])
- routes.render_template.assert_called_with('create-step-2.html',
- songs=songs, missing=0)
+ routes.render_template.assert_called_with('create-step-2.html', songs=songs,
+ missing=0, api_error=False)
def test_get_lyrics_one_error(client, mocker):
# Mock get_song_data, parse_song_lyrics, and render_template
@@ -62,7 +62,8 @@ def test_get_lyrics_one_error(client, mocker):
mocker.call('T1', 'A1'), mocker.call('T2', 'A2')
])
core.parse_song_lyrics.assert_has_calls([mocker.call('L2', 4)])
- routes.render_template.assert_called_with('create-step-2.html', songs=songs, missing=1)
+ routes.render_template.assert_called_with('create-step-2.html', songs=songs,
+ missing=1, api_error=False)
def test_get_lyrics_missing_artist(client, mocker):
# Mock get_song_data