Skip to content

Instantly share code, notes, and snippets.

@BryantD
Created January 23, 2026 15:55
Show Gist options
  • Select an option

  • Save BryantD/eab013706ad80014ba42bf27c1ff54a2 to your computer and use it in GitHub Desktop.

Select an option

Save BryantD/eab013706ad80014ba42bf27c1ff54a2 to your computer and use it in GitHub Desktop.
Bluesky LastFourWatched script
#!/bin/bash
compose_post() {
local temp_file=$(mktemp)
local char_limit=300
# Create initial content with placeholder and alt text for reference
cat > "$temp_file" << EOF
$placeholder
--- Alt text (delete before posting) ---
$(echo -e "$alt_text")
EOF
while true; do
# Open vi editor
vi "$temp_file"
# Read the post content (excluding our helper text)
post_content=$(sed '/^--- Alt text (delete before posting) ---$/,$d' "$temp_file")
# Count characters (only the actual post content)
char_count=$(echo -n "$post_content" | wc -c)
# Display character count and check limit
echo "Current character count: $char_count / $char_limit"
if [ $char_count -le $char_limit ]; then
echo "Post is within character limit!"
echo
echo "Final post content:"
echo "===================="
echo "$post_content"
echo "===================="
# Using iterm utilities to view the image
/Users/durrell/.iterm2/imgcat lb-friday.jpg
echo "Alt text:"
echo "===================="
echo -e "$alt_text"
# Ask for confirmation
read -p "Accept this post? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Time to post!
# Hacked up version of https://github.com/mattn/bsky
# I had to add aspect ratio controls
# I'd make a PR but the maintainer seems idle
post_url=$(~/bin/bsky-bd -V post --image lb-friday.jpg --image-alt "$(echo -e "$alt_text")" "$post_content")
https_url=$(echo "$post_url" | sed -E 's|at://([^/]+)/app\.bsky\.feed\.post/(.+)|https://bsky.app/profile/\1/post/\2|')
echo "Posted: $https_url"
break
else
break
fi
else
echo "Post exceeds character limit by $((char_count - char_limit)) characters."
read -p "Press Enter to edit again, or 'q' to quit: " -r
if [[ $REPLY =~ ^[Qq]$ ]]; then
echo "Post composition cancelled."
rm "$temp_file"
return 1
fi
fi
# Update the temp file with current count
cat > "$temp_file" << EOF
$post_content
--- Alt text (delete before posting) ---
$(echo -e "$alt_text")
--- Character count ---
Current count: $char_count / $char_limit characters
EOF
done
rm "$temp_file"
}
# Original screenshot and image processing
# Dependencies:
# Simon Willamson's shot-scraper:
# https://shot-scraper.datasette.io/en/stable/
# ImageMagick
/Users/durrell/Library/Python/3.12/bin/shot-scraper --silent -b webkit -s "#recent-activity" -p 20 https://letterboxd.com/Thanlis/
magick letterboxd-com-Thanlis.png -gravity South -chop 0x20 lb-friday.jpg
rm letterboxd-com-Thanlis.png
# Original RSS processing
input=$( wget -q https://letterboxd.com/thanlis/rss/ -O - | xq -x "//item[position() <= 10]/title" )
formatted_lines=()
IFS=$'\n' read -rd '' -a lines <<< "$input"
# Process each line
for line in "${lines[@]}"; do
if [[ "$line" =~ ,\ [0-9]{4}\ - ]]; then
# Extract the title
title=$(echo "$line" | sed -E 's/^(.*), [0-9]{4} - .*/\1/')
# Extract the stars and convert to numeric
star_count=$(echo "$line" | grep -o '★' | wc -l)
half_star=$(echo "$line" | grep -o '½' | wc -l)
stars=$(echo "$star_count + 0.5 * $half_star" | bc)
# Create formatted line
formatted_line="$title: $stars stars"
formatted_lines+=("$formatted_line")
fi
done
# Generate placeholder and alt text
placeholder="📽️"
alt_text="Four movie posters, with ratings:\n\n"
for line in "${formatted_lines[@]:0:4}"; do
alt_text+="$line\n"
done
# Launch post composition
echo "Starting post composition..."
compose_post
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment