Rodents, Snakes, and Adhesive

Last week, I proposed a challenge to the tilde.club mailing list. The challenge was to dust off the public_gopher directory sitting in most users’ home folders and put something neat in it. Gopher was (and is) quite new to me, but not to the world; a team at the University of Minnesota created the protocol in 1991, and it’s been lurking out there on the net ever since.

I guess the story goes that Gopher was initially quite popular, particularly since its terminal-friendly interface dropped cleanly into the prevalent hardware and operating systems of the day. Unfortunately, UMN started charging for use of its server implementation in 1993, and that was more or less all it took for the free Web to take over. The owners of the implementation re-licensed under GNU GPL in 2000, but by then it was too late. Gopher probably would have been crushed by the stampede of interest in the graphical Web anyway, and in a way it’s nice that its owners tripped over their own financial feet and made way for multimedia on the Internet, but it’s also a little sad, I think, that Gopher has been reduced to just a curiosity.

At the moment, there aren’t many Gopher servers left. tilde.club has one, of course, and there are a few notable others, such as gopherpedia, but beyond that the protocol is mostly dead. The most important development in Gopher’s history in the past fifteen years was probably its appearance as the butt of a joke in an xkcd comic from 2009.

But still, we press on. Why not have a little fun at the end of the world, hmm? If others aren’t using Gopher, that’s okay. Most people don’t even know about HTTP—which is probably for the best, now that I think of it—but that doesn’t stop nerds from nerding about it. Gopher is a neat way to organize information, and I for one find its terminal-first approach pleasing (in other words, it makes me feel l33t), and that’s really all I need from it. Plus, cool name.

So after all that, what does one put in a gopherspace? Well, in my case, I followed the principle of least effort. Rather than make up some new stuff to put there, I decided to just duplicate my existing blog (which is all Markdown files on the backend anyway) and format it as a gopher blog (or phlog, apparently). You can check it out on the tilde.club Gopher server here. If you don’t notice anything new or interesting, then great! That means it worked.

Just for fun, I thought I’d share the Python script (or “glue”, as I call it) I wrote hacked together to take my existing Jekyll blog and spit out a gophermap (the file that tells Gopher where stuff is) along with the actual text files. It doesn’t handle Liquid templating, images, or anything like that, but it sure does do the minimum viable thing of writing text files. Take a look:

#!/usr/bin/env python3

import os
import regex as re

gopher_path = '/home/bradley/code/blog/_gopher/blog/'

post_path = '/home/bradley/code/blog/_posts/'
gophermap = []
for entry in os.scandir(post_path):
    entry_text = open(entry.path, 'r').read()
    entry_title = re.search('(?<=---\n.*\ntitle: ").*(?=")',
            entry_text).group(0)
    entry_date = re.search('(?<=---\n.*\n.*\ndate: ).*', entry_text).group(0)
    entry_content_start = re.search('---\n\n', entry_text).start() + 5
    entry_content = entry_text[entry_content_start:]
    open(gopher_path + entry.name, 'w').write(entry_title + '\n\n' + entry_date
            + '\n\n' + entry_content)
    gophermap.append('0{0} --- {1}\t/~bradley/blog/{2}\ttilde.club\t70'
            .format(entry_date, entry_title, entry.name))

gophermap_output = open(gopher_path + 'gophermap', 'w')
gophermap_output.write('''blog - noun; a regularly updated website or web page,
typically one run by an individual or small group, that is
written in an informal or conversational style

gopher - noun; a burrowing rodent with fur-lined pouches on
the outside of the cheeks, found in North and Central
America

gopher + blog = phlog

''')

gophermap = sorted(gophermap, reverse=True)
gophermap_output.write('\n'.join(gophermap))
gophermap_output.write('\n\n..')

Note that in order for the above to work, you at least need the regex module from PyPI, since it implements variable-width lookbehinds. In my deployment script, I source a virtual environment where that module is installed, but you can do it however you want. Email or IRC me if you run into issues, but no guarantees. I release this code into the public domain and relinquish any rights to it whatsoever.

One last thing: the challenge I proposed for this week was to set up or update your blog, so this post is what we in the business call a two-birds-one-stone scenario.