Added getting, starting on RESTful
This commit is contained in:
parent
0099f17d34
commit
b31982153f
3 changed files with 99 additions and 69 deletions
|
|
@ -40,14 +40,42 @@ async function alertText(text="Song Added!") {
|
||||||
alertbox.innerHTML = ""
|
alertbox.innerHTML = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getFromServer(source,headersIn={},secure = false, password=adminPass) {
|
||||||
|
try {
|
||||||
|
let href = "";
|
||||||
|
if(secure) {
|
||||||
|
href = "https://"+ip+"/" + source;
|
||||||
|
} else {
|
||||||
|
href = "http://"+ip+"/" + source;
|
||||||
|
}
|
||||||
|
headersIn["Jukebox-Auth"] = password;
|
||||||
|
headersIn["Accept"] = "application/json";
|
||||||
|
let response = await fetch(href,{
|
||||||
|
method:"GET",
|
||||||
|
headers:headersIn,
|
||||||
|
})
|
||||||
|
let data = await response.json();
|
||||||
|
if (response.status == ERR_NO_ADMIN) {
|
||||||
|
alertText("Error: Admin restricted action")
|
||||||
|
} else if(!response.ok){
|
||||||
|
throw new Error(data.error);
|
||||||
|
}
|
||||||
|
// we add some information from the response just in case it is needed
|
||||||
|
data["ok"] = response.ok;
|
||||||
|
data["status"] = response.status;
|
||||||
|
// console.log(data);
|
||||||
|
return await data;
|
||||||
|
} catch(e) {
|
||||||
|
alertText(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// a lot of this is kinda waffly because i was trying to get
|
// a lot of this is kinda waffly because i was trying to get
|
||||||
// it to return the right stuff and javascript is asyrcronouse (boo)
|
// it to return the right stuff and javascript is asyrcronouse (boo)
|
||||||
async function getFromServer(bodyInfo, source="", secure=false, password=adminPass) {
|
async function postFromServer(bodyInfo, source="", secure=false, password=adminPass) {
|
||||||
try{
|
try{
|
||||||
if (bodyInfo != null) {
|
|
||||||
// the currently set password is always included in every request
|
|
||||||
bodyInfo["password"] = password;
|
|
||||||
}
|
|
||||||
let href = "";
|
let href = "";
|
||||||
if(secure) {
|
if(secure) {
|
||||||
href = "https://"+ip+"/" + source;
|
href = "https://"+ip+"/" + source;
|
||||||
|
|
@ -58,7 +86,8 @@ async function getFromServer(bodyInfo, source="", secure=false, password=adminPa
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(bodyInfo),
|
body: JSON.stringify(bodyInfo),
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json; charset=UTF-8"
|
"Content-type": "application/json; charset=UTF-8",
|
||||||
|
"Jukebox-Auth": password
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -111,12 +140,12 @@ function getCookie(cname) {
|
||||||
// also someone who likes things not being dumb more than me would have separated the client and server buttons
|
// also someone who likes things not being dumb more than me would have separated the client and server buttons
|
||||||
async function controlButton(buttonType) {
|
async function controlButton(buttonType) {
|
||||||
if (buttonType == "pp") { // Play-Pause button
|
if (buttonType == "pp") { // Play-Pause button
|
||||||
let result = await getFromServer({control: "play-pause"}, "controls");
|
let result = await postFromServer({control: "play-pause"}, "controls");
|
||||||
// console.log(result);
|
// console.log(result);
|
||||||
currentlyPlaying = result["data"]["playingState"];
|
currentlyPlaying = result["data"]["playingState"];
|
||||||
} else if (buttonType == "sk") { // Skip button
|
} else if (buttonType == "sk") { // Skip button
|
||||||
// clearInterval(playlistTimeTimer);
|
// clearInterval(playlistTimeTimer);
|
||||||
let returnCode = await getFromServer({control: "skip"}, "controls");
|
let returnCode = await postFromServer({control: "skip"}, "controls");
|
||||||
// console.log(returnCode["ok"])
|
// console.log(returnCode["ok"])
|
||||||
if(returnCode["ok"]) {
|
if(returnCode["ok"]) {
|
||||||
if (document.getElementById("playlist-mode").style.display == "block") {
|
if (document.getElementById("playlist-mode").style.display == "block") {
|
||||||
|
|
@ -149,7 +178,7 @@ async function controlButton(buttonType) {
|
||||||
document.getElementById("settings-mode").style.display = "block";
|
document.getElementById("settings-mode").style.display = "block";
|
||||||
checkSettings()
|
checkSettings()
|
||||||
} else if (buttonType == "pm") { //Partymode toggle (in settings)
|
} else if (buttonType == "pm") { //Partymode toggle (in settings)
|
||||||
let response = await getFromServer({setting: "partymode-toggle"}, "settings")
|
let response = await postFromServer({setting: "partymode-toggle"}, "settings")
|
||||||
if(response.ok) {
|
if(response.ok) {
|
||||||
justChangedSetting = true;
|
justChangedSetting = true;
|
||||||
checkSettings();
|
checkSettings();
|
||||||
|
|
@ -171,7 +200,7 @@ function searchSongsEnter(e) {
|
||||||
|
|
||||||
async function searchSongs(searchTerm){
|
async function searchSongs(searchTerm){
|
||||||
document.getElementById("songlist").innerHTML = ""
|
document.getElementById("songlist").innerHTML = ""
|
||||||
let fetchResults = await getFromServer({search:searchTerm},"search").then();
|
let fetchResults = await getFromServer("search?query="+searchTerm);
|
||||||
let searchResults = fetchResults.data;
|
let searchResults = fetchResults.data;
|
||||||
//generate the visual song list
|
//generate the visual song list
|
||||||
for(var fileName in searchResults) {
|
for(var fileName in searchResults) {
|
||||||
|
|
@ -229,7 +258,7 @@ function alertTimeSet(time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function qrCodeGenerate() {
|
function qrCodeGenerate() {
|
||||||
let tempURL = "http://" + document.location.href.split("/")[2] + "/?ip=" + ip;
|
let tempURL = "http://" + URL.parse(document.location.href).host
|
||||||
document.getElementById("qrcode").innerHTML = "";
|
document.getElementById("qrcode").innerHTML = "";
|
||||||
// get the current foreground and background
|
// get the current foreground and background
|
||||||
let dark = window.getComputedStyle(document.body).getPropertyValue("--text-color");
|
let dark = window.getComputedStyle(document.body).getPropertyValue("--text-color");
|
||||||
|
|
@ -304,7 +333,7 @@ async function checkSettings(skipServer=false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//ping the server here
|
//ping the server here
|
||||||
data = await getFromServer({setting: "getsettings"}, "settings");
|
data = await getFromServer("settings");
|
||||||
x = data["data"];
|
x = data["data"];
|
||||||
if (!(skipServer) || partyButtonState=="N/A") {
|
if (!(skipServer) || partyButtonState=="N/A") {
|
||||||
if (x["partymode"] == false) {
|
if (x["partymode"] == false) {
|
||||||
|
|
@ -401,7 +430,7 @@ async function skipInPlaylist() {
|
||||||
|
|
||||||
async function generateVisualPlaylist(conditions="") {
|
async function generateVisualPlaylist(conditions="") {
|
||||||
document.getElementById("playlist").innerHTML = "<h1 id=\"playlist-alert\"></h1>";
|
document.getElementById("playlist").innerHTML = "<h1 id=\"playlist-alert\"></h1>";
|
||||||
data = await getFromServer(null, "playlist");
|
data = await getFromServer("playlist");
|
||||||
playlist = data["data"]["playlist"];
|
playlist = data["data"]["playlist"];
|
||||||
currentlyPlaying = data["data"]["playingState"]
|
currentlyPlaying = data["data"]["playingState"]
|
||||||
playlist = Object.values(playlist).map(obj => {
|
playlist = Object.values(playlist).map(obj => {
|
||||||
|
|
@ -479,9 +508,9 @@ async function generateVisualPlaylist(conditions="") {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitSong(songid) {
|
async function submitSong(songid) {
|
||||||
let returncode = await getFromServer({song: songid}, "songadd");
|
let returncode = await postFromServer({song: songid}, "songadd");
|
||||||
if(returncode["status"] === ERR_NO_ADMIN) {
|
if(returncode["status"] === ERR_NO_ADMIN) {
|
||||||
// right now the error is alerted in getFromServer, maybe will change that
|
// right now the error is alerted in postFromServer, maybe will change that
|
||||||
} else if(returncode["status"]!==200) {
|
} else if(returncode["status"]!==200) {
|
||||||
alertText("That song's already in the queue! Hang on!")
|
alertText("That song's already in the queue! Hang on!")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -555,7 +584,7 @@ async function submitPerms(e) {
|
||||||
tempData["PM"] = document.getElementById("partymodesettingcheckbox").checked;
|
tempData["PM"] = document.getElementById("partymodesettingcheckbox").checked;
|
||||||
tempData["VOL"] = document.getElementById("volumechangesettingcheckbox").checked;
|
tempData["VOL"] = document.getElementById("volumechangesettingcheckbox").checked;
|
||||||
tempData["DUP"] = document.getElementById("duplicateallowesettingcheckbox").checked;
|
tempData["DUP"] = document.getElementById("duplicateallowesettingcheckbox").checked;
|
||||||
let returncode = await getFromServer({"setting":"perms","admin":tempData},"settings");
|
let returncode = await postFromServer({"setting":"perms","admin":tempData},"settings");
|
||||||
if (!(returncode["ok"])) {
|
if (!(returncode["ok"])) {
|
||||||
// if you aren't allowed to check the box then toggle it again
|
// if you aren't allowed to check the box then toggle it again
|
||||||
// its not perfect if you spam click, but it gets the point across to the user
|
// its not perfect if you spam click, but it gets the point across to the user
|
||||||
|
|
@ -567,7 +596,7 @@ async function submitPerms(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clearPlaylist() {
|
async function clearPlaylist() {
|
||||||
let returncode = await getFromServer({control:"clear"},"controls");
|
let returncode = await postFromServer({control:"clear"},"controls");
|
||||||
if(returncode["status"] === ERR_NO_ADMIN || returncode == null) {
|
if(returncode["status"] === ERR_NO_ADMIN || returncode == null) {
|
||||||
// alertText("Admin Restricted ")
|
// alertText("Admin Restricted ")
|
||||||
// there's an admin restrict alert built into getFromServer
|
// there's an admin restrict alert built into getFromServer
|
||||||
|
|
@ -590,7 +619,7 @@ document.getElementById("settings-mode").style.display = "none";
|
||||||
document.getElementById("volumerange").onchange = async function(e) {
|
document.getElementById("volumerange").onchange = async function(e) {
|
||||||
// there is no reason for this not to be a defined function
|
// there is no reason for this not to be a defined function
|
||||||
// FIX THIS
|
// FIX THIS
|
||||||
let returnValue = await getFromServer({setting:"volume",level:e.target.value}, "settings")
|
let returnValue = await postFromServer({setting:"volume",level:e.target.value}, "settings")
|
||||||
if (returnValue["status"] == ERR_NO_ADMIN) {
|
if (returnValue["status"] == ERR_NO_ADMIN) {
|
||||||
// alertText("Error: Admin restricted action");
|
// alertText("Error: Admin restricted action");
|
||||||
// there's an admin restrict alert built into getFromServer
|
// there's an admin restrict alert built into getFromServer
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ controlPerms = {
|
||||||
"AS":True,
|
"AS":True,
|
||||||
"PM":True,
|
"PM":True,
|
||||||
"VOL":True,
|
"VOL":True,
|
||||||
"DUP":True # Not implemented, allow duplicate songs in queue
|
"DUP":True
|
||||||
}
|
}
|
||||||
|
|
||||||
fileofDB = sql.connect("songDatabase.db")
|
fileofDB = sql.connect("songDatabase.db")
|
||||||
|
|
@ -155,7 +155,7 @@ def playerControls():
|
||||||
recieveData=request.get_json(force=True)
|
recieveData=request.get_json(force=True)
|
||||||
try:
|
try:
|
||||||
if recieveData["control"] == "play-pause":
|
if recieveData["control"] == "play-pause":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["PP"]:
|
if ADMIN_PASS == request.headers["Jukebox-Auth"] or controlPerms["PP"]:
|
||||||
playingState = str(player.get_state())=="State.Playing"
|
playingState = str(player.get_state())=="State.Playing"
|
||||||
player.pause()
|
player.pause()
|
||||||
return {"error":"ok","data":{"playingState":not(playingState)}},200
|
return {"error":"ok","data":{"playingState":not(playingState)}},200
|
||||||
|
|
@ -163,14 +163,14 @@ def playerControls():
|
||||||
playingState = str(player.get_state())=="State.Playing"
|
playingState = str(player.get_state())=="State.Playing"
|
||||||
return {"error":"Admin Restricted Action","data":{"playingState":playingState}},401
|
return {"error":"Admin Restricted Action","data":{"playingState":playingState}},401
|
||||||
elif recieveData["control"] == "skip":
|
elif recieveData["control"] == "skip":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["SK"]:
|
if ADMIN_PASS == request.headers["Jukebox-Auth"] or controlPerms["SK"]:
|
||||||
skipNow = True
|
skipNow = True
|
||||||
return ERR_200
|
return ERR_200
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
# Maybe i should have put this next one in the "settings" section
|
# Maybe i should have put this next one in the "settings" section
|
||||||
elif recieveData["control"] == "clear":
|
elif recieveData["control"] == "clear":
|
||||||
if ADMIN_PASS == recieveData['password']: # this is only ever allowed with the adminpassword
|
if ADMIN_PASS == request.headers["Jukebox-Auth"]: # this is only ever allowed with the adminpassword
|
||||||
with playlistLock:
|
with playlistLock:
|
||||||
playlist.clear()
|
playlist.clear()
|
||||||
return ERR_200
|
return ERR_200
|
||||||
|
|
@ -181,16 +181,19 @@ def playerControls():
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return ERR_MISSING_ARGS
|
return ERR_MISSING_ARGS
|
||||||
|
|
||||||
@app.route("/settings", methods=['POST'])
|
@app.route("/settings", methods=['POST','GET'])
|
||||||
def settingsControl():
|
def settingsControl():
|
||||||
global controlPerms
|
global controlPerms
|
||||||
# set the volume and partymode
|
# set the volume and partymode
|
||||||
global partyMode
|
global partyMode
|
||||||
global player
|
global player
|
||||||
|
if (request.method == 'GET'):
|
||||||
|
return {"error":"ok","data":{"partymode":partyMode,"volume":player.audio_get_volume(),"admin":controlPerms}},200
|
||||||
|
elif (request.method == 'POST'):
|
||||||
recieveData = request.get_json(force=True)
|
recieveData = request.get_json(force=True)
|
||||||
try:
|
try:
|
||||||
if recieveData["setting"] == "volume":
|
if recieveData["setting"] == "volume":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["VOL"]:
|
if ADMIN_PASS == request.headers["Jukebox-Auth"] or controlPerms["VOL"]:
|
||||||
volumeLevel = int(recieveData["level"])
|
volumeLevel = int(recieveData["level"])
|
||||||
if(volumeLevel <= 100 and volumeLevel >= 0):
|
if(volumeLevel <= 100 and volumeLevel >= 0):
|
||||||
volumePassed = player.audio_set_volume(volumeLevel)
|
volumePassed = player.audio_set_volume(volumeLevel)
|
||||||
|
|
@ -203,7 +206,7 @@ def settingsControl():
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
elif recieveData["setting"] == "partymode-toggle":
|
elif recieveData["setting"] == "partymode-toggle":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["PM"]:
|
if ADMIN_PASS == request.headers["Jukebox-Auth"] or controlPerms["PM"]:
|
||||||
partyMode = not(partyMode)
|
partyMode = not(partyMode)
|
||||||
partyModeStr = "On" if partyMode else "Off"
|
partyModeStr = "On" if partyMode else "Off"
|
||||||
socketio.emit("settingsChange",{"settingToChange":"partymode","newData":partyModeStr})
|
socketio.emit("settingsChange",{"settingToChange":"partymode","newData":partyModeStr})
|
||||||
|
|
@ -211,34 +214,31 @@ def settingsControl():
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
elif recieveData["setting"] == "perms":
|
elif recieveData["setting"] == "perms":
|
||||||
if ADMIN_PASS == recieveData["password"]:
|
if ADMIN_PASS == request.headers["Jukebox-Auth"]:
|
||||||
controlPerms = recieveData["admin"]
|
controlPerms = recieveData["admin"]
|
||||||
# print(recieveData["admin"])
|
# print(recieveData["admin"])
|
||||||
socketio.emit("settingsChange",{"settingToChange":"perms","newData":controlPerms})
|
socketio.emit("settingsChange",{"settingToChange":"perms","newData":controlPerms})
|
||||||
return ERR_200
|
return ERR_200
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
elif recieveData["setting"] == "getsettings":
|
|
||||||
# probably should have made this a different request type or something but it works
|
|
||||||
return {"error":"ok","data":{"partymode":partyMode,"volume":player.audio_get_volume(),"admin":controlPerms}},200
|
|
||||||
else:
|
else:
|
||||||
return {"error":"Not a valid setting","data":None},400
|
return {"error":"Not a valid setting","data":None},400
|
||||||
except:
|
except Exception as e:
|
||||||
return ERR_MISSING_ARGS
|
return {"error":e,"data":None},500
|
||||||
|
|
||||||
@app.route("/search", methods=['POST'])
|
@app.route("/search", methods=['GET'])
|
||||||
def searchSongDB():
|
def searchSongDB():
|
||||||
recieveData=request.get_json(force=True)
|
recieveData = request.args.get("query")
|
||||||
fileofDB = sql.connect("songDatabase.db")
|
fileofDB = sql.connect("songDatabase.db")
|
||||||
songDatabase = fileofDB.cursor()
|
songDatabase = fileofDB.cursor()
|
||||||
try:
|
try:
|
||||||
results = []
|
results = []
|
||||||
# print(recieveData["search"])
|
# print(recieveData["search"])
|
||||||
if (recieveData['search'] == ""):
|
if (recieveData == None or recieveData == ""):
|
||||||
songDatabase.execute("SELECT * FROM virtualSongs")
|
songDatabase.execute("SELECT * FROM virtualSongs")
|
||||||
results = songDatabase.fetchall()
|
results = songDatabase.fetchall()
|
||||||
else:
|
else:
|
||||||
songDatabase.execute("SELECT * FROM virtualSongs WHERE virtualSongs MATCH ?",['"' + recieveData['search']+'"'])
|
songDatabase.execute("SELECT * FROM virtualSongs WHERE virtualSongs MATCH ?",['"' + recieveData +'"'])
|
||||||
results = songDatabase.fetchall()
|
results = songDatabase.fetchall()
|
||||||
tempdata = {}
|
tempdata = {}
|
||||||
# this is a temporary solution so i dont have to change the client
|
# this is a temporary solution so i dont have to change the client
|
||||||
|
|
@ -253,9 +253,6 @@ def searchSongDB():
|
||||||
fileofDB.close()
|
fileofDB.close()
|
||||||
|
|
||||||
return {"error":"ok","data":tempdata},200
|
return {"error":"ok","data":tempdata},200
|
||||||
except KeyError:
|
|
||||||
fileofDB.close()
|
|
||||||
return ERR_MISSING_ARGS
|
|
||||||
except sql.OperationalError as e:
|
except sql.OperationalError as e:
|
||||||
print(e)
|
print(e)
|
||||||
fileofDB.close()
|
fileofDB.close()
|
||||||
|
|
@ -266,9 +263,9 @@ def searchSongDB():
|
||||||
def songadd():
|
def songadd():
|
||||||
recieveData=request.get_json(force=True)
|
recieveData=request.get_json(force=True)
|
||||||
try:
|
try:
|
||||||
if (ADMIN_PASS == recieveData['password']) or controlPerms["AS"]:
|
if (ADMIN_PASS == request.headers["Jukebox-Auth"]) or controlPerms["AS"]:
|
||||||
# Password exists and is correct, or it's not restricted
|
# Password exists and is correct, or it's not restricted
|
||||||
if not(controlPerms["DUP"]) and (recieveData['song'] in playlist) and not(ADMIN_PASS == recieveData['password']):
|
if not(controlPerms["DUP"]) and (recieveData['song'] in playlist) and not(ADMIN_PASS == request.headers["Jukebox-Auth"]):
|
||||||
return {"error":"This song is already in the queue, hang on!","data":None},409
|
return {"error":"This song is already in the queue, hang on!","data":None},409
|
||||||
else:
|
else:
|
||||||
queueSong(recieveData['song'])
|
queueSong(recieveData['song'])
|
||||||
|
|
@ -280,7 +277,7 @@ def songadd():
|
||||||
print(e)
|
print(e)
|
||||||
return ERR_MISSING_ARGS
|
return ERR_MISSING_ARGS
|
||||||
|
|
||||||
@app.route("/playlist", methods=["POST"])
|
@app.route("/playlist", methods=["GET"])
|
||||||
def getPlaylist():
|
def getPlaylist():
|
||||||
global songNext
|
global songNext
|
||||||
fileofDB = sql.connect("songDatabase.db")
|
fileofDB = sql.connect("songDatabase.db")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
# Wishlist
|
# Wishlist
|
||||||
*Features I would like to add, will be completed in any order*
|
*Features I would like to add, will be completed in any order*
|
||||||
|
- [ ] RESTful design
|
||||||
|
- [ ] Change all necesary POSTs to GET,DELETE (probably not PUT)
|
||||||
|
- [ ] Write an api layout
|
||||||
|
- Despite the fact this isn't necesary (nobody but the app should access any url but root) it's probably still a good idea. It's going to be very simple anyway
|
||||||
- [ ] Loading indicator while awaiting server stuff
|
- [ ] Loading indicator while awaiting server stuff
|
||||||
- [ ] Refactoring existing code
|
- [ ] Refactoring existing code
|
||||||
- [x] Remove old comments
|
- [x] Remove old comments
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue