Skip to content

Commit

Permalink
Add more admin operations (#56)
Browse files Browse the repository at this point in the history
* /admin/restart => /admin/operations
* Add a link to download the database
* Add a SQL editor to query and modify the database in a pinch
  • Loading branch information
breuleux authored Apr 4, 2024
1 parent a4c455d commit cb364dc
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 32 deletions.
34 changes: 34 additions & 0 deletions paperoni/webapp/admin/operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import asyncio
import os
import signal

from hrepr import H
from starbear import Queue

from ...config import papconf
from ..common import mila_template


@mila_template(help="/help#operations")
async def app(page, box):
"""Admin operations."""
q = Queue()

box.print(H.p(H.button("Restart server", onclick=q.tag("restart"))))
box.print(H.p(H.a("Download database", href=papconf.paths.database)))

async for event in q:
match event.tag:
case "restart":
box.set("Restarting. Try to refresh in a few seconds.")
await asyncio.sleep(
0
) # Make sure we send the feedback before the kill()
try:
os.kill(os.getpid(), signal.SIGTERM)
except Exception as exc:
box.print(H.div["error"]("An error occurred"))
box.print(H.div["error"](exc))


ROUTES = app
30 changes: 0 additions & 30 deletions paperoni/webapp/admin/restart.py

This file was deleted.

52 changes: 52 additions & 0 deletions paperoni/webapp/admin/sql.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from hrepr import H
import sqlalchemy
from starbear import Queue

from ...config import papconf
from ..common import mila_template


@mila_template(help="/help#sql")
async def app(page, box):
"""Query and manipulate the database."""
q = Queue()

form = H.form["sql-edit"](
H.div(H.textarea(name="sql")),
H.div(H.button("Run")),
onsubmit=q.wrap(form=True),
)

box.print(H.div(form))
box.print(result_area := H.div().autoid())

with papconf.database as db:
async for event in q:
try:
result = db.session.execute(event["sql"])
except Exception as exc:
page[result_area].set(exc)
continue

try:
t = H.table["sql-results"]()
t = t(H.tr(H.th(row_name) for row_name in result.keys()))
t = t(
H.tr(
H.td(
H.code(value.hex())
if isinstance(value, bytes)
else str(value)
)
for value in row
)
for row in result
)
page[result_area].set(t)

except sqlalchemy.exc.ResourceClosedError:
# Happens when we try to iterate over DELETE results
page[result_area].set("done")


ROUTES = app
26 changes: 26 additions & 0 deletions paperoni/webapp/app-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,29 @@ div.log-stream textarea {
width: 100%;
height: 500px;
}

form.sql-edit {
margin-left: 0px;
}

form.sql-edit textarea {
display: block;
width: 100%;
height: 100px;
box-sizing: border-box;
}

table.sql-results {
border-collapse: collapse;
width: 100%;
}

table.sql-results th, td {
padding-right: 5px;
}

table.sql-results th {
text-align: left;
color: white;
background: black;
}
4 changes: 2 additions & 2 deletions paperoni/webapp/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ Notes:

The configuration is defined as YAML. The `version_tag` field represents the tag on the Paperoni GitHub repository to use for this app. To update the software, you can change this value and then restart the server by going on [/admin/restart](/admin/restart).

## Restart {: #restart}
## Operations {: #operations}

When the server restarts, it checks out the version of the code represented by the `version_tag` key in `config.yaml`.
**Restart:** When the server restarts, it checks out the version of the code represented by the `version_tag` key in `config.yaml`.

# Troubleshooting

Expand Down

0 comments on commit cb364dc

Please sign in to comment.