Add versionNum Object, pages for search

This will be tweaked a lot more but i really need to go study for something instead of doing this
This commit is contained in:
Kristy F 2026-04-14 12:53:26 -04:00
parent 151ed839c3
commit 8a5534482b
6 changed files with 98 additions and 13 deletions

Binary file not shown.

View file

@ -198,11 +198,17 @@ function searchSongsEnter(e) {
}
}
async function searchSongs(searchTerm){
async function searchSongs(searchTerm,page=-1){
document.getElementById("songlist").innerHTML = ""
let fetchResults = await getFromServer("search?query="+searchTerm);
let searchResults = fetchResults.data;
let fetchResults = await getFromServer("search?query="+searchTerm+"&page="+page);
let searchResults = fetchResults.data.songsobj;
//generate the visual song list
// let x = document.createElement("button")
// x.addEventListener("click",()=>{
// searchSongs(searchTerm,page+1);
// })
// x.textContent = "Next Page"
// document.getElementById("songlist-mode").appendChild(x)
for(var fileName in searchResults) {
let currentSongInJSON = searchResults[fileName]
let newItem = document.createElement("div");
@ -241,6 +247,8 @@ async function searchSongs(searchTerm){
if (JSON.stringify(searchResults)==JSON.stringify({})) {
//display error if no results
document.getElementById("songlist").innerHTML = "<h1>We might not have that one...</h1>";
} else {
}
}

View file

@ -113,7 +113,7 @@ changes visibility with JS-->
<button id="clear-button">Clear Playlist</button>
</div>
<p class="versionNumber italic">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>
<p class="versionNumber">Release {{ REL_VER_NUM }}</p>
<p class="versionNumber italic">Release {{ REL_VER_NUM }}</p>
</div>
</div>
<!--All the buttons are down here but settings is just doing its own thing-->

67
Server/versionNum.py Normal file
View file

@ -0,0 +1,67 @@
from __future__ import annotations
class VersionNumber:
def __init__(self,major:int,minor:int,patch:int,extra:str):
self.major = major
self.minor = minor
self.patch = patch
self.extra = extra
# From String like "x.y.z-extra"
@staticmethod
def fromString(verString:str) -> VersionNumber:
numList = verString.split(".")
major = int(numList[0])
minor = int(numList[1])
patch = int(numList[2].split("-")[0])
extra = numList[2].split("-")[1]
return VersionNumber(major,minor,patch,extra)
def clone(verNumIn:VersionNumber) -> VersionNumber:
return VersionNumber(verNumIn.major,verNumIn.minor,verNumIn.patch,verNumIn.extra)
def __str__(self) -> str:
returnStr = f"v{self.major}.{self.minor}.{self.patch}"
if(self.extra):
returnStr += f"-{self.extra}"
return returnStr
def __eq__(self,comp) -> bool:
if type(comp) == VersionNumber:
return self.major == comp.major and self.minor == comp.minor and self.patch == comp.patch and self.extra == comp.extra
elif type(comp) == str:
return self == VersionNumber.fromString(comp)
elif type(comp) == type(None):
return False
else:
raise TypeError
def __gt__(self,comp):
if type(comp) == VersionNumber:
if(self.major > comp.major):
return True
elif(self.major == comp.major and self.minor > comp.minor):
return True
elif(self.major == comp.major and self.minor == comp.minor and self.patch > comp.patch):
return True
return False
elif type(comp) == str:
return self > VersionNumber.fromString(comp)
else:
raise TypeError
def __ge__(self,comp):
return self > comp or self == comp
if __name__ == "__main__":
x = VersionNumber(1,2,4,"alpha")
y = VersionNumber.fromString("1.2.3-beta")
z = VersionNumber.clone(x)
print(x)
print(y)
print(z)
print(f"X == Y: {x==y}")
print(f"X > Y: {x>y}")
print(f"Y < X: {y<x}")
print(f"Z >= Y: {z>=y}")
print(f"Z <= Y: {z<=y}")

View file

@ -1,14 +1,14 @@
import eventlet
eventlet.monkey_patch()
# import eventlet
# eventlet.monkey_patch()
from flask import Flask
from flask import request,render_template
from flask_cors import CORS
from flask_socketio import SocketIO
import sqlite3 as sql
import vlc,threading,random,argparse,dotenv,os,hashlib,string,getpass
from versionNum import VersionNumber
# So i'm famously bad at following Semantic versioning, we're gonna see how this goes
REL_VER_NUM = "0.0.1"
REL_VER_NUM = VersionNumber(0,0,2,"alpha")
# Argparse Stuff
parser=argparse.ArgumentParser(description="Options for the Webby Bits")
@ -19,7 +19,7 @@ portTheUserPicked=os.getenv("SERVER_PORT")
ERR_NO_ADMIN = ({"error":"no-admin","data":None},401)
ERR_200 = ({"error":"OK","data":None},200)
ERR_MISSING_ARGS = ({"error":"Request missing required arguments","data":None}),400
ERR_MISSING_ARGS = ({"error":"Request missing required arguments","data":None},400)
if bool(args.admin) and args.admin.lower() != "false":
ADMIN_PASS = hashlib.sha256(bytes(getpass.getpass("Enter AdminPass: "),'utf-8')).hexdigest()
else:
@ -47,6 +47,7 @@ try:
soundLocation = songDatabase.fetchall()[0][1]
except sql.OperationalError:
print("No Database Found, try running databaseGenerator.py")
os._exit(1)
if soundLocation[-1] == "/" or soundLocation[-1] == "\\":
pass
elif "/" in soundLocation:
@ -147,7 +148,7 @@ def handleConnect():
@app.route("/",methods=['GET'])
def returnStaticFile():
return render_template("index.html",REL_VER_NUM=REL_VER_NUM)
return render_template("index.html",REL_VER_NUM=str(REL_VER_NUM))
@app.route("/controls", methods=['POST'])
def playerControls():
@ -232,6 +233,9 @@ def settingsControl():
@app.route("/search", methods=['GET'])
def searchSongDB():
recieveData = request.args.get("query")
page = int(request.args.get("page"))
if not(page):
page = 1
fileofDB = sql.connect("songDatabase.db")
songDatabase = fileofDB.cursor()
try:
@ -243,6 +247,12 @@ def searchSongDB():
else:
songDatabase.execute("SELECT * FROM virtualSongs WHERE virtualSongs MATCH ?",['"' + recieveData +'"'])
results = songDatabase.fetchall()
pages = (len(results)//20)+1
if(page>0):
# Numbers <0 use old rendering
inBound = 20*(page-1)
outBound = 20*page
results = results[inBound:outBound]
tempdata = {}
# this is a temporary solution so i dont have to change the client
for i in results:
@ -255,7 +265,7 @@ def searchSongDB():
}
fileofDB.close()
return {"error":"ok","data":tempdata},200
return {"error":"ok","data":{"songsobj":tempdata,"pages":pages}},200
except sql.OperationalError as e:
print(e)
fileofDB.close()
@ -325,6 +335,6 @@ if __name__ == "__main__":
queueThread = threading.Thread(target=playQueuedSongs)
queueThread.daemon = True
queueThread.start()
print(f"PartyJukebox v{REL_VER_NUM} running on port {portTheUserPicked}")
print(f"PartyJukebox {REL_VER_NUM} running on port {portTheUserPicked}")
socketio.run(app=app,host='0.0.0.0', port=portTheUserPicked)

View file

@ -14,7 +14,7 @@
- [ ] Security Updates
- [x] `.env` file for the api keys and other runtime info to be set, rather than in the `.py` files
- [x] Hashing rather than plaintext sending passwords (that way at least the password text itself isn't transmitted over the network)
- [ ] Actually use TLS, for posting (CORS seems like an issue)
- [ ] Actually use TLS, for posting
- [ ] Accessibility
- [ ] Better use of semantic HTML tags
- [ ] Full keyboard control (tab, enter to select, tab between control buttons)