Reading List

The most recent articles from a list of feeds I subscribe to.

SQL-Powered Reading List

I have some items burning a hole on my to-do list, so instead I made my reading list queryable via SQL.

Book List

Hit the I'm Feeling Lazy button if you're not feeling especially structured in your queries.

What's going on here, exactly?

I keep my reading list in a Google Sheet. Here's what I looks like (...it's just a spreadsheet).

Book List

For a while, I was relying heavily on Goodreads for my reading data, but now I'm doing my best to live up to Tom MacWrite's Indie Bookshelves guidance, though, like he suggests, I'd ideally love to have some sort of POSSE (Publish (on your) Own Site, Syndicate Elsewhere) setup going.

As you may have noticed (if you squinted), I'm still behind in inputting all of my "data" (the is_fiction and is_reread columns are still not fully populated). Also adding new entries is still painfully manual, which needs further thinking.

But - the key thing here - this reading list is already good/useful enough for an experimental library feature!

ROAPI

My friend QP is a genius and the best programmer I know (hi, QP!). One of his most recent projects is called ROAPI (read-only API). Here's how he describes it:

ROAPI automatically spins up read-only APIs for static datasets without requiring you to write a single line of code. It builds on top of Apache Arrow and Datafusion. The core of its design can be boiled down to the following:

* Query frontends to translate SQL, GraphQL and REST API queries into Datafusion plans.
* Datafusion for query plan execution.
* Data layer to load datasets from a variety of sources and formats with automatic schema inference.
* Response encoding layer to serialize intermediate Arrow record batch into various formats requested by client.

He even made a diagram:

ROAPI

I've been looking for excuses to use ROAPI (I even started learning Rust this month so that I could help contribute to the project. So far, I've made a few measly PRs to ROAPI, but I also got distracted by learning how to make a Dungeon Crawler 2D game in Rust - which you can even play online via WASM!).

ROAPI already supports Google Sheets as a datasource, so this tutorial is pretty much already done. The magic of ROAPI is that there's no bespoke code I need to write - all I need to do is set up its config file to point to my Google spreadsheet and I've got a fast API server that can perform bi-directional communication in JSON, SQL, or GraphQL. Which is insanely cool.

I just needed somewhere to host ROAPI. QP provides a pre-built Docker image as well as via a Python package. My first thought was to host on a free Heroku dyno, but I had some trouble getting their dynamic PORT env variable to work correctly (despite me adding support in ROAPI to set the PORT via env vars, which I tested and confirmed works! Oh, well.)

My next idea was to do something I'd been meaning to do for a while - check out Replit's "always-on" REPL mode.

Replit

I've written before about my love for Replit.

Here's how I got my ROAPI setup on Replit

  • Create a Python repl (make it Private, so you need to be on their $7/month Hacker plan)
  • Install "roapi-http" in packages tab
  • Create a file: "roapi.yaml" with these contents
tables:
  - name: "library"
    uri: "https://docs.google.com/spreadsheets/d/1FCKSd4GBZIOe-bQG7k7Y3oA_MqMrxEx0QDzdkrkzIgI/edit"
    option:
      format: "google_spreadsheet"
      application_secret_path: "ohsheet.json"
  • Create another file called "ohsheet.json" (or whatever you put in your config file) with your Google Sheets creds (remember this REPL needs to be private). Follow QP's Google Sheets guide in the ROAPI docs for instructions of how to get these creds. Feature request for Replit: it would be nice if there were a (hacky) way to read Replit's "Secrets" (env vars) in a YAML file, so that I didn't have to do this.
  • Update "main.py" with these contents:
import subprocess
import os

my_env = os.environ.copy()
my_env["HOST"] = "0.0.0.0"

process = subprocess.Popen(
  [
    'roapi-http',
    '-c',
    './roapi.yml'
  ],
  env=my_env,
  stdout=subprocess.PIPE,
  universal_newlines=True,
)

while True:

  output = process.stdout.readline()
  print(output.strip())
  
  return_code = process.poll()
  if return_code is not None:
    print('RETURN CODE', return_code)
    for output in process.stdout.readlines():
        print(output.strip())
    break  
  • Hit Run at the top and we're done! I can see my logs in the bottom right corner for any incoming requests. Replit's like being able to SSH into your API server and make random changes at will - dangerous AND fun!

