From 5d8da63a00849b0017dd315e470b30c10cdd1a51 Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie Date: Tue, 23 May 2023 00:15:16 -0600 Subject: [PATCH] Adding printers sorta works now --- .../src/python/tentacles/__main__.py | 3 +- .../python/tentacles/blueprints/printer_ui.py | 21 +++++++++- .../src/python/tentacles/blueprints/util.py | 11 ++++++ .../tentacles/src/python/tentacles/schema.sql | 7 ++-- .../python/tentacles/static/css/style.scss | 39 ++++++++++++++++++- .../tentacles/src/python/tentacles/store.py | 8 ++-- .../tentacles/templates/add_printer.html.j2 | 9 +++-- .../python/tentacles/templates/index.html.j2 | 15 ------- .../tentacles/templates/printers.html.j2 | 28 +++++++++++++ 9 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 projects/tentacles/src/python/tentacles/templates/printers.html.j2 diff --git a/projects/tentacles/src/python/tentacles/__main__.py b/projects/tentacles/src/python/tentacles/__main__.py index 926dc8a..b610dc8 100644 --- a/projects/tentacles/src/python/tentacles/__main__.py +++ b/projects/tentacles/src/python/tentacles/__main__.py @@ -65,7 +65,8 @@ def serve(hostname: str, port: int, config: Path): print(app.config) # Before first request - app.before_first_request(create_j2_request_global) + with app.app_context(): + create_j2_request_global() # Before request app.before_request(open_db) diff --git a/projects/tentacles/src/python/tentacles/blueprints/printer_ui.py b/projects/tentacles/src/python/tentacles/blueprints/printer_ui.py index 27e6da0..ed16f7b 100644 --- a/projects/tentacles/src/python/tentacles/blueprints/printer_ui.py +++ b/projects/tentacles/src/python/tentacles/blueprints/printer_ui.py @@ -20,28 +20,45 @@ from flask import ( flash, ) -from .util import is_logged_in +from .util import is_logged_in, requires_admin log = logging.getLogger(__name__) BLUEPRINT = Blueprint("printer", __name__) +@requires_admin @BLUEPRINT.route("/printers") def printers(): return render_template("printers.html.j2") +@requires_admin @BLUEPRINT.route("/printers/add", methods=["get", "post"]) def add_printer(): if not is_logged_in(request): return redirect("/") elif request.method == "POST": - pass + try: + assert request.form["name"] + assert request.form["url"] + assert request.form["api_key"] + request.db.try_create_printer( + request.form["name"], + request.form["url"], + request.form["api_key"], + ) + flash("Printer created") + return redirect("/printers") + + except Exception as e: + log.exception("Failed to create printer") + flash(f"Unable to create printer", category="error") return render_template("add_printer.html.j2") +@requires_admin @BLUEPRINT.route("/printers/delete") def delete_printer(): return render_template("delete_printer.html.j2") diff --git a/projects/tentacles/src/python/tentacles/blueprints/util.py b/projects/tentacles/src/python/tentacles/blueprints/util.py index 25b2725..ed70660 100644 --- a/projects/tentacles/src/python/tentacles/blueprints/util.py +++ b/projects/tentacles/src/python/tentacles/blueprints/util.py @@ -27,3 +27,14 @@ def is_logged_in(request: Request) -> bool: def salt(password: str) -> str: return "$SALT$" + current_app.config["SECRET_KEY"] + password + + +def requires_admin(f): + def _helper(*args, **kwargs): + if not request.is_admin: + flash("Sorry, admins only", category="error") + redirect("/") + else: + return f(*args, **kwargs) + + return _helper diff --git a/projects/tentacles/src/python/tentacles/schema.sql b/projects/tentacles/src/python/tentacles/schema.sql index 3d7aa3a..261d4d2 100644 --- a/projects/tentacles/src/python/tentacles/schema.sql +++ b/projects/tentacles/src/python/tentacles/schema.sql @@ -5,8 +5,8 @@ CREATE TABLE IF NOT EXISTS groups ( ); INSERT OR IGNORE INTO groups (id, name, priority) VALUES (0, 'root', 20); -INSERT OR IGNORE INTO groups (id, name, priority) VALUES (0, 'users', 10); -INSERT OR IGNORE INTO groups (id, name, priority) VALUES (0, 'guests', 0); +INSERT OR IGNORE INTO groups (id, name, priority) VALUES (1, 'users', 10); +INSERT OR IGNORE INTO groups (id, name, priority) VALUES (2, 'guests', 0); CREATE TABLE IF NOT EXISTS user_statuses ( id INTEGER PRIMARY KEY AUTOINCREMENT @@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS user_keys ( ---------------------------------------------------------------------------------------------------- -- Printers represent physical devices (really octoprint API targets) that jobs can go to -CREATE TABLE IF NOT EXISTs printer_statuses ( +CREATE TABLE IF NOT EXISTS printer_statuses ( id INTEGER PRIMARY KEY AUTOINCREMENT , name TEXT , UNIQUE(name) @@ -56,6 +56,7 @@ INSERT OR IGNORE INTO printer_statuses (id, name) values (3, 'running'); CREATE TABLE IF NOT EXISTS printers ( id INTEGER PRIMARY KEY AUTOINCREMENT + , name TEXT , url TEXT , api_key TEXT , status_id INTEGER diff --git a/projects/tentacles/src/python/tentacles/static/css/style.scss b/projects/tentacles/src/python/tentacles/static/css/style.scss index 70af198..4b3bb49 100644 --- a/projects/tentacles/src/python/tentacles/static/css/style.scss +++ b/projects/tentacles/src/python/tentacles/static/css/style.scss @@ -65,8 +65,8 @@ html, body { } .content, .footer { - padding-left: 10%; - padding-right: 10%; + padding-left: 10%; + padding-right: 10%; } .content { @@ -85,6 +85,15 @@ a { padding: 0; } +ul { + list-style: none; + + .decorated { + list-style: auto; + padding: 1em; + } +} + nav { background-color: $beige; box-shadow: 0px 10px 0px $red, @@ -272,3 +281,29 @@ $navbar_padding: 10px; border-color: $secondary_red; } } + +form { + display: flex; + flex-direction: column; + + .form-input { + display: flex; + flex-direction: row; + + .form-label { + width: 200px; + margin-right: 10px; + } + + input { + margin-right: auto; + width: 400px; + } + } +} + +.button { + border: 1px solid; + border-radius: 1em; + padding: 0.5em; +} diff --git a/projects/tentacles/src/python/tentacles/store.py b/projects/tentacles/src/python/tentacles/store.py index 197fcd6..83824b6 100644 --- a/projects/tentacles/src/python/tentacles/store.py +++ b/projects/tentacles/src/python/tentacles/store.py @@ -229,16 +229,16 @@ class Store(object): @fmap(one) @requires_conn - def try_create_printer(self, url, api_key): + def try_create_printer(self, name: str, url: str, api_key: str): self._conn.execute( - "INSERT INTO printers (url, api_key, status_id) VALUES (?, ?, 0) RETURNING id", - [url, api_key], + "INSERT INTO printers (name, url, api_key, status_id) VALUES (?1, ?2, ?3, 0) RETURNING id", + [name, url, api_key], ).fetchone() @requires_conn def list_printers(self): return self._conn.execute( - "SELECT id, url, last_poll_date, s.name as status FROM printers p INNER JOIN printer_stauses s ON p.status_id = s.id" + "SELECT p.id, p.name, p.url, p.last_poll_date, s.name as status FROM printers p INNER JOIN printer_statuses s ON p.status_id = s.id" ).fetchall() @requires_conn diff --git a/projects/tentacles/src/python/tentacles/templates/add_printer.html.j2 b/projects/tentacles/src/python/tentacles/templates/add_printer.html.j2 index 479d7ba..56b094a 100644 --- a/projects/tentacles/src/python/tentacles/templates/add_printer.html.j2 +++ b/projects/tentacles/src/python/tentacles/templates/add_printer.html.j2 @@ -2,10 +2,11 @@ {% block content %}

