Introduce "dev environment" and dotenv

There are now two dockerfiles. One for production, one for development.
All configuration is now also handled through dotenv files,
which these dotenv files, as well as the included VSCode launch tasks
use.
This commit is contained in:
Phillip Kühne 2023-03-28 00:54:04 +02:00
parent 831166f38b
commit b8220732ee
Signed by: phillip
GPG Key ID: E4C1C4D2F90902AA
7 changed files with 112 additions and 93 deletions

14
.env.dev Normal file
View File

@ -0,0 +1,14 @@
# MariaDB
MARIADB_ROOT_PASSWORD=mariadb_root_password
MARIADB_ROOT_HOST=localhost
MARIADB_DATABASE=karaoqueue
MARIADB_USER=karaoqueue
MARIADB_PASSWORD=mariadb_karaoqueue_password
# Karaoqueue
DEPLOYMENT_PLATFORM=Docker
DBSTRING=mysql://karaoqueue:mariadb_karaoqueue_password@127.0.0.1:3306/karaoqueue
BASIC_AUTH_USERNAME=admin
BASIC_AUTH_PASSWORD=change_me
ENTRY_QUOTA=3
MAX_QUEUE=20

3
.gitignore vendored
View File

@ -138,3 +138,6 @@ node_modules/
# Version identification file
.version
# Docker secrets
secrets.yml

5
.vscode/launch.json vendored
View File

