Merge pull request #6 from kristy-fournier/responseCodes
http responses are entirely rewritten
This commit is contained in:
commit
bcf3f28cb0
5 changed files with 136 additions and 90 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
server/sound/
|
server/sound/
|
||||||
*.db
|
*.db
|
||||||
start.bat
|
start.bat
|
||||||
.env
|
.env
|
||||||
|
venv/
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
<link rel="manifest" href="manifest.json" />
|
<link rel="manifest" href="manifest.json" />
|
||||||
|
<meta charset="utf-8">
|
||||||
</head>
|
</head>
|
||||||
<body id="test-body">
|
<body id="test-body">
|
||||||
<!--Cookie Popup(does it matter if im not tracking them? i have no idea)-->
|
<!--Cookie Popup(does it matter if im not tracking them? i have no idea)-->
|
||||||
|
|
@ -107,7 +108,7 @@ changes visibility with JS-->
|
||||||
<p class="italic" title="With PartyMode enabled, the second song will be added back randomly">Wipe the playlist, except the currently playing song*</p>
|
<p class="italic" title="With PartyMode enabled, the second song will be added back randomly">Wipe the playlist, except the currently playing song*</p>
|
||||||
<button id="clear-button">Clear Playlist</button>
|
<button id="clear-button">Clear Playlist</button>
|
||||||
</div>
|
</div>
|
||||||
<p class="versionNumber">PartyJukebox is under an <a href="https://github.com/kristy-fournier/PartyJukebox/blob/main/LICENSE.md">AGPLV3</a> liscense. You can access the source code <a href=https://github.com/kristy-fournier/PartyJukebox>here</a>.</p>
|
<p class="versionNumber">PartyJukebox is under an <a href="https://github.com/kristy-fournier/PartyJukebox/blob/main/LICENSE.md" target="_blank">AGPLV3</a> liscense. You can access the source code <a href=https://github.com/kristy-fournier/PartyJukebox target="_blank">here</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--All the buttons are down here but settings is just doing its own thing-->
|
<!--All the buttons are down here but settings is just doing its own thing-->
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
let ip;
|
let ip;
|
||||||
let alertTime = 2;
|
let alertTime = 2;
|
||||||
let adminPass = "";
|
let adminPass = "";
|
||||||
const ERR_NO_ADMIN = "401"; // gonna use this later to refactor
|
const ERR_NO_ADMIN = 401;
|
||||||
const VALID_FILE_EXT = ["mp3","flac","wav"];
|
const VALID_FILE_EXT = ["mp3","flac","wav"];
|
||||||
|
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
|
|
@ -38,7 +38,6 @@ async function getFromServer(bodyInfo, source="",password=adminPass) {
|
||||||
// the currently set password is always included in every request
|
// the currently set password is always included in every request
|
||||||
bodyInfo["password"] = password;
|
bodyInfo["password"] = password;
|
||||||
}
|
}
|
||||||
// console.log(bodyInfo);
|
|
||||||
const response = await fetch("http://"+ip+"/"+source, {
|
const response = await fetch("http://"+ip+"/"+source, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(bodyInfo),
|
body: JSON.stringify(bodyInfo),
|
||||||
|
|
@ -46,20 +45,27 @@ async function getFromServer(bodyInfo, source="",password=adminPass) {
|
||||||
"Content-type": "application/json; charset=UTF-8"
|
"Content-type": "application/json; charset=UTF-8"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
|
||||||
if (data == ERR_NO_ADMIN) {
|
let data = await response.json(); // original json
|
||||||
|
if (response.status == ERR_NO_ADMIN) {
|
||||||
// im suprised i didn't comment on this already but this is kinda lame desing
|
// im suprised i didn't comment on this already but this is kinda lame desing
|
||||||
// its not wrong but you know
|
// its not wrong but you know
|
||||||
// it is easy which i like
|
// it is easy which i like
|
||||||
// and it overrides any other non-async alerts which is nice
|
// and it overrides any other non-async alerts which is nice
|
||||||
alertText("Error: Admin restricted action")
|
alertText("Error: Admin restricted action")
|
||||||
|
} else if(!response.ok){
|
||||||
|
alertText("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;
|
return await data;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
// console.log("error print here:");
|
||||||
|
// console.log(e);
|
||||||
if (e == "TypeError: Failed to fetch"){
|
if (e == "TypeError: Failed to fetch"){
|
||||||
alertText("Error: Can't Connect to Server (is the ip set?)")
|
alertText("Error: Can't Connect to Server (is the ip set?)")
|
||||||
} else if(e == "") {
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
alertText("Error: " + e);
|
alertText("Error: " + e);
|
||||||
}
|
}
|
||||||
|
|
@ -86,6 +92,7 @@ function getCookie(cname) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
//someone more organised than me would have set all these html elements to variables so they dont have to get them 50 times
|
//someone more organised than me would have set all these html elements to variables so they dont have to get them 50 times
|
||||||
|
// 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
|
||||||
getFromServer({control: "play-pause"}, "controls")
|
getFromServer({control: "play-pause"}, "controls")
|
||||||
|
|
@ -130,7 +137,8 @@ function searchSongsEnter(e) {
|
||||||
|
|
||||||
async function searchSongs(searchTerm){
|
async function searchSongs(searchTerm){
|
||||||
document.getElementById("songlist").innerHTML = ""
|
document.getElementById("songlist").innerHTML = ""
|
||||||
searchResults = await getFromServer({search:searchTerm},"search").then()
|
let fetchResults = await getFromServer({search:searchTerm},"search").then();
|
||||||
|
let searchResults = fetchResults.data;
|
||||||
//generate the visual song list
|
//generate the visual song list
|
||||||
for(var fileName in searchResults) {
|
for(var fileName in searchResults) {
|
||||||
let currentSongInJSON = searchResults[fileName]
|
let currentSongInJSON = searchResults[fileName]
|
||||||
|
|
@ -155,6 +163,13 @@ async function searchSongs(searchTerm){
|
||||||
newItem.appendChild(image);
|
newItem.appendChild(image);
|
||||||
newItem.appendChild(head3);
|
newItem.appendChild(head3);
|
||||||
newItem.appendChild(head4);
|
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);
|
document.getElementById("songlist").appendChild(newItem);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +252,8 @@ async function checkSettings(skipServer=false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//ping the server here
|
//ping the server here
|
||||||
x = await getFromServer({setting: "getsettings"}, "settings");
|
data = await getFromServer({setting: "getsettings"}, "settings");
|
||||||
|
x = data["data"];
|
||||||
if (!(skipServer) || partyButtonState=="N/A") {
|
if (!(skipServer) || partyButtonState=="N/A") {
|
||||||
if (x["partymode"] == false) {
|
if (x["partymode"] == false) {
|
||||||
document.getElementById("partymode-button").innerHTML = "Off";
|
document.getElementById("partymode-button").innerHTML = "Off";
|
||||||
|
|
@ -262,7 +278,8 @@ async function checkSettings(skipServer=false) {
|
||||||
|
|
||||||
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>";
|
||||||
playlist = await getFromServer(null, "playlist");
|
data = await getFromServer(null, "playlist");
|
||||||
|
playlist = data["data"];
|
||||||
playlist = Object.values(playlist).map(obj => {
|
playlist = Object.values(playlist).map(obj => {
|
||||||
const filename = Object.keys(obj)[0]; // Get the filename
|
const filename = Object.keys(obj)[0]; // Get the filename
|
||||||
const songData = obj[filename]; // Get the song metadata
|
const songData = obj[filename]; // Get the song metadata
|
||||||
|
|
@ -301,7 +318,7 @@ async function generateVisualPlaylist(conditions="") {
|
||||||
let timeLeft =document.createElement("h5");
|
let timeLeft =document.createElement("h5");
|
||||||
timeLeft.style.fontWeight = 100;
|
timeLeft.style.fontWeight = 100;
|
||||||
try {
|
try {
|
||||||
if (i == 0) {
|
if (i == 0) { // Only the first song in the loop gets a time
|
||||||
head5.innerHTML="Playing";
|
head5.innerHTML="Playing";
|
||||||
if ((conditions != "skip-button")) {
|
if ((conditions != "skip-button")) {
|
||||||
let mins = Math.floor(playlist[i]["time"]/60);
|
let mins = Math.floor(playlist[i]["time"]/60);
|
||||||
|
|
@ -313,7 +330,7 @@ async function generateVisualPlaylist(conditions="") {
|
||||||
}
|
}
|
||||||
}catch(err){
|
}catch(err){
|
||||||
// i dont know why there's a try catch here but i'm leaving it i dont want to break something
|
// 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")
|
let textdiv = document.createElement("div")
|
||||||
textdiv.className="text"
|
textdiv.className="text"
|
||||||
|
|
@ -332,11 +349,9 @@ async function submitSong(songid) {
|
||||||
let returncode = await getFromServer({song: songid}, "songadd");
|
let returncode = await getFromServer({song: songid}, "songadd");
|
||||||
if(returncode == ERR_NO_ADMIN) {
|
if(returncode == ERR_NO_ADMIN) {
|
||||||
// right now the error is alerted in getFromServer, maybe will change that
|
// 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!")
|
alertText("That song's about to play! Hang on!")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
alertText("Added to Queue");
|
alertText("Added to Queue");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -346,11 +361,10 @@ function checkWhatSongWasClicked(e) {
|
||||||
if ((itemId.length-itemId.lastIndexOf("image") == 5) && itemId.lastIndexOf("image")!=-1) {
|
if ((itemId.length-itemId.lastIndexOf("image") == 5) && itemId.lastIndexOf("image")!=-1) {
|
||||||
itemId = itemId.slice(0,-6)
|
itemId = itemId.slice(0,-6)
|
||||||
}
|
}
|
||||||
|
let filenameSep = itemId.split('.')
|
||||||
//i feel like later kristy won't apreciate this
|
//i feel like later kristy won't apreciate this
|
||||||
//one of my files was "file.MP3" so it didn't work
|
//one of my files was "file.MP3" so it didn't work
|
||||||
//windows be like
|
//windows be like
|
||||||
let filenameSep = itemId.split('.')
|
|
||||||
|
|
||||||
if (VALID_FILE_EXT.includes(filenameSep[filenameSep.length-1].toLowerCase())) {
|
if (VALID_FILE_EXT.includes(filenameSep[filenameSep.length-1].toLowerCase())) {
|
||||||
submitSong(itemId);
|
submitSong(itemId);
|
||||||
}
|
}
|
||||||
|
|
@ -440,16 +454,17 @@ document.getElementById("volumerange").onchange = async function() {
|
||||||
// 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:this.value}, "settings")
|
let returnValue = await getFromServer({setting:"volume",level:this.value}, "settings")
|
||||||
if (returnValue == 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
|
||||||
} else if (returnValue["volumePassed"] !=0) {
|
// 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["data"]["volumePassed"] !=0) {
|
||||||
// i forgot about this, i had to do this because it confused the crap out of me one time
|
// 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
|
// vlc doesn't let you change the volume of nothing, which makes sense if you think about it
|
||||||
alertText("Nothing is playing")
|
alertText("Nothing is playing")
|
||||||
document.getElementById("volumerange").value = -1
|
document.getElementById("volumerange").value = -1
|
||||||
}
|
} else if (this.value == 0) {
|
||||||
else if (this.value == 0) {
|
|
||||||
alertText("The volume is now set to 0 (Pause?)")
|
alertText("The volume is now set to 0 (Pause?)")
|
||||||
} else {
|
} else {
|
||||||
alertText("The volume is now set to " + this.value.toString())
|
alertText("The volume is now set to " + this.value.toString())
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,7 @@ h4 {
|
||||||
.songlist > .item > h3, .songlist > .item > h4{
|
.songlist > .item > h3, .songlist > .item > h4{
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
|
margin: 5px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,6 +153,12 @@ h4 {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
min-width: 50px;
|
min-width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lossless-tag {
|
||||||
|
width:16px;
|
||||||
|
padding: 1px;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
/* playlist mode stuff */
|
/* playlist mode stuff */
|
||||||
|
|
||||||
.playlist {
|
.playlist {
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ parser.add_argument('-a','--admin',help="Add an admin password to be used in the
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
dotenv.load_dotenv()
|
dotenv.load_dotenv()
|
||||||
portTheUserPicked=os.getenv("SERVER_PORT")
|
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
|
ERR_NO_ADMIN = ({"error":"no-admin","data":None},401)
|
||||||
# I mean returning 200 when no return is necesary i think is fine but we'll see
|
ERR_200 = ({"error":"OK","data":None},200)
|
||||||
ERR_NO_ADMIN = "401"
|
ERR_MISSING_ARGS = ({"error":"Request missing required arguments","data":None}),400
|
||||||
if args.admin:
|
if args.admin:
|
||||||
ADMIN_PASS = hashlib.sha256(bytes(args.admin,'utf-8')).hexdigest()
|
ADMIN_PASS = hashlib.sha256(bytes(args.admin,'utf-8')).hexdigest()
|
||||||
else:
|
else:
|
||||||
|
|
@ -99,7 +99,8 @@ def playQueuedSongs():
|
||||||
# the above 2 means this only applies if (a song is playing or paused) and (the queue is empty)
|
# the above 2 means this only applies if (a song is playing or paused) and (the queue is empty)
|
||||||
playlist.append(result[0][0])
|
playlist.append(result[0][0])
|
||||||
# check for new songs every second
|
# 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)
|
time.sleep(1)
|
||||||
|
|
||||||
@app.route("/controls", methods=['POST'])
|
@app.route("/controls", methods=['POST'])
|
||||||
|
|
@ -108,30 +109,31 @@ def playerControls():
|
||||||
global skipNow
|
global skipNow
|
||||||
global partyMode
|
global partyMode
|
||||||
recieveData=request.get_json(force=True)
|
recieveData=request.get_json(force=True)
|
||||||
if recieveData["control"] != None:
|
try:
|
||||||
if recieveData["control"] == "play-pause":
|
if recieveData["control"] == "play-pause":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["PP"]:
|
if ADMIN_PASS == recieveData['password'] or controlPerms["PP"]:
|
||||||
player.pause()
|
player.pause()
|
||||||
return "200"
|
return ERR_200
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
elif recieveData["control"] == "skip":
|
elif recieveData["control"] == "skip":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["SK"]:
|
if ADMIN_PASS == recieveData['password'] or controlPerms["SK"]:
|
||||||
skipNow = True
|
skipNow = True
|
||||||
return "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
|
||||||
elif recieveData["control"] == "clear":
|
elif recieveData["control"] == "clear":
|
||||||
if ADMIN_PASS == recieveData['password']: # this is only ever allowed with the adminpassword
|
if ADMIN_PASS == recieveData['password']: # this is only ever allowed with the adminpassword
|
||||||
with playlistLock:
|
with playlistLock:
|
||||||
playlist.clear()
|
playlist.clear()
|
||||||
return "200"
|
return ERR_200
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
else:
|
else:
|
||||||
return "400"
|
return {"error":"Not a valid control","data":None},400
|
||||||
else:
|
except KeyError:
|
||||||
return "400"
|
return ERR_MISSING_ARGS
|
||||||
|
|
||||||
@app.route("/settings", methods=['POST'])
|
@app.route("/settings", methods=['POST'])
|
||||||
def settingsControl():
|
def settingsControl():
|
||||||
|
|
@ -140,71 +142,90 @@ def settingsControl():
|
||||||
global partyMode
|
global partyMode
|
||||||
global player
|
global player
|
||||||
recieveData = request.get_json(force=True)
|
recieveData = request.get_json(force=True)
|
||||||
if recieveData["setting"] == "volume":
|
try:
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["VOL"]:
|
if recieveData["setting"] == "volume":
|
||||||
volumePassed = player.audio_set_volume(int(recieveData["level"]))
|
if ADMIN_PASS == recieveData['password'] or controlPerms["VOL"]:
|
||||||
return {"volumePassed":volumePassed}
|
volumeLevel = int(recieveData["level"])
|
||||||
|
if(volumeLevel <= 100 and volumeLevel >= 0):
|
||||||
|
volumePassed = player.audio_set_volume(volumeLevel)
|
||||||
|
return {"error":"ok","data":{"volumePassed":volumePassed}},200
|
||||||
|
else:
|
||||||
|
return {"error":"Invalid volume level","data":None},422
|
||||||
|
else:
|
||||||
|
return ERR_NO_ADMIN
|
||||||
|
elif recieveData["setting"] == "partymode-toggle":
|
||||||
|
if ADMIN_PASS == recieveData['password'] or controlPerms["PM"]:
|
||||||
|
partyMode = not(partyMode)
|
||||||
|
return ERR_200
|
||||||
|
else:
|
||||||
|
return ERR_NO_ADMIN
|
||||||
|
elif recieveData["setting"] == "perms":
|
||||||
|
if ADMIN_PASS == recieveData["password"]:
|
||||||
|
controlPerms = recieveData["admin"]
|
||||||
|
return ERR_200
|
||||||
|
else:
|
||||||
|
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 ERR_NO_ADMIN
|
return {"error":"Not a valid setting","data":None},400
|
||||||
elif recieveData["setting"] == "partymode-toggle":
|
except:
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["PM"]:
|
return ERR_MISSING_ARGS
|
||||||
partyMode = not(partyMode)
|
|
||||||
return "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
|
|
||||||
controlPerms = recieveData["admin"]
|
|
||||||
return "200"
|
|
||||||
else:
|
|
||||||
return ERR_NO_ADMIN
|
|
||||||
elif recieveData["setting"] == "getsettings":
|
|
||||||
# probably should have made this a different request type or something but it works
|
|
||||||
return {"partymode":partyMode,"volume":player.audio_get_volume(),"admin":controlPerms}
|
|
||||||
else:
|
|
||||||
return "400"
|
|
||||||
|
|
||||||
@app.route("/search", methods=['POST'])
|
@app.route("/search", methods=['POST'])
|
||||||
def searchSongDB():
|
def searchSongDB():
|
||||||
recieveData=request.get_json(force=True)
|
recieveData=request.get_json(force=True)
|
||||||
fileofDB = sql.connect("songDatabase.db")
|
fileofDB = sql.connect("songDatabase.db")
|
||||||
songDatabase = fileofDB.cursor()
|
songDatabase = fileofDB.cursor()
|
||||||
results = []
|
try:
|
||||||
if (recieveData['search'] == ""):
|
results = []
|
||||||
songDatabase.execute("SELECT * FROM virtualSongs")
|
if (recieveData['search'] == ""):
|
||||||
results = songDatabase.fetchall()
|
songDatabase.execute("SELECT * FROM virtualSongs")
|
||||||
else:
|
results = songDatabase.fetchall()
|
||||||
songDatabase.execute("SELECT * FROM virtualSongs WHERE virtualSongs MATCH ?",[recieveData['search']])
|
else:
|
||||||
results = songDatabase.fetchall()
|
songDatabase.execute("SELECT * FROM virtualSongs WHERE virtualSongs MATCH ?",[recieveData['search']])
|
||||||
tempdata = {}
|
results = songDatabase.fetchall()
|
||||||
# this is a temporary solution so i dont have to change the client
|
tempdata = {}
|
||||||
for i in results:
|
# this is a temporary solution so i dont have to change the client
|
||||||
tempdata[i[0]] = {
|
for i in results:
|
||||||
"title": i[1],
|
tempdata[i[0]] = {
|
||||||
"artist": i[2],
|
"title": i[1],
|
||||||
"art": i[3],
|
"artist": i[2],
|
||||||
"length": i[4]
|
"art": i[3],
|
||||||
}
|
"length": i[4],
|
||||||
fileofDB.close()
|
"lossless":i[5]
|
||||||
return tempdata
|
}
|
||||||
|
fileofDB.close()
|
||||||
|
|
||||||
|
return {"error":"ok","data":tempdata},200
|
||||||
|
except KeyError:
|
||||||
|
fileofDB.close()
|
||||||
|
return ERR_MISSING_ARGS
|
||||||
|
except sql.OperationalError:
|
||||||
|
fileofDB.close()
|
||||||
|
return ({"error":"Invalid search, sorry!","data":None},422)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/songadd", methods=["POST"])
|
@app.route("/songadd", methods=["POST"])
|
||||||
def songadd():
|
def songadd():
|
||||||
recieveData=request.get_json(force=True)
|
recieveData=request.get_json(force=True)
|
||||||
if (ADMIN_PASS and ADMIN_PASS == recieveData['password']) or controlPerms["AS"]:
|
try:
|
||||||
# Password exists and is correct, or it's not restricted
|
if (ADMIN_PASS == recieveData['password']) or controlPerms["AS"]:
|
||||||
# if (recieveData['song'] in playlist):
|
# Password exists and is correct, or it's not restricted
|
||||||
# return {"error":"song-in-queue"}
|
# if (recieveData['song'] in playlist):
|
||||||
# else:
|
# return {"error":"song-in-queue"}
|
||||||
# Right now the above is disabled since i want to make it optional first
|
# else:
|
||||||
# probably with a checkbox like the other admin controls
|
# Right now the above is disabled since i want to make it optional first
|
||||||
if True:
|
# probably with a checkbox like the other admin controls
|
||||||
queueSong(recieveData['song'])
|
if True:
|
||||||
return "200"
|
queueSong(recieveData['song'])
|
||||||
else:
|
return ERR_200
|
||||||
# the password is incorrect (technically a password not existing falls into the above case because controlPerms is never changed)
|
else:
|
||||||
return ERR_NO_ADMIN
|
# the password is incorrect (technically a password not existing falls into the above case because controlPerms is never changed)
|
||||||
|
return ERR_NO_ADMIN
|
||||||
|
except KeyError:
|
||||||
|
return ERR_MISSING_ARGS
|
||||||
|
|
||||||
@app.route("/playlist", methods=["POST"])
|
@app.route("/playlist", methods=["POST"])
|
||||||
def getPlaylist():
|
def getPlaylist():
|
||||||
|
|
@ -238,7 +259,8 @@ def getPlaylist():
|
||||||
}
|
}
|
||||||
tempPlaylist.append({i:k})
|
tempPlaylist.append({i:k})
|
||||||
fileofDB.close()
|
fileofDB.close()
|
||||||
return tempPlaylist
|
|
||||||
|
return {"error":"ok","data":tempPlaylist}
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# There's not really a whole lot of point to a main function for something like this, you'd never use any of these methods
|
# There's not really a whole lot of point to a main function for something like this, you'd never use any of these methods
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue