mirror of
				https://github.com/PhoenixTwoFive/karaoqueue.git
				synced 2025-11-04 09:25:11 +01:00 
			
		
		
		
	
							
								
								
									
										36
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					# EditorConfig is awesome: https://EditorConfig.org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# top-most EditorConfig file
 | 
				
			||||||
 | 
					root = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*]
 | 
				
			||||||
 | 
					indent_style = space
 | 
				
			||||||
 | 
					indent_size = 4
 | 
				
			||||||
 | 
					end_of_line = lf
 | 
				
			||||||
 | 
					charset = utf-8
 | 
				
			||||||
 | 
					trim_trailing_whitespace = false
 | 
				
			||||||
 | 
					insert_final_newline = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.md]
 | 
				
			||||||
 | 
					trim_trailing_whitespace = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.py]
 | 
				
			||||||
 | 
					indent_size = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.js]
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.html]
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.css]
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.scss]
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.yaml]
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.yml]
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
							
								
								
									
										23
									
								
								.github/workflows/lint.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.github/workflows/lint.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					name: Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on: [push, pull_request]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  flake8_py3:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - name: Setup Python
 | 
				
			||||||
 | 
					        uses: actions/setup-python@v4.6.0
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          python-version: '3.10'
 | 
				
			||||||
 | 
					          architecture: x64
 | 
				
			||||||
 | 
					      - name: Checkout PyTorch
 | 
				
			||||||
 | 
					        uses: actions/checkout@master
 | 
				
			||||||
 | 
					      - name: Install flake8
 | 
				
			||||||
 | 
					        run: pip install flake8
 | 
				
			||||||
 | 
					      - name: Run flake8
 | 
				
			||||||
 | 
					        uses: suo/flake8-github-action@releases/v1
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          checkName: 'flake8_py3'   # NOTE: this needs to be the same as the job name
 | 
				
			||||||
 | 
					        env:
 | 
				
			||||||
 | 
					          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
				
			||||||
							
								
								
									
										13
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,14 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "python.pythonPath": "/usr/bin/python"
 | 
					    "python.pythonPath": "/usr/bin/python",
 | 
				
			||||||
 | 
					    "python.testing.unittestArgs": [
 | 
				
			||||||
 | 
					        "-v",
 | 
				
			||||||
 | 
					        "-s",
 | 
				
			||||||
 | 
					        "./backend/tests",
 | 
				
			||||||
 | 
					        "-p",
 | 
				
			||||||
 | 
					        "*test.py"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "python.testing.pytestEnabled": false,
 | 
				
			||||||
 | 
					    "python.testing.unittestEnabled": true,
 | 
				
			||||||
 | 
					    "python.linting.pylintEnabled": false,
 | 
				
			||||||
 | 
					    "python.linting.flake8Enabled": true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
from flask import Flask, render_template, abort, request, redirect, send_from_directory, jsonify
 | 
					from flask import Flask, render_template, abort, request, redirect, send_from_directory, jsonify
 | 
				
			||||||
from flask.wrappers import Request, Response
 | 
					from flask.wrappers import Response
 | 
				
			||||||
import helpers
 | 
					import helpers
 | 
				
			||||||
import database
 | 
					import database
 | 
				
			||||||
import data_adapters
 | 
					import data_adapters
 | 
				
			||||||
@@ -12,6 +12,7 @@ app = Flask(__name__, static_url_path='/static')
 | 
				
			|||||||
basic_auth = BasicAuth(app)
 | 
					basic_auth = BasicAuth(app)
 | 
				
			||||||
accept_entries = True
 | 
					accept_entries = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route("/")
 | 
					@app.route("/")
 | 
				
			||||||
def home():
 | 
					def home():
 | 
				
			||||||
    if basic_auth.authenticate():
 | 
					    if basic_auth.authenticate():
 | 
				
			||||||
@@ -95,7 +96,7 @@ def settings_post():
 | 
				
			|||||||
    else:
 | 
					    else:
 | 
				
			||||||
        abort(400)
 | 
					        abort(400)
 | 
				
			||||||
    if theme is not None and theme in helpers.get_themes():
 | 
					    if theme is not None and theme in helpers.get_themes():
 | 
				
			||||||
        helpers.set_theme(app,theme)
 | 
					        helpers.set_theme(app, theme)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        abort(400)
 | 
					        abort(400)
 | 
				
			||||||
    if username != "" and username != app.config['BASIC_AUTH_USERNAME']:
 | 
					    if username != "" and username != app.config['BASIC_AUTH_USERNAME']:
 | 
				
			||||||
@@ -143,7 +144,7 @@ def update_songs():
 | 
				
			|||||||
    return Response('{"status": "%s" }' % status, mimetype='text/json')
 | 
					    return Response('{"status": "%s" }' % status, mimetype='text/json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route("/api/songs/compl") # type: ignore
 | 
					@app.route("/api/songs/compl")  # type: ignore
 | 
				
			||||||
@nocache
 | 
					@nocache
 | 
				
			||||||
def get_song_completions(input_string=""):
 | 
					def get_song_completions(input_string=""):
 | 
				
			||||||
    input_string = request.args.get('search', input_string)
 | 
					    input_string = request.args.get('search', input_string)
 | 
				
			||||||
@@ -176,7 +177,7 @@ def delete_entries():
 | 
				
			|||||||
        return
 | 
					        return
 | 
				
			||||||
    updates = database.delete_entries(request.json)
 | 
					    updates = database.delete_entries(request.json)
 | 
				
			||||||
    if updates >= 0:
 | 
					    if updates >= 0:
 | 
				
			||||||
        return Response('{"status": "OK", "updates": '+str(updates)+'}', mimetype='text/json')
 | 
					        return Response('{"status": "OK", "updates": ' + str(updates) + '}', mimetype='text/json')
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return Response('{"status": "FAIL"}', mimetype='text/json', status=400)
 | 
					        return Response('{"status": "FAIL"}', mimetype='text/json', status=400)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -190,6 +191,7 @@ def mark_sung(entry_id):
 | 
				
			|||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return Response('{"status": "FAIL"}', mimetype='text/json')
 | 
					        return Response('{"status": "FAIL"}', mimetype='text/json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route("/api/entries/mark_transferred/<entry_id>")
 | 
					@app.route("/api/entries/mark_transferred/<entry_id>")
 | 
				
			||||||
@nocache
 | 
					@nocache
 | 
				
			||||||
@basic_auth.required
 | 
					@basic_auth.required
 | 
				
			||||||
@@ -205,7 +207,7 @@ def mark_transferred(entry_id):
 | 
				
			|||||||
@basic_auth.required
 | 
					@basic_auth.required
 | 
				
			||||||
def set_accept_entries(value):
 | 
					def set_accept_entries(value):
 | 
				
			||||||
    if (value == '0' or value == '1'):
 | 
					    if (value == '0' or value == '1'):
 | 
				
			||||||
        helpers.set_accept_entries(app,bool(int(value)))
 | 
					        helpers.set_accept_entries(app, bool(int(value)))
 | 
				
			||||||
        return Response('{"status": "OK"}', mimetype='text/json')
 | 
					        return Response('{"status": "OK"}', mimetype='text/json')
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return Response('{"status": "FAIL"}', mimetype='text/json', status=400)
 | 
					        return Response('{"status": "FAIL"}', mimetype='text/json', status=400)
 | 
				
			||||||
@@ -215,7 +217,7 @@ def set_accept_entries(value):
 | 
				
			|||||||
@nocache
 | 
					@nocache
 | 
				
			||||||
def get_accept_entries():
 | 
					def get_accept_entries():
 | 
				
			||||||
    accept_entries = helpers.get_accept_entries(app)
 | 
					    accept_entries = helpers.get_accept_entries(app)
 | 
				
			||||||
    return Response('{"status": "OK", "value": '+str(int(accept_entries))+'}', mimetype='text/json')
 | 
					    return Response('{"status": "OK", "value": ' + str(int(accept_entries)) + '}', mimetype='text/json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route("/api/played/clear")
 | 
					@app.route("/api/played/clear")
 | 
				
			||||||
@@ -257,17 +259,17 @@ def activate_job():
 | 
				
			|||||||
    helpers.setup_config(app)
 | 
					    helpers.setup_config(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@app.after_request
 | 
					@app.after_request
 | 
				
			||||||
def add_header(response):
 | 
					def add_header(response):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Add headers to both force latest IE rendering engine or Chrome Frame,
 | 
					    Add headers to both force latest IE rendering engine or Chrome Frame,
 | 
				
			||||||
    and also to cache the rendered page for 10 minutes.
 | 
					    and also to cache the rendered page for 10 minutes.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    if not 'Cache-Control' in response.headers:
 | 
					    if 'Cache-Control' not in response.headers:
 | 
				
			||||||
        response.headers['Cache-Control'] = 'private, max-age=600, no-cache, must-revalidate'
 | 
					        response.headers['Cache-Control'] = 'private, max-age=600, no-cache, must-revalidate'
 | 
				
			||||||
    return response
 | 
					    return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.context_processor
 | 
					@app.context_processor
 | 
				
			||||||
def inject_version():
 | 
					def inject_version():
 | 
				
			||||||
    return dict(karaoqueue_version=app.config['VERSION'])
 | 
					    return dict(karaoqueue_version=app.config['VERSION'])
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
def dict_from_rows(rows):
 | 
					def dict_from_rows(rows):
 | 
				
			||||||
    outlist=[]
 | 
					    outlist = []
 | 
				
			||||||
    for row in rows:
 | 
					    for row in rows:
 | 
				
			||||||
        outlist.append(dict(row._mapping))
 | 
					        outlist.append(dict(row._mapping))
 | 
				
			||||||
    return outlist
 | 
					    return outlist
 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
# -*- coding: utf_8 -*-
 | 
					# -*- coding: utf_8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from email.mime import base
 | 
					 | 
				
			||||||
from MySQLdb import Connection
 | 
					 | 
				
			||||||
from sqlalchemy import create_engine, engine, text
 | 
					from sqlalchemy import create_engine, engine, text
 | 
				
			||||||
import pandas
 | 
					import pandas
 | 
				
			||||||
from io import StringIO
 | 
					from io import StringIO
 | 
				
			||||||
@@ -209,7 +207,7 @@ def delete_entries(ids):
 | 
				
			|||||||
                               "par_id": idlist})
 | 
					                               "par_id": idlist})
 | 
				
			||||||
            conn.commit()
 | 
					            conn.commit()
 | 
				
			||||||
        return cur.rowcount
 | 
					        return cur.rowcount
 | 
				
			||||||
    except Exception as error:
 | 
					    except Exception:
 | 
				
			||||||
        return -1
 | 
					        return -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -227,7 +225,7 @@ def get_config(key: str) -> str:
 | 
				
			|||||||
                text("SELECT `Value` FROM config WHERE `Key`= :par_key"), {"par_key": key})  # type: ignore
 | 
					                text("SELECT `Value` FROM config WHERE `Key`= :par_key"), {"par_key": key})  # type: ignore
 | 
				
			||||||
            conn.commit()
 | 
					            conn.commit()
 | 
				
			||||||
        return cur.fetchall()[0][0]
 | 
					        return cur.fetchall()[0][0]
 | 
				
			||||||
    except IndexError as error:
 | 
					    except IndexError:
 | 
				
			||||||
        return ""
 | 
					        return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -256,7 +254,7 @@ def check_config_table() -> bool:
 | 
				
			|||||||
        if conn.dialect.has_table(conn, 'config'):
 | 
					        if conn.dialect.has_table(conn, 'config'):
 | 
				
			||||||
            # type: ignore
 | 
					            # type: ignore
 | 
				
			||||||
            # type: ignore
 | 
					            # type: ignore
 | 
				
			||||||
            if (conn.execute(text("SELECT COUNT(*) FROM config")).fetchone()[0] > 0): # type: ignore
 | 
					            if (conn.execute(text("SELECT COUNT(*) FROM config")).fetchone()[0] > 0):  # type: ignore
 | 
				
			||||||
                return True
 | 
					                return True
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                return False
 | 
					                return False
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
import requests
 | 
					import requests
 | 
				
			||||||
