“Wisdom” Bot for Mastodon

I left the Birdsite about six months ago when the new owner started mucking about.

No regrets! Mastodon has been so much better! I decided to try my hand at creating an automated “robot” to post quotations alongside some of my photographs.

Wisdom in Space Posts Every Four Hours

Mastodon is much more civilized and well organized—including best practices for social media bots. There is even a server dedicated to bots called “botsin.space”–so I called my new bot “Wisdom in Space“.

There are many helpful websites to get started. Most use the mastodon interface package for Python. This is the first time I’ve written code in the python language, but fortunately the learning curve isn’t very steep. The biggest conceptual hurdle for me was understanding and using virtual environments on the shared server. Once I got those pesky details worked out I set up a cron job to post every four hours. The quotes are in a tab-delimited text file and the images are in a nearby directory. Note the development code below works locally on my laptop. The directory paths and other details are different on the server. I hope someone finds this useful!

#
#	wisdombot 0.2
#	quote of the day service for mastodon
#	copyright richard rathe 2023
#	(cc) attrib-noncomm-share-alike
#

import re

import glob

import random

from mastodon import Mastodon

quote_list = []

with open('wisdom.dat') as file:

	for line in file:

		line = line[:-1]  # remove newline

		quote_list.append(line)


qmax = str(len(quote_list))

image_list = glob.glob('images/*.jpg')

imax = str(len(image_list))

qrand = random.randrange(int(qmax))

line = quote_list[qrand]

line = line.replace('—'  , '--')	# fix entities
line = line.replace('"'   , '\"')
line = line.replace('é' , 'e')
line = line.replace('ø' , 'o')
line = line.replace('ö'   , 'o')
line = line.replace('&'    , '&')

data_list = line.split('\t\t')		# double tab delimited

irand = random.randrange(int(imax))	# pick image at random

img = image_list[irand]

match = re.search(r'^images/([a-z0-9-]+)', img, re.I)

if match:
	stem = match.group(1)
else:
	stem = ''

ikeyw = ''

for i in stem.split('-'):
	i = i[0].upper() + i[1:]	# capitalize
	ikeyw += " #" + i

ikeyw = ikeyw[1:]	# nuke leading space

keyw = ''

for i in data_list[2].split('/'):	# keywords are '/' delimited
	i = i.replace(' ', '')
	i = i.replace('-', '')
	keyw += " #" + i

keyw = keyw[1:]		# nuke leading space

quote = data_list[3]

name = data_list[0]				# author name

ntag = re.sub('[^0-9a-zA-Z]+', '', name)	# author hashtag
ntag = '#' + ntag

other = data_list[1]				# source info (if available)

if other == 'None':
	other = '';
else:
	other = ' (' + other + ')'

out = quote + '\n    -- ' + name + other + '\n\n'

out += '⬆ #Quotes ' + ntag + ' ' + keyw + '\n\n⬇ #Photography ' + ikeyw

if len(out) < 500:		# limited to 500 chars

	print('\n' + out + '\n')

	mastodon = Mastodon(
		access_token = 'token.secret',
		api_base_url = 'https://botsin.space/'
	)

	media = mastodon.media_post(img, description="photo by richard rathe")
 	mastodon.status_post(out, media_ids=[media])

Telegraph Codes from 1914

Opinions Expressed Here Are My Own

Back in the days when long distance telephone calls were very expensive, families had various ring codes to let their loved ones know that they got there safe but avoided paying for an actual call. Ours was to let it ring twice and hang up (if I remember correctly).

This little gem of a book illustrates how inventive our ancestors were when it came to the telephone equivalent of the day—the ten word telegram. The basic idea was don’t let any leftover words go to waste (you already paid for them after all!).

The Private Code and Post-Card Cypher Book Cover
Theodore Newton Vail was the first president of AT&T! [source:wikipedia]

The introductory Apology (in the sense of a reasoned argument or writing in justification of something) hints at an axiom of human nature—avoiding small marginal costs (the $9.99 price tag and the 9/10s cent added to gas prices). Ten words it must be. This code will aid the perplexed, homesick, and abandoned among us… a bold claim!

The approach is pretty simple (elegant?)… the non-coded message comes first, followed by the delimiter word CODE. A mix of code words and specifiers completes the message. Specifiers might be a specific item (keys in the example below) or the name of a city or hotel. There is also the interesting parts of speech variation indicating 1) a statement with no need to reply, 2) a question expecting a reply by letter, and 3) a question expecting a reply by wire (telegram).

Example Codes

The bulk of the book lists the actual code words as conceived by the authors. One thing that becomes obvious is that some of these codes are jocular or even absurd. There is no differentiation or explanation of these. My favorite is…

Jab = The servants have left, the house is on fire, all the children have smallpox, and I have lost a filling out of my tooth… but don’t think of hurrying home.

Each section ends with a page or two of unassigned code words, presumably for readers to add their own messages. I’m trying to imagine using the word Bigot in a telegram to my grandmother?!

Love these intimate messages!

I see the moon and the moon sees me, and the moon sees somebody I want to see.

Will you marry me, or won’t you? Wire yes or no, using Johnson Code.

The last makes no sense since yes and no are not code words. I guess they expect sweet nothings to follow a yes, not sure what you’d say after a no?

…Perchance cheese and coffee would amply suffice.

Appendices

The book ends with two chapters that are only loosely connected to the code system (as far as I can tell). The first is titled Model Letters. Not sure if you were supposed to take out a sheaf of pre-written letters and read them based on the code words?!

