Compare commits
2 commits
90e2c1a888
...
4840a15c00
Author | SHA1 | Date | |
---|---|---|---|
4840a15c00 | |||
eba7b80fac |
13 changed files with 141 additions and 38 deletions
6
projects/cherry-shim/BUILD
Normal file
6
projects/cherry-shim/BUILD
Normal file
|
@ -0,0 +1,6 @@
|
|||
py_project(
|
||||
name = "cherry-shim",
|
||||
lib_deps = [
|
||||
py_requirement("cherrypy"),
|
||||
]
|
||||
)
|
28
projects/cherry-shim/src/python/cherry_shim.py
Normal file
28
projects/cherry-shim/src/python/cherry_shim.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Import CherryPy
|
||||
import cherrypy
|
||||
|
||||
|
||||
def shim(app):
|
||||
# Mount the application
|
||||
cherrypy.tree.graft(app, "/")
|
||||
|
||||
# Unsubscribe the default server
|
||||
cherrypy.server.unsubscribe()
|
||||
|
||||
# Instantiate a new server object
|
||||
server = cherrypy._cpserver.Server()
|
||||
|
||||
def _run(host="0.0.0.0", port=8080, pool_size=16):
|
||||
# Configure the server object
|
||||
server.socket_host = host
|
||||
server.socket_port = port
|
||||
server.thread_pool = pool_size
|
||||
server.subscribe()
|
||||
cherrypy.engine.start()
|
||||
cherrypy.engine.block()
|
||||
|
||||
server.run = _run
|
||||
|
||||
return server
|
|
@ -4,6 +4,7 @@ py_project(
|
|||
main_deps = [
|
||||
"//projects/anosql",
|
||||
"//projects/anosql-migrations",
|
||||
"//projects/cherry-shim",
|
||||
py_requirement("click"),
|
||||
py_requirement("flask"),
|
||||
py_requirement("jinja2"),
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
SECRET_KEY = "SgvzxsO5oPBGInmqsyyGQWAJXkS9"
|
||||
UPLOAD_FOLDER = "/home/arrdem/Documents/hobby/programming/source/projects/tentacles/tmp"
|
||||
|
||||
[db]
|
||||
uri = "/home/arrdem/Documents/hobby/programming/source/projects/tentacles/tentacles.sqlite3"
|
||||
|
||||
[[users]]
|
||||
email = "root@tirefireind.us"
|
||||
group_id = 0
|
||||
status_id = 1
|
|
@ -8,6 +8,8 @@ import tomllib
|
|||
|
||||
import click
|
||||
from flask import Flask, request
|
||||
|
||||
from cherry_shim import shim
|
||||
from tentacles.blueprints import (
|
||||
api,
|
||||
file_ui,
|
||||
|
@ -102,10 +104,11 @@ def serve(hostname: str, port: int, config: Path):
|
|||
|
||||
# Shove our middleware in there
|
||||
app.wsgi_app = custom_ctx(app, app.wsgi_app)
|
||||
cherry = shim(app)
|
||||
|
||||
# And run the blame thing
|
||||
try:
|
||||
app.run(host=hostname, port=port)
|
||||
cherry.run(host=hostname, port=port)
|
||||
finally:
|
||||
shutdown_event.set()
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ class Ctx:
|
|||
sid: str = None
|
||||
username: str = None
|
||||
is_admin: bool = None
|
||||
base_url: str = None
|
||||
|
||||
|
||||
_ctx = ContextVar("tentacles.ctx")
|
||||
|
|
|
@ -14,8 +14,9 @@ CREATE TABLE IF NOT EXISTS user_statuses (
|
|||
, UNIQUE(name)
|
||||
);
|
||||
|
||||
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (-1, 'disabled');
|
||||
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (-3, 'unapproved');
|
||||
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (-2, 'unverified');
|
||||
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (-1, 'disabled');
|
||||
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (1, 'enabled');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
|
@ -25,7 +26,9 @@ CREATE TABLE IF NOT EXISTS users (
|
|||
, email TEXT
|
||||
, hash TEXT
|
||||
, status_id INTEGER
|
||||
, verification_token TEXT DEFAULT (lower(hex(randomblob(32))))
|
||||
, verified_at TEXT
|
||||
, approved_at TEXT
|
||||
, enabled_at TEXT
|
||||
, FOREIGN KEY(group_id) REFERENCES groups(id)
|
||||
, FOREIGN KEY(status_id) REFERENCES user_statuses(id)
|
||||
|
@ -61,6 +64,7 @@ CREATE TABLE IF NOT EXISTS printers (
|
|||
id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
, name TEXT
|
||||
, url TEXT
|
||||
, stream_url TEXT
|
||||
, api_key TEXT
|
||||
, status_id INTEGER
|
||||
, last_poll_date TEXT
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{ base_url }}/static/css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="container navbar">
|
||||
<span class="logo">
|
||||
<a class="row" href="/">
|
||||
<img src="{{ base_url }}/static/tentacles.svg" alt="Tentacles">
|
||||
<span class="name color-yellow">Tentacles</span>
|
||||
</a>
|
||||
</span>
|
||||
</nav>
|
||||
|
||||
<div class="container content">
|
||||
<div class="row">
|
||||
<p>
|
||||
Welcome {{ username }}!
|
||||
</p>
|
||||
<p>
|
||||
Before you can use your account, please confirm your email address by clicking <a href="{{ base_url }}/user/verify?token={{token_id}}">this link</a> or pasting the following text into your browser's navigation bar.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ base_url }}/user/verify?token={{token_id}}
|
||||
</code>
|
||||
</pre>
|
||||
<p>
|
||||
Once your email has been verified, one of our administrators will review and approve your account. Then you can get to printing!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<footer>
|
||||
|
||||
</footer>
|
||||
</html>
|
|
@ -31,7 +31,7 @@ from tentacles.store import Store
|
|||
class OctoRest(_OR):
|
||||
def _get(self, path, params=None):
|
||||
url = urlparse.urljoin(self.url, path)
|
||||
response = self.session.get(url, params=params, timeout=(0.1, 1.0))
|
||||
response = self.session.get(url, params=params, timeout=(1.0, 1.0))
|
||||
self._check_response(response)
|
||||
|
||||
return response.json()
|
||||
|
@ -265,7 +265,13 @@ def send_verifications(app, store: Store):
|
|||
fm.send_message(
|
||||
from_addr="root@tirefireind.us",
|
||||
to_addrs=[user.email],
|
||||
msg=render_template("verification_email.html.j2"),
|
||||
subject="Email verification from tentacles",
|
||||
msg=render_template(
|
||||
"verification_email.html.j2",
|
||||
base_url=app.config.get("base_url"),
|
||||
username=user.username,
|
||||
token_id=user.verification_token,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
@ -280,7 +286,7 @@ def send_approvals(app, store: Store):
|
|||
|
||||
|
||||
@corn_job(timedelta(seconds=5))
|
||||
def run_worker(app, db_factory):
|
||||
def run_worker(app: App, db_factory):
|
||||
with app.app_context(), closing(db_factory(app)) as store:
|
||||
poll_printers(app, store)
|
||||
assign_jobs(app, store)
|
||||
|
@ -291,7 +297,7 @@ def run_worker(app, db_factory):
|
|||
send_approvals(app, store)
|
||||
|
||||
|
||||
def create_workers(app, db_factory: Callable[[], Store]) -> Event:
|
||||
def create_workers(app, db_factory: Callable[[App], Store]) -> Event:
|
||||
Thread(target=run_worker, args=[app, db_factory]).start()
|
||||
|
||||
return SHUTDOWN
|
||||
|
|
2
tools/python/constraints.in
Normal file
2
tools/python/constraints.in
Normal file
|
@ -0,0 +1,2 @@
|
|||
# jaraco.text==git+https://github.com/arrdem/jaraco.text.git@0dd8d0b25a93c3fad896f3a92d11caff61ff273d
|
||||
cherrypy==18.8.0
|
|
@ -44,7 +44,7 @@ def py_pytest(name, srcs, deps, main=None, python_version=None, args=None, **kwa
|
|||
|
||||
deps = sets.to_list(sets.make([
|
||||
py_requirement("pytest"),
|
||||
py_requirement("pytest-pudb"),
|
||||
# py_requirement("pytest-pudb"),
|
||||
py_requirement("pytest-cov"),
|
||||
py_requirement("pytest-timeout"),
|
||||
] + deps))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
-c constraints.in
|
||||
|
||||
ExifRead
|
||||
aiohttp
|
||||
aiohttp_basicauth
|
||||
|
@ -7,6 +9,7 @@ autoflake
|
|||
beautifulsoup4
|
||||
black
|
||||
cachetools
|
||||
cherrypy
|
||||
click
|
||||
colored
|
||||
flake8
|
||||
|
@ -40,6 +43,7 @@ redis
|
|||
requests
|
||||
requests
|
||||
retry
|
||||
pip-tools
|
||||
smbus2
|
||||
sphinx
|
||||
sphinxcontrib-openapi
|
||||
|
|
|
@ -5,34 +5,42 @@ alabaster==0.7.13
|
|||
async-lru==2.0.2
|
||||
async-timeout==4.0.2
|
||||
attrs==23.1.0
|
||||
autocommand==2.2.2
|
||||
autoflake==2.1.1
|
||||
Babel==2.12.1
|
||||
beautifulsoup4==4.12.2
|
||||
black==23.3.0
|
||||
blinker==1.6.2
|
||||
cachetools==5.3.0
|
||||
certifi==2022.12.7
|
||||
build==0.10.0
|
||||
cachetools==5.3.1
|
||||
certifi==2023.5.7
|
||||
charset-normalizer==3.1.0
|
||||
cheroot==10.0.0
|
||||
CherryPy==18.8.0
|
||||
click==8.1.3
|
||||
colored==1.4.4
|
||||
commonmark==0.9.1
|
||||
coverage==7.2.2
|
||||
coverage==7.2.7
|
||||
decorator==5.1.1
|
||||
deepmerge==1.1.0
|
||||
docutils==0.19
|
||||
exceptiongroup==1.1.1
|
||||
docutils==0.20.1
|
||||
ExifRead==3.0.0
|
||||
flake8==6.0.0
|
||||
Flask==2.3.2
|
||||
frozenlist==1.3.3
|
||||
hypothesis==6.75.5
|
||||
hypothesis==6.75.9
|
||||
ibis==3.2.0
|
||||
icmplib==3.0.3
|
||||
idna==3.4
|
||||
imagesize==1.4.1
|
||||
inflect==6.0.4
|
||||
iniconfig==2.0.0
|
||||
isort==5.12.0
|
||||
itsdangerous==2.1.2
|
||||
jaraco.collections==4.2.0
|
||||
jaraco.context==4.3.0
|
||||
jaraco.functools==3.7.0
|
||||
jaraco.text @ git+https://github.com/arrdem/jaraco.text.git@0dd8d0b25a93c3fad896f3a92d11caff61ff273d
|
||||
jedi==0.18.2
|
||||
Jinja2==3.1.2
|
||||
jsonschema==4.17.3
|
||||
|
@ -43,52 +51,60 @@ libsass==0.22.0
|
|||
livereload==2.6.3
|
||||
lxml==4.9.2
|
||||
Markdown==3.4.3
|
||||
MarkupSafe==2.1.2
|
||||
MarkupSafe==2.1.3
|
||||
mccabe==0.7.0
|
||||
meraki==1.33.0
|
||||
mirakuru==2.5.1
|
||||
mistune==2.0.5
|
||||
more-itertools==9.1.0
|
||||
multidict==6.0.4
|
||||
mypy-extensions==1.0.0
|
||||
octorest==0.4
|
||||
openapi-schema-validator==0.4.4
|
||||
openapi-spec-validator==0.5.6
|
||||
packaging==23.0
|
||||
packaging==23.1
|
||||
parso==0.8.3
|
||||
pathable==0.4.3
|
||||
pathspec==0.11.1
|
||||
picobox==2.2.0
|
||||
platformdirs==3.2.0
|
||||
picobox==3.0.0
|
||||
pip==23.1.2
|
||||
pip-tools==6.13.0
|
||||
platformdirs==3.5.1
|
||||
pluggy==1.0.0
|
||||
port-for==0.6.3
|
||||
portend==3.1.0
|
||||
prompt-toolkit==3.0.38
|
||||
proquint==0.2.1
|
||||
psutil==5.9.4
|
||||
psutil==5.9.5
|
||||
psycopg==3.1.9
|
||||
psycopg2==2.9.6
|
||||
pudb==2022.1.3
|
||||
py==1.11.0
|
||||
pycodestyle==2.10.0
|
||||
pycryptodome==3.18.0
|
||||
pydantic==1.10.8
|
||||
pyflakes==3.0.1
|
||||
Pygments==2.14.0
|
||||
Pygments==2.15.1
|
||||
pyproject_hooks==1.0.0
|
||||
pyrsistent==0.19.3
|
||||
pytest==7.2.2
|
||||
pytest==7.3.1
|
||||
pytest-cov==4.1.0
|
||||
pytest-postgresql==5.0.0
|
||||
pytest-pudb==0.7.0
|
||||
pytest-timeout==2.1.0
|
||||
pytz==2023.3
|
||||
PyYAML==6.0
|
||||
recommonmark==0.7.1
|
||||
redis==4.5.5
|
||||
requests==2.31.0
|
||||
retry==0.9.2
|
||||
rfc3339-validator==0.1.4
|
||||
setuptools==67.7.2
|
||||
six==1.16.0
|
||||
smbus2==0.4.2
|
||||
snowballstemmer==2.2.0
|
||||
sortedcontainers==2.4.0
|
||||
soupsieve==2.4
|
||||
soupsieve==2.4.1
|
||||
Sphinx==7.0.1
|
||||
sphinx_mdinclude==0.5.3
|
||||
sphinxcontrib-applehelp==1.0.4
|
||||
|
@ -100,19 +116,21 @@ sphinxcontrib-openapi==0.8.1
|
|||
sphinxcontrib-programoutput==0.17
|
||||
sphinxcontrib-qthelp==1.0.3
|
||||
sphinxcontrib-serializinghtml==1.1.5
|
||||
termcolor==2.2.0
|
||||
tempora==5.2.2
|
||||
termcolor==2.3.0
|
||||
toml==0.10.2
|
||||
tomli==2.0.1
|
||||
tornado==6.2
|
||||
typing_extensions==4.5.0
|
||||
tornado==6.3.2
|
||||
typing_extensions==4.6.3
|
||||
unify==0.5
|
||||
untokenize==0.1.1
|
||||
urllib3==1.26.15
|
||||
urllib3==2.0.2
|
||||
urwid==2.1.2
|
||||
urwid-readline==0.13
|
||||
wcwidth==0.2.6
|
||||
websocket-client==1.5.1
|
||||
websocket-client==1.5.2
|
||||
Werkzeug==2.3.4
|
||||
wheel==0.40.0
|
||||
yamllint==1.32.0
|
||||
yarl==1.8.2
|
||||
yarl==1.9.2
|
||||
yaspin==2.3.0
|
||||
zc.lockfile==3.0.post1
|
||||
|
|
Loading…
Reference in a new issue