Replit

My API is public, so anyone can give this a shot in their terminal (why not try out the GraphQL endpoint?):

curl -X POST -d "query { library(limit: 10) {title, amazon_link, author, is_favorite} }" https://roapi-library.whatrocks.repl.co/api/graphql

[{"title":"Heir to the Empire","amazon_link":"https://amzn.to/3r38doD","author":"Timothy Zahn","is_favorite":false},{"title":"Dark Force Rising","amazon_link":"https://amzn.to/3pXfpkE","author":"Timothy Zahn","is_favorite":false},{"title":"The Making of Prince of Persia","amazon_link":"https://amzn.to/2Pcc7gE","author":"Jordan Mechner","is_favorite":false},{"title":"Butcher's Crossing","amazon_link":"https://amzn.to/3kvbGtz","author":"John  Williams","is_favorite":true},{"title":"Surely You're Joking, Mr. Feynman!: Adventures of a Curious Character","amazon_link":"https://amzn.to/2MxqkUu","author":"Richard P. Feynman","is_favorite":false},{"title":"This Boy's Life","amazon_link":"https://amzn.to/3r8gqru","author":"Tobias Wolff","is_favorite":true},{"title":"The Once and Future King","amazon_link":"https://amzn.to/2NErKgH","author":"T.H. White","is_favorite":false},{"title":"The Knight","amazon_link":"https://amzn.to/3bLgUNH","author":"Gene Wolfe","is_favorite":false},{"title":"Birds Without Wings","amazon_link":"https://amzn.to/3r5oQQi","author":"Louis de Bernières","is_favorite":false},{"title":"Cryptonomicon","amazon_link":"https://amzn.to/2O402cV","author":"Neal Stephenson","is_favorite":false}]

I have no idea what happens if this endpoint gets hammered. Maybe Replit just turns it off? Regardless, I enabled their "Always On" feature, as well as "Boosted" which gives my REPL some extra compute juice.

No, 'drop table library' does not work

Cause it's "read only", remember?

My library is up and running and you can try it out now. I even added a consistent query param with the SQL query so that I could share links to books about Writing or my favorite books about ancient Rome, for example. I used a bunch of "vanilla JS" to make this work, given that my blog is a static site built with Syte / EJS, so there was a lot of googling for XMLHTTPRequest docs.

Some things I'm going to think about more, next time I'm procrastinating:

  • Automatically trigger daily restarts of the REPL so that I can get an updates to the spreadsheet (ROAPI does not yet dynamically re-load contents, it only does so one time, at the beginning)
  • Finish up adding the remaining fields/data to the spreadsheet, maybe while re-watching Halt and Catch Fire.
  • I can't seem to get doubly-nested group by SQL queries working, maybe I can look into this on the ROAPI side
  • Add WASM support to ROAPI so that I don't need a server at all

My New Old Apple Macintosh SE/30 Computer

I just finished reading The Order of Time by Carlo Rovelli last night. It's a lovely little book about quantum gravity and the nature of time that I barely understood. But one thing I took away was that time -- and, by extension, the true meaning in our lives -- is driven by our memory, our nostalgia.

"...which is why I think it makes sense to keep this vintage 1989 Apple Macintosh SE/30 on our bedside table."

No dice. I also tried appealing to hobbies, and their role in maintaining a balanced life.

But, alas, my new precious is headed for The Troll Pit where (more than) a few Apple II's will keep it company.

How does one go from having zero vintage computers to... many of them? Gradually, and then suddenly.

But, for at least a few more days, I'll be rocking this utterly tricked-out compact Macintosh on our dining room table. It is #MARCHintosh, after all.

Mac SE/30

That's right. I've acquired the computer of my dreams: an Apple Macintosh SE/30, considered by many Apple wizards to be the greatest Mac of all time (or, at least, the 6th most "notable" Mac ever).

Buying something from someone

We're still allowed to do this on the Internet. Two live human beings can arrange an exchange of an owned, physical item for some form of (let's be honest, digital) payment. You don't need to buy everything from Amazon.

eBay's still a thing. Craiglist is still its weird self. And FB Marketplace is probably the best one of them all right now, for a very specific reason: it's insanely easy to go from a listing to a little Messenger chat with the seller. No more weird anonymized emails via Craigslist that feel like you're sending a fax to your grandfather in 1978. Yes, you do have to have the FB app AND its companion Messenger app, but there's gold in them thar vintage computer listings, I tell you. Actually, I shouldn't be saying this, because I don't want lose this precious alpha.

