diff --git a/Client/index.html b/Client/index.html index 7172540..428fb2d 100644 --- a/Client/index.html +++ b/Client/index.html @@ -5,6 +5,7 @@ + @@ -107,7 +108,7 @@ changes visibility with JS-->

Wipe the playlist, except the currently playing song*

-

PartyJukebox is under an AGPLV3 liscense. You can access the source code here.

+

PartyJukebox is under an AGPLV3 liscense. You can access the source code here.

diff --git a/Client/scripts.js b/Client/scripts.js index 826709f..1d34c71 100644 --- a/Client/scripts.js +++ b/Client/scripts.js @@ -2,7 +2,7 @@ let ip; let alertTime = 2; let adminPass = ""; -const ERR_NO_ADMIN = "401"; // gonna use this later to refactor +const ERR_NO_ADMIN = 401; // gonna use this later to refactor const VALID_FILE_EXT = ["mp3","flac","wav"]; const params = new URLSearchParams(location.search); @@ -46,8 +46,9 @@ async function getFromServer(bodyInfo, source="",password=adminPass) { "Content-type": "application/json; charset=UTF-8" } }); + const data = await response.json(); - if (data == ERR_NO_ADMIN) { + if (response.status == ERR_NO_ADMIN) { // im suprised i didn't comment on this already but this is kinda lame desing // its not wrong but you know // it is easy which i like @@ -56,9 +57,11 @@ async function getFromServer(bodyInfo, source="",password=adminPass) { } return await data; } catch(e) { + console.log("error print here:"); + console.log(e); if (e == "TypeError: Failed to fetch"){ alertText("Error: Can't Connect to Server (is the ip set?)") - } else if(e == "") { + } else if(e === "") { } else { alertText("Error: " + e); @@ -155,6 +158,13 @@ async function searchSongs(searchTerm){ newItem.appendChild(image); newItem.appendChild(head3); newItem.appendChild(head4); + // I like this concept but i'm leaving it out for now + // if(currentSongInJSON.lossless === 1) { + // let losslesstag = document.createElement("p"); + // losslesstag.textContent = "Ⓛ"; + // losslesstag.classList.add("lossless-tag"); + // newItem.appendChild(losslesstag); + // } document.getElementById("songlist").appendChild(newItem); } @@ -301,7 +311,7 @@ async function generateVisualPlaylist(conditions="") { let timeLeft =document.createElement("h5"); timeLeft.style.fontWeight = 100; try { - if (i == 0) { + if (i == 0) { // Only the first song in the loop gets a time head5.innerHTML="Playing"; if ((conditions != "skip-button")) { let mins = Math.floor(playlist[i]["time"]/60); @@ -313,7 +323,7 @@ async function generateVisualPlaylist(conditions="") { } }catch(err){ // i dont know why there's a try catch here but i'm leaving it i dont want to break something - console.log(err) + console.error(err) } let textdiv = document.createElement("div") textdiv.className="text" @@ -332,11 +342,9 @@ async function submitSong(songid) { let returncode = await getFromServer({song: songid}, "songadd"); if(returncode == ERR_NO_ADMIN) { // right now the error is alerted in getFromServer, maybe will change that - } - else if(returncode["error"]=="song-in-queue") { + } else if(returncode["error"]=="song-in-queue") { alertText("That song's about to play! Hang on!") - } - else { + } else { alertText("Added to Queue"); } } @@ -346,11 +354,10 @@ function checkWhatSongWasClicked(e) { if ((itemId.length-itemId.lastIndexOf("image") == 5) && itemId.lastIndexOf("image")!=-1) { itemId = itemId.slice(0,-6) } + let filenameSep = itemId.split('.') //i feel like later kristy won't apreciate this //one of my files was "file.MP3" so it didn't work //windows be like - let filenameSep = itemId.split('.') - if (VALID_FILE_EXT.includes(filenameSep[filenameSep.length-1].toLowerCase())) { submitSong(itemId); } @@ -443,6 +450,8 @@ document.getElementById("volumerange").onchange = async function() { if (returnValue == ERR_NO_ADMIN) { // alertText("Error: Admin restricted action"); // there's an admin restrict alert built into getFromServer + // i wanna put the volume slider back to where it was but idk a good way to keep the previous volume + checkSettings(false); } else if (returnValue["volumePassed"] !=0) { // i forgot about this, i had to do this because it confused the crap out of me one time // vlc doesn't let you change the volume of nothing, which makes sense if you think about it diff --git a/Client/styles.css b/Client/styles.css index 024e988..21f7b7c 100644 --- a/Client/styles.css +++ b/Client/styles.css @@ -134,6 +134,7 @@ h4 { .songlist > .item > h3, .songlist > .item > h4{ margin-left: 2px; margin-right: 2px; + margin: 5px; word-wrap: break-word; } @@ -152,6 +153,12 @@ h4 { width: 20%; min-width: 50px; } + +.lossless-tag { + width:16px; + padding: 1px; + margin-left: auto; +} /* playlist mode stuff */ .playlist { diff --git a/Server/webbyBits.py b/Server/webbyBits.py index 130131b..056d23f 100644 --- a/Server/webbyBits.py +++ b/Server/webbyBits.py @@ -10,10 +10,9 @@ parser.add_argument('-a','--admin',help="Add an admin password to be used in the args = parser.parse_args() dotenv.load_dotenv() portTheUserPicked=os.getenv("SERVER_PORT") -# Just a note that the return code "401" as of now is used to mean "you don't have the password" -# This is not great design, and the whole "returning string codes" thing is something to add to the todo list -# I mean returning 200 when no return is necesary i think is fine but we'll see -ERR_NO_ADMIN = "401" + +ERR_NO_ADMIN = ({"error":"no-admin"},401) +ERR_200 = ({"error":"OK"},200) if args.admin: ADMIN_PASS = hashlib.sha256(bytes(args.admin,'utf-8')).hexdigest() else: @@ -99,7 +98,8 @@ def playQueuedSongs(): # the above 2 means this only applies if (a song is playing or paused) and (the queue is empty) playlist.append(result[0][0]) # check for new songs every second - # I just didn't want to eat too much processing looping + # I just didn't want to eat too much processing looping + # this also has another useful affect that skips get "queued" to only 1 per second, that way somebody usually can't skip twice accidentally time.sleep(1) @app.route("/controls", methods=['POST']) @@ -112,26 +112,27 @@ def playerControls(): if recieveData["control"] == "play-pause": if ADMIN_PASS == recieveData['password'] or controlPerms["PP"]: player.pause() - return "200" + return ERR_200 else: return ERR_NO_ADMIN elif recieveData["control"] == "skip": if ADMIN_PASS == recieveData['password'] or controlPerms["SK"]: skipNow = True - return "200" + return ERR_200 else: return ERR_NO_ADMIN + # Maybe i should have put this next one in the "settings" section elif recieveData["control"] == "clear": if ADMIN_PASS == recieveData['password']: # this is only ever allowed with the adminpassword with playlistLock: playlist.clear() - return "200" + return ERR_200 else: return ERR_NO_ADMIN else: - return "400" + return {"error":"Not a valid control"},400 else: - return "400" + return {"error":"No control sent"},400 @app.route("/settings", methods=['POST']) def settingsControl(): @@ -149,14 +150,13 @@ def settingsControl(): elif recieveData["setting"] == "partymode-toggle": if ADMIN_PASS == recieveData['password'] or controlPerms["PM"]: partyMode = not(partyMode) - return "200" + return ERR_200 else: return ERR_NO_ADMIN elif recieveData["setting"] == "perms": - if ADMIN_PASS == recieveData["password"] and ADMIN_PASS: - #if an adminpass doesn't exist these perms can never be changed + if ADMIN_PASS == recieveData["password"]: controlPerms = recieveData["admin"] - return "200" + return ERR_200 else: return ERR_NO_ADMIN elif recieveData["setting"] == "getsettings": @@ -184,7 +184,8 @@ def searchSongDB(): "title": i[1], "artist": i[2], "art": i[3], - "length": i[4] + "length": i[4], + "lossless":i[5] } fileofDB.close() return tempdata @@ -201,7 +202,7 @@ def songadd(): # probably with a checkbox like the other admin controls if True: queueSong(recieveData['song']) - return "200" + return ERR_200 else: # the password is incorrect (technically a password not existing falls into the above case because controlPerms is never changed) return ERR_NO_ADMIN