1
0
Fork 0
forked from anton/matekasse

Compare commits

...

68 commits

Author SHA1 Message Date
bton 9c7f2cd0cb fixed somthing I hope 2024-03-29 19:57:11 +01:00
bton 03654ac4cf fixed 2024-03-20 20:02:11 +01:00
bton ed8bd817b7 fixed 2024-03-20 20:01:37 +01:00
bton 404e292450 fixed 2024-03-20 20:01:00 +01:00
bton fbe6b45050 fixed 2024-03-20 19:58:02 +01:00
bton cdbcbea91a deleted non used file 2024-03-20 19:53:16 +01:00
bton be77d21577 Merge branch 'master' of ssh://hannover.ccc.de:3071/anton/matekasse 2024-03-20 00:19:46 +01:00
bton 960f79f8e5 removed matekasse.server.c3h 2024-03-19 23:59:40 +01:00
bton 8387b6ccba removet matekasse.server.c3h 2024-03-19 23:54:51 +01:00
bton dd9e3463c9 Transaction log without time 2024-03-19 23:52:49 +01:00
bton e76e5beae7 there where still some safe 2024-03-13 21:49:23 +01:00
bton 6b70c563b5 - 2024-03-13 21:31:51 +01:00
bton 5ab0b3db7d - 2024-03-13 21:22:57 +01:00
bton 069efb54f2 ( 2024-03-13 21:20:45 +01:00
bton 22d441a1c0 escape kram wieder rückgängig machen 2024-03-13 21:10:34 +01:00
bton 437a7e596c log statements 2024-03-13 20:50:34 +01:00
bton 657c500f24 Ahhhhhhhhhhhhhhhh 2024-03-13 19:29:15 +01:00
bton f6c06771dd Ahhhhhhhhhhh 2024-03-13 19:27:45 +01:00
bton 6f0edf0feb Ahhhh 2024-03-13 19:26:21 +01:00
bton ce8acc10b1 fixed stuff 2024-03-06 21:54:57 +01:00
bton 5e9e584f04 added escape 2024-03-06 21:45:02 +01:00
bton f4a1cb8369 added escape 2024-03-06 21:44:02 +01:00
bton f8dc320735 added escape 2024-03-06 21:41:49 +01:00
bton 04fd8a20c2 added escape 2024-03-06 21:38:53 +01:00
bton ff0c91e3e8 added escape 2024-03-06 21:35:34 +01:00
bton 3127e2de1f added escape 2024-03-06 21:31:00 +01:00
bton c86b91a246 removed escape 2024-03-06 21:27:12 +01:00
bton f4181ade07 Was Commite ich hier? 2024-03-06 20:43:48 +01:00
bton f691e7534d AHHH escape 2024-03-06 20:41:45 +01:00
anton 364dfb69b6 Merge pull request 'add css / wolkenflattern wegwerfen' (#34) from 33_schoeeeener into master
Reviewed-on: anton/matekasse#34
2024-03-06 18:17:45 +00:00
Jonas 64ce118f80 add static socket.io.js 2024-03-06 19:03:13 +01:00
Jonas 389c14358e add css / wolkenflattern wegwerfen 2024-03-06 19:03:06 +01:00
bton ce009a278b new db system 2024-03-01 21:59:30 +01:00
bton 7f1f908961 ahh 2024-02-25 17:54:51 +01:00
bton dc71f8dcf4 ahh 2024-02-25 17:53:25 +01:00
bton 0147e61c6b Es muss im Stable getestet werden 2024-02-25 17:36:36 +01:00
bton ac907638e6 log und so 2024-02-25 17:24:44 +01:00
bton 5cb4dcc533 float errors fixed 2024-02-24 00:14:43 +01:00
bton 64e0c340c3 removed print 2024-02-23 23:57:54 +01:00
bton a8fec178e6 fixed number errors 2024-02-23 23:57:31 +01:00
bton 389e6ffcee AHHHHH 2024-02-23 22:49:25 +01:00
bton 1a51402170 float to int 2024-02-23 22:47:12 +01:00
bton 701d9c2f1e main wurde gesäubert 2024-02-22 00:19:59 +01:00
bton ccb4d64cde Updated README 2024-02-22 00:04:59 +01:00
bton 34eb392ce0 doch nicht 2024-02-21 23:36:32 +01:00
bton 109f7eb4c2 removed lines from main.py 2024-02-21 23:33:32 +01:00
anton 42b8a774ea Merge pull request 'könnte so klappen' (#32) from 31_templates_vereinfachen into master
Reviewed-on: anton/matekasse#32
2024-02-21 22:30:36 +00:00
Jonas 1f227df358 hupsala noch was vergessen 2024-02-21 22:13:24 +01:00
Jonas 19fbecda56 könnte so klappen 2024-02-21 22:02:07 +01:00
bton 727617e2be main 2024-02-21 18:54:55 +01:00
bton 75081d5020 , and . 2024-02-20 18:11:23 +01:00
bton ef43f79ff4 typo 2024-02-20 18:05:43 +01:00
bton 8d25e0b645 main.py wird doch gebraucht 2024-02-20 18:05:14 +01:00
bton d55b7c5aea balance get api 2024-02-20 17:33:56 +01:00
bton 55124040ae fixed the README 2024-02-17 02:16:49 +01:00
bton 66babf1b2c delted stuff 2024-02-17 02:14:08 +01:00
bton 5179ec792c jinja 2024-02-17 02:12:27 +01:00
bton 2432eed1ae Doc repariert 2024-02-16 23:11:12 +01:00
bton fd5fd4d78c -1.5€ Button und preis var 2024-02-16 22:51:32 +01:00
bton 64580f02cb New error 2024-02-16 21:19:11 +01:00
bton 56aa79378b Doc Input Error 2024-02-16 19:54:32 +01:00
bton e9acd07fb4 test 2024-02-14 20:52:50 +01:00
2000-Trek e11512f458 1 ct 2023-12-20 19:47:38 +01:00
2000-Trek f927a70f60 removed get method from /api/change 2023-12-02 18:14:34 +01:00
2000-Trek 3832282101 change balance next to balance 2023-12-02 17:27:36 +01:00
2000-Trek d9aff6a56a Documentation api to post 2023-12-01 23:23:11 +01:00
anton fda3f58cca Merge pull request 'Update Website/templates/documentation.html' (#22) from j3d1/matekasse:j3d1-patch-1 into master
Reviewed-on: anton/matekasse#22
2023-12-01 16:38:39 +00:00
j3d1 2b33f89d8c Update Website/templates/documentation.html 2023-11-26 21:47:24 +00:00
23 changed files with 6507 additions and 313 deletions

4
.gitignore vendored
View file

@ -1,5 +1,4 @@
*.db
socket.io.js
__pycache__/
logs/*
venv/*
@ -10,4 +9,5 @@ flask_session/
/test/.pytest_cache/
/test/flask_session/
/Website/__pycache__/
/Website/.pytest_cache/
/Website/.pytest_cache/
/.idea

6
README
View file

@ -5,8 +5,6 @@ How to get started:
source venv/bin/activate
install requiremens:
pip install -r requirements.txt
create the log folder:
mkdir logs
start the program:
python main.py
You can now accses the Website on http://127.0.0.1:5000
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

View file

@ -1,28 +1,15 @@
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_session import Session
from markupsafe import escape
from .db import get_db
from Website.db import get_db
import Website.db as db_handler
from datetime import datetime
finished = None
preis = -150 #Ein Getraenk
#flask_config
DATABASE = './Website/mate.db'
#def create_logs(app):
# now = datetime.datetime.now().strftime('%d-%m-%Y-%H-%M-%S')
# 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)
# app.logger = logging.getLogger('db')
#
# app.logger.info("Website is starting")
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):
app = Flask(__name__)
key = str(uuid.uuid4().hex)
@ -35,10 +22,9 @@ def create_app(test_config=None):
try:
os.makedirs(app.instance_path)
except OSError:
pass
#with app.app_context():
# create_logs(app)
Session(app)
socketio = SocketIO(app)
@ -55,25 +41,21 @@ def create_app(test_config=None):
#website
@app.route('/favicon.ico')
@app.route('/ccc_logo.png')
def favicon():
return send_file("../static/Logo_CCC.svg.png")
#@app.route('/socket.io.js')
#def socketiojs():
# return url_for('static', filename='socket.io.js')
@app.route('/socket.io.js')
def socketiojs():
return send_file('../static/socket.io.js')
@app.route('/new.css')
def newcss():
return send_file('../static/new.min.css')
@app.route("/")
def index():
return """
<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>
"""
return render_template("index.html")
@app.route("/list")
def list():
@ -81,34 +63,54 @@ def create_app(test_config=None):
c = db.cursor()
c.execute("SELECT * FROM users")
users = c.fetchall()
text = ""
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>'
return render_template("list.html", users=users, preis=(preis/100))
@app.route("/transactionlist")
def transactionlist():
db = get_db()
c = db.cursor()
text = ""
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()
for i in transactionlist:
text = text + f"<p>{i[0]} userid: {i[1]} {i[2]} {i[3]} to {i[4]}</p>"
statement = i[0]
user_id = i[1]
before = i[2]
after = i[3]
change = i[4]
if statement == "balance":
reverse_statement = "balance"
reverse_user_id = user_id
reverse_before = None
reverse_after = None
reverse_change = change *(-1)
elif statement == "add_user":
reverse_statement = "remove_user"
reverse_user_id = user_id
reverse_before = after
reverse_after = None
reverse_change = None
elif statement == "remove_user":
reverse_statement = "add_user"
reverse_user_id = user_id
reverse_before = None
reverse_after = before
reverse_change = None
elif statement == "add_tag":
reverse_statement = "remove_tag"
reverse_user_id = user_id
reverse_before = after
reverse_after = None
reverse_change = None
elif statement == "remove_tag":
reverse_statement = "add_tag"
reverse_user_id = user_id
reverse_before = None
reverse_after = before
reverse_change = None
else:
raise Exception(statement)
text = text + f'<form action="/api/change" method="post"><p style="display: inline;">{statement} userid:{user_id} {before} {after} {change}</p><input type="hidden" name="statement" value={reverse_statement}><input type="hidden" name="user_id" value={reverse_user_id}><input type="hidden" name="before" value={reverse_before}><input type="hidden" name="after" value={reverse_after}><input type="hidden" name="change" value={reverse_change}><button type="submit">rollback</button></form><br></br>'
return text
@app.route("/list/user", methods=['GET'])
@ -117,41 +119,18 @@ def create_app(test_config=None):
c = db.cursor()
id = request.args.get("id")
c.execute(f"SELECT * FROM users WHERE id=?", [id])
user_list = c.fetchall()
if user_list != []:
user = user_list[0]
user = c.fetchone()
if user != None :
c.execute(f"SELECT * FROM tags WHERE userid={user[0]}")
tags = c.fetchall()
text = ""
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>
"""
return render_template("user.html", user=user, tags=tags)
else:
return render_template("error.html", error_code="043")
@app.route("/adduser", methods=['POST'])
def new_user():
return render_template("adduser.html")
return render_template("adduser.html")
@app.route("/removeuser", methods=['POST'])
def remove_user():
@ -159,16 +138,12 @@ def create_app(test_config=None):
c = db.cursor()
user_id = request.form["id"]
c.execute(f"SELECT * FROM users WHERE id=?", [user_id])
users = c.fetchall()
if users != []:
user_name = users[0][1]
c.execute(f"DELETE FROM tags WHERE userid=?", [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)
user = c.fetchone()
if user != None:
user_name = user[1]
db_handler.remove_user(user_id)
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:
return render_template("error.html", error_code="043")
@ -181,20 +156,11 @@ def create_app(test_config=None):
return render_template("error.html", error_code="418")
c.execute("SELECT * FROM users WHERE username=?", [username])
if c.fetchall() == []:
c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [username])
db.commit()
db_handler.add_user(username)
socketio.emit("update", "update")
c.execute(f"SELECT * FROM users WHERE username=?", [username])
user = c.fetchone()
log(type="adduser", userid=user[0], after=user[1])
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>
"""
return render_template("redirect.html")
else:
return render_template("error.html", error_code="757")
@ -205,27 +171,16 @@ def create_app(test_config=None):
c = db.cursor()
try:
user_id = request.form["id"]
change = float(request.form["change"])
print(change)
change = int(float(request.form["change"]) * float(100))
except:
return render_template("error.html", error_code="095")
c.execute(f"SELECT * FROM users WHERE id=?", [user_id])
users = c.fetchall()
if users != []:
balance_old = users[0][2]
c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user_id}")
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])
db_handler.change_balance(user_id, change)
socketio.emit("update", "update")
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>
</html>
"""
return render_template("redirect.html")
else:
return render_template("error.html", error_code="043")
@ -285,17 +240,9 @@ def create_app(test_config=None):
c = db.cursor()
c.execute(f"SELECT * FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id])
if c.fetchall != []:
c.execute(f"DELETE FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id])
db.commit()
db_handler.remove_tag(tag_id)
message = f"Removed {tag_id} from user {user_id}"
log(type="removetag", userid=user_id, before=tag_id)
return f"""
<html>
<script>
window.location="/"
</script>
</html>
"""
return render_template("redirect.html")
else:
return render_template("error.html", error_code="054")
@ -326,44 +273,50 @@ def create_app(test_config=None):
socketio.emit("error", "418", to=session[id])
leave_room(session[id])
#api
@app.route("/api/change", methods=['GET', 'POST'])
@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=['POST'])
def get_id():
db = get_db()
c = db.cursor()
try:
userid = request.form["id"]
except:
userid = request.args.get("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 = -1.5
c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user[0]}")
db.commit()
c.execute(f"SELECT * FROM users WHERE id = {userid}")
user_new = c.fetchone()
log(type="balance", userid=user[0], before=user[2], after=user_new[2])
socketio.emit("update", "update")
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user_new[2]}))
else:
return make_response(json.dumps({"mode":"error","error":"043"}))
@app.route("/api/tag_id", methods=['GET', 'POST'])
def get_id():
global finished
global message
db = get_db()
c = db.cursor()
try:
tag_id = request.form["id"]
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])
tag_list = c.fetchall()
@ -383,20 +336,16 @@ def create_app(test_config=None):
finished = queue_item
return make_response(json.dumps({"mode":"error","error":"170"}))
else:
c.execute(f"INSERT OR IGNORE INTO tags (tagid, userid) VALUES ({tag_id}, ?)", [user_id])
db.commit()
db_handler.add_tag(user_id, tag_id)
message = f"Added {tag_id} to {username}"
log(type="addtag", userid=user_id ,after=tag_id)
finished = queue_item
return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was added"}))
elif state == "remove":
c.execute(f"SELECT * FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id])
tags = c.fetchall()
if tags != []:
c.execute(f"DELETE FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id])
db.commit()
message = f"Removed {tag_id} from {username}"
log(type="removetag", userid=user_id, before=tag_id)
finished = queue_item
return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was removed"}))
else:
@ -414,11 +363,9 @@ def create_app(test_config=None):
if user_list != []:
balance_old = user_list[0][2]
if user_queue.qsize() == 0:
c.execute(f"UPDATE users SET balance = balance - 150 WHERE id={tag[1]}")
db.commit()
db_handler.change_balance(tag[1], preis)
c.execute(f"SELECT * FROM users WHERE id={tag[1]}")
user = c.fetchone()
log(type="balance", userid=user[0], before=balance_old, after=user[2])
socketio.emit("update", "update")
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]/100}))
else:
@ -426,9 +373,35 @@ def create_app(test_config=None):
socketio.emit("update", "update")
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
@app.route("/documentation")
def documentation():
return render_template("documentation.html")
return {"app":app,"socketio":socketio}
return {"app":app,"socketio":socketio}

View file

@ -1,9 +1,58 @@
from re import M
from markupsafe import escape
import sqlite3
from datetime import datetime
import click
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():
if 'db' not in g:

View file

@ -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;

View file

@ -12,10 +12,10 @@ CREATE TABLE IF NOT EXISTS "tags" (
PRIMARY KEY("tagid")
);
CREATE TABLE IF NOT EXISTS "transaction_log" (
"timestamp" INTEGER NOT NULL,
"userid" INTEGER NOT NULL,
"type" TEXT NOT NULL,
"before" TEXT,
"after" TEXT
"type" TEXT NOT NULL,
"user_id" INTEGER,
"before" TEXT,
"after" TEXT,
"change" INTEGER
);
COMMIT;
COMMIT;

View file

@ -1,26 +1,25 @@
<!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();
var user = {{ user }}
socket.on('connect', function() {
socket.emit('addtag', {data: user});
});
socket.on("busy", function(){
document.write('<p>the nfc reader is busy at the moment. Pleas Wait ...</p>')
socket.emit('addtag', {data: user})
});
socket.on("wait", function(){
document.write('<p>Pleas hold your tag on to the nfc reader</p>')
});
socket.on("error", function(data) {
alert(data)
window.location="http://matekasse.server.c3h/"
});
socket.on("finished", function(data){
alert(data)
window.location="http://matekasse.server.c3h/"
});
</script>
</html>
{% extends "base.html" %}
{% block customscript %}
<script type="text/javascript" charset="utf-8">
var socket = io();
var user = {{ user }}
socket.on('connect', function() {
socket.emit('addtag', {data: user});
});
socket.on("busy", function(){
document.write('<p>the nfc reader is busy at the moment. Pleas Wait ...</p>')
socket.emit('addtag', {data: user})
});
socket.on("wait", function(){
document.write('<p>Pleas hold your tag on to the nfc reader</p>')
});
socket.on("error", function(data) {
alert(data)
window.location="http://matekasse.server.c3h/"
});
socket.on("finished", function(data){
alert(data)
window.location="http://matekasse.server.c3h/"
});
</script>
{% endblock %}

View file

@ -1,8 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<title>add user</title>
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
<p>
<form action="/adduser/user" method="post"><input name="username" type="search" placeholder="Username"><button>Add user</button></form>
</p>
</html>
{% extends "base.html" %}
{% block title %}
add user
{% endblock %}
{% block content %}
<form action="/adduser/user" method="post"><input name="username" type="search" placeholder="Username">
<button>Add user</button>
</form>
</p>
{% endblock %}

View file

@ -1,17 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>
{% block title %} {% endblock %} - FlaskApp
</title>
</head>
<body>
<nav>
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
</nav>
<hr>
<div class="conntent">
{% block content %} {% endblock %}
</div>
</body>
</html>
<head>
<title>{% block title %}{% endblock %}</title>
<script src="/socket.io.js"
integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA=="
crossorigin="anonymous"
></script>
<link rel="stylesheet" href="/new.css">
<link rel="shortcut icon" type="Logo/png" href="/ccc_logo.png"/>
{% block customscript %}{% endblock %}
</head>
<body>
<nav>
<p><a href="/">index page</a>
| <a href="/list">user and tag list</a>
| <a href="/documentation">Documentation</a>
| <a href="/transactionlist">transactionlist</a>
</p>
</nav>
<hr>
<div class="conntent">
{% block content %} {% endblock %}
</div>
</body>
</html>

View file

@ -1,6 +1,5 @@
<!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>
{% extends "base.html" %}
{% block customscript %}
<script type="text/javascript" charset="utf-8">
var socket = io();
var change = {{change}}
@ -16,11 +15,11 @@
});
socket.on("error", function(data) {
alert(data)
window.location="http://matekasse.server.c3h/"
window.location="/list"
});
socket.on("finished", function(data){
alert(data)
window.location="http://matekasse.server.c3h/"
window.location="/list"
});
</script>
</html>
{% endblock %}

View 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 %}

View file

@ -1,47 +1,44 @@
<html>
<head>
<title>Documentation</title>
<link rel="stylesheet" type="text/css" href="documentation.css">
<link rel="shortcut icon" type="Logo/png" href="ccc_logo.png"/>
</head>
<body>
<div id="Infos">
<p> <a href="/">index page</a> | <a href="/list">user and tag list</a></p>
<p><a href="https://hannover.ccc.de/gitlab/anton/matekasse">https://hannover.ccc.de/gitlab/anton/matekasse</a></p>
</div>
<h1 class="header"> <u>Documentation</u> </h1>
<p>&nbsp;</p>
<div id="text">
<h2>API:</h2>
<p>http://matekasse.server.c3h/api/tag_id?={tag_id}</p>
<p>Response:
{"mode":"error" "error":"{error}"} or
{"mode":"message","username":"{username}","message":"{message}"} or
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
</p>
<br></br>
<p>http://matekasse.server.c3h/api/change?id={user_id}&?change={change}</p>
<p>
If change = None or NaN the change will be -1
</p>
<p>
Response:
{"mode":"error" "error":"{error}"} or
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
</p>
<br></br>
<h2>Error Codes:</h2>
<p>170: Tag already exists</p>
<p>054: Tag does not exists</p>
<p>757: Usere already exists</p>
<p>043: User does not exists</p>
<p>352: Timeout</p>
<p>095: Input is not a Number</p>
<P>418: I'm a teapot</P>
</div>
</body>
</html>
{% extends "base.html" %}
{% block title %}
Documentation
{% endblock %}
{% block customscript %}
<link rel="stylesheet" type="text/css" href="documentation.css">
{% endblock %}
{% block content %}
<h1 class="header"> <u>Documentation</u> </h1>
<p>&nbsp;</p>
<div id="text">
<h2>API:</h2>
<p>http://matekasse.server.c3h/api/tag_id</p>
<p>Post method {"id":tag_id}</p>
<p>Response:
{"mode":"error" "error":"{error}"} or
{"mode":"message","username":"{username}","message":"{message}"} or
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
</p>
<br></br>
<p>http://matekasse.server.c3h/api/balance</p>
<p>Post method {"id":user_id, "change":change}</p>
<p>
If change = None or NaN the change will be -1
</p>
<p>Get method ?id=user_id</p>
<p>
Response:
{"mode":"error" "error":"{error}"} or
{"mode":"balance", "username":"{username}", "balance":"{balance}"}
</p>
<br></br>
<h2>Error Codes:</h2>
<p>170: Tag already in use</p>
<p>054: Tag does not exists</p>
<p>757: User already exists</p>
<p>043: User does not exists</p>
<p>352: Timeout</p>
<p>095: Input is not a Number</p>
<p>638: Wrong Input</p>
<P>418: I'm a teapot</P>
</div>
{% endblock %}

View file

@ -1,8 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<title>Error</title>
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
<p>
{% extends "base.html" %}
{% block title %}Error{% endblock %}
{% block customscript %}
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
<p>
Error: {{error_code}}
</p>
</html>
</p>
{% endblock %}

View 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 %}

View file

@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block title %}
Strichliste
{% endblock %}
{% block customscript %}
<script type="text/javascript" charset="utf-8">
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 i in users %}
<form action="/change" method="post" style="display: inline;">
<p style="display: inline;">
<a href="list/user?id={{i[0]}}">{{i[1]}}</a>: {{i[2]/100}}€
</p>
<input name="id" type="hidden" value="{{i[0]}}">
<input name="change" type="number" lang="nb" step="0.01" placeholder="add to balance">
</form>
<form action="/change" method="post" style="display: inline">
<input name="id" type="hidden" value="{{i[0]}}">
<button type="submit" name="change" value={{preis}}>{{preis}}€</button>
</form>
<br style="line-height: 50%;"></br>
{% endfor %}
{% endblock %}

View 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 %}

View file

@ -1,7 +1,6 @@
<!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">
{% extends "base.html" %}
{% block customscript %}
<script type="text/javascript" charset="utf-8">
var socket = io();
var user = {{ user }}
socket.on('connect', function() {
@ -23,4 +22,4 @@
window.location="http://matekasse.server.c3h/"
});
</script>
</html>
{% endblock %}

View 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 %}

View 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" placeholder="change 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 %}

View file

@ -10,11 +10,9 @@ def exit_handler():
sys.exit("Program sucsesfully exited")
def main():
app_data = create_app()
app = app_data["app"]
socketio = app_data["socketio"]
atexit.register(exit_handler)
socketio.run(app, host='0.0.0.0', port=5000)
if __name__ == "__main__":
main()
main()

8
static/new.min.css vendored Normal file
View 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

File diff suppressed because it is too large Load diff

View file

@ -23,14 +23,14 @@ def test_index(client):
#/adduser
def test_adduser(client):
response = client.get('/adduser/user')
response = client.post('/adduser/user', data={})
assert "418" in response.data.decode('utf-8')
def test_adduser_new(app, client):
with app.app_context():
db = 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.execute("SELECT * FROM users WHERE username = ?", ["test"])
data = c.fetchone()
@ -40,7 +40,7 @@ def test_adduser_new(app, client):
assert data[2] == 0
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')
#/addtag
@ -49,7 +49,7 @@ def test_addtag(client):
assert response.data.decode('utf-8') == "Error: 095"
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"
def test_add_tag_direktli(app):
@ -166,4 +166,4 @@ def test_sqlinjektion_adduser(app, client):
assert data[1] == i
assert data[2] == 0
assert "tag was sucsesfully added" in response.data.decode('utf-8')
count += 1
count += 1