forked from bton/matekasse
Compare commits
84 commits
Author | SHA1 | Date | |
---|---|---|---|
d306e0a7a1 | |||
baf7277247 | |||
ac400f9db7 | |||
f6e8383a57 | |||
2357d37228 | |||
379f8b1fd3 | |||
3c87a971ea | |||
e5bdad65df | |||
|
71ddc32f49 | ||
cfafd0e148 | |||
b8f54c497e | |||
a6dd6310b7 | |||
efff31aa27 | |||
a31337f0f2 | |||
14624a4f6e | |||
79a31ab6d5 | |||
9c7f2cd0cb | |||
03654ac4cf | |||
ed8bd817b7 | |||
404e292450 | |||
fbe6b45050 | |||
cdbcbea91a | |||
be77d21577 | |||
960f79f8e5 | |||
8387b6ccba | |||
dd9e3463c9 | |||
e76e5beae7 | |||
6b70c563b5 | |||
5ab0b3db7d | |||
069efb54f2 | |||
22d441a1c0 | |||
437a7e596c | |||
657c500f24 | |||
f6c06771dd | |||
6f0edf0feb | |||
ce8acc10b1 | |||
5e9e584f04 | |||
f4a1cb8369 | |||
f8dc320735 | |||
04fd8a20c2 | |||
ff0c91e3e8 | |||
3127e2de1f | |||
c86b91a246 | |||
f4181ade07 | |||
f691e7534d | |||
364dfb69b6 | |||
64ce118f80 | |||
389c14358e | |||
ce009a278b | |||
7f1f908961 | |||
dc71f8dcf4 | |||
0147e61c6b | |||
ac907638e6 | |||
5cb4dcc533 | |||
64e0c340c3 | |||
a8fec178e6 | |||
389e6ffcee | |||
1a51402170 | |||
701d9c2f1e | |||
ccb4d64cde | |||
34eb392ce0 | |||
109f7eb4c2 | |||
42b8a774ea | |||
1f227df358 | |||
19fbecda56 | |||
727617e2be | |||
75081d5020 | |||
ef43f79ff4 | |||
8d25e0b645 | |||
d55b7c5aea | |||
55124040ae | |||
66babf1b2c | |||
5179ec792c | |||
2432eed1ae | |||
fd5fd4d78c | |||
64580f02cb | |||
56aa79378b | |||
e9acd07fb4 | |||
e11512f458 | |||
f927a70f60 | |||
3832282101 | |||
d9aff6a56a | |||
fda3f58cca | |||
2b33f89d8c |
26 changed files with 6614 additions and 312 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
||||||
*.db
|
*.db
|
||||||
socket.io.js
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
logs/*
|
logs/*
|
||||||
venv/*
|
venv/*
|
||||||
|
@ -10,4 +9,5 @@ flask_session/
|
||||||
/test/.pytest_cache/
|
/test/.pytest_cache/
|
||||||
/test/flask_session/
|
/test/flask_session/
|
||||||
/Website/__pycache__/
|
/Website/__pycache__/
|
||||||
/Website/.pytest_cache/
|
/Website/.pytest_cache/
|
||||||
|
/.idea
|
6
README
6
README
|
@ -5,8 +5,6 @@ How to get started:
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
install requiremens:
|
install requiremens:
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
create the log folder:
|
|
||||||
mkdir logs
|
|
||||||
start the program:
|
start the program:
|
||||||
python main.py
|
venv/bin/gunicorn -b "127.0.0.1:5000" -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 main:app
|
||||||
You can now accses the Website on http://127.0.0.1:5000
|
You can now accses the Website on http://127.0.0.1:5000
|
||||||
|
|
|
@ -1,27 +1,21 @@
|
||||||
import queue, time, uuid, json, logging, datetime, os
|
import queue, time, uuid, json, logging, datetime, os
|
||||||
from flask import Flask, render_template, request, make_response, session, send_file, g
|
from flask import Flask, render_template, render_template_string, request, make_response, session, send_file, g
|
||||||
from flask_socketio import SocketIO, join_room, leave_room
|
from flask_socketio import SocketIO, join_room, leave_room
|
||||||
from flask_session import Session
|
from flask_session import Session
|
||||||
from markupsafe import escape
|
from Website.db import get_db
|
||||||
from .db import get_db
|
import Website.db as db_handler
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
finished = None
|
finished = None
|
||||||
|
preis = -150 #Ein Getraenk
|
||||||
#flask_config
|
#flask_config
|
||||||
DATABASE = './Website/mate.db'
|
DATABASE = './Website/mate.db'
|
||||||
|
|
||||||
#def create_logs(app):
|
def limit_length(text, length=50):
|
||||||
# now = datetime.datetime.now().strftime('%d-%m-%Y-%H-%M-%S')
|
if type(text) != str:
|
||||||
# logging.basicConfig(filename=f"logs/matekasse-{now}.log",filemode='w', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ,encoding='utf-8', level=logging.INFO)
|
text = str(text)
|
||||||
# app.logger = logging.getLogger('db')
|
if len(text) > length:
|
||||||
#
|
return f"{text[:(length -3)]}..."
|
||||||
# app.logger.info("Website is starting")
|
return text
|
||||||
|
|
||||||
def log(type=None, userid=None, before=None, after=None):
|
|
||||||
db = get_db()
|
|
||||||
c = db.cursor()
|
|
||||||
c.execute("INSERT or IGNORE INTO transaction_log (timestamp, userid, type, before, after) VALUES (?, ?, ?, ?, ?)", [datetime.now(), userid, type, before, after])
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
def create_app(test_config=None):
|
def create_app(test_config=None):
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
@ -30,15 +24,15 @@ def create_app(test_config=None):
|
||||||
app.config['SESSION_TYPE'] = 'filesystem'
|
app.config['SESSION_TYPE'] = 'filesystem'
|
||||||
app.config['SECRET_KEY'] = key
|
app.config['SECRET_KEY'] = key
|
||||||
app.config['DATABASE'] = DATABASE
|
app.config['DATABASE'] = DATABASE
|
||||||
|
app.jinja_env.filters['limit_length'] = limit_length
|
||||||
else:
|
else:
|
||||||
app.config.from_mapping(test_config)
|
app.config.from_mapping(test_config)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.makedirs(app.instance_path)
|
os.makedirs(app.instance_path)
|
||||||
|
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
#with app.app_context():
|
|
||||||
# create_logs(app)
|
|
||||||
|
|
||||||
Session(app)
|
Session(app)
|
||||||
socketio = SocketIO(app)
|
socketio = SocketIO(app)
|
||||||
|
@ -48,32 +42,32 @@ def create_app(test_config=None):
|
||||||
# db = getattr(g, '_database', None)
|
# db = getattr(g, '_database', None)
|
||||||
# if db is not None:
|
# if db is not None:
|
||||||
# db.close()
|
# db.close()
|
||||||
# app.logger.info("Website exited")
|
# appt.logger.info("Website exited")
|
||||||
|
|
||||||
#var
|
#var
|
||||||
user_queue = queue.Queue()
|
user_queue = queue.Queue()
|
||||||
|
|
||||||
#website
|
#website
|
||||||
@app.route('/favicon.ico')
|
@app.route('/favicon.ico')
|
||||||
|
@app.route('/ccc_logo.png')
|
||||||
def favicon():
|
def favicon():
|
||||||
return send_file("../static/Logo_CCC.svg.png")
|
return send_file("../static/Logo_CCC.svg.png")
|
||||||
|
|
||||||
#@app.route('/socket.io.js')
|
@app.route('/socket.io.js')
|
||||||
#def socketiojs():
|
def socketiojs():
|
||||||
# return url_for('static', filename='socket.io.js')
|
return send_file('../static/socket.io.js')
|
||||||
|
|
||||||
|
@app.route('/ka-ching.wav')
|
||||||
|
def kaching():
|
||||||
|
return send_file('../static/ka-ching.wav')
|
||||||
|
|
||||||
|
@app.route('/new.css')
|
||||||
|
def newcss():
|
||||||
|
return send_file('../static/new.min.css')
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
return """
|
return render_template("index.html")
|
||||||
<a href="/list">user and tag list</a>
|
|
||||||
<p>The creator of this website accepts no liability for any linguistic or technical errors!</p>
|
|
||||||
<br style="line-height: 500%;"></br>
|
|
||||||
<a href="/documentation">Doumentation</a><script src="/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous">
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
window.location="/list"
|
|
||||||
</script>
|
|
||||||
"""
|
|
||||||
|
|
||||||
@app.route("/list")
|
@app.route("/list")
|
||||||
def list():
|
def list():
|
||||||
|
@ -81,35 +75,57 @@ def create_app(test_config=None):
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
c.execute("SELECT * FROM users")
|
c.execute("SELECT * FROM users")
|
||||||
users = c.fetchall()
|
users = c.fetchall()
|
||||||
text = ""
|
return render_template("list.html", users=users, preis=(preis/100), min_value=-50000)
|
||||||
for i in users:
|
|
||||||
text = text + f'<p><a href="list/user?id={i[0]}">{escape(i[1])}</a>: {i[2]/100}€ <form action="/change" method="post"><input name="id" type="hidden" value="{i[0]}"> <input name="change" type="number" step="0.1" placeholder="add to balance"></form></p> <br style="line-height: 50%;"></br>'
|
|
||||||
return '''<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
var socket = io();
|
|
||||||
socket.on("update", function(){
|
|
||||||
window.location="http://matekasse.server.c3h/list"
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<title>Strichliste</title>
|
|
||||||
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
|
|
||||||
<form action="/list/user" method="get"><input name="user" type="search" placeholder="Search for user"><button>Search</button></form>
|
|
||||||
<form action="/adduser" method="post"><button type="submit">Add User</button></form>
|
|
||||||
<br></br>
|
|
||||||
''' + text + '</html>'
|
|
||||||
|
|
||||||
@app.route("/transactionlist")
|
@app.route("/transactionlist")
|
||||||
def transactionlist():
|
def transactionlist():
|
||||||
db = get_db()
|
db = get_db()
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
text = ""
|
action_list = []
|
||||||
c.execute("SELECT * FROM transaction_log ORDER BY ROWID DESC LIMIT 100")
|
c.execute("SELECT * FROM transaction_log ORDER BY ROWID DESC LIMIT 1000")
|
||||||
transactionlist = c.fetchall()
|
transactionlist = c.fetchall()
|
||||||
for i in transactionlist:
|
for i in transactionlist:
|
||||||
text = text + f"<p>{i[0]} userid: {i[1]} {i[2]} {i[3]} to {i[4]}</p>"
|
action = {
|
||||||
return text
|
"statement":i[0],
|
||||||
|
"user_id":i[1],
|
||||||
|
"before":i[2],
|
||||||
|
"after":i[3],
|
||||||
|
"change":i[4]
|
||||||
|
}
|
||||||
|
if action["statement"] == "balance":
|
||||||
|
action["reverse_statement"] = "balance"
|
||||||
|
action["reverse_user_id"] = action["user_id"]
|
||||||
|
action["reverse_before"] = None
|
||||||
|
action["reverse_after"] = None
|
||||||
|
action["reverse_change"] = action["change"] *(-1)
|
||||||
|
elif action["statement"] == "add_user":
|
||||||
|
action["reverse_statement"] = "remove_user"
|
||||||
|
action["reverse_user_id"] = action["user_id"]
|
||||||
|
action["reverse_before"] = action["after"]
|
||||||
|
action["reverse_after"] = None
|
||||||
|
action["reverse_change"] = None
|
||||||
|
elif action["statement"] == "remove_user":
|
||||||
|
action["reverse_statement"] = "add_user"
|
||||||
|
action["reverse_user_id"] = action["user_id"]
|
||||||
|
action["reverse_before"] = None
|
||||||
|
action["reverse_after"] = action["before"]
|
||||||
|
action["reverse_change"] = None
|
||||||
|
elif action["statement"] == "add_tag":
|
||||||
|
action["reverse_statement"] = "remove_tag"
|
||||||
|
action["reverse_user_id"] = action["user_id"]
|
||||||
|
action["reverse_before"] = action["after"]
|
||||||
|
action["reverse_after"] = None
|
||||||
|
action["reverse_change"] = None
|
||||||
|
elif action["statement"] == "remove_tag":
|
||||||
|
action["reverse_statement"] = "add_tag"
|
||||||
|
action["reverse_user_id"] = action["user_id"]
|
||||||
|
action["reverse_before"] = None
|
||||||
|
action["reverse_after"] = action["before"]
|
||||||
|
action["reverse_change"] = None
|
||||||
|
else:
|
||||||
|
raise Exception(statement)
|
||||||
|
action_list.append(action)
|
||||||
|
return render_template("transactionlist.html", action_list=action_list)
|
||||||
|
|
||||||
@app.route("/list/user", methods=['GET'])
|
@app.route("/list/user", methods=['GET'])
|
||||||
def user_info():
|
def user_info():
|
||||||
|
@ -117,41 +133,18 @@ def create_app(test_config=None):
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
id = request.args.get("id")
|
id = request.args.get("id")
|
||||||
c.execute(f"SELECT * FROM users WHERE id=?", [id])
|
c.execute(f"SELECT * FROM users WHERE id=?", [id])
|
||||||
user_list = c.fetchall()
|
user = c.fetchone()
|
||||||
if user_list != []:
|
if user != None :
|
||||||
user = user_list[0]
|
|
||||||
c.execute(f"SELECT * FROM tags WHERE userid={user[0]}")
|
c.execute(f"SELECT * FROM tags WHERE userid={user[0]}")
|
||||||
tags = c.fetchall()
|
tags = c.fetchall()
|
||||||
text = ""
|
return render_template("user.html", user=user, tags=tags, min_value=-50000)
|
||||||
for tag in tags:
|
|
||||||
text = text + f'<p><form action="/removetag" method="post"><label for="removetag">{tag[0]} </label><input name="id" type="hidden" value="{user[0]}"><input name="tagid" type="hidden" value="{tag[0]}"><button id="removetag" type="submit">Remove Tag</button></form> </p>'
|
|
||||||
return f"""<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
var socket = io();
|
|
||||||
""" + 'socket.on("update", function(){ window.location="http://matekasse.server.c3h/list/user?id=' + id + '"});' + f"""
|
|
||||||
</script>
|
|
||||||
<title>{escape(user[1])}</title>
|
|
||||||
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
|
|
||||||
<p> {escape(user[1])} : {escape(user[2]/100)}€ <p>
|
|
||||||
<form action="/addtag" method="post"><input name="id" type="hidden" value="{user[0]}"><button type="submit">Add Tag</button></form>
|
|
||||||
<form action="/removetag" method="post"><input name="id" type="hidden" value="{user[0]}"><button type="submit">Remove Tag</button></form>
|
|
||||||
</p><form action="/change" method="post"><input name="id" type="hidden" value="{user[0]}"> <input name="change" type="number" step="0.1" placeholder="change balance"></form>
|
|
||||||
</p>
|
|
||||||
<br></br>
|
|
||||||
<p>Tags:</p>
|
|
||||||
{text}
|
|
||||||
<br></br>
|
|
||||||
<form action="/removeuser" method="post"><input name="id" type="hidden" value="{user[0]}"><button type="submit">Remove User</button></form>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
else:
|
else:
|
||||||
return render_template("error.html", error_code="043")
|
return render_template("error.html", error_code="043")
|
||||||
|
|
||||||
@app.route("/adduser", methods=['POST'])
|
@app.route("/adduser", methods=['POST'])
|
||||||
def new_user():
|
def new_user():
|
||||||
return render_template("adduser.html")
|
return render_template("adduser.html")
|
||||||
|
|
||||||
@app.route("/removeuser", methods=['POST'])
|
@app.route("/removeuser", methods=['POST'])
|
||||||
def remove_user():
|
def remove_user():
|
||||||
|
@ -159,16 +152,12 @@ def create_app(test_config=None):
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
user_id = request.form["id"]
|
user_id = request.form["id"]
|
||||||
c.execute(f"SELECT * FROM users WHERE id=?", [user_id])
|
c.execute(f"SELECT * FROM users WHERE id=?", [user_id])
|
||||||
users = c.fetchall()
|
user = c.fetchone()
|
||||||
if users != []:
|
if user != None:
|
||||||
user_name = users[0][1]
|
user_name = user[1]
|
||||||
c.execute(f"DELETE FROM tags WHERE userid=?", [user_id])
|
db_handler.remove_user(user_id)
|
||||||
app.logger.info(f"Deleted all tags from user ?", [user_id])
|
|
||||||
c.execute(f"DELETE FROM users WHERE id=?", [user_id])
|
|
||||||
db.commit()
|
|
||||||
log(type="removeuser", userid=user_id, before=user_name)
|
|
||||||
socketio.emit("update", "update")
|
socketio.emit("update", "update")
|
||||||
return f'<title>remove user</title><p><p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p> <p>Deleted user {escape(user_name)}</p><a href="/list">return to the tags and user list</a></p>'
|
return render_template("removeuser.html", user_name=user_name)
|
||||||
else:
|
else:
|
||||||
return render_template("error.html", error_code="043")
|
return render_template("error.html", error_code="043")
|
||||||
|
|
||||||
|
@ -181,20 +170,11 @@ def create_app(test_config=None):
|
||||||
return render_template("error.html", error_code="418")
|
return render_template("error.html", error_code="418")
|
||||||
c.execute("SELECT * FROM users WHERE username=?", [username])
|
c.execute("SELECT * FROM users WHERE username=?", [username])
|
||||||
if c.fetchall() == []:
|
if c.fetchall() == []:
|
||||||
c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [username])
|
db_handler.add_user(username)
|
||||||
db.commit()
|
|
||||||
socketio.emit("update", "update")
|
socketio.emit("update", "update")
|
||||||
c.execute(f"SELECT * FROM users WHERE username=?", [username])
|
c.execute(f"SELECT * FROM users WHERE username=?", [username])
|
||||||
user = c.fetchone()
|
user = c.fetchone()
|
||||||
log(type="adduser", userid=user[0], after=user[1])
|
return render_template("redirect.html")
|
||||||
return """<html>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
window.location="/list";
|
|
||||||
</script>
|
|
||||||
<p>tag was sucsesfully added</p>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
else:
|
else:
|
||||||
return render_template("error.html", error_code="757")
|
return render_template("error.html", error_code="757")
|
||||||
|
|
||||||
|
@ -205,27 +185,16 @@ def create_app(test_config=None):
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
try:
|
try:
|
||||||
user_id = request.form["id"]
|
user_id = request.form["id"]
|
||||||
change = float(request.form["change"])
|
change = int(float(request.form["change"]) * float(100))
|
||||||
print(change)
|
|
||||||
except:
|
except:
|
||||||
return render_template("error.html", error_code="095")
|
return render_template("error.html", error_code="095")
|
||||||
c.execute(f"SELECT * FROM users WHERE id=?", [user_id])
|
c.execute(f"SELECT * FROM users WHERE id=?", [user_id])
|
||||||
users = c.fetchall()
|
users = c.fetchall()
|
||||||
if users != []:
|
if users != []:
|
||||||
balance_old = users[0][2]
|
balance_old = users[0][2]
|
||||||
c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user_id}")
|
db_handler.change_balance(user_id, change)
|
||||||
db.commit()
|
|
||||||
c.execute(f"SELECT * FROM users WHERE id={user_id}")
|
|
||||||
user = c.fetchone()
|
|
||||||
log(type="balance", userid=user[0], before=balance_old, after=user[2])
|
|
||||||
socketio.emit("update", "update")
|
socketio.emit("update", "update")
|
||||||
return """<html>
|
return render_template("redirect.html")
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
window.location="/list";
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
else:
|
else:
|
||||||
return render_template("error.html", error_code="043")
|
return render_template("error.html", error_code="043")
|
||||||
|
|
||||||
|
@ -285,17 +254,9 @@ def create_app(test_config=None):
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
c.execute(f"SELECT * FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id])
|
c.execute(f"SELECT * FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id])
|
||||||
if c.fetchall != []:
|
if c.fetchall != []:
|
||||||
c.execute(f"DELETE FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id])
|
db_handler.remove_tag(tag_id)
|
||||||
db.commit()
|
|
||||||
message = f"Removed {tag_id} from user {user_id}"
|
message = f"Removed {tag_id} from user {user_id}"
|
||||||
log(type="removetag", userid=user_id, before=tag_id)
|
return render_template("redirect.html")
|
||||||
return f"""
|
|
||||||
<html>
|
|
||||||
<script>
|
|
||||||
window.location="/"
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
else:
|
else:
|
||||||
return render_template("error.html", error_code="054")
|
return render_template("error.html", error_code="054")
|
||||||
|
|
||||||
|
@ -326,44 +287,75 @@ def create_app(test_config=None):
|
||||||
socketio.emit("error", "418", to=session[id])
|
socketio.emit("error", "418", to=session[id])
|
||||||
leave_room(session[id])
|
leave_room(session[id])
|
||||||
|
|
||||||
#api
|
@app.route("/transfare")
|
||||||
@app.route("/api/change", methods=['GET', 'POST'])
|
def transfare():
|
||||||
def api_change():
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
try:
|
c.execute("SELECT * FROM users")
|
||||||
userid = request.form["id"]
|
|
||||||
except:
|
|
||||||
userid = request.args.get("id")
|
|
||||||
c.execute("SELECT * FROM users WHERE id=?", [userid])
|
|
||||||
user_list = c.fetchall()
|
user_list = c.fetchall()
|
||||||
if user_list != []:
|
return render_template("transfare.html", user_list=user_list)
|
||||||
user = user_list[0]
|
|
||||||
try:
|
@app.route("/api/transfare", methods=['POST'])
|
||||||
change = int(request.args.get("change"))
|
def api_transfare():
|
||||||
except:
|
db = get_db()
|
||||||
change = -1.5
|
c = db.cursor()
|
||||||
c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user[0]}")
|
transfare_from = request.form["transfarefrom"]
|
||||||
db.commit()
|
transfare_to = request.form["transfareto"]
|
||||||
c.execute(f"SELECT * FROM users WHERE id = {userid}")
|
change = int(float(request.form["change"]) * float(100))
|
||||||
user_new = c.fetchone()
|
c.execute("SELECT * FROM users WHERE id=?", [transfare_from])
|
||||||
log(type="balance", userid=user[0], before=user[2], after=user_new[2])
|
if c.fetchall() == []:
|
||||||
socketio.emit("update", "update")
|
return render_template("error.html", error_code="043")
|
||||||
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user_new[2]}))
|
c.execute("SELECT * FROM users WHERE id=?", [transfare_to])
|
||||||
else:
|
if c.fetchall() == []:
|
||||||
return make_response(json.dumps({"mode":"error","error":"043"}))
|
return render_template("error.html", error_code="043")
|
||||||
|
db_handler.change_balance(transfare_from, -change)
|
||||||
|
db_handler.change_balance(transfare_to, change)
|
||||||
|
return render_template("redirect.html")
|
||||||
|
|
||||||
|
@app.route("/api/balance", methods=['POST', 'GET'])
|
||||||
|
def api_change():
|
||||||
|
if request.method == 'POST':
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
userid = request.form["id"]
|
||||||
|
c.execute("SELECT * FROM users WHERE id=?", [userid])
|
||||||
|
user_list = c.fetchall()
|
||||||
|
if user_list != []:
|
||||||
|
user = user_list[0]
|
||||||
|
try:
|
||||||
|
change = int(request.args.get("change"))
|
||||||
|
except:
|
||||||
|
change = preis
|
||||||
|
db_handler.change_balance(userid, change)
|
||||||
|
socketio.emit("update", "update")
|
||||||
|
c.execute("SELECT * FROM users WHERE id=?",[userid])
|
||||||
|
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":c.fetchone()[2]}))
|
||||||
|
else:
|
||||||
|
return make_response(json.dumps({"mode":"error","error":"043"}))
|
||||||
|
|
||||||
|
elif request.method == 'GET':
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
userid = request.args.get("id")
|
||||||
|
c.execute("SELECT * FROM users WHERE id=?", [userid])
|
||||||
|
user = c.fetchone()
|
||||||
|
if user != None:
|
||||||
|
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]}))
|
||||||
|
else:
|
||||||
|
return make_response(json.dumps({"mode":"error", "error":"043"}))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/tag_id", methods=['GET', 'POST'])
|
@app.route("/api/tag_id", methods=['POST'])
|
||||||
def get_id():
|
def get_id():
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
global finished
|
global finished
|
||||||
global message
|
global message
|
||||||
db = get_db()
|
|
||||||
c = db.cursor()
|
|
||||||
try:
|
try:
|
||||||
tag_id = request.form["id"]
|
tag_id = request.form["id"]
|
||||||
except:
|
except:
|
||||||
tag_id = request.args.get("id")
|
return make_response(json.dumps({"mode":"error", "error":"638"}))
|
||||||
c.execute(f"SELECT * FROM tags WHERE tagid=?", [tag_id])
|
c.execute(f"SELECT * FROM tags WHERE tagid=?", [tag_id])
|
||||||
|
|
||||||
tag_list = c.fetchall()
|
tag_list = c.fetchall()
|
||||||
|
@ -383,20 +375,16 @@ def create_app(test_config=None):
|
||||||
finished = queue_item
|
finished = queue_item
|
||||||
return make_response(json.dumps({"mode":"error","error":"170"}))
|
return make_response(json.dumps({"mode":"error","error":"170"}))
|
||||||
else:
|
else:
|
||||||
c.execute(f"INSERT OR IGNORE INTO tags (tagid, userid) VALUES ({tag_id}, ?)", [user_id])
|
db_handler.add_tag(user_id, tag_id)
|
||||||
db.commit()
|
|
||||||
message = f"Added {tag_id} to {username}"
|
message = f"Added {tag_id} to {username}"
|
||||||
log(type="addtag", userid=user_id ,after=tag_id)
|
|
||||||
finished = queue_item
|
finished = queue_item
|
||||||
return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was added"}))
|
return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was added"}))
|
||||||
elif state == "remove":
|
elif state == "remove":
|
||||||
c.execute(f"SELECT * FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id])
|
c.execute(f"SELECT * FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id])
|
||||||
tags = c.fetchall()
|
tags = c.fetchall()
|
||||||
if tags != []:
|
if tags != []:
|
||||||
c.execute(f"DELETE FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id])
|
|
||||||
db.commit()
|
db.commit()
|
||||||
message = f"Removed {tag_id} from {username}"
|
message = f"Removed {tag_id} from {username}"
|
||||||
log(type="removetag", userid=user_id, before=tag_id)
|
|
||||||
finished = queue_item
|
finished = queue_item
|
||||||
return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was removed"}))
|
return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was removed"}))
|
||||||
else:
|
else:
|
||||||
|
@ -414,11 +402,9 @@ def create_app(test_config=None):
|
||||||
if user_list != []:
|
if user_list != []:
|
||||||
balance_old = user_list[0][2]
|
balance_old = user_list[0][2]
|
||||||
if user_queue.qsize() == 0:
|
if user_queue.qsize() == 0:
|
||||||
c.execute(f"UPDATE users SET balance = balance - 150 WHERE id={tag[1]}")
|
db_handler.change_balance(tag[1], preis)
|
||||||
db.commit()
|
|
||||||
c.execute(f"SELECT * FROM users WHERE id={tag[1]}")
|
c.execute(f"SELECT * FROM users WHERE id={tag[1]}")
|
||||||
user = c.fetchone()
|
user = c.fetchone()
|
||||||
log(type="balance", userid=user[0], before=balance_old, after=user[2])
|
|
||||||
socketio.emit("update", "update")
|
socketio.emit("update", "update")
|
||||||
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]/100}))
|
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]/100}))
|
||||||
else:
|
else:
|
||||||
|
@ -426,9 +412,35 @@ def create_app(test_config=None):
|
||||||
socketio.emit("update", "update")
|
socketio.emit("update", "update")
|
||||||
return make_response(json.dumps({"mode":"error","error":"054"}))
|
return make_response(json.dumps({"mode":"error","error":"054"}))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/api/change", methods=['POST'])
|
||||||
|
def reroll():
|
||||||
|
statement = request.form["statement"]
|
||||||
|
user_id = request.form["user_id"]
|
||||||
|
before = request.form["before"]
|
||||||
|
after = request.form["after"]
|
||||||
|
change = request.form["change"]
|
||||||
|
|
||||||
|
if statement == "add_user":
|
||||||
|
db_handler.add_user(after)
|
||||||
|
elif statement == "remove_user":
|
||||||
|
db_handler.remove_user(user_id)
|
||||||
|
elif statement == "add_tag":
|
||||||
|
db_handler.add_tag(user_id, after)
|
||||||
|
elif statement == "remove_tag":
|
||||||
|
db_handler.remove_tag(befor)
|
||||||
|
elif statement == "balance":
|
||||||
|
db_handler.change_balance(user_id, change)
|
||||||
|
else:
|
||||||
|
return make_response(json.dumps({"mode":"error", "error":"418"})) #Error code
|
||||||
|
|
||||||
|
socketio.emit("update", "update")
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
#Documentation
|
#Documentation
|
||||||
@app.route("/documentation")
|
@app.route("/documentation")
|
||||||
def documentation():
|
def documentation():
|
||||||
return render_template("documentation.html")
|
return render_template("documentation.html")
|
||||||
|
|
||||||
return {"app":app,"socketio":socketio}
|
|
||||||
|
return {"app":app,"socketio":socketio}
|
||||||
|
|
|
@ -1,9 +1,58 @@
|
||||||
from re import M
|
from re import M
|
||||||
|
from markupsafe import escape
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
from datetime import datetime
|
||||||
import click
|
import click
|
||||||
from flask import current_app, g
|
from flask import current_app, g
|
||||||
|
|
||||||
|
def log(statement, user_id=None, before=None, after=None, change=None):
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
c.execute("INSERT INTO transaction_log (type, user_id, before, after, change) VALUES (?, ?, ?, ?, ?)", [ statement, user_id, before, after, change])
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
def add_user(after):
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [after])
|
||||||
|
user_id = c.lastrowid
|
||||||
|
log("add_user", user_id=user_id, after=after)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
def remove_user(user_id):
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
c.execute("SELECT * FROM users WHERE id = ?", [user_id])
|
||||||
|
user_name = c.fetchone()[1]
|
||||||
|
c.execute("SELECT * FROM tags WHERE userid = ?", [user_id])
|
||||||
|
for tag in c.fetchall():
|
||||||
|
remove_tag(tag[0])
|
||||||
|
c.execute("DELETE FROM users WHERE id = ?", [user_id])
|
||||||
|
log("remove_user", user_id=user_id, before=user_name)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
def add_tag(user_id, tag_id):
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
c.execute("INSERT OR IGNORE INTO tags (tagid, userid) VALUES (?, ?)", [tag_id, user_id])
|
||||||
|
db.commit()
|
||||||
|
log("add_tag", after=tag_id, user_id=user_id)
|
||||||
|
|
||||||
|
def remove_tag(tag_id):
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
c.execute("SELECT * FROM tags WHERE tagid = ?", [tag_id])
|
||||||
|
user_id = c.fetchone()[1]
|
||||||
|
c.execute("DELETE FROM tags WHERE tagid = ?", [tag_id])
|
||||||
|
log("remove_tag", before=tag_id, user_id=user_id)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
def change_balance(user_id, change):
|
||||||
|
db = get_db()
|
||||||
|
c = db.cursor()
|
||||||
|
c.execute("UPDATE users SET balance = balance + ? WHERE id=?", [change, user_id])
|
||||||
|
log("balance", user_id=user_id, change=change)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
def get_db():
|
def get_db():
|
||||||
if 'db' not in g:
|
if 'db' not in g:
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
BEGIN TRANSACTION;
|
|
||||||
CREATE TABLE IF NOT EXISTS "users" (
|
|
||||||
"id" INTEGER NOT NULL,
|
|
||||||
"username" TEXT NOT NULL,
|
|
||||||
"balance" INTEGER NOT NULL,
|
|
||||||
PRIMARY KEY("id")
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS "tags" (
|
|
||||||
"tagid" INEGER NOT NULL,
|
|
||||||
"userid" INTEGER,
|
|
||||||
FOREIGN KEY("userid") REFERENCES "users"("id"),
|
|
||||||
PRIMARY KEY("tagid")
|
|
||||||
);
|
|
||||||
COMMIT;
|
|
|
@ -12,10 +12,10 @@ CREATE TABLE IF NOT EXISTS "tags" (
|
||||||
PRIMARY KEY("tagid")
|
PRIMARY KEY("tagid")
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS "transaction_log" (
|
CREATE TABLE IF NOT EXISTS "transaction_log" (
|
||||||
"timestamp" INTEGER NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
"userid" INTEGER NOT NULL,
|
"user_id" INTEGER,
|
||||||
"type" TEXT NOT NULL,
|
"before" TEXT,
|
||||||
"before" TEXT,
|
"after" TEXT,
|
||||||
"after" TEXT
|
"change" INTEGER
|
||||||
);
|
);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block customscript %}
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
<script type="text/javascript" charset="utf-8">
|
||||||
<script type="text/javascript" charset="utf-8">
|
var socket = io();
|
||||||
var socket = io();
|
var user = {{ user }}
|
||||||
var user = {{ user }}
|
socket.on('connect', function() {
|
||||||
socket.on('connect', function() {
|
socket.emit('addtag', {data: user});
|
||||||
socket.emit('addtag', {data: user});
|
});
|
||||||
});
|
socket.on("busy", function(){
|
||||||
socket.on("busy", function(){
|
document.write('<p>the nfc reader is busy at the moment. Pleas Wait ...</p>')
|
||||||
document.write('<p>the nfc reader is busy at the moment. Pleas Wait ...</p>')
|
socket.emit('addtag', {data: user})
|
||||||
socket.emit('addtag', {data: user})
|
});
|
||||||
});
|
socket.on("wait", function(){
|
||||||
socket.on("wait", function(){
|
document.write('<p>Pleas hold your tag on to the nfc reader</p>')
|
||||||
document.write('<p>Pleas hold your tag on to the nfc reader</p>')
|
});
|
||||||
});
|
socket.on("error", function(data) {
|
||||||
socket.on("error", function(data) {
|
alert(data)
|
||||||
alert(data)
|
window.location="http://matekasse.server.c3h/"
|
||||||
window.location="http://matekasse.server.c3h/"
|
});
|
||||||
});
|
socket.on("finished", function(data){
|
||||||
socket.on("finished", function(data){
|
alert(data)
|
||||||
alert(data)
|
window.location="http://matekasse.server.c3h/"
|
||||||
window.location="http://matekasse.server.c3h/"
|
});
|
||||||
});
|
</script>
|
||||||
</script>
|
{% endblock %}
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block title %}
|
||||||
<title>add user</title>
|
add user
|
||||||
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
|
{% endblock %}
|
||||||
<p>
|
{% block content %}
|
||||||
<form action="/adduser/user" method="post"><input name="username" type="search" placeholder="Username"><button>Add user</button></form>
|
<form action="/adduser/user" method="post"><input name="username" type="search" placeholder="Username">
|
||||||
</p>
|
<button>Add user</button>
|
||||||
</html>
|
</form>
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
{% block title %} {% endblock %} - FlaskApp
|
<script src="/socket.io.js"
|
||||||
</title>
|
integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA=="
|
||||||
</head>
|
crossorigin="anonymous"
|
||||||
<body>
|
></script>
|
||||||
<nav>
|
<link rel="stylesheet" href="/new.css">
|
||||||
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
|
|
||||||
</nav>
|
<link rel="prefetch" href="/ka-ching.wav" />
|
||||||
<hr>
|
<link rel="shortcut icon" type="Logo/png" href="/ccc_logo.png"/>
|
||||||
<div class="conntent">
|
{% block customscript %}{% endblock %}
|
||||||
{% block content %} {% endblock %}
|
</head>
|
||||||
</div>
|
<body>
|
||||||
</body>
|
<nav>
|
||||||
</html>
|
<p><a href="/">index page</a>
|
||||||
|
| <a href="/list">user and tag list</a>
|
||||||
|
| <a href="/documentation">Documentation</a>
|
||||||
|
| <a href="/transactionlist">transactionlist</a>
|
||||||
|
| <a href="/transfare">transfare<font face="emoji">🎺⚧</font></a>
|
||||||
|
</p>
|
||||||
|
</nav>
|
||||||
|
<hr>
|
||||||
|
<div class="conntent">
|
||||||
|
{% block content %} {% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block customscript %}
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
var socket = io();
|
var socket = io();
|
||||||
var change = {{change}}
|
var change = {{change}}
|
||||||
|
@ -16,11 +15,11 @@
|
||||||
});
|
});
|
||||||
socket.on("error", function(data) {
|
socket.on("error", function(data) {
|
||||||
alert(data)
|
alert(data)
|
||||||
window.location="http://matekasse.server.c3h/"
|
window.location="/list"
|
||||||
});
|
});
|
||||||
socket.on("finished", function(data){
|
socket.on("finished", function(data){
|
||||||
alert(data)
|
alert(data)
|
||||||
window.location="http://matekasse.server.c3h/"
|
window.location="/list"
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
{% endblock %}
|
||||||
|
|
16
Website/templates/confirmation.html
Normal file
16
Website/templates/confirmation.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block customscript %}
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
if (confirm("{message}") == true) {
|
||||||
|
fetch("{{destination}}", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({data}),
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json; charset=UTF-8"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
window.location = "/list"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -1,47 +1,44 @@
|
||||||
<html>
|
{% extends "base.html" %}
|
||||||
|
{% block title %}
|
||||||
<head>
|
Documentation
|
||||||
<title>Documentation</title>
|
{% endblock %}
|
||||||
<link rel="stylesheet" type="text/css" href="documentation.css">
|
{% block customscript %}
|
||||||
<link rel="shortcut icon" type="Logo/png" href="ccc_logo.png"/>
|
<link rel="stylesheet" type="text/css" href="documentation.css">
|
||||||
</head>
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
<body>
|
<h1 class="header"> <u>Documentation</u> </h1>
|
||||||
<div id="Infos">
|
|
||||||
<p> <a href="/">index page</a> | <a href="/list">user and tag list</a></p>
|
<p> </p>
|
||||||
<p><a href="https://hannover.ccc.de/gitlab/anton/matekasse">https://hannover.ccc.de/gitlab/anton/matekasse</a></p>
|
<div id="text">
|
||||||
</div>
|
<h2>API:</h2>
|
||||||
<h1 class="header"> <u>Documentation</u> </h1>
|
<p>http://matekasse.server.c3h/api/tag_id</p>
|
||||||
|
<p>Post method {"id":tag_id}</p>
|
||||||
<p> </p>
|
<p>Response:
|
||||||
<div id="text">
|
{"mode":"error" "error":"{error}"} or
|
||||||
<h2>API:</h2>
|
{"mode":"message","username":"{username}","message":"{message}"} or
|
||||||
<p>http://matekasse.server.c3h/api/tag_id?={tag_id}</p>
|
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
|
||||||
<p>Response:
|
</p>
|
||||||
{"mode":"error" "error":"{error}"} or
|
<br></br>
|
||||||
{"mode":"message","username":"{username}","message":"{message}"} or
|
<p>http://matekasse.server.c3h/api/balance</p>
|
||||||
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
|
<p>Post method {"id":user_id, "change":change}</p>
|
||||||
</p>
|
<p>
|
||||||
<br></br>
|
If change = None or NaN the change will be -1
|
||||||
<p>http://matekasse.server.c3h/api/change?id={user_id}&?change={change}</p>
|
</p>
|
||||||
<p>
|
<p>Get method ?id=user_id</p>
|
||||||
If change = None or NaN the change will be -1
|
<p>
|
||||||
</p>
|
Response:
|
||||||
<p>
|
{"mode":"error" "error":"{error}"} or
|
||||||
Response:
|
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
|
||||||
{"mode":"error" "error":"{error}"} or
|
</p>
|
||||||
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
|
<br></br>
|
||||||
</p>
|
<h2>Error Codes:</h2>
|
||||||
<br></br>
|
<p>170: Tag already in use</p>
|
||||||
<h2>Error Codes:</h2>
|
<p>054: Tag does not exists</p>
|
||||||
<p>170: Tag already exists</p>
|
<p>757: User already exists</p>
|
||||||
<p>054: Tag does not exists</p>
|
<p>043: User does not exists</p>
|
||||||
<p>757: Usere already exists</p>
|
<p>352: Timeout</p>
|
||||||
<p>043: User does not exists</p>
|
<p>095: Input is not a Number</p>
|
||||||
<p>352: Timeout</p>
|
<p>638: Wrong Input</p>
|
||||||
<p>095: Input is not a Number</p>
|
<P>418: I'm a teapot</P>
|
||||||
<P>418: I'm a teapot</P>
|
</div>
|
||||||
</div>
|
{% endblock %}
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block title %}Error{% endblock %}
|
||||||
<title>Error</title>
|
{% block customscript %}
|
||||||
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
|
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
|
||||||
<p>
|
<p>
|
||||||
Error: {{error_code}}
|
Error: {{error_code}}
|
||||||
</p>
|
</p>
|
||||||
</html>
|
{% endblock %}
|
12
Website/templates/index.html
Normal file
12
Website/templates/index.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block customscript %}
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
window.location="/list"
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<a href="/list">user and tag list</a>
|
||||||
|
<p>The creator of this website accepts no liability for any linguistic or technical errors!</p>
|
||||||
|
<br style="line-height: 500%;"></br>
|
||||||
|
<a href="/documentation">Doumentation</a>
|
||||||
|
{% endblock %}
|
51
Website/templates/list.html
Normal file
51
Website/templates/list.html
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
Strichliste
|
||||||
|
{% endblock %}
|
||||||
|
{% block customscript %}
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
function play() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
var audio = new Audio('/ka-ching.wav');
|
||||||
|
audio.play();
|
||||||
|
|
||||||
|
audio.addEventListener("ended", function(){
|
||||||
|
resolve()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ka_ching(element) {
|
||||||
|
await play();
|
||||||
|
element.parentElement.submit();
|
||||||
|
}
|
||||||
|
var socket = io();
|
||||||
|
socket.on("update", function () {
|
||||||
|
window.location = "http://matekasse.server.c3h/list"
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form action="/list/user" method="get"><input name="user" type="search" placeholder="Search for user">
|
||||||
|
<button>Search</button>
|
||||||
|
</form>
|
||||||
|
<form action="/adduser" method="post">
|
||||||
|
<button type="submit">Add User</button>
|
||||||
|
</form>
|
||||||
|
<br></br>
|
||||||
|
{% for user in users %}
|
||||||
|
<form action="/change" method="post" style="display: inline;">
|
||||||
|
<p style="display: inline;">
|
||||||
|
<a href="list/user?id={{user[0]}}">{{user[1]|limit_length}}</a>: {{user[2]/100}}€
|
||||||
|
</p>
|
||||||
|
<input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<input name="change" type="number" lang="nb" step="0.01" max={{50000-user[2]/100}} min={{min_value-user[2]/100}} placeholder="add to balance">
|
||||||
|
</form>
|
||||||
|
<form action="/change" method="post" style="display: inline">
|
||||||
|
<input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<input name="change" value={{preis}} type="hidden">
|
||||||
|
<button onclick="ka_ching(this)" type="button">{{preis}}€</button>
|
||||||
|
</form>
|
||||||
|
<br style="line-height: 50%;"></br>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
12
Website/templates/redirect.html
Normal file
12
Website/templates/redirect.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<p>redirekting</p>
|
||||||
|
<a href="/list">destination</a>
|
||||||
|
{% endblock %}
|
||||||
|
{% block customscript %}
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
window.location = "/list";
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -1,7 +1,6 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
{% block customscript %}
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
<script type="text/javascript" charset="utf-8">
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
var socket = io();
|
var socket = io();
|
||||||
var user = {{ user }}
|
var user = {{ user }}
|
||||||
socket.on('connect', function() {
|
socket.on('connect', function() {
|
||||||
|
@ -23,4 +22,4 @@
|
||||||
window.location="http://matekasse.server.c3h/"
|
window.location="http://matekasse.server.c3h/"
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
{% endblock %}
|
||||||
|
|
10
Website/templates/removeuser.html
Normal file
10
Website/templates/removeuser.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
remove user
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<p>
|
||||||
|
<p>Deleted user {{user_name|safe}}</p>
|
||||||
|
<a href="/list">return to the tags and user list</a>
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
17
Website/templates/transactionlist.html
Normal file
17
Website/templates/transactionlist.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
Transactionlist
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
{% for action in action_list%}
|
||||||
|
<form action="/api/change" method="post">
|
||||||
|
<p style="display: inline;">{{action["statement"]}} userid:{{action["user_id"]}} {{action["before"]|limit_length}} {{action["after"]|limit_length}} {{action["change"]}}</p>
|
||||||
|
<input type="hidden" name="statement" value={{action["reverse_statement"]}}>
|
||||||
|
<input type="hidden" name="user_id" value={{action["reverse_user_id"]}}>
|
||||||
|
<input type="hidden" name="before" value={{action["reverse_before"]}}>
|
||||||
|
<input type="hidden" name="after" value={{action["reverse_after"]}}>
|
||||||
|
<input type="hidden" name="change" value={{action["reverse_change"]}}>
|
||||||
|
<button type="submit">rollback</button></form><br></br>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
34
Website/templates/transfare.html
Normal file
34
Website/templates/transfare.html
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
transfare
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form action="/api/transfare" method="post">
|
||||||
|
<p>
|
||||||
|
<select name="transfarefrom">
|
||||||
|
<option value="">Select the user to transfare from</option>
|
||||||
|
{% for user in user_list %}
|
||||||
|
<option value={{user[0]}}>{{user[1]}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<select name="transfareto">
|
||||||
|
<option value="">Select the user to transfare to</option>
|
||||||
|
{% for user in user_list %}
|
||||||
|
<option value={{user[0]}}>{{user[1]}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input name="change" type="number" lang="nb" step="0.01" max=1000 min=-1000 placeholder="money to transfare">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<button type="submit">transfare money</button>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
45
Website/templates/user.html
Normal file
45
Website/templates/user.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block customscript %}
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
var socket = io();
|
||||||
|
socket.on("update", function () {
|
||||||
|
window.location = "/list/user?id={{user[0]}}"
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
{% block title %}
|
||||||
|
{{user[1]}}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<p> {{user[1]}} : {{user[2]/100}}€ <p>
|
||||||
|
<form action="/addtag" method="post">
|
||||||
|
<input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<button type="submit">Add Tag</button>
|
||||||
|
</form>
|
||||||
|
<form action="/removetag" method="post">
|
||||||
|
<input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<button type="submit">Remove Tag</button>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
<form action="/change" method="post">
|
||||||
|
<input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<input name="change" type="number" lang="nb" step="0.01" max={{50000-user[2]/100}} min={{min_value-user[2]/100}} placeholder="add to balance">
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
<br></br>
|
||||||
|
<p>Tags:</p>
|
||||||
|
{% for tag in tags %}
|
||||||
|
<p>
|
||||||
|
<form action="/removetag" method="post">
|
||||||
|
<label for="removetag">{{tag[0]}} </label>
|
||||||
|
<input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<input name="tagid" type="hidden" value="{{tag[0]}}">
|
||||||
|
<button id="removetag" type="submit">Remove Tag</button>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
<br></br>
|
||||||
|
<form action="/removeuser" method="post"><input name="id" type="hidden" value="{{user[0]}}">
|
||||||
|
<button type="submit">Remove User</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
4
main.py
4
main.py
|
@ -10,11 +10,9 @@ def exit_handler():
|
||||||
sys.exit("Program sucsesfully exited")
|
sys.exit("Program sucsesfully exited")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
app_data = create_app()
|
|
||||||
app = app_data["app"]
|
|
||||||
socketio = app_data["socketio"]
|
socketio = app_data["socketio"]
|
||||||
atexit.register(exit_handler)
|
atexit.register(exit_handler)
|
||||||
socketio.run(app, host='0.0.0.0', port=5000)
|
socketio.run(app, host='0.0.0.0', port=5000)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
BIN
static/ka-ching.wav
Normal file
BIN
static/ka-ching.wav
Normal file
Binary file not shown.
8
static/new.min.css
vendored
Normal file
8
static/new.min.css
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Minified by jsDelivr using clean-css v4.2.1.
|
||||||
|
* Original file: /npm/@exampledev/new.css@1.1.2/new.css
|
||||||
|
*
|
||||||
|
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
|
||||||
|
*/
|
||||||
|
:root{--nc-font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--nc-font-mono:Consolas,monaco,'Ubuntu Mono','Liberation Mono','Courier New',Courier,monospace;--nc-tx-1:#000000;--nc-tx-2:#1A1A1A;--nc-bg-1:#FFFFFF;--nc-bg-2:#F6F8FA;--nc-bg-3:#E5E7EB;--nc-lk-1:#0070F3;--nc-lk-2:#0366D6;--nc-lk-tx:#FFFFFF;--nc-ac-1:#79FFE1;--nc-ac-tx:#0C4047}@media (prefers-color-scheme:dark){:root{--nc-tx-1:#ffffff;--nc-tx-2:#eeeeee;--nc-bg-1:#000000;--nc-bg-2:#111111;--nc-bg-3:#222222;--nc-lk-1:#3291FF;--nc-lk-2:#0070F3;--nc-lk-tx:#FFFFFF;--nc-ac-1:#7928CA;--nc-ac-tx:#FFFFFF}}*{margin:0;padding:0}address,area,article,aside,audio,blockquote,datalist,details,dl,fieldset,figure,form,iframe,img,input,meter,nav,ol,optgroup,option,output,p,pre,progress,ruby,section,table,textarea,ul,video{margin-bottom:1rem}button,html,input,select{font-family:var(--nc-font-sans)}body{margin:0 auto;max-width:750px;padding:2rem;border-radius:6px;overflow-x:hidden;word-break:break-word;overflow-wrap:break-word;background:var(--nc-bg-1);color:var(--nc-tx-2);font-size:1.03rem;line-height:1.5}::selection{background:var(--nc-ac-1);color:var(--nc-ac-tx)}h1,h2,h3,h4,h5,h6{line-height:1;color:var(--nc-tx-1);padding-top:.875rem}h1,h2,h3{color:var(--nc-tx-1);padding-bottom:2px;margin-bottom:8px;border-bottom:1px solid var(--nc-bg-2)}h4,h5,h6{margin-bottom:.3rem}h1{font-size:2.25rem}h2{font-size:1.85rem}h3{font-size:1.55rem}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:.875rem}a{color:var(--nc-lk-1)}a:hover{color:var(--nc-lk-2)}abbr:hover{cursor:help}blockquote{padding:1.5rem;background:var(--nc-bg-2);border-left:5px solid var(--nc-bg-3)}abbr{cursor:help}blockquote :last-child{padding-bottom:0;margin-bottom:0}header{background:var(--nc-bg-2);border-bottom:1px solid var(--nc-bg-3);padding:2rem 1.5rem;margin:-2rem calc(0px - (50vw - 50%)) 2rem;padding-left:calc(50vw - 50%);padding-right:calc(50vw - 50%)}header h1,header h2,header h3{padding-bottom:0;border-bottom:0}header>:first-child{margin-top:0;padding-top:0}header>:last-child{margin-bottom:0}a button,button,input[type=button],input[type=reset],input[type=submit]{font-size:1rem;display:inline-block;padding:6px 12px;text-align:center;text-decoration:none;white-space:nowrap;background:var(--nc-lk-1);color:var(--nc-lk-tx);border:0;border-radius:4px;box-sizing:border-box;cursor:pointer;color:var(--nc-lk-tx)}a button[disabled],button[disabled],input[type=button][disabled],input[type=reset][disabled],input[type=submit][disabled]{cursor:default;opacity:.5;cursor:not-allowed}.button:focus,.button:hover,button:focus,button:hover,input[type=button]:focus,input[type=button]:hover,input[type=reset]:focus,input[type=reset]:hover,input[type=submit]:focus,input[type=submit]:hover{background:var(--nc-lk-2)}code,kbd,pre,samp{font-family:var(--nc-font-mono)}code,kbd,pre,samp{background:var(--nc-bg-2);border:1px solid var(--nc-bg-3);border-radius:4px;padding:3px 6px;font-size:.9rem}kbd{border-bottom:3px solid var(--nc-bg-3)}pre{padding:1rem 1.4rem;max-width:100%;overflow:auto}pre code{background:inherit;font-size:inherit;color:inherit;border:0;padding:0;margin:0}code pre{display:inline;background:inherit;font-size:inherit;color:inherit;border:0;padding:0;margin:0}details{padding:.6rem 1rem;background:var(--nc-bg-2);border:1px solid var(--nc-bg-3);border-radius:4px}summary{cursor:pointer;font-weight:700}details[open]{padding-bottom:.75rem}details[open] summary{margin-bottom:6px}details[open]>:last-child{margin-bottom:0}dt{font-weight:700}dd::before{content:'→ '}hr{border:0;border-bottom:1px solid var(--nc-bg-3);margin:1rem auto}fieldset{margin-top:1rem;padding:2rem;border:1px solid var(--nc-bg-3);border-radius:4px}legend{padding:auto .5rem}table{border-collapse:collapse;width:100%}td,th{border:1px solid var(--nc-bg-3);text-align:left;padding:.5rem}th{background:var(--nc-bg-2)}tr:nth-child(even){background:var(--nc-bg-2)}table caption{font-weight:700;margin-bottom:.5rem}textarea{max-width:100%}ol,ul{padding-left:2rem}li{margin-top:.4rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}mark{padding:3px 6px;background:var(--nc-ac-1);color:var(--nc-ac-tx)}input,select,textarea{padding:6px 12px;margin-bottom:.5rem;background:var(--nc-bg-2);color:var(--nc-tx-2);border:1px solid var(--nc-bg-3);border-radius:4px;box-shadow:none;box-sizing:border-box}img{max-width:100%}
|
||||||
|
/*# sourceMappingURL=/sm/4a51164882967d28a74fabce02685c18fa45a529b77514edc75d708f04dd08b9.map */
|
6046
static/socket.io.js
Normal file
6046
static/socket.io.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -23,14 +23,14 @@ def test_index(client):
|
||||||
|
|
||||||
#/adduser
|
#/adduser
|
||||||
def test_adduser(client):
|
def test_adduser(client):
|
||||||
response = client.get('/adduser/user')
|
response = client.post('/adduser/user', data={})
|
||||||
assert "418" in response.data.decode('utf-8')
|
assert "418" in response.data.decode('utf-8')
|
||||||
|
|
||||||
def test_adduser_new(app, client):
|
def test_adduser_new(app, client):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db = get_db()
|
db = get_db()
|
||||||
assert db is get_db()
|
assert db is get_db()
|
||||||
response = client.get('/adduser/user?username=test')
|
response = client.post('/adduser/user', data={user_name:"test"})
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
c.execute("SELECT * FROM users WHERE username = ?", ["test"])
|
c.execute("SELECT * FROM users WHERE username = ?", ["test"])
|
||||||
data = c.fetchone()
|
data = c.fetchone()
|
||||||
|
@ -40,7 +40,7 @@ def test_adduser_new(app, client):
|
||||||
assert data[2] == 0
|
assert data[2] == 0
|
||||||
|
|
||||||
def test_adduser_allreadyexists(client):
|
def test_adduser_allreadyexists(client):
|
||||||
response = client.get('/adduser/user?username=test')
|
response = client.post('/adduser/user', data={username:"test"})
|
||||||
assert "Error: 757" in response.data.decode('utf-8')
|
assert "Error: 757" in response.data.decode('utf-8')
|
||||||
|
|
||||||
#/addtag
|
#/addtag
|
||||||
|
@ -49,7 +49,7 @@ def test_addtag(client):
|
||||||
assert response.data.decode('utf-8') == "Error: 095"
|
assert response.data.decode('utf-8') == "Error: 095"
|
||||||
|
|
||||||
def test_addtag_userid_nan(client):
|
def test_addtag_userid_nan(client):
|
||||||
response = client.get('/addtag?id=test')
|
response = client.post('/addtag', data={id:1})
|
||||||
assert response.data.decode('utf-8') == "Error: 095"
|
assert response.data.decode('utf-8') == "Error: 095"
|
||||||
|
|
||||||
def test_add_tag_direktli(app):
|
def test_add_tag_direktli(app):
|
||||||
|
@ -166,4 +166,4 @@ def test_sqlinjektion_adduser(app, client):
|
||||||
assert data[1] == i
|
assert data[1] == i
|
||||||
assert data[2] == 0
|
assert data[2] == 0
|
||||||
assert "tag was sucsesfully added" in response.data.decode('utf-8')
|
assert "tag was sucsesfully added" in response.data.decode('utf-8')
|
||||||
count += 1
|
count += 1
|
||||||
|
|
Loading…
Reference in a new issue