@ -15,8 +15,8 @@
"FLASK_APP": "backend/app.py",
"FLASK_ENV": "development",
"FLASK_DEBUG": "1",
"DBSTRING": "mysql://devuser:devpw@127.0.0.1:3306/karaoqueue"
},
"envFile": "${workspaceFolder}/.env.dev",
"args": [
"run",
"--no-debugger",
@ -36,6 +36,7 @@
"FLASK_ENV": "development",
"FLASK_DEBUG": "1"
},
"envFile": "${workspaceFolder}/.env.dev",
"args": [
"run",
"--no-debugger"
@ -54,6 +55,7 @@
"FLASK_ENV": "development",
"FLASK_DEBUG": "1"
},
"envFile": "${workspaceFolder}/.env.dev",
"args": [
"run",
"--no-debugger",
@ -73,6 +75,7 @@
"FLASK_ENV": "development",
"FLASK_DEBUG": "1"
},
"envFile": "${workspaceFolder}/.env.dev",
"args": [
"run",
"--no-debugger",

2
.vscode/tasks.json vendored
View File

@ -12,7 +12,7 @@
{
"label": "mariadb",
"type": "shell",
"command": "docker run --rm --name some-mariadb --env MARIADB_USER=devuser --env MARIADB_PASSWORD=devpw --env MARIADB_ROOT_PASSWORD=devrootpw --env MARIADB_DATABASE=karaoqueue -p 3306:3306 mariadb:latest",
"command": "docker-compose -f docker-compose.yml up --remove-orphans",
"isBackground": true,
"activeOnStart": false
}

View File

@ -12,48 +12,43 @@ entry_table = "entries"
index_label = "Id"
done_table = "done_songs"
connection = None
sql_engine = None
def open_db() -> engine.base.Connection:
global connection
if (not connection):
def get_db_engine() -> engine.base.Engine:
global sql_engine
if (not sql_engine):
print(current_app.config.get("DBCONNSTRING"))
engine = create_engine(current_app.config.get("DBCONNSTRING")) # type: ignore
connection = engine.connect()
# cur.execute('PRAGMA encoding = "UTF-8";')
return connection
sql_engine = create_engine(current_app.config.get("DBCONNSTRING")) # type: ignore
return sql_engine
def import_songs(song_csv):
print("Start importing Songs...")
df = pandas.read_csv(StringIO(song_csv), sep=';')
conn = open_db()
with get_db_engine().connect() as conn:
df.to_sql(song_table, conn, if_exists='replace',
index=False)
cur = conn.execute("SELECT Count(Id) FROM songs")
num_songs = cur.fetchone()[0] # type: ignore
# conn.close()
print("Imported songs ({} in Database)".format(num_songs))
return("Imported songs ({} in Database)".format(num_songs))
def create_entry_table():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute('CREATE TABLE IF NOT EXISTS '+entry_table +
' (ID INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, Song_Id INTEGER NOT NULL, Name VARCHAR(255), Client_Id VARCHAR(36), Transferred INTEGER DEFAULT 0)')
# conn.close()
def create_done_song_table():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute('CREATE TABLE IF NOT EXISTS '+done_table +
' (Song_Id INTEGER PRIMARY KEY NOT NULL, Plays INTEGER)')
# conn.close()
def create_song_table():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute("CREATE TABLE IF NOT EXISTS `"+song_table+"""` (
`Id` INTEGER,
`Title` TEXT,
@ -65,48 +60,45 @@ def create_song_table():
`Styles` TEXT,
`Languages` TEXT
)""")
# conn.close()
def create_list_view():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute("""CREATE OR REPLACE VIEW `Liste` AS
SELECT Name, Title, Artist, entries.Id AS entry_ID, songs.Id AS song_ID, entries.Transferred
FROM entries, songs
WHERE entries.Song_Id=songs.Id""")
# conn.close()
def create_done_song_view():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute("""CREATE OR REPLACE VIEW `Abspielliste` AS
SELECT CONCAT(Artist," - ", Title) AS Song, Plays AS Wiedergaben
FROM songs, done_songs
WHERE done_songs.Song_Id=songs.Id""")
# conn.close()
def get_list():
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute("SELECT * FROM Liste")
return cur.fetchall()
def get_played_list():
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute("SELECT * FROM Abspielliste")
return cur.fetchall()
def get_song_list():
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute(
"SELECT Artist || \" - \" || Title AS Song, Id FROM songs;")
return cur.fetchall()
def get_song_completions(input_string):
conn = open_db()
with get_db_engine().connect() as conn:
# Don't look, it burns...
prepared_string = "%{0}%".format(
input_string).upper() # "Test" -> "%TEST%"
@ -117,33 +109,24 @@ def get_song_completions(input_string):
def add_entry(name, song_id, client_id):
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute(
"INSERT INTO entries (Song_Id,Name,Client_Id) VALUES(%s,%s,%s);", (song_id, name, client_id))
# conn.close()
return
def add_sung_song(entry_id):
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute(
"""SELECT Song_Id FROM entries WHERE Id=%s""", (entry_id,))
song_id = cur.fetchone()[0] # type: ignore
conn.execute("""INSERT INTO done_songs (Song_Id, Plays) VALUES("""+str(song_id)+""",1) ON DUPLICATE KEY UPDATE Plays=Plays + 1;""")
# SQLite bullshittery
# conn.execute("""REPLACE INTO done_songs (Song_Id, Plays)
# VALUES("""+str(song_id)+""",
# COALESCE(
# (SELECT Plays FROM done_songs
# WHERE Song_Id="""+str(song_id)+"), 0) + 1)"
# )
delete_entry(entry_id)
# conn.close()
return True
def toggle_transferred(entry_id):
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute(
"SELECT Transferred FROM entries WHERE ID =%s", (entry_id,))
marked = cur.fetchall()[0][0]
@ -153,34 +136,31 @@ def toggle_transferred(entry_id):
else:
conn.execute(
"UPDATE entries SET Transferred = 0 WHERE ID =%s", (entry_id,))
# conn.close()
return True
def check_entry_quota(client_id):
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute(
"SELECT Count(*) FROM entries WHERE entries.Client_Id = %s", (client_id,))
return cur.fetchall()[0][0]
def check_queue_length():
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute("SELECT Count(*) FROM entries")
return cur.fetchall()[0][0]
def clear_played_songs():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute("DELETE FROM done_songs")
# conn.close()
return True
def delete_entry(id):
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute("DELETE FROM entries WHERE id=%s", (id,))
# conn.close()
return True
@ -189,16 +169,15 @@ def delete_entries(ids):
for x in ids:
idlist.append((x,))
try:
conn = open_db()
with get_db_engine().connect() as conn:
cur = conn.execute("DELETE FROM entries WHERE id=%s", idlist)
# conn.close()
return cur.rowcount
except Exception as error:
return -1
def delete_all_entries():
conn = open_db()
with get_db_engine().connect() as conn:
conn.execute("DELETE FROM entries")
# conn.close()
return True

View File

@ -1,10 +1,15 @@
version: "3.9"
secrets:
secrets:
file: ./secrets.yml
services:
karaoqueue:
image: "phillipkhne/karaoqueue:latest"
restart: always
ports:
- "127.0.0.1:8081:80"
- "127.0.0.1:8081:80" # Please put a reverse proxy in front of this
environment:
DEPLOYMENT_PLATFORM: Docker
DBSTRING: mysql://user:pass@host:3306/database
@ -16,8 +21,8 @@ services:
image: mariadb
restart: always
environment:
MARIADB_ROOT_PASSWORD: dpMAZj*Mc4%FZM!V
MARIADB_ROOT_PASSWORD: changeme!
MARIADB_ROOT_HOST: localhost
MARIADB_DATABASE: karaoqueue
MARIADB_USER: karaoqueue
MARIADB_PASSWORD: a5G@P*^tCW$$w@wE
MARIADB_PASSWORD: change

15
docker-compose.yml Normal file
View File

@ -0,0 +1,15 @@
# This Compose file is for development only. It is not intended for production use.
# It only starts auxiliary services, such as a database, that are required for the
# application to run. The application itself is started separately, using the
# command "python -m flask run" or your favorite IDE.
# Useful for attaching a debugger to the application.
version: "3.9"
services:
db:
image: mariadb
restart: always
env_file: .env.dev
ports:
- "3306:3306"