1
0
Fork 0
forked from bton/matekasse
matekasse/main.py
2023-07-05 23:15:44 +02:00

369 lines
No EOL
15 KiB
Python

from crypt import methods
from fileinput import filename
import queue, sqlite3, time, atexit, sys, uuid, json, urllib.parse, logging, datetime, os
from flask import Flask, render_template, request, make_response, session, url_for
from flask_socketio import SocketIO, join_room, leave_room
from flask_session import Session
from markupsafe import escape
#db_config test
db_path = 'mate.db'
conn = sqlite3.connect(db_path, check_same_thread=False)
c = conn.cursor()
#flask_config
app = Flask(__name__)
key = str(uuid.uuid4().hex)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = key
Session(app)
socketio = SocketIO(app)
#logging_config
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)
db_log = logging.getLogger('db')
website_log = logging.getLogger('website')
#var
status = True
users = queue.Queue()
finished = None
message = None
def exit_handler():
conn.commit()
conn.close()
website_log.info("Website exited")
sys.exit("Program sucsesfully exited")
#website
@app.route('/favicon.ico')
def favicon():
return url_for('static', filename='Logo_CCC.svg.png')
@app.route('/socket.io.js')
def socketiojs():
return url_for('static', filename='socket.io.js')
@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="http://matekasse.server.c3h/list"
</script>
"""
@app.route("/list")
def list():
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]} <form action="/change" method="get"><input name="id" type="hidden" value="{i[0]}"> Change balance: <input name="change"><input type="submit"></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>
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
<p>1 Credit = 1,50 Euro</p>
<form action="/list/user" method="get"> Search for User: <input name="user"><input type="submit"></form>
<form action="/adduser" method="get"><button type="submit">Add User</button></form>
<br></br>
''' + text + '<a href="/documentation">Doumentation</a></html>'
@app.route("/list/user", methods=['GET'])
def user_info():
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]
c.execute(f"SELECT * FROM tags WHERE userid={user[0]}")
tags = c.fetchall()
text = ""
for tag in tags:
text = text + f"<p>{tag[0]}</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>
<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p>
<p> {escape(user[1])} : {user[2]} <p>
<form action="/addtag" method="get"><input name="id" type="hidden" value="{user[0]}"><button type="submit">Add Tag</button></form>
<form action="/removetag" method="get"><input name="id" type="hidden" value="{user[0]}"><button type="submit">Remove Tag</button></form>
</p><form action="/change" method="get"><input name="id" type="hidden" value="{user[0]}"> Change balance: <input name="change"><input type="submit"></form>
</p>
<br></br>
<p>Tags:</p>
{text}
<br></br>
<form action="/removeuser/confirmation" method="get"><input name="id" type="hidden" value="{user[0]}"><button type="submit">Remove User</button></form>
</html>
"""
else:
return "Error: 043"
@app.route("/adduser")
def new_user():
return render_template("adduser.html")
@app.route("/removeuser/confirmation", methods=['GET'])
def confirm_remove_user():
user_id = request.args.get("id")
return f'<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p> <p>Do your realy want to <a href="/removeuser?id={user_id}">remove the user</a></p>'
@app.route("/removeuser", methods=['GET'])
def remove_user():
user_id = request.args.get("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}")
db_log.info(f"Deleted all tags from user {user_id}")
c.execute(f"DELETE FROM users WHERE id={user_id}")
db_log.info(f"Deleted user {user_id}")
conn.commit()
socketio.emit("update", "update")
return f'<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>'
else:
return "Error: 043"
@app.route("/adduser/user", methods=['GET'])
def adduser():
username = request.args.get("username")
c.execute("SELECT * FROM users WHERE username=?", [username])
if c.fetchall() == []:
c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [username])
conn.commit()
socketio.emit("update", "update")
c.execute(f"SELECT * FROM users WHERE username=?", [username])
user = c.fetchall()[0]
db_log.info(f"Added user id: {user[0]} name: {user[2]}")
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="http://matekasse.server.c3h/list";
</script>
</html>
"""
else:
return '<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p><p>Error: 170</p> '
@app.route("/change", methods=['GET'])
def change():
try:
user_id = request.args.get("id")
change = int(request.args.get("change"))
except:
return '<p>Error: 095</p><a href="/list">tags and user list</a>'
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} WHERE id={user_id}")
conn.commit()
c.execute(f"SELECT * FROM users WHERE id={user_id}")
user = c.fetchall()[0]
db_log.info(f"Changed the balance from user {user[0]} from {balance_old} to {user[2]}")
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="http://matekasse.server.c3h/list";
</script>
</html>
"""
else:
return '<p><a href="/list">user and tag list</a> | <a href="/documentation">Documentation</a></p> <p>Error: 043</p>'
@app.route("/addtag", methods=['GET'])
def get_addtag_request():
global users
try:
user_id = int(request.args.get("id"))
except: #except im Normalen Code!
return "Error: 095"
session_id = uuid.uuid4()
session[id] = session_id
users.put([user_id, "add", session_id])
return render_template("addtag.html", user=user_id)
@socketio.on('addtag')
def request_addtag(data):
global finished
global message
join_room(session[id])
if len(users.queue) > 0:
user = users.queue[len(users.queue) - 1]
if user == [data["data"], "add", session[id]]:
socketio.emit("wait", "wait", to=session[id])
i = 0
while finished != [data["data"], "add", session[id]]:
time.sleep(1)
i += 1
if i > 20:
socketio.emit("error", "352", to=session[id])
notimportant = users.get()
break
else:
finished = None
socketio.emit("finished", f"{message}", to=session[id])
else:
socketio.emit("busy", "busy", to=session[id])
else:
socketio.emit("error", "418", to=session[id])
leave_room(session[id])
@app.route("/removetag", methods=['GET'])
def get_removetag_request():
global users
try:
user_id = int(request.args.get("id"))
except: #except im Normalen Code!
return "Wrong user id!"
session_id = uuid.uuid4()
session[id] = session_id
users.put([user_id, "remove", session_id])
return render_template("removetag.html", user=user_id)
@socketio.on('removetag')
def request_removetag(data):
global finished
global message
join_room(session[id])
if len(users.queue) > 0:
queue_item = users.queue[len(users.queue) - 1]
user = queue_item[0]
if queue_item == [data["data"], "remove", session[id]]:
socketio.emit("wait", "wait", to=session[id])
i = 0
while finished != [data["data"], "remove", session[id]]:
time.sleep(1)
i += 1
if i > 20:
socketio.emit("error", "352", to=session[id])
notimportant = users.get()
break
else:
finished = None
socketio.emit("finished", f"{message}", to=session[id])
else:
socketio.emit("busy", "busy", to=session[id])
else:
socketio.emit("error", "418", to=session[id])
leave_room(session[id])
#api
@app.route("/api/change", methods=['GET'])
def api_change():
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:
return make_response(json.dumps({"mode":"error","error":"095"}))
if change == None:
change = 1
c.execute(f"UPDATE users SET balance = balance + {change} WHERE id={user[0]}")
c.execute(f"SELECT * FROM users WHERE id = {userid}")
user_new = c.fetchall()[0]
db_log.info(f"Changed the balance from user {user[0]} from {user[2]} to {user_new[2]}")
socketio.emit("update", "update")
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'])
def get_id():
global finished
global message
tag_id = request.args.get("id")
c.execute(f"SELECT * FROM tags WHERE tagid=?", [tag_id])
tag_list = c.fetchall()
if users.qsize() > 0:
queue_item = users.get()
user = queue_item[0]
state = queue_item[1]
c.execute(f"SELECT * FROM users WHERE id={user}")
username = c.fetchall()[0][1]
if state == "add":
c.execute(f"SELECT * FROM tags WHERE tagid={tag_id}")
if c.fetchall() != []:
message = "Error: 170"
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})")
message = f"Added {tag_id} to {username}"
db_log.info(message)
finished = queue_item
conn.commit()
return make_response(json.dumps({"mode":"message","username":username,"message":"A tag was added"}))
elif state == "remove":
c.execute(f"SELECT * FROM tags WHERE (tagid = {tag_id} AND userid = {user})")
tags = c.fetchall()
if tags != []:
c.execute(f"DELETE FROM tags WHERE (tagid = {tag_id} AND userid = {user}) ")
message = f"Removed {tag_id} from {username}"
db_log.info(message)
finished = queue_item
conn.commit()
return make_response(json.dumps({"mode":"message","username":username,"message":"A tag was removed"}))
else:
message = "054"
finished = queue_item
return make_response(json.dumps({"mode":"error","error":"054"}))
finished = queue_item
socketio.emit("update", "update")
return make_response(json.dumps({"mode":"error","error":"418"}))
elif tag_list != []:
tag = tag_list[0]
c.execute(f"SELECT * FROM users WHERE id={tag[1]}")
user_list = c.fetchall()
if user_list != []:
balance_old = user_list[0][2]
if users.qsize() == 0:
c.execute(f"UPDATE users SET balance = balance - 1 WHERE id={tag[1]}")
conn.commit()
c.execute(f"SELECT * FROM users WHERE id={tag[1]}")
user = c.fetchall()[0]
db_log.info(f"Changed the balance from user {user[0]} from {balance_old} to {user[2]}")
socketio.emit("update", "update")
return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]}))
else:
return make_response(json.dumps({"mode":"error", "error":"043"}))
socketio.emit("update", "update")
return make_response(json.dumps({"mode":"error","error":"054"}))
#Documentation
@app.route("/documentation")
def documentation():
return render_template("documentation.html")
def main():
atexit.register(exit_handler)
website_log.info("Website is starting")
socketio.run(app, host='0.0.0.0', port=5000, cors_allowed_origins="*")