Setting up a Gopher site isn't terribly difficult, but I wanted a setup that allowed my to manage my posts using Git and to essentially mirror what I have on the web. I'm documenting my solution here mostly for my own future reference.
Here's the workflow.
blog
directory.date
directoryblog
directory for any post with a publish_date
of today, and copy that post to the blog
directory, and add it to the date
gophermapOn the Gopher server, add a bare Git repo to receive posts you push through Git:
$ mkdir /my/gopher/dir/blog.git
$ cd !$
$ git init --bare .
Create a staging directory as a destination for posts received, but waiting to go live:
$ mkdir /my/gopher/dir/staging
Create a directory for live posts. This is the directory users actually get to see.
$ mkdir /my/gopher/dir/blog
Edit /my/gopher/dir/blog.git/hooks/post-receive
to create a Git hook to copy received posts to the staging
directory:
#!/usr/bin/bash
# GNU All-Permissive License
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.
WEB_DIR="/my/gopher/dir/staging"
while read oldrev newrev refname
do
BR=`git rev-parse --symbolic --abbrev-ref $refname`
if [ "$BR" == "master" ]; then
export GIT_DIR="$WEB_DIR/.git"
pushd $WEB_DIR > /dev/null
git pull
popd > /dev/null
fi
done
Make it executable so that Git executes it whene a post is received:
$ chmod +x /my/gopher/dir/blog.git/hooks/post-receive
Next, add the Gopher server as a Git remote.
$ git remote add gopher example.com:/my/gopher/dir
Now you can push to your remote Gopher server:
$ git push gopher HEAD
On the Gopher server, create a date
directory as a location to link to all blog posts in order of date.
Because this was my first time setting this up, I had to copy all extant posts to my Gopher server.
I did this by pushing my Git HEAD to gopher
, and then logging into the server and copying all item.md
files in all subdirectories to new files named for the subdirectory.
I can't recall the exact command I used for this, but it would have been something to rename each file based the dirname
of the basename
.
date
directoryOnce again, only because I was starting from nothing I had to sort all posts by the publish_date
listed in the header of each post, and generate a gophermap
file in the date
directory.
#!/usr/bin/bash
# GNU All-Permissive License
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.
DIR_BASE=/my/gopher
DIR_TOP=dir
DIR_DATE=date
DIR_LIVE=blog
DIR_STAGING=staging
# start fresh
rm "$DIR_BASE"/"$DIR_TOP"/"$DIR_DATE"/gophermap
for POST in `find "$DIR_BASE"/"$DIR_TOP"/"$DIR_STAGING" -type f -name "item.md"`;
do
POSTDIR=`dirname "$POST"`
DATE=`grep '_date:' "$POST" | cut -f2 -d' '`
echo -e 0"$DATE" `basename $POSTDIR`'\t'"$DIR_TOP"/"$DIR_LIVE"/`basename $POSTDIR`.txt >> "$DIR_BASE"/"$DIR_TOP"/"$DIR_DATE"/gophermap
done
Create the script to check for posts in staging
that need to be published on the current date.
This is the script that makes a post go live.
It could be more robust than it is.
For example, currently it only checks for a post with a publish_date
of exactly today, but it would probably be better to post anything with a date of today or earlier.
#!/usr/bin/bash
# GNU All-Permissive License
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.
SED=/usr/bin/sed
DIR_BASE=/my/gopher
DIR_TOP=dir
DIR_LIVE=blog
DIR_STAGING=staging
DATE=${DATE:-`date --rfc-3339=date`}
for POST in `find "$DIR_BASE"/"$DIR_TOP"/"$DIR_STAGING" -type f -name "item.md" -exec grep -Hl "$DATE" {} \;`;
do
POSTDIR=`dirname "$POST"`
cp "$POST" "$DIR_BASE"/"$DIR_TOP"/"$DIR_LIVE"/`basename $POSTDIR`.txt
echo Found $POST
echo On $DATE
echo -e 0Latest'\t'../"$DIR_LIVE"/`basename $POSTDIR`.txt > /tmp/klaatu-blog-updater.tmp || echo "tmp file creation failed"
echo -e 0"$DATE" `basename $POSTDIR`'\t'../"$DIR_LIVE"/`basename $POSTDIR`.txt >> /tmp/blog-updater.tmp || echo "tmp file creation failed"
"${SED}" -i "/0Latest/ r /tmp/blog-updater.tmp" "$DIR_BASE"/date/gophermap || echo "failed"
"${SED}" -i '0,/0Latest/{/0Latest/d;}' "$DIR_BASE"/"$DIR_TOP"/date/gophermap
rm /tmp/blog-updater.tmp
done
Now create a cron job to run the script at midnight every night.
Open your crontab using crontab -e
and then add a line like this:
0 0 * * * /home/tux/bin/copy-post-to-blog.sh
You can create a fake blog entry and then run copy-post-to-blog.sh
to test the process.
Then check back regularly to ensure your script is updating the date
gophermap.
As I've said in a previous post, I don't love Gopher for what it is, I appreciate that it is not www. Using some open source software and a little ingenuity (if it can be called that), Gopher is relatively easy to automate. It may not be anywhere near as robust as HTML and HTTP, but it's nice to contribute content to a place where it's appreciated.
Solarized GNUby Linux Pictures under the idgaf license.