AdamTBradley.net

gopher

For April Fools, 2021, I migrated Dinerville to Gopher (I know: lol). It was a refreshingly simple change from web development. Three evenings of work gave me a gopher server that presents all the content from a much more complex website.

Pituophis is a Python module for writing both Gopher servers and clients. Pituophis's default “handler” function acts as a basic Gopher server, publishing items in a specified directory to Gopherspace; an optional user-defined alternate handler function responds when a missing file is requested. You can also replace the default handler and build your own Gopher application from the ground up.

One limitation of Pituophis compared to a web framework is the lack of a routing engine. That's easy enough to work around with a list of regular expressions and “controller” functions:

if request.path in ('', '/'):
    return homePage(request)
if request.path == '/about':
    return aboutPage(request)

paths = [
    (re.compile('/image/([\w-]+)\.(gif|jpg|png)$', re.IGNORECASE), sendImage),
    (re.compile('/([a-z]{2})$'), statePage),
    (re.compile('/([a-z]{2})/([\w-]+)$'), cityPage),
]

for pat, func in paths:
    m = pat.match(request.path)
    if m:
        return func(request, m)

Gopher Responses

While it’s possible to just serve text files from Gopher, at some point you’ll need to construct a menu (Wikipedia was surprisingly helpful with the syntax here). The term “menu” covers any gopher interface that includes links. Menus are tab-separated value files—the first column is a one-character content-type code followed by text that’s displayed to the user; that’s followed by an address on the server you’re linking to, the server address itself, and a port number. These columns are all required even for informational lines.

The lines below that start with “1” are links to other menus; lines with “i” (lowercase i) are “informational”, meaning just lines of text. Other important codes are “h” for HTML pages and “I” (uppercase I) for images.

iSOME OTHER USEFUL GOPHER SITES	/		0
i	/		0
1Gopherpedia	/	gopherpedia.com	70
1Floodgap systems, including the Veronica-2 search engine	/	gopher.floodgap.com	70
1The Gopher Movie Database	/1/cgi-bin/gmdb.py	jan.bio	70
1gopher.club (A collection of Gopher logs, or "phlogs")	/1/phlogs/	gopher.club	70

Building Menus with Pituophis

Pituophis provides an Item class that represents an individual line of a gopher menu and will convert a list of them, returned from a handler function, into a Gopher menu page. This code comes after a few database queries and returns basic information about a diner, including links to photos and outside info:

outp =  [Item(text=f'{diner.name} ({diner.make}{serial})'),
          Item(text=diner.address),
          Item(text=f"{diner.city}, {diner.state}  {diner.zip}"),
          Item(),
          Item(text=f"Status: {diner.status_str}"),]
outp += [Item(itype='h', text=row.title, path=f"URL:{row.url}") for row in links]
outp += [Item(itype='I', text=caption[0], path=f"/image/{photo.filename}", host=settings.HOST, port=settings.PORT)]

(Item(), in the code above, produces a blank line).

Finally

That's a very basic overview, but hopefully enough for some exploration if you're interested.

#gopher #python #django