from bs4 import BeautifulSoup
 | 
					from bs4 import BeautifulSoup
 | 
				
			||||||
import json
 | 
					 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
from flask import make_response, Flask
 | 
					from flask import make_response, Flask
 | 
				
			||||||
@@ -8,6 +7,7 @@ from functools import wraps, update_wrapper
 | 
				
			|||||||
from datetime import datetime
 | 
					from datetime import datetime
 | 
				
			||||||
import database
 | 
					import database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_catalog_url():
 | 
					def get_catalog_url():
 | 
				
			||||||
    r = requests.get('https://www.karafun.de/karaoke-song-list.html')
 | 
					    r = requests.get('https://www.karafun.de/karaoke-song-list.html')
 | 
				
			||||||
    soup = BeautifulSoup(r.content, 'html.parser')
 | 
					    soup = BeautifulSoup(r.content, 'html.parser')
 | 
				
			||||||
@@ -69,13 +69,15 @@ def load_dbconfig(app: Flask):
 | 
				
			|||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    app.config['DBCONNSTRING'] = ""
 | 
					                    app.config['DBCONNSTRING'] = ""
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            exit("No database connection string found. Cannot continue. Please set the environment variable DBSTRING or create a file .dbconn in the root directory of the project.")
 | 
					            exit("""No database connection string found. Cannot continue.
 | 
				
			||||||
 | 
					                 Please set the environment variable DBSTRING or
 | 
				
			||||||
 | 
					                 create a file .dbconn in the root directory of the project.""")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Check if config exists in DB, if not, create it.
 | 
					# Check if config exists in DB, if not, create it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup_config(app: Flask):
 | 
					def setup_config(app: Flask):
 | 
				
			||||||
    if check_config_exists() == False:
 | 
					    if check_config_exists() is False:
 | 
				
			||||||
        print("No config found, creating new config")
 | 
					        print("No config found, creating new config")
 | 
				
			||||||
        initial_username = os.environ.get("INITIAL_USERNAME")
 | 
					        initial_username = os.environ.get("INITIAL_USERNAME")
 | 
				
			||||||
        initial_password = os.environ.get("INITIAL_PASSWORD")
 | 
					        initial_password = os.environ.get("INITIAL_PASSWORD")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
from app import app
 | 
					from app import app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
        app.run()
 | 
					    app.run()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user