Poetry… ?!

And finally, a description of how to play the Game of Telegrams.

Another Example

During our discussion my neighbor produced a Ford Model T Parts Catalog also from 1914. It turns out they used an extensive system of code words to indicate how and what you were ordering!

1914 Ford Model T Parts Catalog
“Top…” Shipping Codes
Typical Page

See Also: Telegraphic and Signal Codes

Books pictured/reviewed here are from the
Alachua County Friends of the Library
unless otherwise specified.
Materials presented for review purposes only.

Sailing Kayak Mods & Camping

In 2018 I acquired a used Hobie Adventure Island sailing kayak. It came with trampolines that fit between the outriggers. As I learned the particulars of the craft it became obvious that getting out of the cockpit and sitting in/on the tramps wasn’t going to work for me.

I started looking around and found many kindred spirits on the Hobie Forums site. Adding homemade benches (aka “hakas“) was the obvious solution. To summarize the many materials and designs: simple wooden slats, PVC pipe, metal pipe, ladders, and something called FRP (fiber-reinforced plastic). Here is a sample of what I found…

Source: Hobie Forums

Version 1

I have basic woodworking skills so I decided to use generic 1x4s from the local lumber yard (about $100). I focused on making them as strong as possible. I finished the benches and took off for the Everglades with them untested. Here is a photo of my version 1 hakas…

Pavilion Key, Everglades

One obvious design element was putting the hakas together to make a sleeping platform. This turned out to be useful when making camp on shore. (Being four inches above the sand makes a big difference!) They were also handy for cooking and just having a clean, dry place to layout gear.

Rabbit Key, Everglades

It happened to be VERY windy (15-30 knots) while I was there, so I had to limit the amount of actual sailing I did. The hakas worked well and I made it back with my sail half reefed. The major problem was the weight (about 27 pounds each). With my gear, water and supplies I was probably at the limit of what the boat could handle. It was also obvious that version 1 was much stronger than it needed to be. Finally, I should have positioned the benches further out so there’d be room to paddle when necessary.

Version 2

So back to the drawing board! I decided to decrease the width of the benches and nix the undercarriage. I also planned to add a “quarter deck” behind the seat. The complete setup is shown here…

This time I made use of aluminum angle stock in two critical places: 1) I needed a strong “hook” to go under the aft crosspiece to support my weight on the opposite corner.

2) The three 3/4 inch planks are not very strong by themselves, so I ran aluminum angle down the center of each bench to help carry the load. They’re still springy but this seems to strike the right balance between strength and weight. (The small blocks seen on the left give clearance for the jam-cleats on the crossbar.)

Here’s the result after my maiden voyage!

It is so much nicer to be up out of the spray and for the first time I was really able to keep the boat trimmed in a strong wind. Notice that I’m using a half paddle. This makes paddling with the sail up much easier.

Camping

When the two hakas are brought together they make a platform exactly two by six feet. This turns out to be just enough room to lay out a pad and sleeping bag. But what to do about shelter (bugs and weather)? I started with half paddles for the uprights using the mast step for one and the quarter deck to stabilize the other. Then I ran the rope that controls the sail (called the sheet) over the rear paddle and connected it to a rope from the front. This became very stable when put under tension.

I added small loops to a camping hammock and hung this from the ridge line. (Also shown here are the short pieces of flexible conduit I fashioned to keep the rope on top of the paddles.) After much experimentation I settled on the harness you see here.

This has the added benefit of allowing the whole thing to slide to one end when not needed.

As proof of concept I tied the boat to a tree and slept on the water…

It worked remarkably well. I had enough room to stretch out and nothing got wet! It’s worth noting that the little extensions of the quarterdeck were remarkably useful for getting on and off the boat

Finally I worked on the rain fly. Starting with a generic 10×10 foot nylon tarp, I added grommets 18 inches from the ends to make it fit the outriggers.

It’s worth noting here that I’m a recent convert to these shock-corded toggles. I used them almost exclusively for this project. I love ’em!

The tarp is supported by the ridge line and tied at the bow and stern. The extra length is folded under to keep it from flapping. This setup is a bit vulnerable to blowing rain on the ends but probably not an issue under normal circumstances (at anchor in a sheltered place).

As you can see, there is plenty of head room inside.

The strengths of this design are:

  • The quarterdeck and hakas work well together and add to the sailing experience/capabilities of the boat.
  • The weight is down to about half of version 1.
  • Almost all the components are dual use, nothing is wasted.
  • The camping setup is flexible, only use the bits that you need. If there are no bugs or rain sleep out under the stars!
  • The hakas, hammock and tarp work just as well on shore. In fact all you need are the straps and you have a complete camping hammock with fly!

The main thing I would do differently is a build a larger quarterdeck that straddles the rear crossbar. I’ll add a third plank forward of the other two. This will allow more control of the boat’s trim when I’m not all the way out on the hakas.

Quarterdeck Version 2

A few weeks later I bought some more 1x4s and built a new & improved quarterdeck to the specifications above.

This design was much better and easier to fit to the kayak. Note the 3/4″ aluminum strip (not an angle this time). I’m not sure this is necessary but it helps support weight when leaning out and back.

Here is the final result after a day of sailing. It fits snugly over the crossbar and the leading edge is supported by the diagonal strut. Eliminating the length-wise cross pieces makes it mostly transparent to the waves, which is a big improvement!