Adding printers sorta works now

This commit is contained in:
Reid 'arrdem' McKenzie 2023-05-23 00:15:16 -06:00
parent 66c08101c7
commit 3ad716837c
9 changed files with 110 additions and 31 deletions

View file

@ -65,7 +65,8 @@ def serve(hostname: str, port: int, config: Path):
print(app.config) print(app.config)
# Before first request # Before first request
app.before_first_request(create_j2_request_global) with app.app_context():
create_j2_request_global()
# Before request # Before request
app.before_request(open_db) app.before_request(open_db)

View file

@ -20,28 +20,45 @@ from flask import (
flash, flash,
) )
from .util import is_logged_in from .util import is_logged_in, requires_admin
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
BLUEPRINT = Blueprint("printer", __name__) BLUEPRINT = Blueprint("printer", __name__)
@requires_admin
@BLUEPRINT.route("/printers") @BLUEPRINT.route("/printers")
def printers(): def printers():
return render_template("printers.html.j2") return render_template("printers.html.j2")
@requires_admin
@BLUEPRINT.route("/printers/add", methods=["get", "post"]) @BLUEPRINT.route("/printers/add", methods=["get", "post"])
def add_printer(): def add_printer():
if not is_logged_in(request): if not is_logged_in(request):
return redirect("/") return redirect("/")
elif request.method == "POST": 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") return render_template("add_printer.html.j2")
@requires_admin
@BLUEPRINT.route("/printers/delete") @BLUEPRINT.route("/printers/delete")
def delete_printer(): def delete_printer():
return render_template("delete_printer.html.j2") return render_template("delete_printer.html.j2")

View file

@ -27,3 +27,14 @@ def is_logged_in(request: Request) -> bool:
def salt(password: str) -> str: def salt(password: str) -> str:
return "$SALT$" + current_app.config["SECRET_KEY"] + password 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

View file

@ -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, 'root', 20);
INSERT OR IGNORE INTO groups (id, name, priority) VALUES (0, 'users', 10); INSERT OR IGNORE INTO groups (id, name, priority) VALUES (1, 'users', 10);
INSERT OR IGNORE INTO groups (id, name, priority) VALUES (0, 'guests', 0); INSERT OR IGNORE INTO groups (id, name, priority) VALUES (2, 'guests', 0);
CREATE TABLE IF NOT EXISTS user_statuses ( CREATE TABLE IF NOT EXISTS user_statuses (
id INTEGER PRIMARY KEY AUTOINCREMENT 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 -- 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 id INTEGER PRIMARY KEY AUTOINCREMENT
, name TEXT , name TEXT
, UNIQUE(name) , UNIQUE(name)
@ -56,6 +56,7 @@ INSERT OR IGNORE INTO printer_statuses (id, name) values (3, 'running');
CREATE TABLE IF NOT EXISTS printers ( CREATE TABLE IF NOT EXISTS printers (
id INTEGER PRIMARY KEY AUTOINCREMENT id INTEGER PRIMARY KEY AUTOINCREMENT
, name TEXT
, url TEXT , url TEXT
, api_key TEXT , api_key TEXT
, status_id INTEGER , status_id INTEGER

View file

@ -65,8 +65,8 @@ html, body {
} }
.content, .footer { .content, .footer {
padding-left: 10%; padding-left: 10%;
padding-right: 10%; padding-right: 10%;
} }
.content { .content {
@ -85,6 +85,15 @@ a {
padding: 0; padding: 0;
} }
ul {
list-style: none;
.decorated {
list-style: auto;
padding: 1em;
}
}
nav { nav {
background-color: $beige; background-color: $beige;
box-shadow: 0px 10px 0px $red, box-shadow: 0px 10px 0px $red,
@ -272,3 +281,29 @@ $navbar_padding: 10px;
border-color: $secondary_red; 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;
}

View file

@ -229,16 +229,16 @@ class Store(object):
@fmap(one) @fmap(one)
@requires_conn @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( self._conn.execute(
"INSERT INTO printers (url, api_key, status_id) VALUES (?, ?, 0) RETURNING id", "INSERT INTO printers (name, url, api_key, status_id) VALUES (?1, ?2, ?3, 0) RETURNING id",
[url, api_key], [name, url, api_key],
).fetchone() ).fetchone()
@requires_conn @requires_conn
def list_printers(self): def list_printers(self):
return self._conn.execute( 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() ).fetchall()
@requires_conn @requires_conn

View file

@ -2,10 +2,11 @@
{% block content %} {% block content %}
<h1>Add printer</h1> <h1>Add printer</h1>
<form method="post" id="form"> <form method="post" id="form">
<p>Hostname: <input type="text" name="hostname" /></p> <span class="form-input"><span class="form-label">Printer name</span><input type="text" name="name" /></span>
<p>API key: <input type="text" name="key" /></p> <span class="form-input"><span class="form-label">Printer API URL</span><input type="text" name="url" /></span>
<p><input id="test" type="button" value="Test" enabled="false" /></p> <span class="form-input"><span class="form-label">API key</span><input type="text" name="api_key" /></span>
<p><input id="submit" type="submit" value="Add" onclick="maybeSubmit();" /></p> <span><input id="test" type="button" value="Test" enabled="false" /></span>
<span><input id="submit" type="submit" value="Add" onclick="maybeSubmit();" /></span>
<input type="hidden" name="tested" value="false" /> <input type="hidden" name="tested" value="false" />
</form> </form>

View file

@ -1,20 +1,5 @@
{% extends "base.html.j2" %} {% extends "base.html.j2" %}
{% block content %} {% block content %}
<div class="panel printers">
<h2>Printers</h2>
{% with printers = request.db.list_printers() %}
{% if printers %}
<ul>
{% for printer in printers %}
<li></li>
{% endfor %}
</ul>
{% else %}
No printers available. {% if request.is_admin %}<a href="/printers/add">Configure one!</a>{% else %}Ask the admin to configure one!{% endif %}
{% endif %}
{% endwith %}
</div>
<div class="panel queue"> <div class="panel queue">
<h2>Queue</h2> <h2>Queue</h2>
{% with jobs = request.db.list_jobs(uid=request.uid) %} {% with jobs = request.db.list_jobs(uid=request.uid) %}

View file

@ -0,0 +1,28 @@
{% extends "base.html.j2" %}
{% block content %}
<div class="panel printers">
<h2>Printers</h2>
{% with printers = request.db.list_printers() %}
{% if printers %}
<ul>
{% for printer in printers %}
{% with id, name, url, last_poll, status = printer %}
<li class="printer">
<span class="printer-name">{{name}}</span>
<span class="printer-url">{{url}}</span>
<span class="printer-status">{{status}}</span>
<span class="printer-date">{{last_poll}}</span>
{# FIXME: How should these action buttons work? #}
<a class="button" href="/printers/action?id={{id}}">Test</a>
<a class="button" href="/printers/edit?id={{id}}">Edit</a>
<a class="button" href="/printers/delete?id={{id}}">Remove</a>
</li>
{% endwith %}
{% endfor %}
</ul>
{% else %}
No printers available. {% if request.is_admin %}<a href="/printers/add">Configure one!</a>{% else %}Ask the admin to configure one!{% endif %}
{% endif %}
{% endwith %}
</div>
{% endblock %}