Remove Flask-based backend

This commit is contained in:
Phillip Kühne 2020-05-26 16:07:29 +02:00
parent a8ded945e2
commit 27eb10d222
36 changed files with 0 additions and 1521 deletions

View File

@ -1,8 +0,0 @@
def dict_from_row(row):
return dict(zip(row.keys(), row))
def dict_from_rows(rows):
outlist=[]
for row in rows:
outlist.append(dict_from_row(row))
return outlist

View File

@ -1,174 +0,0 @@
# -*- coding: utf_8 -*-
import sqlite3
import pandas
import pymongo
from bson.regex import Regex
from io import StringIO
db_name = "karaoqueue"
song_collection_name = "songs"
entry_collection_name = "entries"
playback_collection_name = "played"
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
def open_db_client():
mongoClient = pymongo.MongoClient("mongodb://localhost:27017")
return mongoClient
def import_songs(song_csv):
print("Start importing Songs...")
client = open_db_client()
db = client[db_name]
if not song_collection_name in db.list_collection_names():
songsCollection = db[song_collection_name]
songsCollection.create_index("karafun_id", unique=True)
songsCollection.create_index([("title","text"),("artist","text")])
else:
songsCollection = db[song_collection_name]
def f(x): return (x.split(","))
df = pandas.read_csv(StringIO(song_csv), sep=';',
engine='python', parse_dates=["Date Added"])
df.Styles = df.Styles.apply(f, convert_dtype=True)
df.Languages = df.Languages.apply(f, convert_dtype=True)
df.Duo = df.Duo.astype('bool')
df.Explicit = df.Explicit.astype('bool')
df.columns = map(str.lower, df.columns)
df.rename(columns={'id': 'karafun_id'}, inplace=True)
num_songs = df.shape[0]
song_dict = df.to_dict('records')
try:
songsCollection.insert_many(song_dict)
except pymongo.errors.BulkWriteError as bwe:
return(bwe.details)
finally:
client.close()
print("Imported songs ({} in Database)".format(num_songs))
return("Imported songs ({} in Database)".format(num_songs))
def get_list():
client = open_db_client()
db = client[db_name]
collection = db[entry_collection_name]
query = {}
cursor = collection.find()
result = {}
try:
for doc in cursor:
result += doc
finally:
client.close()
def get_played_list():
conn = open_db_client()
cur = conn.cursor()
cur.execute("SELECT * FROM Abspielliste")
return cur.fetchall()
def get_song_list():
conn =open_db_client()
cur = conn.cursor()
cur.execute("SELECT Artist || \" - \" || Title AS Song, Id FROM songs;")
return cur.fetchall()
def get_song_completions(input_string):
client = open_db_client()
db = client[db_name]
collection = db[song_collection_name]
cursor = collection.find({'$text': {'$search': input_string}}, {'_txtscr': {'$meta': 'textScore'}}, limit=30).sort([('_txtscr', {'$meta': 'textScore'})])
result = []
try:
for doc in cursor:
tmpdoc = doc
tmpdoc["_id"] = str(tmpdoc["_id"])
result.append(doc)
finally:
client.close()
# conn = open_db_client()
# conn.row_factory = dict_factory
# cur = conn.cursor()
# # Don't look, it burns...
# prepared_string = "%{0}%".format(input_string).upper() # "Test" -> "%TEST%"
# print(prepared_string)
# cur.execute(
# "SELECT * FROM songs WHERE REPLACE(REPLACE(REPLACE(REPLACE(UPPER( Title ),'ö','Ö'),'ü','Ü'),'ä','Ä'),'ß','ẞ') LIKE (?) LIMIT 20;", (prepared_string,))
print(result)
return result
def add_entry(name,song_id):
conn = open_db_client()
cur = conn.cursor()
cur.execute(
"INSERT INTO entries (Song_Id,Name) VALUES(?,?);", (song_id,name))
conn.commit()
conn.close()
return
def add_sung_song(entry_id):
conn = open_db_client()
cur = conn.cursor()
cur.execute("""SELECT Song_Id FROM entries WHERE Id=?""",(entry_id,))
song_id = cur.fetchone()[0]
cur.execute("""INSERT OR 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)"
)
conn.commit()
delete_entry(entry_id)
conn.close()
return True
def clear_played_songs():
conn = open_db_client()
cur = conn.cursor()
cur.execute("DELETE FROM done_songs")
conn.commit()
conn.close()
return True
def delete_entry(id):
conn = open_db_client()
cur = conn.cursor()
cur.execute("DELETE FROM entries WHERE id=?",(id,))
conn.commit()
conn.close()
return True
def delete_entries(ids):
idlist = []
for x in ids:
idlist.append( (x,) )
try:
conn = open_db_client()
cur = conn.cursor()
cur.executemany("DELETE FROM entries WHERE id=?", idlist)
conn.commit()
conn.close()
return cur.rowcount
except sqlite3.Error as error:
return -1
def delete_all_entries():
conn = open_db_client()
cur = conn.cursor()
cur.execute("DELETE FROM entries")
conn.commit()
conn.close()
return True

View File

@ -1,48 +0,0 @@
import requests
from bs4 import BeautifulSoup
import json
import os
import datetime
import bson.objectid
data_directory = "data"
config_file = data_directory+"/config.json"
def create_data_directory():
if not os.path.exists(data_directory):
os.makedirs(data_directory)
def get_catalog_url():
r = requests.get('https://www.karafun.de/karaoke-song-list.html')
soup = BeautifulSoup(r.content, 'html.parser')
url = soup.findAll('a', href=True, text='Available in CSV format')[0]['href']
return url
def get_songs(url):
r = requests.get(url)
return r.text
def check_config_exists():
return os.path.isfile(config_file)
def setup_config(app):
if check_config_exists():
config = json.load(open(config_file))
with open(config_file, 'r') as handle:
config = json.load(handle)
print("Loaded existing config")
else:
config = {'username': 'admin', 'password': 'changeme'}
with open(config_file, 'w') as handle:
json.dump(config, handle, indent=4, sort_keys=True)
print("Wrote new config")
app.config['BASIC_AUTH_USERNAME'] = config['username']
app.config['BASIC_AUTH_PASSWORD'] = config['password']
def serialization_helper(obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
elif isinstance(obj, bson.objectid.ObjectId):
return str(obj)

View File

@ -1,155 +0,0 @@
from flask import Flask, render_template, Response, abort, request, redirect
from flask_cors import CORS
import helpers
import database
import data_adapters
import os, errno
import json
from flask_basicauth import BasicAuth
from pprint import pprint
app = Flask(__name__, static_url_path='/static')
CORS(app)
basic_auth = BasicAuth(app)
accept_entries = False
@app.route("/")
def home():
if basic_auth.authenticate():
return render_template('main_admin.html', list=database.get_list(), auth=basic_auth.authenticate())
else:
return render_template('main.html', list=database.get_list(), auth=basic_auth.authenticate())
@app.route('/api/enqueue', methods=['POST'])
def enqueue():
if accept_entries:
if not request.json:
print(request.data)
abort(400)
name = request.json['name']
song_id = request.json['id']
database.add_entry(name, song_id)
return Response('{"status":"OK"}', mimetype='text/json')
else:
return Response('{"status":"Currently not accepting entries"}', mimetype='text/json',status=423)
@app.route("/list")
def songlist():
return render_template('songlist.html', list=database.get_song_list(), auth=basic_auth.authenticate())
@app.route("/api/queue")
def queue_json():
list = data_adapters.dict_from_rows(database.get_list())
return Response(json.dumps(list, ensure_ascii=False).encode('utf-8'), mimetype='text/json')
@app.route("/plays")
@basic_auth.required
def played_list():
return render_template('played_list.html', list=database.get_played_list(), auth=basic_auth.authenticate())
@app.route("/api/songs")
def songs():
list = database.get_song_list()
return Response(json.dumps(list, ensure_ascii=False).encode('utf-8'), mimetype='text/json')
@app.route("/api/songs/update")
@basic_auth.required
def update_songs():
# database.delete_all_entries()
status = database.import_songs(helpers.get_songs(helpers.get_catalog_url()))
print(status)
return Response('{"status": "%s" }' % status, mimetype='text/json')
@app.route("/api/songs/compl")
def get_song_completions(input_string=""):
input_string = request.args.get('search',input_string)
if input_string!="":
print(input_string)
list = database.get_song_completions(input_string=input_string)
return Response(json.dumps(list, default=helpers.serialization_helper).encode('utf-8'), mimetype='application/json')
# return Response(json.dumps(list, ensure_ascii=False).encode('utf-8'), mimetype='text/json')
else:
return 400
@app.route("/api/entries/delete/<entry_id>")
@basic_auth.required
def delete_entry(entry_id):
if database.delete_entry(entry_id):
return Response('{"status": "OK"}', mimetype='text/json')
else:
return Response('{"status": "FAIL"}', mimetype='text/json')
@app.route("/api/entries/delete", methods=['POST'])
@basic_auth.required
def delete_entries():
if not request.json:
print(request.data)
abort(400)
return
updates = database.delete_entries(request.json)
if updates >= 0:
return Response('{"status": "OK", "updates": '+str(updates)+'}', mimetype='text/json')
else:
return Response('{"status": "FAIL"}', mimetype='text/json', status=400)
@app.route("/api/entries/mark_sung/<entry_id>")
@basic_auth.required
def mark_sung(entry_id):
if database.add_sung_song(entry_id):
return Response('{"status": "OK"}', mimetype='text/json')
else:
return Response('{"status": "FAIL"}', mimetype='text/json')
@app.route("/api/entries/accept/<value>")
@basic_auth.required
def set_accept_entries(value):
global accept_entries
if (value=='0' or value=='1'):
accept_entries=bool(int(value))
return Response('{"status": "OK"}', mimetype='text/json')
else:
return Response('{"status": "FAIL"}', mimetype='text/json', status=400)
@app.route("/api/entries/accept")
def get_accept_entries():
global accept_entries
return Response('{"status": "OK", "value": '+str(int(accept_entries))+'}', mimetype='text/json')
@app.route("/api/played/clear")
@basic_auth.required
def clear_played_songs():
if database.clear_played_songs():
return Response('{"status": "OK"}', mimetype='text/json')
else:
return Response('{"status": "FAIL"}', mimetype='text/json')
@app.route("/api/entries/delete_all")
@basic_auth.required
def delete_all_entries():
if database.delete_all_entries():
return Response('{"status": "OK"}', mimetype='text/json')
else:
return Response('{"status": "FAIL"}', mimetype='text/json')
@app.route("/login")
@basic_auth.required
def admin():
return redirect("/", code=303)
@app.before_first_request
def activate_job():
helpers.create_data_directory()
helpers.setup_config(app)
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')

View File

@ -1,77 +0,0 @@
body {
padding-top: 5rem;
}
html, body {
height: 100%;
}
.site {
height: auto;
min-height: 100%;
}
main {
padding-bottom: 60px; /* Höhe des Footers */
}
.footer {
margin-top: -60px;
width: 100%;
height: 60px;
/* Set the fixed height of the footer here */
/*line-height: 60px; /* Vertically center the text there */
background-color: #f5f5f5;
}
.topbutton {
width: 100%;
}
table td {
overflow: hidden;
text-overflow: ellipsis;
}
table.entries tbody tr:first-child {
background-color: #007bff80;
font-weight: 600;
}
table.entries tbody tr:nth-child(2) {
background-color: #007bff40;
font-weight: 500;
}
table.entries tbody tr:nth-child(3) {
background-color: #007bff20;
font-weight: 400;
}
table.entries tbody tr:nth-child(4) {
background-color: #007bff10;
}
table td:first-child {
max-width: 200px !important;
}
@media (min-width: 768px) {
.topbutton {
width: auto;
}
}
@media print {
body {
font-size: 1.3em;
}
.footer {
display: none !important;
}
.admincontrols {
display: none;
}
}

View File

@ -1,16 +0,0 @@
{
"name": "KaraoQueue",
"short_name": "KaraoQueue",
"start_url": "/",
"display": "standalone",
"background_color": "#343a40",
"description": "Eine Karaokewarteliste.",
"icons": [{
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}],
"related_applications": [{
"platform": "Web"
}]
}

View File

@ -1,112 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<link rel="manifest" href="/static/manifest.webmanifest">
<title>{% block title %}{% endblock %} - KaraoQueue</title>
<!-- Bootstrap-Tables -->
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.15.3/dist/bootstrap-table.min.css">
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<!-- Custom styles for this template -->
<link href="static/css/style.css" rel="stylesheet">
<!-- Fontawesome Icons -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css"
integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
<!-- Bootstraptoggle -->
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="/">KaraoQueue</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="/">Warteliste</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/list">Songsuche</a>
</li>
{% if auth %}
<li class="nav-item">
<a class="nav-link" href="/plays">Abspielliste</a>
</li>
{% endif %}
</ul>
<!--<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>-->
</div>
</nav>
<div class="site">
<main role="main" class="container">
{% block content %}{% endblock %}
</main><!-- /.container -->
</div>
<!-- Footer -->
<footer class="footer">
<div class="container text-center py-3">
{% if not auth %}
<a href="/login" class="ml-1 mr-1"><i
class="fas fa-sign-in-alt mr-1"></i><span>Login</span></a>
{% endif %}
<a href="https://github.com/PhoenixTwoFive/karaoqueue"
class="ml-1 mr-1"><i class="fab fa-github mr-1"></i><span>Github</span></a>
<span class="text-muted">KaraoQueue -&nbsp;<span
style="display:inline-block;transform: rotate(180deg) translateY(-0.2rem)">&copy</span>&nbsp;2019 - Phillip
Kühne</span>
</div>
</footer>
<!-- Footer -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"
integrity="sha256-4F7e4JsAJyLUdpP7Q8Sah866jCOhv72zU5E8lIRER4w=" crossorigin="anonymous">
</script>
<script src="https://unpkg.com/bootstrap-table@1.15.3/dist/bootstrap-table.min.js"></script>
<script src="https://unpkg.com/bootstrap-table@1.15.3/dist/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js"></script>
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
{% block extrajs %}{% endblock %}
<script>
$(document).ready(function () {
// get current URL path and assign 'active' class
var pathname = window.location.pathname;
$('.navbar-nav > li > a[href="' + pathname + '"]').parent().addClass('active');
$('[data-toggle="tooltip"]').tooltip()
})
</script>
</body>
</html>

View File

@ -1,35 +0,0 @@
{% extends 'base.html' %}
{% block title %}Warteliste{% endblock %}
{% block content %}
<a id="bfb" role="button" class="btn btn-primary btn-lg btn-block mb-2" href="/list">Eintragen</a>
<table class="table entries"
data-toggle="table"
data-url="/api/queue"
data-pagination="true"
data-classes="table"
data-show-refresh="false"
data-auto-refresh="true"
data-auto-refresh-interval="10">
<thead>
<tr>
<th data-field="Name">Name</th>
<th data-field="Title">Song</th>
<th data-field="Artist">Künstler</th>
</tr>
</thead>
</table>
<a name="end"></a>
{% endblock %}
{% block extrajs %}
<script>
$.getJSON("/api/entries/accept", (data) => {
if (data["value"]==0) {
$("#bfb").addClass("disabled")
$("#bfb").prop("aria-disabled",true);
$("#bfb").prop("tabindex","-1");
}
})
</script>
{% endblock %}

View File

@ -1,69 +0,0 @@
{% extends 'base.html' %}
{% block title %}Warteliste-Admin{% endblock %}
{% block content %}
<style>
table td:nth-child(2) {
max-width: 450px !important;
overflow: scroll;
}
</style>
<div class="container">
<div id="toolbar">
<button type="button" class="topbutton btn btn-danger" onclick="confirmDeleteSelectedEntries()"><i
class="fas fa-trash mr-2"></i>Gewählte Einträge löschen</button>
<button type="button" class="topbutton btn btn-danger" onclick="confirmUpdateSongDatabase()"><i
class="fas fa-file-import mr-2"></i>Song-Datenbank
aktualisieren</button>
<input id="entryToggle" type="checkbox" class="topbutton" data-toggle="toggle" data-on="Eintragen erlaubt" data-off="Eintragen deaktiviert" data-onstyle="success" data-offstyle="danger">
</div>
<a name="end"></a>
</div>
{% endblock %}
{% block extrajs %}
<script>
function confirmUpdateSongDatabase() {
bootbox.confirm({
message: "Wirklich die Song-Datenbank aktualisieren?<br>Dies lädt die Aktuelle Song-Liste von <a href='https://www.karafun.de/karaoke-song-list.html'>KaraFun</a> herunter, <b>und wird alle Eintragungen löschen!</b>",
buttons: {
confirm: {
label: 'Ja',
className: 'btn-primary'
},
cancel: {
label: 'Nein',
className: 'btn btn-secondary'
}
},
callback: function(result){
if (result) {
var dialog = bootbox.dialog({
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Aktualisiere Song-Datenbank...</p>',
closeButton: false
});
updateSongDatabase(dialog)
}
}
})
}
function updateSongDatabase(wait_dialog) {
$.ajax({
type: 'GET',
url: '/api/songs/update',
contentType: "application/json",
dataType: 'json',
success: function(data) {
wait_dialog.modal('hide')
bootbox.alert({
message: data["status"],
callback: function() {
$("#entrytable").bootstrapTable('refresh')
}
})
}
});
}
</script>
{% endblock %}

View File

@ -1,102 +0,0 @@
{% extends 'base.html' %}
{% block title %}Abspielliste{% endblock %}
{% block content %}
<div id="toolbar">
<button type="button" class="topbutton btn btn-danger" onclick="confirmDeleteAllEntries()"><i
class="fas fa-trash mr-2"></i>Abspielliste löschen</button>
<button type="button" class="topbutton btn btn-primary" onclick="exportPDF()"><i
class="fas fa-file-pdf mr-2"></i>Als PDF herunterladen</button>
<button type="button" class="topbutton btn btn-secondary" onclick="printPDF()"><i
class="fas fa-print mr-2"></i>Drucken</button>
</div>
<table class="table"
id="table"
data-toggle="table"
data-search="true"
data-show-columns="true"
data-toolbar="#toolbar"
data-pagination="true"
data-classes="table table-bordered table-striped"
data-show-extended-pagination="true">
<thead>
<tr>
<th scope="col">Song</th>
<th scope="col">Wiedergaben</th>
</tr>
</thead>
{% for entry in list: %}
<tr>
<td>
{{ entry[0] }}
</td>
<td>
{{ entry[1] }}
</td>
</tr>
{% endfor %}
</table>
</table>
{% endblock %}
{% block extrajs %}
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
<script src="https://unpkg.com/jspdf-autotable@3.1.1/dist/jspdf.plugin.autotable.js"></script>
<script>
function confirmDeleteAllEntries() {
bootbox.confirm({
message: "Wirklich Abspielliste löschen?<br>Stelle sicher, dass du sie vorher zwecks Abrechnung gedruckt und/oder heruntergeladen hast!",
buttons: {
confirm: {
label: 'Ja',
className: 'btn btn-danger'
},
cancel: {
label: 'Nein',
className: 'btn btn-secondary'
}
},
callback: function(result){
if (result) {
deleteAllEntries()
}
}
})
}
function deleteAllEntries() {
$.ajax({
type: 'GET',
url: '/api/played/clear',
contentType: "application/json",
dataType: 'json',
async: false
});
location.reload();
}
function exportPDF() {
var doc = new jsPDF();
doc.autoTable({
head: [["Song","Wiedergaben"]],
body: createTableArray(),
theme: 'grid'
});
doc.save('Abspielliste.pdf');
}
function printPDF() {
var doc = new jsPDF();
doc.autoTable({
head: [["Song","Wiedergaben"]],
body: createTableArray(),
theme: 'grid'
});
doc.autoPrint();
doc.output('dataurlnewwindow');
}
function createTableArray() {
var data = $("#table").bootstrapTable('getData')
out = data.map(x => [x["0"],x["1"]])
return out;
}
</script>
{% endblock %}

View File

@ -1,129 +0,0 @@
{% extends 'base.html' %}
{% block title %}Songsuche{% endblock %}
{% block content %}
<input class="form-control" id="filter" type="text" placeholder="Suchen...">
<table class="table">
<tbody id="songtable">
</tbody>
</table>
<div class="modal fade" id="enqueueModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Auf Liste setzen</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="form-group">
<form id="nameForm">
<div class="modal-body">
<label for="singerNameInput">Sängername</label>
<input type="text" class="form-control" id="singerNameInput" placeholder="Max Mustermann"
required>
<input id="selectedId" name="selectedId" type="hidden" value="">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" id="submitSongButton">Anmelden</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extrajs %}
<script>
$(document).ready(function () {
$("#filter").focus();
$("#filter").keyup( function () {
var value = $(this).val().toLowerCase();
//alert(value);
if(value.length >= 1) {
$.getJSON("/api/songs/compl", { search: value }, function (data) {
var items = [];
$.each(data, function (key, val) {
items.push("<tr><td>"+val[0]+`</td>
<td><button type='button'
class='btn btn-primary justify-content-center align-content-between enqueueButton'
data-toggle='modal'
data-target='#enqueueModal' onclick='setSelectedId(`+val[1]+`)'><i
class="fas fa-plus"></i></button></td>
</tr>`)
});
$("#songtable").html("")
$(items.join("")).appendTo("#songtable");
entriesAccepted()
});
} else {
$("#songtable").html("")
}
});
$("#nameForm").submit( function (e) {
e.preventDefault();
submitModal();
});
});
function enqueue(id,name,success_callback, blocked_callback) {
var data = {
"name": name,
"id": id
}
$.ajax({
type: 'POST',
url: '/api/enqueue',
data: JSON.stringify(data), // or JSON.stringify ({name: 'jonas'}),
success: success_callback,
statusCode: {
423: blocked_callback
},
contentType: "application/json",
dataType: 'json'
});
}
function setSelectedId(id) {
$("#selectedId").attr("value",id);
}
function submitModal() {
var name = $("#singerNameInput").val();
var id = $("#selectedId").attr("value");
enqueue(id,name,function () {
$("#enqueueModal").modal('hide');
window.location.href = '/#end';
}, function () {
bootbox.alert({
message: "Es werden leider keine neuen Anmeldungen mehr angenommen. Tut mir leid :(",
});
$(".enqueueButton").prop("disabled",true);
$("#enqueueModal").modal('hide');
});
}
function entriesAccepted() {
$.getJSON("/api/entries/accept", (data,out) => {
if(data["value"]==0) {
$(".enqueueButton").prop("disabled",true)
$(".enqueueButton").prop("style","pointer-events: none;")
$(".enqueueButton").wrap("<span class='tooltip-span' tabindex='0' data-toggle='tooltip' data-placement='top'></span>" );
$(".tooltip-span").prop("title","Eintragungen sind leider nicht mehr möglich.")
$('[data-toggle="tooltip"]').tooltip()
} else {
$(".enqueueButton").prop("disabled",false)
}
})
}
</script>
{% endblock %}

View File

@ -1,230 +0,0 @@
<#
.Synopsis
Activate a Python virtual environment for the current Powershell session.
.Description
Pushes the python executable for a virtual environment to the front of the
$Env:PATH environment variable and sets the prompt to signify that you are
in a Python virtual environment. Makes use of the command line switches as
well as the `pyvenv.cfg` file values present in the virtual environment.
.Parameter VenvDir
Path to the directory that contains the virtual environment to activate. The
default value for this is the parent of the directory that the Activate.ps1
script is located within.
.Parameter Prompt
The prompt prefix to display when this virtual environment is activated. By
default, this prompt is the name of the virtual environment folder (VenvDir)
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
.Example
Activate.ps1
Activates the Python virtual environment that contains the Activate.ps1 script.
.Example
Activate.ps1 -Verbose
Activates the Python virtual environment that contains the Activate.ps1 script,
and shows extra information about the activation as it executes.
.Example
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
Activates the Python virtual environment located in the specified location.
.Example
Activate.ps1 -Prompt "MyPython"
Activates the Python virtual environment that contains the Activate.ps1 script,
and prefixes the current prompt with the specified string (surrounded in
parentheses) while the virtual environment is active.
#>
Param(
[Parameter(Mandatory = $false)]
[String]
$VenvDir,
[Parameter(Mandatory = $false)]
[String]
$Prompt
)
<# Function declarations --------------------------------------------------- #>
<#
.Synopsis
Remove all shell session elements added by the Activate script, including the
addition of the virtual environment's Python executable from the beginning of
the PATH variable.
.Parameter NonDestructive
If present, do not remove this function from the global namespace for the
session.
#>
function global:deactivate ([switch]$NonDestructive) {
# Revert to original values
# The prior prompt:
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
}
# The prior PYTHONHOME:
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
}
# The prior PATH:
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
}
# Just remove the VIRTUAL_ENV altogether:
if (Test-Path -Path Env:VIRTUAL_ENV) {
Remove-Item -Path env:VIRTUAL_ENV
}
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
}
# Leave deactivate function in the global namespace if requested:
if (-not $NonDestructive) {
Remove-Item -Path function:deactivate
}
}
<#
.Description
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
given folder, and returns them in a map.
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
two strings separated by `=` (with any amount of whitespace surrounding the =)
then it is considered a `key = value` line. The left hand string is the key,
the right hand is the value.
If the value starts with a `'` or a `"` then the first and last character is
stripped from the value before being captured.
.Parameter ConfigDir
Path to the directory that contains the `pyvenv.cfg` file.
#>
function Get-PyVenvConfig(
[String]
$ConfigDir
) {
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
# An empty map will be returned if no config file is found.
$pyvenvConfig = @{ }
if ($pyvenvConfigPath) {
Write-Verbose "File exists, parse `key = value` lines"
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
$pyvenvConfigContent | ForEach-Object {
$keyval = $PSItem -split "\s*=\s*", 2
if ($keyval[0] -and $keyval[1]) {
$val = $keyval[1]
# Remove extraneous quotations around a string value.
if ("'""".Contains($val.Substring(0,1))) {
$val = $val.Substring(1, $val.Length - 2)
}
$pyvenvConfig[$keyval[0]] = $val
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
}
}
}
return $pyvenvConfig
}
<# Begin Activate script --------------------------------------------------- #>
# Determine the containing directory of this script
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
$VenvExecDir = Get-Item -Path $VenvExecPath
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
# Set values required in priority: CmdLine, ConfigFile, Default
# First, get the location of the virtual environment, it might not be
# VenvExecDir if specified on the command line.
if ($VenvDir) {
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
} else {
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
Write-Verbose "VenvDir=$VenvDir"
}
# Next, read the `pyvenv.cfg` file to determine any required value such
# as `prompt`.
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
# Next, set the prompt from the command line, or the config file, or
# just use the name of the virtual environment folder.
if ($Prompt) {
Write-Verbose "Prompt specified as argument, using '$Prompt'"
} else {
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
$Prompt = $pyvenvCfg['prompt'];
}
else {
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)"
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
$Prompt = Split-Path -Path $venvDir -Leaf
}
}
Write-Verbose "Prompt = '$Prompt'"
Write-Verbose "VenvDir='$VenvDir'"
# Deactivate any currently active virtual environment, but leave the
# deactivate function in place.
deactivate -nondestructive
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
# that there is an activated venv.
$env:VIRTUAL_ENV = $VenvDir
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
Write-Verbose "Setting prompt to '$Prompt'"
# Set the prompt to include the env name
# Make sure _OLD_VIRTUAL_PROMPT is global
function global:_OLD_VIRTUAL_PROMPT { "" }
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
function global:prompt {
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
_OLD_VIRTUAL_PROMPT
}
}
# Clear PYTHONHOME
if (Test-Path -Path Env:PYTHONHOME) {
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
Remove-Item -Path Env:PYTHONHOME
}
# Add the venv to the PATH
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"

