Blog Post

Randomizing Mastodon Max Post Length

Randomizing Mastodon Max Post Length

I’ve been really bogged down on a couple personal development projects lately so yesterday I gave myself time to tackle a different problem. Namely, Nora Reed’s idea for randomized maximum post length on a Mastodon instance.

Yes, I know it’s kind of funny to link to a Bluesky post talking about Mastodon.

But I love this idea and I love hir description of it as being weather for the Internet. So I wanted to see how to do it.

The first thing I came across is that, while Nora isn’t wrong about Mastodon allowing you to change the maximum post length, in vanilla Mastodon exactly how to do it is version-dependent. I’m not looking for another thing to have to maintain; I wanted this to be a relatively-simple one-day project. So, instead, I focused on the Glitch-soc fork of Mastodon, which has extracted MAX_TOOT_CHARS into a value in the instance configuration file.

My shell script generates a new max length by “rolling dice” and then updates the configuration file with that value.

The code is all available on GitHub but I’m going to walk through it here.

It’s a bash script to which three optional parameters can be passed. The first is the configuration of the dice, with “2D6” (two six-sided dice) set as the default. The second is a multiplier, as Nora’s original idea had the result of the dice roll multiplied by 100. The third is the path to the configuration file, with $HOME/live/.env.production being the default.

As such, the following commands would execute the same functionality:

$HOME/randomize_max_toot_chars.sh
$HOME/randomize_max_toot_chars.sh "2D6" 100 "$HOME/live/.env.production"

Unsurprisingly, the opening chunk of code facilitates that parameter handling.

#!/bin/bash

if [ -z "$1" ]; then
  dice='2d6'
else
  dice=$1
fi

if [ -z "$2" ]; then
  multiplier=100
else
  multiplier=$2
fi

if [ -z "$3" ]; then
  config_path="$HOME/live/.env.production"
else
  config_path=$3
fi

We then sanitize those values a bit and error out if any of them are inappropriate.

# Validate config file
if [ ! -f "$config_path" ]; then
  echo "Config file '${config_path}' does not exist"
  exit
fi

# Validate dice definition
if [[ "$dice" =~ ^([0-9]+)[Dd]([0-9]+)$ ]]; then
  dice_count=${BASH_REMATCH[1]}
  dice_sides=${BASH_REMATCH[2]}
else
  echo "Invalid Dice Definition '${dice}'"
  exit
fi

# Sanitize multiplier
if [ "$multiplier" -lt 0 ]
then
  multiplier=$((multiplier * -1))
fi

For the config file, we just need to know that a configuration file exists at that path. For the dice, we make sure that they’re defined in the right format (an integer, followed by the letter D, followed by another integer). If it’s the right format, we know how many dice to use and how many sides to give them but if it’s the wrong format we error out. Finally, we force our multiplier to be a positive number.

Then we roll our dice.

# Roll the dice
new_value=0
for (( i=0; i<dice_count; i++ ))
do
  new_value=$((new_value + (RANDOM%(dice_sides)+1)))
done

For each die we generate a random number between 1 and the defined number of sides. We add this to a running total.

Obviously we could just randomly generate a number but Nora’s concept was to roll dice and I wanted to keep that in place.

Finally, we apply the multiplier.

# Apply the multiplier
new_value=$((new_value * multiplier))

At this point we have a newly-generated value to use for our max post length. It’s time to do some file manipulation to handle that.

I developed this on a Mac and sed interactive mode behaves oddly on Mac, so I do some of the updating in a temporary file.

# Set temporary config file path
config_tmp_path="${config_path}.tmp"

Then I check to see if the config file already has MAX_TOOT_CHARS defined.

# Check if the setting is already defined
setting_name="MAX_TOOT_CHARS"
setting_pattern="^${setting_name}=([0-9]+)$"

if grep -qE "$setting_pattern" "$config_path"; then
  # Replace existing setting with new value in temporary file
  sed -E "s/${setting_pattern}/${setting_name}=${new_value}/g" "${config_path}" > "${config_tmp_path}"
else
  # Create temporary file
  cp "$config_path" "$config_tmp_path"

  # Add a newline to the end of the file if necessary
  if [ ! "$(tail -c 1 "$config_path")" = "" ]; then
    printf "\n" >> "${config_tmp_path}"
  fi

  # Add new setting to temporary config file
  echo "${setting_name}=${new_value}" >> "${config_tmp_path}"
fi

If the setting is already defined, we can use sed and regex to replace the old value with the new value and pipe the result into our temporary file.

If not, we copy the existing config over to the temporary file and prepare to add MAX_TOOT_CHARS to the end of the file.

If there’s not a newline on the file, we append one. Then we append the new configuration value line.

Finally, we replace the existing configuration file with our temporary one.

# Replace the existing config file with the temporary one
mv "$config_tmp_path" "$config_path"

As I note in the README for this repo, this script can be run as a cron and applied by then recompiling assets and restarting the server. Exact steps for doing that would depend on the Mastodon version so I opted not to handle it natively.

And as I’ve noted elsewhere, my bash-foo is relatively terrible so there are probably better ways to do some of these things. Additionally, I’m not totally plugged into the Mastodon ecosystem so maybe I don’t have to so awkwardly handle differences in sed interactive mode.

I don’t really expect anyone to actually use this but it was a fun exercise for an afternoon. I think it could be expanded upon to work for vanilla Mastodon… I just probably won’t be the person to do it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.