mirror of
https://github.com/PhoenixTwoFive/karaoqueue.git
synced 2025-05-18 18:41:48 +02:00
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:
parent
831166f38b
commit
b8220732ee
14
.env.dev
Normal file
14
.env.dev
Normal 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
3
.gitignore
vendored
@ -138,3 +138,6 @@ node_modules/
|
|||||||
|
|
||||||
# Version identification file
|
# Version identification file
|
||||||
.version
|
.version
|
||||||
|
|
||||||
|
# Docker secrets
|
||||||
|
secrets.yml
|
5
.vscode/launch.json
vendored
5
.vscode/launch.json
vendored
@ -15,8 +15,8 @@
|
|||||||
"FLASK_APP": "backend/app.py",
|
"FLASK_APP": "backend/app.py",
|
||||||
"FLASK_ENV": "development",
|
"FLASK_ENV": "development",
|
||||||
"FLASK_DEBUG": "1",
|
"FLASK_DEBUG": "1",
|
||||||
"DBSTRING": "mysql://devuser:devpw@127.0.0.1:3306/karaoqueue"
|
|
||||||
},
|
},
|
||||||
|
"envFile": "${workspaceFolder}/.env.dev",
|
||||||
"args": [
|
"args": [
|
||||||
"run",
|
"run",
|
||||||
"--no-debugger",
|
"--no-debugger",
|
||||||
@ -36,6 +36,7 @@
|
|||||||
"FLASK_ENV": "development",
|
"FLASK_ENV": "development",
|
||||||
"FLASK_DEBUG": "1"
|
"FLASK_DEBUG": "1"
|
||||||
},
|
},
|
||||||
|
"envFile": "${workspaceFolder}/.env.dev",
|
||||||
"args": [
|
"args": [
|
||||||
"run",
|
"run",
|
||||||
"--no-debugger"
|
"--no-debugger"
|
||||||
@ -54,6 +55,7 @@
|
|||||||
"FLASK_ENV": "development",
|
"FLASK_ENV": "development",
|
||||||
"FLASK_DEBUG": "1"
|
"FLASK_DEBUG": "1"
|
||||||
},
|
},
|
||||||
|
"envFile": "${workspaceFolder}/.env.dev",
|
||||||
"args": [
|
"args": [
|
||||||
"run",
|
"run",
|
||||||
"--no-debugger",
|
"--no-debugger",
|
||||||
@ -73,6 +75,7 @@
|
|||||||
"FLASK_ENV": "development",
|
"FLASK_ENV": "development",
|
||||||
"FLASK_DEBUG": "1"
|
"FLASK_DEBUG": "1"
|
||||||
},
|
},
|
||||||
|
"envFile": "${workspaceFolder}/.env.dev",
|
||||||
"args": [
|
"args": [
|
||||||
"run",
|
"run",
|
||||||
"--no-debugger",
|
"--no-debugger",
|
||||||
|
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@ -12,7 +12,7 @@
|
|||||||
{
|
{
|
||||||
"label": "mariadb",
|
"label": "mariadb",
|
||||||
"type": "shell",
|
"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,
|
"isBackground": true,
|
||||||
"activeOnStart": false
|
"activeOnStart": false
|
||||||
}
|
}
|
||||||
|
@ -12,48 +12,43 @@ entry_table = "entries"
|
|||||||
index_label = "Id"
|
index_label = "Id"
|
||||||
done_table = "done_songs"
|
done_table = "done_songs"
|
||||||
|
|
||||||
connection = None
|
sql_engine = None
|
||||||
|
|
||||||
|
|
||||||
def open_db() -> engine.base.Connection:
|
def get_db_engine() -> engine.base.Engine:
|
||||||
global connection
|
global sql_engine
|
||||||
if (not connection):
|
if (not sql_engine):
|
||||||
print(current_app.config.get("DBCONNSTRING"))
|
print(current_app.config.get("DBCONNSTRING"))
|
||||||
engine = create_engine(current_app.config.get("DBCONNSTRING")) # type: ignore
|
sql_engine = create_engine(current_app.config.get("DBCONNSTRING")) # type: ignore
|
||||||
connection = engine.connect()
|
return sql_engine
|
||||||
# cur.execute('PRAGMA encoding = "UTF-8";')
|
|
||||||
return connection
|
|
||||||
|
|
||||||
|
|
||||||
def import_songs(song_csv):
|
def import_songs(song_csv):
|
||||||
print("Start importing Songs...")
|
print("Start importing Songs...")
|
||||||
df = pandas.read_csv(StringIO(song_csv), sep=';')
|
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',
|
df.to_sql(song_table, conn, if_exists='replace',
|
||||||
index=False)
|
index=False)
|
||||||
cur = conn.execute("SELECT Count(Id) FROM songs")
|
cur = conn.execute("SELECT Count(Id) FROM songs")
|
||||||
num_songs = cur.fetchone()[0] # type: ignore
|
num_songs = cur.fetchone()[0] # type: ignore
|
||||||
# conn.close()
|
|
||||||
print("Imported songs ({} in Database)".format(num_songs))
|
print("Imported songs ({} in Database)".format(num_songs))
|
||||||
return("Imported songs ({} in Database)".format(num_songs))
|
return("Imported songs ({} in Database)".format(num_songs))
|
||||||
|
|
||||||
|
|
||||||
def create_entry_table():
|
def create_entry_table():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute('CREATE TABLE IF NOT EXISTS '+entry_table +
|
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)')
|
' (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():
|
def create_done_song_table():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute('CREATE TABLE IF NOT EXISTS '+done_table +
|
conn.execute('CREATE TABLE IF NOT EXISTS '+done_table +
|
||||||
' (Song_Id INTEGER PRIMARY KEY NOT NULL, Plays INTEGER)')
|
' (Song_Id INTEGER PRIMARY KEY NOT NULL, Plays INTEGER)')
|
||||||
# conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
def create_song_table():
|
def create_song_table():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute("CREATE TABLE IF NOT EXISTS `"+song_table+"""` (
|
conn.execute("CREATE TABLE IF NOT EXISTS `"+song_table+"""` (
|
||||||
`Id` INTEGER,
|
`Id` INTEGER,
|
||||||
`Title` TEXT,
|
`Title` TEXT,
|
||||||
@ -65,48 +60,45 @@ def create_song_table():
|
|||||||
`Styles` TEXT,
|
`Styles` TEXT,
|
||||||
`Languages` TEXT
|
`Languages` TEXT
|
||||||
)""")
|
)""")
|
||||||
# conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
def create_list_view():
|
def create_list_view():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute("""CREATE OR REPLACE VIEW `Liste` AS
|
conn.execute("""CREATE OR REPLACE VIEW `Liste` AS
|
||||||
SELECT Name, Title, Artist, entries.Id AS entry_ID, songs.Id AS song_ID, entries.Transferred
|
SELECT Name, Title, Artist, entries.Id AS entry_ID, songs.Id AS song_ID, entries.Transferred
|
||||||
FROM entries, songs
|
FROM entries, songs
|
||||||
WHERE entries.Song_Id=songs.Id""")
|
WHERE entries.Song_Id=songs.Id""")
|
||||||
# conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
def create_done_song_view():
|
def create_done_song_view():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute("""CREATE OR REPLACE VIEW `Abspielliste` AS
|
conn.execute("""CREATE OR REPLACE VIEW `Abspielliste` AS
|
||||||
SELECT CONCAT(Artist," - ", Title) AS Song, Plays AS Wiedergaben
|
SELECT CONCAT(Artist," - ", Title) AS Song, Plays AS Wiedergaben
|
||||||
FROM songs, done_songs
|
FROM songs, done_songs
|
||||||
WHERE done_songs.Song_Id=songs.Id""")
|
WHERE done_songs.Song_Id=songs.Id""")
|
||||||
# conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
def get_list():
|
def get_list():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute("SELECT * FROM Liste")
|
cur = conn.execute("SELECT * FROM Liste")
|
||||||
return cur.fetchall()
|
return cur.fetchall()
|
||||||
|
|
||||||
|
|
||||||
def get_played_list():
|
def get_played_list():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute("SELECT * FROM Abspielliste")
|
cur = conn.execute("SELECT * FROM Abspielliste")
|
||||||
return cur.fetchall()
|
return cur.fetchall()
|
||||||
|
|
||||||
|
|
||||||
def get_song_list():
|
def get_song_list():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute(
|
cur = conn.execute(
|
||||||
"SELECT Artist || \" - \" || Title AS Song, Id FROM songs;")
|
"SELECT Artist || \" - \" || Title AS Song, Id FROM songs;")
|
||||||
return cur.fetchall()
|
return cur.fetchall()
|
||||||
|
|
||||||
|
|
||||||
def get_song_completions(input_string):
|
def get_song_completions(input_string):
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
# Don't look, it burns...
|
# Don't look, it burns...
|
||||||
prepared_string = "%{0}%".format(
|
prepared_string = "%{0}%".format(
|
||||||
input_string).upper() # "Test" -> "%TEST%"
|
input_string).upper() # "Test" -> "%TEST%"
|
||||||
@ -117,33 +109,24 @@ def get_song_completions(input_string):
|
|||||||
|
|
||||||
|
|
||||||
def add_entry(name, song_id, client_id):
|
def add_entry(name, song_id, client_id):
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"INSERT INTO entries (Song_Id,Name,Client_Id) VALUES(%s,%s,%s);", (song_id, name, client_id))
|
"INSERT INTO entries (Song_Id,Name,Client_Id) VALUES(%s,%s,%s);", (song_id, name, client_id))
|
||||||
# conn.close()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def add_sung_song(entry_id):
|
def add_sung_song(entry_id):
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute(
|
cur = conn.execute(
|
||||||
"""SELECT Song_Id FROM entries WHERE Id=%s""", (entry_id,))
|
"""SELECT Song_Id FROM entries WHERE Id=%s""", (entry_id,))
|
||||||
song_id = cur.fetchone()[0] # type: ignore
|
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;""")
|
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)
|
delete_entry(entry_id)
|
||||||
# conn.close()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def toggle_transferred(entry_id):
|
def toggle_transferred(entry_id):
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute(
|
cur = conn.execute(
|
||||||
"SELECT Transferred FROM entries WHERE ID =%s", (entry_id,))
|
"SELECT Transferred FROM entries WHERE ID =%s", (entry_id,))
|
||||||
marked = cur.fetchall()[0][0]
|
marked = cur.fetchall()[0][0]
|
||||||
@ -153,34 +136,31 @@ def toggle_transferred(entry_id):
|
|||||||
else:
|
else:
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"UPDATE entries SET Transferred = 0 WHERE ID =%s", (entry_id,))
|
"UPDATE entries SET Transferred = 0 WHERE ID =%s", (entry_id,))
|
||||||
# conn.close()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_entry_quota(client_id):
|
def check_entry_quota(client_id):
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute(
|
cur = conn.execute(
|
||||||
"SELECT Count(*) FROM entries WHERE entries.Client_Id = %s", (client_id,))
|
"SELECT Count(*) FROM entries WHERE entries.Client_Id = %s", (client_id,))
|
||||||
return cur.fetchall()[0][0]
|
return cur.fetchall()[0][0]
|
||||||
|
|
||||||
|
|
||||||
def check_queue_length():
|
def check_queue_length():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute("SELECT Count(*) FROM entries")
|
cur = conn.execute("SELECT Count(*) FROM entries")
|
||||||
return cur.fetchall()[0][0]
|
return cur.fetchall()[0][0]
|
||||||
|
|
||||||
|
|
||||||
def clear_played_songs():
|
def clear_played_songs():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute("DELETE FROM done_songs")
|
conn.execute("DELETE FROM done_songs")
|
||||||
# conn.close()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def delete_entry(id):
|
def delete_entry(id):
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute("DELETE FROM entries WHERE id=%s", (id,))
|
conn.execute("DELETE FROM entries WHERE id=%s", (id,))
|
||||||
# conn.close()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -189,16 +169,15 @@ def delete_entries(ids):
|
|||||||
for x in ids:
|
for x in ids:
|
||||||
idlist.append((x,))
|
idlist.append((x,))
|
||||||
try:
|
try:
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
cur = conn.execute("DELETE FROM entries WHERE id=%s", idlist)
|
cur = conn.execute("DELETE FROM entries WHERE id=%s", idlist)
|
||||||
# conn.close()
|
|
||||||
return cur.rowcount
|
return cur.rowcount
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def delete_all_entries():
|
def delete_all_entries():
|
||||||
conn = open_db()
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute("DELETE FROM entries")
|
conn.execute("DELETE FROM entries")
|
||||||
# conn.close()
|
|
||||||
return True
|
return True
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
version: "3.9"
|
version: "3.9"
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
secrets:
|
||||||
|
file: ./secrets.yml
|
||||||
|
|
||||||
services:
|
services:
|
||||||
karaoqueue:
|
karaoqueue:
|
||||||
image: "phillipkhne/karaoqueue:latest"
|
image: "phillipkhne/karaoqueue:latest"
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:8081:80"
|
- "127.0.0.1:8081:80" # Please put a reverse proxy in front of this
|
||||||
environment:
|
environment:
|
||||||
DEPLOYMENT_PLATFORM: Docker
|
DEPLOYMENT_PLATFORM: Docker
|
||||||
DBSTRING: mysql://user:pass@host:3306/database
|
DBSTRING: mysql://user:pass@host:3306/database
|
||||||
@ -16,8 +21,8 @@ services:
|
|||||||
image: mariadb
|
image: mariadb
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MARIADB_ROOT_PASSWORD: dpMAZj*Mc4%FZM!V
|
MARIADB_ROOT_PASSWORD: changeme!
|
||||||
MARIADB_ROOT_HOST: localhost
|
MARIADB_ROOT_HOST: localhost
|
||||||
MARIADB_DATABASE: karaoqueue
|
MARIADB_DATABASE: karaoqueue
|
||||||
MARIADB_USER: karaoqueue
|
MARIADB_USER: karaoqueue
|
||||||
MARIADB_PASSWORD: a5G@P*^tCW$$w@wE
|
MARIADB_PASSWORD: change
|
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal 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"
|
Loading…
x
Reference in New Issue
Block a user