View File

@ -1,76 +0,0 @@
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "${1:-}" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
if [ "x(pyenv) " != x ] ; then
PS1="(pyenv) ${PS1:-}"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi

View File

@ -1,37 +0,0 @@
# This file must be used with "source bin/activate.csh" *from csh*.
# You cannot run it directly.
# Created by Davide Di Blasi <davidedb@gmail.com>.
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate'
# Unset irrelevant variables.
deactivate nondestructive
setenv VIRTUAL_ENV "/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv"
set _OLD_VIRTUAL_PATH="$PATH"
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
set _OLD_VIRTUAL_PROMPT="$prompt"
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
if ("pyenv" != "") then
set env_name = "pyenv"
else
if (`basename "VIRTUAL_ENV"` == "__") then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
else
set env_name = `basename "$VIRTUAL_ENV"`
endif
endif
set prompt = "[$env_name] $prompt"
unset env_name
endif
alias pydoc python -m pydoc
rehash

View File

@ -1,75 +0,0 @@
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org)
# you cannot run it directly
function deactivate -d "Exit virtualenv and return to normal shell environment"
# reset old environment variables
if test -n "$_OLD_VIRTUAL_PATH"
set -gx PATH $_OLD_VIRTUAL_PATH
set -e _OLD_VIRTUAL_PATH
end
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
set -e _OLD_VIRTUAL_PYTHONHOME
end
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
functions -e fish_prompt
set -e _OLD_FISH_PROMPT_OVERRIDE
functions -c _old_fish_prompt fish_prompt
functions -e _old_fish_prompt
end
set -e VIRTUAL_ENV
if test "$argv[1]" != "nondestructive"
# Self destruct!
functions -e deactivate
end
end
# unset irrelevant variables
deactivate nondestructive
set -gx VIRTUAL_ENV "/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv"
set -gx _OLD_VIRTUAL_PATH $PATH
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
# unset PYTHONHOME if set
if set -q PYTHONHOME
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
set -e PYTHONHOME
end
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
# fish uses a function instead of an env var to generate the prompt.
# save the current fish_prompt function as the function _old_fish_prompt
functions -c fish_prompt _old_fish_prompt
# with the original prompt function renamed, we can override with our own.
function fish_prompt
# Save the return status of the last command
set -l old_status $status
# Prompt override?
if test -n "(pyenv) "
printf "%s%s" "(pyenv) " (set_color normal)
else
# ...Otherwise, prepend env
set -l _checkbase (basename "$VIRTUAL_ENV")
if test $_checkbase = "__"
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal)
else
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)
end
end
# Restore the return status of the previous command.
echo "exit $old_status" | .
_old_fish_prompt
end
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
end

View File

@ -1,12 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'autopep8==1.5','console_scripts','autopep8'
__requires__ = 'autopep8==1.5'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('autopep8==1.5', 'console_scripts', 'autopep8')()
)

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from chardet.cli.chardetect import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from setuptools.command.easy_install import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from setuptools.command.easy_install import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pylint import run_epylint
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run_epylint())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from numpy.f2py.f2py2e import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from numpy.f2py.f2py2e import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from numpy.f2py.f2py2e import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from flask.cli import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from isort.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pycodestyle import _main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(_main())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pylint import run_pylint
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run_pylint())

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pylint import run_pyreverse
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run_pyreverse())

View File

@ -1 +0,0 @@
python3

View File

@ -1 +0,0 @@
/usr/bin/python3

View File

@ -1,10 +0,0 @@
#!/home/phillipk/Projekte/Software/StuK/KaraokeWarteliste/backend/pyenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from pylint import run_symilar
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run_symilar())

View File

@ -1 +0,0 @@
lib

View File

@ -1,3 +0,0 @@
home = /usr/bin
include-system-site-packages = false
version = 3.8.2