Add printer

-

Hostname:

-

API key:

-

-

+ Printer name + Printer API URL + API key + +
diff --git a/projects/tentacles/src/python/tentacles/templates/index.html.j2 b/projects/tentacles/src/python/tentacles/templates/index.html.j2 index 265a51d..bfc48a1 100644 --- a/projects/tentacles/src/python/tentacles/templates/index.html.j2 +++ b/projects/tentacles/src/python/tentacles/templates/index.html.j2 @@ -1,20 +1,5 @@ {% extends "base.html.j2" %} {% block content %} -
-

Printers

- {% with printers = request.db.list_printers() %} - {% if printers %} - - {% else %} - No printers available. {% if request.is_admin %}Configure one!{% else %}Ask the admin to configure one!{% endif %} - {% endif %} - {% endwith %} -
-

Queue

{% with jobs = request.db.list_jobs(uid=request.uid) %} diff --git a/projects/tentacles/src/python/tentacles/templates/printers.html.j2 b/projects/tentacles/src/python/tentacles/templates/printers.html.j2 new file mode 100644 index 0000000..2bdf710 --- /dev/null +++ b/projects/tentacles/src/python/tentacles/templates/printers.html.j2 @@ -0,0 +1,28 @@ +{% extends "base.html.j2" %} +{% block content %} +
+

Printers

+ {% with printers = request.db.list_printers() %} + {% if printers %} +
    + {% for printer in printers %} + {% with id, name, url, last_poll, status = printer %} +
  • + {{name}} + {{url}} + {{status}} + {{last_poll}} + {# FIXME: How should these action buttons work? #} + Test + Edit + Remove +
  • + {% endwith %} + {% endfor %} +
+ {% else %} + No printers available. {% if request.is_admin %}Configure one!{% else %}Ask the admin to configure one!{% endif %} + {% endif %} + {% endwith %} +
+{% endblock %}