Developing¶
The guestbook has no build step and no dependencies. The page is plain HTML, CSS and one ES module, and the server is one file of Python's standard library.
The files¶
| File | What |
|---|---|
app/index.html |
the page: masthead, the signing window, the book, the footer |
app/style.css |
the look, with light and dark from prefers-color-scheme; the sky tile is an inline SVG |
app/guestbook.js |
the doodle pad (Bresenham lines on a 96×48 canvas), signing, the book, the counter |
app/fonts/ |
Pixelify Sans, served from here, with its licence |
server/guestbook.py |
GET /entries, POST /sign, POST /hit, GET/POST /mod |
tools/dev.py |
the page and a throwaway server on one port, with no notify command |
tools/deploy.sh |
copies app/ and the server to the live site and restarts it (the stuffs setup) |
What the server checks when someone signs¶
- The hidden
hpfield is empty. If it isn't, the server says "thanks" and drops the entry without a word. - At least four seconds have passed since the page opened (the page sends its opening time as
t). - There's a name and a message of at least two characters. Lengths are capped at 40, 40, 120 and 600 characters, and control characters and direction overrides are taken out.
- The website, if any, starts with
http://orhttps://, and the message has one link at most. - The doodle, if any, is a PNG data URL of exactly 96×48 pixels and under about 30 KB.
- That address hasn't signed three times this hour or eight times today.
Then the entry is saved as pending with its own random token, and the notify command runs in the background, so a
slow or failed message never loses an entry.
Trying it on your computer¶
python3 tools/dev.py
That prints an address like http://127.0.0.1:8458/ and a throwaway data folder. Sign it, then open the link from
guestbook.log in that folder to let the entry in. Pass a port and a folder to keep the data:
python3 tools/dev.py 8458 /tmp/gb.
The page puts everything people write on the page with textContent, never as HTML, and the owner's page escapes
everything and sends a strict Content-Security-Policy, so a message can't run anything.