Adding printers sorta works now
This commit is contained in:
parent
66c08101c7
commit
3ad716837c
9 changed files with 110 additions and 31 deletions
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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) %}
|
||||||
|
|
|
@ -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 %}
|
Loading…
Reference in a new issue