commit 5b721aa15e1d9455822128df7335696b66d5928e
parent 1020e70e356e4dfe9ca7ce77a30f5cd3cf60471e
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date: Sat, 25 Apr 2020 08:38:35 -0700
Merge pull request #2 from AsherMorgan/feature-review
Implement review lyrics feature in the web interface.
Diffstat:
4 files changed, 148 insertions(+), 37 deletions(-)
diff --git a/Songs2Slides/routes.py b/Songs2Slides/routes.py
@@ -1,5 +1,5 @@
# Import dependencies
-from flask import render_template, request, send_file, url_for
+from flask import render_template, request, send_file, url_for, jsonify
import io
import json
import os
@@ -15,19 +15,21 @@ def index():
-# Powerpoint download
+# Get Powerpoint
@app.route("/pptx", methods=["POST"])
def pptx():
# Parse POST parameters
- data = json.loads(request.form["data"])
-
- # Get lyrics
- lyrics = []
- for song in data:
- try:
- lyrics += models.ParseLyrics(song[0], song[1])
- except:
- pass
+ if "songs" in request.json:
+ # Get lyrics
+ lyrics = []
+ for song in request.json["songs"]:
+ try:
+ lyrics += models.ParseLyrics(song[0], song[1])
+ except:
+ pass
+ elif "lyrics" in request.json:
+ # Get lyrics
+ lyrics = request.json["lyrics"]
try:
# Create powerpoint
@@ -44,3 +46,19 @@ def pptx():
# Return powerpoint
return send_file(pptx, as_attachment=True, attachment_filename='download.pptx')
+
+
+
+# Get lyrics
+@app.route("/lyrics", methods=["POST"])
+def lyrics():
+ # Get lyrics
+ lyrics = []
+ for song in request.json["songs"]:
+ try:
+ lyrics += models.ParseLyrics(song[0], song[1])
+ except:
+ pass
+
+ # Return lyrics
+ return jsonify({"lyrics": lyrics})
+\ No newline at end of file
diff --git a/Songs2Slides/static/index.css b/Songs2Slides/static/index.css
@@ -1,9 +1,13 @@
+/******** Body styles ********/
body {
text-align: center;
font-family: Arial, Helvetica, sans-serif;
touch-action: manipulation;
}
+
+
+/******** Element styles ********/
button {
height: 25px;
}
@@ -13,6 +17,24 @@ button {
font-weight: bold;
}
+
+
+/******** Songs styles ********/
.songRemove {
cursor: pointer;
+}
+
+
+
+/******** Lyrics styles ********/
+#lyricsContainer {
+ width: 100%;
+ max-width: 500px;
+ margin: auto;
+ text-align: left;
+}
+
+#lyrics {
+ width: 100%;
+ resize: none;
}
\ No newline at end of file
diff --git a/Songs2Slides/static/index.js b/Songs2Slides/static/index.js
@@ -4,7 +4,7 @@ setId = 0; // Next valid song id number
// Adds a song
-function Add() {
+function AddSong() {
// Create row
var clone = document.getElementById("songTemplate").content.cloneNode(true);
@@ -23,8 +23,8 @@ function Add() {
-// Prepares form data for a POST request
-function PrepareForm() {
+// Gets the list of songs
+function getSongs() {
// Get song info
var titles = [];
for (title of document.getElementsByClassName("title")) {
@@ -35,12 +35,77 @@ function PrepareForm() {
artists.push(artist.value);
}
- // Prepare data
- data = []
+ // Prepare songs
+ songs = []
for (var i = 0; i < titles.length; i++) {
- data.push([titles[i], artists[i]])
+ songs.push([titles[i], artists[i]])
}
- // Set data
- document.getElementsByName("data")[0].value = JSON.stringify(data)
+ // Set songs
+ return songs
+}
+
+
+
+// Gets the powerpoint by submitting songs
+async function SubmitSongs() {
+ // Get songs
+ songs = getSongs();
+
+ // Send POST request
+ const rawResponse = await fetch("/pptx", {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ }, body: JSON.stringify({"songs":songs})
+ });
+
+ // Download powerpoint
+ download(await rawResponse.blob());
+}
+
+
+
+// Get the parsed lyrics for the user to review
+async function ReviewLyrics() {
+ // Get songs
+ songs = getSongs();
+
+ // Send POST request
+ const rawResponse = await fetch("/lyrics", {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ }, body: JSON.stringify({"songs":songs})
+ });
+ const json = await rawResponse.json();
+
+ // Set lyrics
+ document.getElementById("lyrics").value = json["lyrics"].join("\n\n")
+
+ // Show and hide elements
+ document.getElementById("songs").hidden = true;
+ document.getElementById("lyricsContainer").hidden = false;
+}
+
+
+
+// Gets the powerpoint by submitting lyrics
+async function SubmitLyrics() {
+ // Get lyrics
+ lyrics = document.getElementById("lyrics").value.split('\n\n');
+
+ // Send POST request
+ const rawResponse = await fetch("/pptx", {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ }, body: JSON.stringify({"lyrics":lyrics})
+ });
+
+ // Download powerpoint
+ download(await rawResponse.blob());
}
\ No newline at end of file
diff --git a/Songs2Slides/templates/index.html b/Songs2Slides/templates/index.html
@@ -5,29 +5,34 @@
<meta name="viewport" content="width=device-width, user-scalable=no"/>
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}"></link>
<script src="{{ url_for('static', filename='index.js') }}"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/downloadjs/1.4.8/download.min.js"></script>
</head>
- <body onload="Add();">
+ <body onload="AddSong()">
<label id="title">Songs2Slides</label>
<br/>
<label>Create a lyrics powerpoints from a list of songs.</label>
<br/><br/>
- <form action="/pptx" method="POST" onsubmit="PrepareForm();">
- <input hidden name="data">
- <button type="button" onclick="Add();">Add song</button>
- <button type="submit">Create Powerpoint</button>
- </form>
-
-
- <template id="songTemplate">
- <div>
- <input type="text" class="title" placeholder="Song Title">
- <input type="text" class="artist" placeholder="Song Artist">
- <a id="remove" class="songRemove">╳</a>
- </div>
- </template>
-
- <br/>
- <div id="songs"></div>
+ <div id="songs">
+ <button onclick="AddSong();">Add song</button>
+ <button onclick="SubmitSongs();">Create Powerpoint</button>
+ <button onclick="ReviewLyrics();">Review Lyrics</button><br/><br/>
+
+ <template id="songTemplate">
+ <div>
+ <input type="text" class="title" placeholder="Song Title"/>
+ <input type="text" class="artist" placeholder="Song Artist"/>
+ <a id="remove" class="songRemove">╳</a>
+ </div>
+ </template>
+ </div>
+
+ <div id="lyricsContainer" hidden>
+ Review and edit the parsed lyrics below and then click the create PowerPoint button.
+ One blank line signifies a new slide and three blank lines signifies a blank slide.<br/><br/>
+
+ <textarea rows="10" id="lyrics">Loading lyrics...</textarea><br/>
+ <button onclick="SubmitLyrics();">Create Powerpoint</button>
+ </div>
</body>
</html>
\ No newline at end of file