diff --git a/api-backend_blueprint/.env b/archiv/NETWORK-api-backend_blueprint/.env similarity index 100% rename from api-backend_blueprint/.env rename to archiv/NETWORK-api-backend_blueprint/.env diff --git a/api-backend_blueprint/README.md b/archiv/NETWORK-api-backend_blueprint/README.md similarity index 100% rename from api-backend_blueprint/README.md rename to archiv/NETWORK-api-backend_blueprint/README.md diff --git a/api-backend_blueprint/datenbank_erstellen.py b/archiv/NETWORK-api-backend_blueprint/datenbank_erstellen.py similarity index 100% rename from api-backend_blueprint/datenbank_erstellen.py rename to archiv/NETWORK-api-backend_blueprint/datenbank_erstellen.py diff --git a/api-backend_blueprint/requirements.txt b/archiv/NETWORK-api-backend_blueprint/requirements.txt similarity index 100% rename from api-backend_blueprint/requirements.txt rename to archiv/NETWORK-api-backend_blueprint/requirements.txt diff --git a/api-backend_blueprint/server.py b/archiv/NETWORK-api-backend_blueprint/server.py similarity index 100% rename from api-backend_blueprint/server.py rename to archiv/NETWORK-api-backend_blueprint/server.py diff --git a/api-backend_blueprint/ultimaker_example-integration.py b/archiv/NETWORK-api-backend_blueprint/ultimaker_example-integration.py similarity index 100% rename from api-backend_blueprint/ultimaker_example-integration.py rename to archiv/NETWORK-api-backend_blueprint/ultimaker_example-integration.py diff --git a/backend/myp_backend.db b/backend/myp_backend.db new file mode 100644 index 0000000..e69de29 diff --git a/backend/myp_backend.py b/backend/myp_backend.py new file mode 100644 index 0000000..e79a8af --- /dev/null +++ b/backend/myp_backend.py @@ -0,0 +1,148 @@ +from flask import Flask, render_template, request, redirect, url_for, jsonify, session +import sqlite3 +import bcrypt + +app = Flask(__name__) +app.secret_key = 'supersecretkey' + +# Database setup +def init_db(): + conn = sqlite3.connect('database.db') + c = conn.cursor() + c.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, password TEXT)''') + c.execute('''CREATE TABLE IF NOT EXISTS printers (id INTEGER PRIMARY KEY, name TEXT, status TEXT)''') + c.execute('''CREATE TABLE IF NOT EXISTS jobs (id INTEGER PRIMARY KEY, printer_id INTEGER, user TEXT, date TEXT, status TEXT)''') + conn.commit() + conn.close() + +init_db() + +# User registration (Admin setup) +def add_admin(): + conn = sqlite3.connect('database.db') + c = conn.cursor() + hashed_pw = bcrypt.hashpw('adminpassword'.encode('utf-8'), bcrypt.gensalt()) + c.execute("INSERT INTO users (username, password) VALUES (?, ?)", ('admin', hashed_pw)) + conn.commit() + conn.close() + +# Comment the next line after the first run +# add_admin() + +# API Endpoints +@app.route('/api/printers/status', methods=['GET']) +def get_printer_status(): + conn = sqlite3.connect('database.db') + c = conn.cursor() + c.execute("SELECT * FROM printers") + printers = c.fetchall() + conn.close() + return jsonify(printers) + +@app.route('/api/printers/job', methods=['POST']) +def create_job(): + if not session.get('logged_in'): + return jsonify({'error': 'Unauthorized'}), 403 + + data = request.json + user = session['username'] + printer_id = data['printer_id'] + conn = sqlite3.connect('database.db') + c = conn.cursor() + + c.execute("SELECT status FROM printers WHERE id=?", (printer_id,)) + status = c.fetchone()[0] + + if status == 'frei': + c.execute("INSERT INTO jobs (printer_id, user, date, status) VALUES (?, ?, datetime('now'), 'in progress')", + (printer_id, user)) + c.execute("UPDATE printers SET status='belegt' WHERE id=?", (printer_id,)) + conn.commit() + elif status == 'belegt': + return jsonify({'error': 'Printer already in use'}), 409 + else: + return jsonify({'error': 'Invalid printer status'}), 400 + + conn.close() + return jsonify({'message': 'Job created and printer turned on'}), 200 + +@app.route('/api/printers/reserve', methods=['POST']) +def reserve_printer(): + if not session.get('logged_in'): + return jsonify({'error': 'Unauthorized'}), 403 + + data = request.json + printer_id = data['printer_id'] + conn = sqlite3.connect('database.db') + c = conn.cursor() + + c.execute("SELECT status FROM printers WHERE id=?", (printer_id,)) + status = c.fetchone()[0] + + if status == 'frei': + c.execute("UPDATE printers SET status='reserviert' WHERE id=?", (printer_id,)) + conn.commit() + message = 'Printer reserved' + else: + message = 'Printer cannot be reserved' + + conn.close() + return jsonify({'message': message}), 200 + +@app.route('/api/printers/release', methods=['POST']) +def release_printer(): + if not session.get('logged_in'): + return jsonify({'error': 'Unauthorized'}), 403 + + data = request.json + printer_id = data['printer_id'] + conn = sqlite3.connect('database.db') + c = conn.cursor() + + c.execute("UPDATE printers SET status='frei' WHERE id=?", (printer_id,)) + conn.commit() + conn.close() + return jsonify({'message': 'Printer released'}), 200 + +# Authentication routes +@app.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'].encode('utf-8') + + conn = sqlite3.connect('database.db') + c = conn.cursor() + c.execute("SELECT * FROM users WHERE username=?", (username,)) + user = c.fetchone() + conn.close() + + if user and bcrypt.checkpw(password, user[2].encode('utf-8')): + session['logged_in'] = True + session['username'] = username + return redirect(url_for('dashboard')) + else: + return render_template('login.html', error='Invalid Credentials') + + return render_template('login.html') + +@app.route('/dashboard') +def dashboard(): + if not session.get('logged_in'): + return redirect(url_for('login')) + + conn = sqlite3.connect('database.db') + c = conn.cursor() + c.execute("SELECT * FROM printers") + printers = c.fetchall() + conn.close() + + return render_template('dashboard.html', printers=printers) + +@app.route('/logout') +def logout(): + session.clear() + return redirect(url_for('login')) + +if __name__ == '__main__': + app.run(debug=True) diff --git a/backend/templates/base.html b/backend/templates/base.html new file mode 100644 index 0000000..092d9aa --- /dev/null +++ b/backend/templates/base.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>3D Printer Management</title> + <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> + <link href="https://cdn.jsdelivr.net/npm/daisyui@1.14.0/dist/full.css" rel="stylesheet"> +</head> +<body class="bg-black text-white"> + <nav class="bg-gray-800 p-4"> + <div class="container mx-auto"> + <h1 class="text-xl">3D Printer Management Dashboard</h1> + </div> + </nav> + <div class="container mx-auto mt-5"> + {% block content %}{% endblock %} + </div> +</body> +</html> diff --git a/backend/templates/dashboard.html b/backend/templates/dashboard.html new file mode 100644 index 0000000..812b5a6 --- /dev/null +++ b/backend/templates/dashboard.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block content %} +<h2 class="text-2xl mb-4">Printer Status</h2> +<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> + {% for printer in printers %} + <div class="card bg-gray-900 shadow-xl"> + <div class="card-body"> + <h2 class="card-title">{{ printer[1] }}</h2> + <p>Status: {{ printer[2] }}</p> + {% if printer[2] == 'frei' %} + <form method="POST" action="/api/printers/job"> + <input type="hidden" name="printer_id" value="{{ printer[0] }}"> + <button class="btn btn-success mt-4 w-full">Start Job</button> + </form> + {% elif printer[2] == 'belegt' %} + <button class="btn btn-warning mt-4 w-full" disabled>In Use</button> + {% elif printer[2] == 'reserviert' %} + <form method="POST" action="/api/printers/release"> + <input type="hidden" name="printer_id" value="{{ printer[0] }}"> + <button class="btn btn-info mt-4 w-full">Release</button> + </form> + {% endif %} + </div> + </div> + {% endfor %} +</div> +<a href="/logout" class="btn btn-secondary mt-4">Logout</a> +{% endblock %} diff --git a/backend/templates/login.html b/backend/templates/login.html new file mode 100644 index 0000000..f91fdca --- /dev/null +++ b/backend/templates/login.html @@ -0,0 +1,33 @@ +{% extends "base.html" %} + +{% block content %} +<div class="flex justify-center items-center h-screen"> + <div class="card w-96 bg-gray-900 shadow-xl"> + <div class="card-body"> + <h2 class="card-title">Login</h2> + <form method="POST"> + <div class="form-control"> + <label class="label"> + <span class="label-text">Username</span> + </label> + <input type="text" name="username" class="input input-bordered w-full" required> + </div> + <div class="form-control"> + <label class="label"> + <span class="label-text">Password</span> + </label> + <input type="password" name="password" class="input input-bordered w-full" required> + </div> + <div class="form-control mt-6"> + <button class="btn btn-primary w-full">Login</button> + </div> + </form> + {% if error %} + <div class="mt-4 text-red-500"> + {{ error }} + </div> + {% endif %} + </div> + </div> +</div> +{% endblock %} diff --git a/docs/Aktueller Stand.md b/docs/Aktueller Stand.md index cf70b64..2fe85be 100644 --- a/docs/Aktueller Stand.md +++ b/docs/Aktueller Stand.md @@ -38,8 +38,9 @@ use mix of shadcn ui and tremor.so blocks Bestellliste: - 1x Switch +- 1x wlan access point - 2x Raspberry Pi (4B / 5) -- Xx LAN-Kabel +(- Xx LAN-Kabel) - Adapter für 3D-Drucker oder Schaltbare Steckdosen -> Datensicherung?!?!?!