burrow: Static Gopherhole Generator

  _                                        _ 
 | |__   _  _   _ _   _ _   ___  __ __ __ (_)
 | '_ \ | || | | '_| | '_| / _ \ \ V  V /  _ 
 |_.__/  \_,_| |_|   |_|   \___/  \_/\_/  (_)
                                             

  ___   _            _     _      
 / __| | |_   __ _  | |_  (_)  __ 
 \__ \ |  _| / _` | |  _| | | / _|
 |___/  \__| \__,_|  \__| |_| \__|
                                  

   ___                _                  _            _       
  / __|  ___   _ __  | |_    ___   _ _  | |_    ___  | |  ___ 
 | (_ | / _ \ | '_ \ | ' \  / -_) | '_| | ' \  / _ \ | | / -_)
  \___| \___/ | .__/ |_||_| \___| |_|   |_||_| \___/ |_| \___|
              |_|                                             

   ___                                   _               
  / __|  ___   _ _    ___   _ _   __ _  | |_   ___   _ _ 
 | (_ | / -_) | ' \  / -_) | '_| / _` | |  _| / _ \ | '_|
  \___| \___| |_||_| \___| |_|   \__,_|  \__| \___/ |_|  
                                                         

╔─*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*─╗
║1   ........................................   1║
║2*  ........................................  *2║
║3   ........................................   3║
║1   ...........Posted: 2024-03-10...........   1║
║2*  Tags: gopher haskell showcase my_warez .  *2║
║3   ........................................   3║
║1   ........................................   1║
╚────────────────────────────────────────────────╝

You may have heard of *static site generators*. You may even have heard of the
Gopher Protocol[1]. But have you heard of a *static gopherhole generator?*

burrow[2] creates gopherholes for you. It has a lot of features to do so. It's
so good, in my opinion, I'm considering expanding the output to websites as
well, or at least abstracting-out some of its library components.

Here's my gopherhole, which I built with burrow:

* Visit in gopherspace: gopher://gopher.someodd.zip:7071/
* Try visiting using my Gopher Protocol client, "waffle"[3]
* `sudo apt-get install gopher && gopher -p "/" gopher.someodd.zip 7071`
* Visit using the Floodgap Gopher-HTTP gateway[4] (although, I'm not so sure
  about
  its UTF-8 support)


Some highlights:

* Particularly proud of the code quality here, written mostly before AI became a
  big part of my workflow. Some examples:
* Some descriptive FrontMatter error handling[5]
* Getting abstract with the usage of `MultiParamTypeClasses`,
  `FunctionalDependencies`, `AllowAmiguousTypes`, and `FlexibleInstances`[6]
* I got to work with the author (@sternenseemann[7]) of my favorite Gopher
  Protocol server daemon (spacecookie[8]), who I believe I have worked with on
  other matters as well.
* I went out-of-my-way to have fantastic error handling in some respects
* Had some fun with some very abstract features of Haskell, to me


The example:

## Serving/Docker Setup

I made a Docker setup for spacecookie[9]. It was nice working with the author of
Spacecookie on this project, and I think others!

I even made a setup/branch specific to burrow[10], which makes it easy to simply
push a commit and the server rebuilds the gopherhole for you!.

I think these setups were made originally around serving a Gopherhole via Tor so
I'll suggest some modifications.

### Using the burrow setup (no Tor)

I had to tweak the Docker spacecookie burrow setup[11] a bit to get it to play
nice.

Using nonstandard ports.

Firewall for the gopherhole service:

```
sudo ufw allow 7071/tcp comment 'gopherhole (docker)'
```

Firewall for git/ssh, my rule makes is for only accessing via local network or
my VPN:

```
sudo ufw allow from 192.168.1.0/24 to any port 2222 proto tcp comment 'gopherhole (docker) git ssh'
sudo ufw allow from 10.1.0.0/24 to any port 2222 proto tcp comment 'gopherhole (docker) git ssh'
```

also making it listen ssh different port! -- only allow from localnet ufw. had
to edit docker expose, i also had to add this to dockerfile, modifying so this
section looks like this (the sed command)

```
RUN apt-get install -y openssh-server
RUN sed -i '/^#Port 22/c\Port 2222' /etc/ssh/sshd_config
RUN service ssh start


```

This is in my `~/.ssh/config` (`192.168.1.100` is the IP of my server, although
I realize now I want to modify this now to also specify the IP on the VPN too,
if possible):