After many evenings of eBay alerts and FB Marketplace searches, I found a Mac SE/30 for sale in the greater Boston area, where I don't live, but I frequently visit. The rest is just boring details, which I fully document in the riveting Episode III of IN THE TROLL PIT (my live-stream / YouTube channel about vintage computers):

Long story short, I got the dang thing, and it works! But I was also scared, because what if it stopped working?

In fact, I did a lil' research, and found out that these compact Macs got problems. There's a thing inside called a PRAM battery that looks like a mini D-cell and it helps keep things like the correct date going, and it's basically doomed to explode. Sages tell us that it's an absolute must to remove this battery in the modern era, or you're gonna have a bad time.

Next big ticking time-bomb are the electrolytic capacitors, which are just gonna do pretty much the same thing as the battery: get all weird and puffy and oozy and start leaking everywhere on the circuit board. One of the tell-tale signs of leaking electrolytic fluid in compact Macs is when the sound stops working.

Guess what? This thing's got no sound.

After that, I was afraid to turn on my precious. If you recall my adventures with the Apple IIe I found in the trash, I'm no stranger to capacitor issues.

Knowing when to ask for help

Thanks to my prolific 8-Bit Guy viewing habits, I knew that my Mac needed "professional" help.

Why didn't I try to fix this myself? This computer -- unlike the Apple II -- has some serious high voltage components inside: the CRT. Basically, the cuteness-factor of its built-in screen is what makes this computer so tricky -- and dangerous -- to repair. There are all sorts of guides on YouTube explaining how to safely discharge the CRT with some screwdriver-looking-grounded gadget, but that's something I don't want to fumble through.

During my extensive vision quest for this machine, I had many conversations with folks on eBay and FB Marketplace about their various wares, so I decided to reach out to one of them who seemed pretty nice on our first go-round. Maybe they could help me out or knew someone who could help.

I hit the jackpot with my first reach out.

Soon, I delivered him my machine. Almost immediately, I started receiving regular text updates about my Mac: before-and-after cleaning photos, absurd RAM upgrade options, etc. He also sent along pictures throughout the restoration, which were like little treats for me. I knew my Mac was in capable, caring hands. When I finally picked it up two weeks later, my little cutie had changed, a lot.

Why this computer is super cool

In addition to giving it a nice once-over (no retrobrite, just some wiping), removing the PRAM battery, swapping out the capacitors, my "dealer" also offered to upgrade my machine's RAM (which started out as a measly 1MB). Going to 4 MB seemed like a good idea (and the max stock RAM was 8 MB), but he also offered going further... to the absolute max possible in this machine: a whopping 128MB, which would also require an upgraded ROM chip.

"Go for it," I said.

He went for it. Here are some action shots.

First, opening up the hood.

Under Hood

Now we can see the original state of the board. Note the little red battery in the upper left. That's our PRAM battery. Goodbye, accurate dates. Also, the upper right is where the RAM goes. Notice that we're not using all of the available slots, which seems less than ideal.

Original Board

In addition to the RAM chips, we installed the Mac ROM-inator-II from Big Mess O'Wires.

Before

For $39 bucks, this ROM chip gives my Mac (according to their website):

  • Diskless booting option
  • HD20 hard disk support built-in
  • 32-bit clean – allows use of System 7.6+ and more than 8MB RAM
  • Memory test is disabled for faster booting on 16MB+ systems
  • Customized startup chime – major 9th arpeggio
  • Happy Mac icon is replaced by a color smiling “pirate” Mac
  • New startup menu screen displays installed RAM, addressing mode, and ROM disk details

Heck, yeah, I want a smiling "pirate" Mac icon.

Pirate

"Computer, enhance."

enhance

Here's our baby with its upgraded ROM and RAM:

RAM

After Shot

Another angle

RAM2

ActionRetro has a great YouTube video describing the same RAM/ROM setup. Honestly, I have no idea how to even leverage this RAM, but I had to have it.

