Sockets are implemented

need a lot of fixes but are in a mostly working state as of now
This commit is contained in:
Kristy Fournier 2026-01-31 00:08:53 -05:00
parent 384b369eee
commit f064183b9a
4 changed files with 111 additions and 32 deletions

View file

@ -1,6 +1,7 @@
from flask import Flask
from flask import request
from flask_cors import CORS
from flask_socketio import SocketIO
import sqlite3 as sql
import vlc,threading,time,random,argparse,dotenv,os,hashlib,string
# Argparse Stuff
@ -64,20 +65,46 @@ player.audio_set_volume(100)
app = Flask(__name__)
# because you are POSTing from another domain to this one, you need CORS
CORS(app)
# Replace the star with the frontend domain if you dislike being hacked
socketio = SocketIO(app, cors_allowed_origins="*")
def queueSong(song):
with playlistLock:
playlist.append(song)
socketio.emit("songAdd",getSongInfo(song))
def getSongInfo(song):
fileofDB = sql.connect("songDatabase.db")
songDatabase = fileofDB.cursor()
songDatabase.execute("SELECT * FROM songs WHERE filename = ?",[song])
result = songDatabase.fetchall()[0]
# again, this is still using the old JSON format to avoid client changes
k = {
"title": result[1],
"artist": result[2],
"art": result[3],
"length": result[4]
}
fileofDB.close()
return {song:k}
# this is a loop that plays the songs and checks for playlist changes, skips, ect.
counter = 0
def playQueuedSongs():
global skipNow
global songNext
global partyMode
global counter
while True:
with playlistLock:
counter+=1
if(counter > 10):
playingState = str(player.get_state()) == "State.Playing"
socketio.emit('timeUpdate',{"elapsedTime":player.get_time()/1000,"playingState":playingState})
playerState = str(player.get_state())
endStates = ["State.Ended","State.Stopped","State.NothingSpecial"]
if playerState == "State.Ended":
socketio.emit("skipSong",None)
if playlist and (playerState in endStates or skipNow == True):
# New song is in the queue and (the previous song is over or skip has been pressed)
player.stop()
@ -87,6 +114,7 @@ def playQueuedSongs():
player.set_media(media)
player.play()
elif (skipNow==True or (playerState in endStates)):
# print(playerState)
# skip was pressed and there are no new songs
skipNow=False
songNext = None
@ -99,11 +127,16 @@ def playQueuedSongs():
# adds the random songs for party mode
# the above 2 means this only applies if (a song is playing or paused) and (the queue is empty)
playlist.append(result[0][0])
socketio.emit('songAdd',getSongInfo(result[0][0]))
# check for new songs every second
# 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)
@socketio.on("connect")
def handleConnect():
pass
@app.route("/controls", methods=['POST'])
def playerControls():
# recieve control inputs (play/pause and skip) from the webUI
@ -113,10 +146,12 @@ def playerControls():
try:
if recieveData["control"] == "play-pause":
if ADMIN_PASS == recieveData['password'] or controlPerms["PP"]:
playingState = str(player.get_state())=="State.Playing"
player.pause()
return ERR_200
return {"error":"ok","data":{"playingState":not(playingState)}},200
else:
return ERR_NO_ADMIN
playingState = str(player.get_state())=="State.Playing"
return {"error":"Admin Restricted Action","data":{"playingState":playingState}},401
elif recieveData["control"] == "skip":
if ADMIN_PASS == recieveData['password'] or controlPerms["SK"]:
skipNow = True
@ -163,7 +198,7 @@ def settingsControl():
elif recieveData["setting"] == "perms":
if ADMIN_PASS == recieveData["password"]:
controlPerms = recieveData["admin"]
print(recieveData["admin"])
# print(recieveData["admin"])
return ERR_200
else:
return ERR_NO_ADMIN
@ -261,8 +296,11 @@ def getPlaylist():
}
tempPlaylist.append({i:k})
fileofDB.close()
return {"error":"ok","data":tempPlaylist}
playingState = False
if(str(player.get_state())=="State.Playing"):
playingState = True
# print(playingState)
return {"error":"ok","data":{"playlist":tempPlaylist,"playingState":playingState}},200
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
@ -271,5 +309,5 @@ if __name__ == "__main__":
queueThread = threading.Thread(target=playQueuedSongs)
queueThread.daemon = True
queueThread.start()
app.run(host='0.0.0.0', port=portTheUserPicked)
socketio.run(app=app,host='0.0.0.0', port=portTheUserPicked)