```
Host gopherhole
    HostName 192.168.1.100
    Port 2222
        User git
        IdentityFile ~/.ssh/id_rsa_hgopher
```

I modified `make run` (`Makefile`):

```
docker run -d --restart=always --net servicenet --hostname=spacecookie -p 2222:2222 -p 7071:7071 --ip=172.18.0.68 spacecookie
```

Port forward on router, then it should all work.

Try to `git push` to the server IP hosting the docker container and also make
sure you port forward and you should be able to access...

### tweaks i made due to port conflicts and stuff?

```
+++ b/Dockerfile
@@ -44,11 +44,12 @@ RUN wget -O /tmp/burrow.deb https://github.com/someodd/burrow/releases/download/
 RUN apt install /tmp/burrow.deb
 
 RUN apt-get install -y openssh-server
+RUN sed -i '/^#Port 22/c\Port 2222' /etc/ssh/sshd_config
 RUN service ssh start
 
 
-EXPOSE 70
-EXPOSE 22
+EXPOSE 7071
+EXPOSE 2222

+++ b/Makefile
@@ -12,7 +12,7 @@ build:
        docker build -t spacecookie .
 
 run:
-       docker run -d --restart=always --net servicenet --hostname=spacecookie --ip=172.18.0.68 spacecookie
+       docker run -d --restart=always --net servicenet --hostname=spacecookie -p 2222:2222 -p 7071:7071 --ip=172.18.0.68 spacecookie
 
 test:
        echo "$(running_id)"

+++ b/spacecookie.json
@@ -1,8 +1,8 @@
 {
-  "hostname" : "localhost",
+  "hostname" : "someodd.duckdns.org",
   "listen" : {
     "addr" : "::",
-    "port" : 70
+    "port" : 7071
   },

```

## Example image

This is an example of a gopherhole generated with *burrow,* as rendered by my
software waffle[12]:

!burrow-generated gopherhole in waffle =>
/assets/showcase/burrow/burrow-columnate-fonts-justify-example.png

The burrow repository[13] (hopefully) has an example of a gopherhole that can be
built with `burrow`.

## Example fonts

Here are some fonts that I and others have made for `burrow`:

* Fonts I made for burrow, as part of the repo[14]

## Story of development

I think I started developing this piece of software before AI started being
something I leaned heavily on in my development process. I think the code is
very clean, well organized/architectured, and well researched.

### Using abstract and advanced Haskell features

In this project I feel like I used very abstract and advanced Haskell features.

Here I will talk about the language extensions and documentation practices...

How I made my own markdown parser?

### Markdown parsing

### Coming back to this project after a while

* Needed to pin versions
* Trying to get nix working
* GHC versions...
* cabal freeze, lock.nix
* Removed depend marked as broken by nixpkgs, with code generated by ai

## Footnotes

[1]: Gopher Protocol: https://en.wikipedia.org/wiki/Gopher_(protocol)
[2]: burrow: https://github.com/someodd/burrow
[3]: my Gopher Protocol client, "waffle": /showcase/waffle
[4]: Visit using the Floodgap Gopher-HTTP gateway: https://gopher.floodgap.com/gopher/gw?a=gopher%3A%2F%2Fgopher.someodd.zip%3A7071%2F
[5]: Some descriptive FrontMatter error handling: https://github.com/someodd/burrow/blob/dfecdace53504dfadda34f7d5717d14a763f373b/src/FrontMatter.hs
[6]: Getting abstract with the usage of `MultiParamTypeClasses`, `FunctionalDependencies`, `AllowAmiguousTypes`, and `FlexibleInstances`: https://github.com/someodd/burrow/blob/dfecdace53504dfadda34f7d5717d14a763f373b/src/Phlog.hs
[7]: @sternenseemann: https://github.com/sternenseemann
[8]: spacecookie: https://github.com/sternenseemann/spacecookie
[9]: a Docker setup for spacecookie: https://github.com/someodd/docker-spacecookie
[10]: a setup/branch specific to burrow: https://github.com/someodd/docker-spacecookie/tree/feature/git-server-burrow
[11]: Docker spacecookie burrow setup: https://github.com/someodd/docker-spacecookie/tree/feature/git-server-burrow
[12]: waffle: /showcase/waffle
[13]: The burrow repository: https://github.com/someodd/burrow
[14]: Fonts I made for burrow, as part of the repo: https://github.com/someodd/burrow/tree/master/data/fonts