Also, my "computer guy" replaced the existing hard disk with a SCSI2SD, installing System 7 and even Mac OS 8.1 along with the original System 6 on the SD card. There are also other options for this like BlueSCSI or the FloppyEmu. My guy was familiar with SCSI2SD, so we went with this approach. I'm happy. The only thing I'm slightly concerned about is what happens if the SD card just randomly dies (like has happened on several of my Raspberry Pi's), cause I'd have to open up the case to fix it, I think. I'm thinking that I might grab a FloppyEmu as a back-up.

Switching between the OS versions is super easy. There's a shortcut to called System Picker - and I just pick a system and then restart and boom, I'm in the selected OS. Mac OS 8.1 takes a bit longer to load than the others, but that's probably cause it was never supposed to work on this machine in the first place, which is cool.

Finally, my guy left me a little Welcome note (written in SimpleText) on the desktop with some tips, like how to set the correct date in the Control Panel now that the battery's gone, as well as how to enable 32-bit addressing to make use of the 128 MB RAM (as 24-bit addressing has a 16 MB limit).

This was all-around fantastic customer service, facilitated via shared nerdy interests on the Internet.

Games and apps and stuff

Finally! What we've all been waiting for! Here are some early highlights and delights among the apps on my SE/30.

MacPaint

A true classic, written by Bill Atkinson himself. Without MacPaint, I would posit there would be no Mario Paint, so I'm forever grateful.

MacPaint

HyperCard

Another Atkinson wonder. I'm pretty sure that the original version of Myst was just a HyperCard stack. As an amateur Tools-For-Thought-o-phile, I'm excited to poke around here and make something as weird as my brain.

To that end, I bought the HyperCard manual on eBay.

HyperCard

MusicWorks

There are songs and you can play them on your computer. And even write your own. This feels like the origins of GarageBand or Logic, but for people who understand music notation (not me -- yet!)

BBEdit

What Mac would be complete without a copy of BBEdit? I'm excited to figure out how to code up some stuff on this Mac soon. I don't even know what language that would be in... Objective C? Smalltalk? I need to do some more research.

Lemmings

The music, just as good as I remember. The graphics, not so much.

Lemmings1

Lemmings2

Sid Meier's Civilization

The game that birthed an utterly time-consuming franchise for many of my close friends. I'm worried about diving in too deep here.

Civilization

Oregon Trail

Yes, Mom, this has Oregon Trail.

Oregon Trail

AfterDark

Everyone's favorite screen saver application! And I get it. I've already spent over an hour reminding myself of all the different options. I probably should have mentioned this before, but this isn't my first rodeo with compact Macs. My Uncle Sean had one, and my cousins and I spent hours playing games on it in their attic bedroom.

After Dark

Flying Toaster

Rainy day to-do list

Here's my current ideas list for Mac SE/30 projects:

  • Figure out how to get new software. Do I really need an early 2000s "bridge" Mac to write floppies?
  • Get on the internet. Mac OS 8.1 has Netscape and an early Microsoft browser, but I need some sort of ethernet card, I think. Or use a Raspberry Pi as a bridge?
  • Get a color video card (rare and expensive) and set up dual monitor
  • Write Apple-Script to automate turning on 32-bit addressing automatically and setting the correct date every time I turn on the computer
  • Code a game and publish it on GitHub / archive.org for other weirdos like me
  • Pixel-art PFP for myself in MacPaint
  • Get The Dungeon Revealed on this machine (its shareware version "The Dungeon of Doom" was our favorite game on Uncle Sean's Mac SE)

Send me your ideas or old floppies, please.

P.S. Some meditations on a beige box

This is my personal computer. My data lives here. Not on the internet. When I turn this on and play Tetris, I can see my friend Steve's high score from last week on the leader board, when he visited me and I forced him to play this thing.

The Mac SE/30 feels "personal" in a way that my swappable, cloud-backed-up phone and modern laptop just don't. They're dumb terminals, but this is MY smart computer.

A final coda

I now get the love for the Apple Extended Keyboard II. Also, plugging the one-button mouse into it is also weird and cute.

keyboard

Fahrenheit 52

I love a good challenge. Which isn't quite the same thing as a competition, although that can be part of it. In general, I think I've done well with "frameworks" for my hobbies - whether that's running or writing or coding or music. I don't have to be The Best at anything, I just want to encourage habits that help me get in flow and have fun and make weird stuff, and some scaffolding for my creativity has helped me.

For example, NaNoWriMo kicked off my novel-writing habit a few years back, and now I've got a real-life novel that I've written and printed out on my home printer and spiral-bound at FedEx (I'm working on getting the book in more people's hands this year!).

Right now, I'm craving more writing, so I've concocted a new challenge for 2022 that I'm calling Fahrenheit 52.

Fahrenheit 52 logo

With F52, I'll be writing a new short story, every week, for a year. The concept's based on a quote from my fav spooky guy Ray Bradbury:

"The best hygiene for beginning writers or intermediate writers is to write a hell of a lot of short stories. If you can write one short story a week—it doesn’t matter what the quality is to start, but at least you’re practicing, and at the end of the year you have 52 short stories, and I defy you to write 52 bad ones. Can’t be done. At the end of 30 weeks or 40 weeks or at the end of the year, all of a sudden a story will come that’s just wonderful." - Ray Bradbury

The goal isn't perfection. It's about putting in the reps.

For fun, I'm also reading the story out loud each week and releasing it as a podcast. You can read the stories on the F52 website, subscribe to the F52 RSS feed, or subscribe to the podcast RSS feed with your favorite podcast player (Overcast, Spotify, Apple Podcasts).

For more fun, I made the F52 website using Syte - the static site generator that my friend Ben wrote and that I've been tweaking a bit. For this project specifically I added podcast RSS feed generation to Syte (which I wrote about in this post on hosting podcasts for free).

I'll close this post with another quote from Ray Bradbury. It's from my favorite book Dandelion Wine and it makes me cry:

The wine still waits in the cellars below. My beloved family still sits on the porch in the dark. The fire balloon still drifts and burns in the night sky of an as yet unburied summer. Why and how? Because I say it is so.

Found Myself Driving

Last night I got to ride in my first driverless Cruise car (adorably named Cheddar) and I brought along my guitar.

Lyrics, for the record:

Hop into the back seat
It's time for a ride
Tonight we're Cruisin'
Yeah, let's autonomously drive

There's no one behind the wheel
But it keeps on turning
I still can't believe this thing is real
and it's continuously learning

I found myself driving in a self driving car
I found myself driving in a self driving car

I use a laser beam to find my way to you
I use a laser beam to deliver lots of food

I found myself driving in a self driving car
I found myself driving in a self driving car

I'm assuming this is the first ever song performed in a driverless car. We're making history over here at Cruise.

Other than the song, the ride was unremarkable insofar as it just felt normal, even though there was no one behind the wheel. The whole experience was a weird blend of this is amazing and this is an everyday thing, if that makes sense. I'm excited for more people to get to use Cruise soon!

My DIY Free Podcast Hosting Setup

You either die a hero or start a podcast. That's it. That's the blog post.

If you're still reading, good. Let's do this thing. Let's host a podcast for free.

Wait, some questions

Doesn't iTunes host podcasts?

Nope. They're just the most popular podcast directory. You need to host your RSS feed and audio files somewhere else on the Internet, and ideally somewhere that won't charge you a lot for bandwidth every time someone downloads one of your episodes. You also need to generate a podcast RSS feed (an XML file with specific fields) in the first place.

Well, then, what about Spotify?

Yeah, Spotify does some podcast stuff, too. I think they like podcasts because they don't have to pay royalties like they do on songs. I also remember hearing that they're actually re-hosting public podcasts on their side, which potentially had weird implications for the podcasts with those annoying "dynamic ads." They also bought Anchor, which I think also hosts podcasts for free, but maybe they "own" your podcast or something. Honestly, don't really care and it may be quite different from what I said. Let's just move on.

Shouldn't I use some managed service instead of trying to do this myself?

Yes, probably. In fact, I'd recommend Transistor.fm. I initially used them for Escaping Web before migrating the weird setup I'm about to describe. Transistor comes with great features like analytics, YouTube integration, private feeds, and more. It's a small bootstrapped team and I love their own podcast "Build Your SaaS." Lots of popular podcasts that you may already know and love use Transistor (like Indie Hackers). Shilling complete.

Enough. Get to the good stuff.

Charlie's DIY Free Podcast Hosting Setup

Here's the TLDR:

That's probably enough to get you started. But, if you're up for it, I'll walkthrough creating a new podcast from scratch.

Quick note - an earlier version of this article recommended using GitHub Pages for audio hosting, but I've switched to using the free tier of archive.org based on some suggestions in the discussion of this post on Lobsters.

Host your episode audio on archive.org

Jurassic Park scene

Ah, now eventually you do plan to have audio on your, on your podcast, right? Hello?

Dr. Ian Malcolm's right. We do need some audio. Let's think. I've got this supremely unpopular Twitch / YouTube series called IN THE TROLL PIT where I fix interact with old Apple II computers (and hopefully soon a Commodore 64 and a Mac SE/30!). There's only two episodes so far (I'm not getting in as much Troll Pit time as I'd like to these days), but these YouTube videos should work for our podcast.

Let's use youtube-dl to download just the audio of IN THE TROLL PIT playlist into a new folder:

mkdir in-the-troll-pit-audio

cd in-the-troll-pit-audio

youtube-dl --extract-audio --audio-format mp3 -o "%(title)s.%(ext)s" https://www.youtube.com/playlist?list=PLC_pWofH2gku_gToeh1lZN8dssjcSUAft

Now, I'll rename them because I don't like spaces in my file names:

mv Apple\ IIc\ unboxing.mp3 2-apple-iic-unboxing.mp3

mv Apple\ IIe\ computer\ floppy\ drive\ setup.mp3 1-apple-iie-floppy-drive-setup.mp3

Excellent. Now we can go to archive.org, hit Upload in the upper right, and fill out the metadata for our audio files:

archive.org upload

Each episode mp3 file will have its own page on Archive.org, like so:

archive.org page

Finally, we can grab our mp3 file URL with the VBR MP3 link, which should give us a URL like this for episode 2: https://archive.org/download/ittp-002/2-apple-iic-unboxing.mp3. Paste each episode's mp3 link into a scratch file somewhere, because we'll need it later!

Generate your podcast RSS Feed and Podcast Website with Syte

Nothing special up to this point, but here's where things get fun. I've written before about my friend Ben's static site generator Syte. It's written in TypeScript and it's quite simple and easy to understand. I'm planning to migrate this here blog to Syte from Gatsby very very soon because I'm tired of my blog breaking every few weeks for some unknown node dependency reason. In the mean time, I've already used Syte for other projects, including my "writing tools" interview site Writes With (repo here).

More to the point, I've contributed two new features to Syte in the last few weeks that make this whole podcast feed thing possible:

  • RSS feed generation (aka standard blog RSS feeds - example with Writes With!)
  • Podcast RSS feed generation (aka exactly what you need to give the iTunes Podcast Directory to list your show)

We'll use syte to create a website for our show and add a page for each episode. The contents of the episode pages will become the episode shownotes, and the frontmatter for each page will contain metadata that our podcast feed needs.You'll see!

First, let's make a new repo on GitHub called in-the-troll-pit to host our Syte site (hehe).

Now, back on your computer terminal, navigate back to your favorite directory for projects (mainly, just make sure you are not still in the in-the-troll-pit-audio directory). Let's install syte now:

npm install -g syte@0.0.1-beta.12

Yeah, it's still in beta. I keep telling Ben it's ready for prime time. Maybe you can convince him. Anyway, now we can run the syte new <site> command to create a new project:

syte new in-the-troll-pit 
cd in-the-troll-pit

Syte does hot-reloading locally, because its 2021, so let's fire it up and see where we're at.

syte serve

Head on over to localhost:3500:

Syte default page

Looking good. Let's first update the home page. Change your pages/index.md file to this:

Nothing's showing up in our episode list anymore (cause I filtered out the homepage), so let's add our episode pages. We'll need a Markdown file for each, and a folder to hold them:

mkdir pages/episodes
touch pages/episodes/{1..2}.md

Let's populate the page for episode 1.

---
title: '1: Apple IIe Floppy Drive Setup'
date: '2021-05-26'
episode_url: 'https://ia801500.us.archive.org/1/items/ittp-001/1-apple-iie-floppy-drive-setup.mp3'
episode_duration: ''
episode_length: ''
episode_summary: Charlie's down in The Troll Pit and he's trying to setup an Apple DuoDisk floppy drive so that he can play the branch new game Attack of the Petscii Robots.
episode_explict: 'no'
---

Charlie installs the DuoDisk floppy drive on his Apple IIe and plays Attack of the Petscii Robots!

Links and resources:

* [Apple IIe](https://en.wikipedia.org/wiki/Apple_IIe)
* [Apple DuoDisc](https://en.wikipedia.org/wiki/Disk_II#DuoDisk)
* [Attack of the Petscii Robots for Apple II](https://www.the8bitguy.com/26654/petscii-robots-for-apple-ii-now-available/)

The fields in the frontmatter are important - they are used by the podcast RSS feed generation process. iTunes needs/wants to know if your expisode is explicit or no, and so on. Take note of the episode_url field - this is the link to the mp3 we uploaded to archive.org. If you go to that link in your browser, it should just play the mp3 file. Very cool.

Also, two of the fields are blank right now - the episode duration and the expisode length. The episode duration refers to the length of your episode in seconds and the episode length refers to the size of your episode in bytes. Maybe these aren't the best names, but that's what I came up with. Let's calculate those from our mp3 file.

First, the duration in seconds:

cd ../in-the-troll-pit-audio

ffprobe -show_entries stream=duration -of compact=p=0:nk=1 -v fatal 1-apple-iie-floppy-drive-setup.mp3

727.693061

There's our duration! Now let's grab the file size in bytes:

wc -c < 1-apple-iie-floppy-drive-setup.mp3

6403740

Now we can update those fields in our frontmatter:

episode_duration: '728'
episode_length: '6403740'

Next, I'll repeat the process for episode two:

---
title: '2: Apple IIc Unboxing'
date: '2021-08-01'
episode_url: 'https://ia601509.us.archive.org/20/items/ittp-002/2-apple-iic-unboxing.mp3'
episode_duration: '2141'
episode_length: '19075912'
episode_summary: Charlie's friend Jason sent him an Apple IIc that's been sitting in Jason's childhood basement, and the two try to see if it still works.
episode_explict: 'no'
---

Charlie's friend Jason sent him an Apple IIc that's been sitting in Jason's childhood basement, and the two try to see if it still works.

Links and resources:

* [Apple IIc](https://en.wikipedia.org/wiki/Apple_IIc)
* [Where in the World Is Carmen Sandiego](https://en.wikipedia.org/wiki/Where_in_the_World_Is_Carmen_Sandiego%3F_(1985_video_game))

If you head back to localhost:3500, our episodes now show up on the homepage:

Syte default page with episodes

And here's what an episode page looks like.

Syte default page

It's terrible (terribly awesome?). I'll leave it as an exercise to the reader to update the CSS (start with the the app.css in the /static folder). But you know? It's enough for our purposes.

Just two more things to do:

  1. Add a few more fields to the app.yaml file that are needed for podcast feed generation
  2. Create/add podcast cover art

app.yaml

This file is an overall config used by Syte, kind of like frontmatter for the whole website. Let's add some more required fields for podcast feeds.

layout: app
title: in-the-troll-pit
base_url: https://ittp.charlieharrington.com
podcast_category: Technology
podcast_language: en-us
podcast_subtitle: Old computers are the best
podcast_author: Charlie Harrington
podcast_summary: Charlie Harrington has a problem - he loves old computers. He's down in the Troll Pit and  
podcast_explicit: 'no'
podcast_email: ittp@whatrocks.org
podcast_img_url: ''

Coverart

We need podcast art! According to the Apple podcast guidance, our podcast art should be 3000 by 3000.

Here's what I'm thinking. Grab a random screenshot from an episode and overlay some text on top. Probably gonna be terrible, but we can always change it later.

I've been thinking a lot about Goosebumps series lately, so that's the vibe I'm feeling for IN THE TROLL PIT logo. I found this font called Creepster on Google Fonts, downloaded it, and installed it locally (easier than you think on a Mac, just double click on the unzipped font file and click Install in the window that pops up).

Here's what I came up with: take a perfect-square screenshot of one of my episodes, add the show title text in Creepster font on top, save it to my Desktop, and then use ImageMagick to resize it:

convert screenshot.jpg -resize 3000x3000 ittp.jpg

ITTP coverart

Put this awesome file in your /static folder and then add this to app.yaml:

podcast_img_url: https://whatrocks.github.io/in-the-troll-pit/static/ittp.jpg

Let's make our podcast feed!

We're basically done now. let's test out the Syte feed generator. Try this command:

syte build

You should now see a new directory called build with your static site (all the HTML generated from the Markdown) as well as a rss.xml file (this is your site's RSS feed) and a podcast.xml (this is your podcast's RSS feed). Amazing!

All that's left now is to deploy these somewhere on the Internet. I suggest two options here:

(Option 1) Use GitHub Pages

This is the easier option. Tell syte to output to the docs directory, git init this directory, add your origin as the in-the-troll-pit repo, git add everything, commit, and push to your Github repo. Then enable Github Pages in the settings using the docs folder and you're done! You should be able to access your podcast RSS feed on the internet, and then submit that URL to iTunes.

syte build -o docs

I'm going to go with option 2 because I like trying new things.

(Option 2) Use Cloudflare Pages

We're going to set up Cloudflare Pages to deploy on changes to the main branch in this repo. Before we do that, we need to make a few more changes here because Syte is not (yet) natively supported by CloudFlare Pages (I'd love to get this added if anyone from Cloudflare is reading!).

Create a package.json file with these contents:

{
    "dependencies": {
      "syte": "^0.0.1-beta.12"
    }
  }

Then npm install, which should create a big ol' node_modules folder.

Finally, add a .gitignore with these contents:

.DS_Store
node_modules
build

Now we're ready to get this up to Github:

git init
git add .
git commit -m "just setting up my syte"
git branch -M main
git remote add origin git@github.com:whatrocks/in-the-troll-pit.git
git push -u origin main

Let's also turn on GitHub Pages for this repo so we can access our coverart. We can do that in the Settings tab and Pages section for this repo.

Set up Cloudflare Pages

Now I'm not going to do a full walkthrough of this part, because Cloudflare Pages is a rapidly changing new product. At a high-level, create a new Project with Pages, add your GitHub repo, and then configure your build. This build configuration step is important to get right, so here's what mine looks like:

Cloudflare Pages

It's important to get these details in the Build Configuration:

  • Build command: syte build
  • Build output directory: /build

Then I'd also add this environment variable:

NODE_VERSION: 15.12.0

I know this one won't age well, but I've found it helps me to stay consistent here.

Then, hit build and Cloudflare will build and deploy your site! Mine's now live here: https://in-the-troll-pit.pages.dev/ and the podcast feed is here: https://in-the-troll-pit.pages.dev/podcast.xml.

You're basically again at a nice enough place to stop and submit your podcast feed to iTunes. I'm going to go one step further and set up a subdomain on my main website for my project, which I'll also use Cloudflare to do. If you don't want to do this, then just update your app.yaml file to the new base_url provided by Cloudflare Pages:

base_url: https://in-the-troll-pit.pages.dev

But since mine is base_url: https://ittp.charlieharrington.com, I'm going to make that change now in Cloudflare, which is super easy if Cloudflare is managing your DNS - just hit the "Custom domains" tab and follow their guide. It takes a while for DNS to reflect your changes, so just wait ~2 days until the URL works correctly before you move on to the next step.

Cloudflare Pages Custom Domain

Upload your RSS feed to iTunes directory

This part is less interesting to me, so I'm not going to go too deep. Go to Podcasts Connect (in Safari!) and create a new show and fill out the info with a link to your feed.

PodcastConnect

It takes a couple days for the show to appear in iTunes. Keep refreshing, though. That helps it go faster.

You can also upload your show to other directories like Google. I may need to update the Syte feed generation code to provide the required RSS metafields for these other directories, so if you run into any issues, please let me know on Twitter.

If you really can't wait for iTunes, you can usually just add a podcast RSS url manually in your player of choice (mine's Overcast). Let's give that a shot.

Overcast Example 1

Overcast Example 2

Overcast Example 3

That looks awesome! The shownotes look perfect!!

We're now ready for the final step.

Reach out to Squarespace for sponsorship

Good luck with that!

My final comment is that I think this approach is well-suited for putting your podcast into maintenance mode - no new episodes coming out any time soon, but you still want to keep the old ones up, without paying any monthly fees for hosting. That's exactly what I did with Escaping Web, and I'm sure there are still a few EW-ers out there who are grateful that they can still listen to Oz's wisdom (I know I am!). And who knows, maybe we'll do season two one day :)

There's probably a bunch of things I could have done better or smarter in this article, and I'm open to learning about them if you want to reach out. For now, happy casting, villians!