commit eb2f67bd77645358a8ce5c2477fc687b1d30bf02
parent a1c5038d223fb2f05e6681001e00f7251e2662d5
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Tue, 26 Mar 2024 12:12:10 -0700
Implement title slide and blank slide settings
Diffstat:
4 files changed, 108 insertions(+), 15 deletions(-)
diff --git a/songs2slides/routes.py b/songs2slides/routes.py
@@ -67,9 +67,12 @@ def get_lyrics():
def create_slides():
# Parse form data
songs = parse_form(request.form)
+ title_slides = 'title-slides' in request.form
+ blank_slides = 'blank-slides' in request.form
# Assemble slides
- slides = core.assemble_slides(songs, lines_per_slide = None)
+ slides = core.assemble_slides(songs, lines_per_slide = None,
+ title_slides=title_slides, blank_slides=blank_slides)
if (request.form.get('output-type') == 'pptx'):
# Create and send powerpoint
diff --git a/songs2slides/static/create.css b/songs2slides/static/create.css
@@ -76,8 +76,9 @@ textarea {
fieldset {
border: none;
+ margin-top: 1rem;
}
-fieldset label {
+label {
display: block;
margin-top: 0.5rem;
}
diff --git a/songs2slides/templates/create.html b/songs2slides/templates/create.html
@@ -144,17 +144,30 @@
{% endfor %}
</div>
- <fieldset>
- <legend>Output type:</legend>
- <label>
- <input type="radio" name="output-type" value="pptx" checked/>
- PowerPoint Download
- </label>
- <label>
- <input type="radio" name="output-type" value="html"/>
- Online View
- </label>
- </fieldset>
+ <div>
+ <fieldset>
+ <legend>Extra slides:</legend>
+ <label>
+ <input type="checkbox" name="title-slides" checked/>
+ Include a title slide before each song
+ </label>
+ <label>
+ <input type="checkbox" name="blank-slides" checked/>
+ Include a blank slide between each song
+ </label>
+ </fieldset>
+ <fieldset>
+ <legend>Output type:</legend>
+ <label>
+ <input type="radio" name="output-type" value="pptx" checked/>
+ PowerPoint Download
+ </label>
+ <label>
+ <input type="radio" name="output-type" value="html"/>
+ Online View
+ </label>
+ </fieldset>
+ </div>
<div id="actions">
<input onclick="back()" type="button" value="Back"/>
diff --git a/tests/test_routes.py b/tests/test_routes.py
@@ -90,6 +90,8 @@ class TestRoutes(unittest.TestCase):
'artist-2': 'A2',
'lyrics-2': 'L2',
'output-type': 'pptx',
+ 'title-slides': 'on',
+ 'blank-slides': 'on',
})
# Assert mocks called correctly
@@ -97,7 +99,9 @@ class TestRoutes(unittest.TestCase):
core.SongData('T1', 'A1', 'L1'),
core.SongData('T2', 'A2', 'L2'),
],
- lines_per_slide = None
+ lines_per_slide = None,
+ title_slides = True,
+ blank_slides = True,
)
file = mocked_create.call_args.args[1]
mocked_send.assert_called_with(file, as_attachment=True,
@@ -114,6 +118,8 @@ class TestRoutes(unittest.TestCase):
'title-2': 'T2',
'lyrics-2': 'L2',
'output-type': 'pptx',
+ 'title-slides': 'on',
+ 'blank-slides': 'on',
})
# Assert response has 400 status code
@@ -140,6 +146,8 @@ class TestRoutes(unittest.TestCase):
'artist-2': 'A2',
'lyrics-2': 'L2',
'output-type': 'html',
+ 'title-slides': 'on',
+ 'blank-slides': 'on',
})
# Assert mocks called correctly
@@ -147,7 +155,75 @@ class TestRoutes(unittest.TestCase):
core.SongData('T1', 'A1', 'L1'),
core.SongData('T2', 'A2', 'L2'),
],
- lines_per_slide = None
+ lines_per_slide = None,
+ title_slides = True,
+ blank_slides = True,
+ )
+ mocked_create.assert_not_called()
+ mocked_render.assert_called_with('slides.html', slides=slides)
+
+ def test_create_slides_no_title_slides(self):
+ with patch('songs2slides.core.assemble_slides') as mocked_assemble, \
+ patch('songs2slides.core.create_pptx') as mocked_create, \
+ patch('songs2slides.routes.render_template') as mocked_render:
+
+ # Mock assemble_slides
+ slides = ['T1', 'L1\nL2', 'L3', 'T2', 'L4']
+ mocked_assemble.return_value = slides
+
+ # Send request
+ self.client.post('/slides/', data={
+ 'title-1': 'T1',
+ 'artist-1': 'A1',
+ 'lyrics-1': 'L1',
+ 'title-2': 'T2',
+ 'artist-2': 'A2',
+ 'lyrics-2': 'L2',
+ 'output-type': 'html',
+ 'blank-slides': 'on',
+ })
+
+ # Assert mocks called correctly
+ mocked_assemble.assert_called_with([
+ core.SongData('T1', 'A1', 'L1'),
+ core.SongData('T2', 'A2', 'L2'),
+ ],
+ lines_per_slide = None,
+ title_slides = False,
+ blank_slides = True,
+ )
+ mocked_create.assert_not_called()
+ mocked_render.assert_called_with('slides.html', slides=slides)
+
+ def test_create_slides_no_blank_slides(self):
+ with patch('songs2slides.core.assemble_slides') as mocked_assemble, \
+ patch('songs2slides.core.create_pptx') as mocked_create, \
+ patch('songs2slides.routes.render_template') as mocked_render:
+
+ # Mock assemble_slides
+ slides = ['T1', 'L1\nL2', 'L3', 'T2', 'L4']
+ mocked_assemble.return_value = slides
+
+ # Send request
+ self.client.post('/slides/', data={
+ 'title-1': 'T1',
+ 'artist-1': 'A1',
+ 'lyrics-1': 'L1',
+ 'title-2': 'T2',
+ 'artist-2': 'A2',
+ 'lyrics-2': 'L2',
+ 'output-type': 'html',
+ 'title-slides': 'on',
+ })
+
+ # Assert mocks called correctly
+ mocked_assemble.assert_called_with([
+ core.SongData('T1', 'A1', 'L1'),
+ core.SongData('T2', 'A2', 'L2'),
+ ],
+ lines_per_slide = None,
+ title_slides = True,
+ blank_slides = False,
)
mocked_create.assert_not_called()
mocked_render.assert_called_with('slides.html', slides=slides)