jetforce/examples/guestbook.py

69 lines
2.1 KiB
Python

"""
A simple guestbook application that accepts and displays text messages.
This is an example of how to return a 10 INPUT request to the client and
retrieve their response by parsing the URL query string.
This example stores the guestbook inside of a persistent sqlite database.
Because each request will run inside of a separate thread, we must create a new
connection object inside of the request handler instead of re-using a global
database connection. This thread-safety can be disabled in sqlite3 by using the
check_same_thread=False argument, but then it's up to you to ensure that only
connection request is writing to the database at any given time.
"""
import sqlite3
from datetime import datetime
from jetforce import GeminiServer, JetforceApplication, Response, Status
DB = "/tmp/guestbook.sqlite"
SCHEMA = """
CREATE TABLE IF NOT EXISTS guestbook (
ip_address TEXT,
created_at timestamp,
message TEXT
)
"""
with sqlite3.connect(DB) as c:
c.execute(SCHEMA)
app = JetforceApplication()
@app.route("", strict_trailing_slash=False)
def index(request):
lines = ["Guestbook", "=>/submit Sign the Guestbook"]
with sqlite3.connect(DB, detect_types=sqlite3.PARSE_DECLTYPES) as c:
for row in c.execute("SELECT * FROM guestbook ORDER BY created_at"):
ip_address, created_at, message = row
line = f"{created_at:%Y-%m-%d} - [{ip_address}] {message}"
lines.append("")
lines.append(line)
lines.extend(["", "...", ""])
body = "\n".join(lines)
return Response(Status.SUCCESS, "text/gemini", body)
@app.route("/submit")
def submit(request):
if request.query:
message = request.query[:256]
created = datetime.now()
ip_address = request.environ["REMOTE_HOST"]
with sqlite3.connect(DB) as c:
values = (ip_address, created, message)
c.execute("INSERT INTO guestbook VALUES (?, ?, ?)", values)
return Response(Status.REDIRECT_TEMPORARY, "")
else:
return Response(Status.INPUT, "Enter your message (max 256 characters)")
if __name__ == "__main__":
server = GeminiServer(app)
server.run()