Using dotenv, refactored some stuff, made making database slightly faster with art

This commit is contained in:
Kristy Fournier 2026-01-21 16:49:04 -05:00
parent 0cd6b4ce2e
commit 5772edf88a
4 changed files with 30 additions and 26 deletions

View file

@ -4,26 +4,27 @@ from mutagen.mp3 import MP3
import mutagen.flac
import mutagen.wave
import sqlite3 as sql
import requests, ast, time, math, argparse
import requests, ast, time, math, argparse, dotenv
loading = ["-","\\","|","/"]
parser=argparse.ArgumentParser(description="Options for the generation of the song database")
parser.add_argument('-k','--apikey', help='String: LastFM api key', default="")
# parser.add_argument('-k','--apikey', help='String: LastFM api key', default="")
parser.add_argument('-m', '--mode', help='new/update: Remake database or update current', default= "update")
parser.add_argument('-a', '--art', help="True/False: Add art to the database using LastFm (takes minimum 0.25s per song)", default="True")
parser.add_argument('-d','--directory',help="Directory of the song files", default="./sound/")
args = parser.parse_args()
apikeylastfm = args.apikey
dotenv.load_dotenv()
apikeylastfm = os.getenv("API_KEY")
soundLocation = os.getenv("DIRECTORY")
# apikeylastfm = args.apikey
if args.directory[-1] == "/" or args.directory[-1] == "\\":
soundLocation = args.directory
elif "/" in args.directory:
soundLocation = args.directory + "/"
else:
soundLocation = args.directory + "\\"
# if you want to set the api key/sound directory permenantly for your setup just uncomment the next line
# apikeylastfm = "KeyHere"
# soundLocation = "directoryHere"
songFiles = os.listdir(soundLocation)
fileOfDB = sql.connect("songDatabase.db")
songDatabase = fileOfDB.cursor()
@ -54,12 +55,12 @@ elif args.mode.lower()=="new":
else:
raise ValueError("Must be \"new\" or \"update\"")
if args.art.lower() == "true" and not(args.apikey == ""):
x = len(songFiles)*0.25
if x > 60:
print("ETA "+ str(x/60) + " minutes")
if args.art.lower() == "true" and not(apikeylastfm == ""):
eta = len(songFiles)*0.25
if eta > 60:
print(f"ETA {eta/60:.2f} minutes")
else:
print("ETA "+ str(x) + " seconds")
print(f"ETA {eta} seconds")
# will be used soon
validFormats = ["mp3","flac","wav"]
@ -103,7 +104,8 @@ for i in songFiles:
#if the file is not formatted with an underscore or hyphen, the title is the file name
title = i
artist = None
if args.art.lower() == "true" and not(args.apikey == ""):
if args.art.lower() == "true" and not(apikeylastfm == "") and artist:
# and artist just means anything that only has the x.mp3 title won't bother to check since it'll never exist on last fm
try:
# get the images from last fm, try 2 different sizes
image = ast.literal_eval(requests.post(url="http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key="+apikeylastfm+"&artist="+artist+"&track="+title+"&format=json").text)["track"]["album"]["image"][2]["#text"]
@ -111,7 +113,7 @@ for i in songFiles:
image = ast.literal_eval(requests.post(url="http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key="+apikeylastfm+"&artist="+artist+"&track="+title+"&format=json").text)["track"]["album"]["image"][1]["#text"]
if image == "":
image = None
time.sleep(0.25)
time.sleep(0.01)
except:
image=None
else:

3
Server/example.env Normal file
View file

@ -0,0 +1,3 @@
API_KEY=
DIRECTORY=./sound
SERVER_PORT=19054

View file

@ -2,14 +2,14 @@ from flask import Flask
from flask import request
from flask_cors import CORS
import sqlite3 as sql
import vlc,threading,time,random, argparse
import vlc,threading,time,random,argparse,dotenv,os
# Argparse Stuff
parser=argparse.ArgumentParser(description="Options for the Webby Bits")
parser.add_argument('-p','--port',help="Port to host on, not the same as the web (client) port",default='19054')
# parser.add_argument('-p','--port',help="Port to host on, not the same as the web (client) port",default='19054')
parser.add_argument('-a','--admin',help="Add an admin password to be used in the client. DO NOT use a password you use elsewhere",default="")
args = parser.parse_args()
portTheUserPicked=args.port
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
@ -20,11 +20,11 @@ if not(ADMIN_PASS):
# True = everyone, False = admin only. Change in client while in use.
# play-pause,skip,addsong,partymode,volume in order
controlPerms = {
"PP":True, #done
"SK":True, #done
"AS":True, #done
"PM":True, #done
"VOL":True #done
"PP":True,
"SK":True,
"AS":True,
"PM":True,
"VOL":True
}
fileofDB = sql.connect("songDatabase.db")
@ -150,8 +150,7 @@ def settingsControl():
return ERR_NO_ADMIN
elif recieveData["setting"] == "getsettings":
# probably should have made this a different request type or something but it works
x = {"partymode":partyMode,"volume":player.audio_get_volume(),"admin":controlPerms}
return x
return {"partymode":partyMode,"volume":player.audio_get_volume(),"admin":controlPerms}
else:
return "400"

View file

@ -7,8 +7,8 @@
- [ ] Verify all if-else sequences are correct and not redundant
- [x] Remove old comments
- [ ] Security Updates
- [ ] `.env` file for the api keys and other runtime info to be set, rather than in the `.py` files
- [ ] Hashing rather than plaintext sending (that way at least the password text itself stays private)
- [x] `.env` file for the api keys and other runtime info to be set, rather than in the `.py` files
- [ ] Hashing rather than plaintext sending passwords (that way at least the password text itself isn't transmitted over the network)
- [ ] Actually use SSL, for posting (CORS seems like an issue)
- [ ] Accessibility
- [ ] Better use of semantic HTML tags