Mastodon Comments Activate. I'll need to actually post about my blog to mastodon to use it but I'll start soon I think.

This commit is contained in:
2025-12-24 20:43:35 -06:00
parent 87b70ad855
commit 2fdff679f5
9 changed files with 692 additions and 37 deletions

View File

@@ -6,13 +6,18 @@ Usage:
python scripts/import_letterboxd.py # Interactive mode - pick from recent
python scripts/import_letterboxd.py --latest # Import most recent entry
python scripts/import_letterboxd.py --list # Just list recent entries
python scripts/import_letterboxd.py --theater # Skip to theater questions
python scripts/import_letterboxd.py --home # Skip to home video questions
The script will prompt for viewing details (theater vs home) and pre-fill
the front matter table accordingly.
"""
import argparse
import os
import re
import sys
from datetime import datetime
from datetime import datetime, timezone
from pathlib import Path
from urllib.parse import urlparse
import xml.etree.ElementTree as ET
@@ -129,7 +134,124 @@ def rating_to_stars(rating):
return f"{stars} ({rating})"
def create_draft_post(movie, tmdb_details, poster_url):
def prompt_viewing_details():
"""Prompt user for viewing location details."""
print("\nWhere did you watch this?")
print(" 1. Theater")
print(" 2. Home")
while True:
choice = input("Enter 1 or 2: ").strip()
if choice == "1":
return prompt_theater_details()
elif choice == "2":
return prompt_home_details()
else:
print("Please enter 1 or 2")
def prompt_theater_details():
"""Prompt for theater-specific details."""
print("\nWhich theater?")
theaters = [
("1", "Gucci", "gucci"),
("2", "Ghost Theater", "ghost-theater"),
("3", "Marcel", "marcel"),
("4", "AMC South", "amc-south"),
("5", "AMC Lakeline", "amc-lakeline"),
("6", "Other", None),
]
for num, name, _ in theaters:
print(f" {num}. {name}")
theater_name = ""
theater_tag = None
while True:
choice = input("Enter number: ").strip()
for num, name, tag in theaters:
if choice == num:
if name == "Other":
theater_name = input("Theater name: ").strip()
else:
theater_name = name
theater_tag = tag
break
if theater_name:
break
print("Please enter a valid number")
show_time = input("Show time (e.g. 7:30pm): ").strip()
theater_num = input("Theater number: ").strip()
pizza = input("Pizza? (Yes/No): ").strip() or ""
tickets = input("Tickets (e.g. 'At Box Office', 'A-List'): ").strip()
crew = input("Crew (e.g. 'Me, Coach T, Science Bro'): ").strip()
return {
"type": "theater",
"theater": theater_name,
"theater_tag": theater_tag,
"show_time": show_time,
"theater_num": theater_num,
"pizza": pizza,
"tickets": tickets,
"crew": crew,
}
def prompt_home_details():
"""Prompt for home viewing details."""
location = input("Location (e.g. 'Living Room', 'Woodrow Apt'): ").strip() or "Home"
show_time = input("Show time (optional, e.g. 'evening'): ").strip()
pizza = input("Pizza? (Yes/No): ").strip() or "No"
# Media format
print("\nMedia format?")
media_options = [
("1", "Online"),
("2", "BluRay"),
("3", "DVD"),
("4", "VHS"),
]
for num, name in media_options:
print(f" {num}. {name}")
media = "Online"
media_choice = input("Enter number (default 1): ").strip()
for num, name in media_options:
if media_choice == num:
media = name
break
# Screen type
print("\nScreen?")
screen_options = [
("1", "4k TV"),
("2", "4k Computer"),
("3", "1080p Computer"),
("4", "Cell Phone"),
("5", "Someone Elses TV"),
]
for num, name in screen_options:
print(f" {num}. {name}")
screen = "4k TV"
screen_choice = input("Enter number (default 1): ").strip()
for num, name in screen_options:
if screen_choice == num:
screen = name
break
return {
"type": "home",
"theater": "Home Video",
"theater_tag": "homevideo",
"show_time": show_time,
"theater_num": location,
"pizza": pizza,
"media": media,
"screen": screen,
}
def create_draft_post(movie, tmdb_details, poster_url, viewing_details=None):
"""Create a Hugo draft post for the movie."""
slug = slugify(movie["title"])
filename = f"{slug}.md"
@@ -140,7 +262,7 @@ def create_draft_post(movie, tmdb_details, poster_url):
return None
# Format the date for Hugo
now = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
# Format watched date nicely
watched = movie["watched_date"]
@@ -156,6 +278,52 @@ def create_draft_post(movie, tmdb_details, poster_url):
imdb_id = tmdb_details.get("imdb_id", "")
rating_display = rating_to_stars(movie["rating"])
# Use viewing details if provided, otherwise use empty defaults
if viewing_details:
show_time = viewing_details.get("show_time", "")
theater = viewing_details.get("theater", "")
theater_num = viewing_details.get("theater_num", "")
pizza = viewing_details.get("pizza", "")
is_home = viewing_details.get("type") == "home"
# Build tags based on viewing type
tags = []
if viewing_details.get("theater_tag"):
tags.append(viewing_details["theater_tag"])
tags.extend(["no-expectations"])
if pizza.lower() == "yes":
tags.append("had pizza")
tags_yaml = "\n".join(f" - {tag}" for tag in tags)
# Different last two rows for home vs theater
if is_home:
row5_label = "Media"
row5_value = viewing_details.get("media", "")
row7_label = "Screen"
row7_value = viewing_details.get("screen", "")
else:
row5_label = "Tickets"
row5_value = viewing_details.get("tickets", "")
row7_label = "Crew"
row7_value = viewing_details.get("crew", "")
else:
show_time = ""
theater = ""
theater_num = ""
pizza = ""
row5_label = "Tickets"
row5_value = ""
row7_label = "Crew"
row7_value = ""
tags_yaml = """ - gucci
- ghost-theater
- marcel
- amc-south
- amc-lakeline
- anticipated
- no-expectations
- had pizza"""
# Build the frontmatter and content
content = f'''---
title: '{movie["title"]}'
@@ -166,26 +334,25 @@ summary: ""
imdb: "{imdb_id}"
poster: "{poster_url or ''}"
tags:
- gucci
- ghost theater
- marcel
- amc-south
- amc-lakeline
- anticipated
- no-expectations
- had pizza
{tags_yaml}
# Mastodon comments: After posting about this on Mastodon, add the post ID below.
# Get the ID from the end of the toot URL, e.g. https://tilde.zone/@mnw/123456789
# mastodon_id: ""
# To block a reply from showing, add its full URL to this list:
# mastodon_blocked:
# - "https://tilde.zone/@someone/123456789"
---
{{{{< imdbposter >}}}}
| Date watched | {watched_display} |
| Date watched | {watched_display:<17} |
|---------------------|-------------------|
| Show Time | |
| Theater | |
| Theater Number | |
| Pizza | |
| Tickets | |
| Letterboxd Rating | {rating_display} |
| Crew | |
| Show Time | {show_time:<17} |
| Theater | {theater:<17} |
| Theater Number | {theater_num:<17} |
| Pizza | {pizza:<17} |
| {row5_label:<19} | {row5_value:<17} |
| Letterboxd Rating | {rating_display:<17} |
| {row7_label:<19} | {row7_value:<17} |
{{{{< /imdbposter >}}}}
@@ -209,12 +376,25 @@ def display_movies(movies, limit=10):
print()
def import_movie(movie):
"""Import a single movie: fetch details, download poster, create post."""
def import_movie(movie, viewing_mode=None):
"""Import a single movie: fetch details, download poster, create post.
Args:
movie: Movie data from Letterboxd RSS
viewing_mode: 'theater', 'home', or None (will prompt)
"""
print(f"\nImporting: {movie['title']} ({movie['year']})")
# Get viewing details
if viewing_mode == "theater":
viewing_details = prompt_theater_details()
elif viewing_mode == "home":
viewing_details = prompt_home_details()
else:
viewing_details = prompt_viewing_details()
# Get TMDB details
print(" Fetching TMDB details...")
print("\n Fetching TMDB details...")
tmdb = get_tmdb_details(movie["tmdb_id"])
# Download poster
@@ -226,7 +406,7 @@ def import_movie(movie):
# Create draft post
print(" Creating draft post...")
filepath = create_draft_post(movie, tmdb, poster_url)
filepath = create_draft_post(movie, tmdb, poster_url, viewing_details)
if filepath:
print(f"\nDone! Edit your draft at: {filepath.relative_to(PROJECT_ROOT)}")
@@ -241,8 +421,17 @@ def main():
parser.add_argument("--latest", action="store_true", help="Import most recent entry")
parser.add_argument("--list", action="store_true", help="Just list recent entries")
parser.add_argument("--count", type=int, default=10, help="Number of entries to show")
parser.add_argument("--theater", action="store_true", help="Skip viewing prompt, go straight to theater questions")
parser.add_argument("--home", action="store_true", help="Skip viewing prompt, go straight to home questions")
args = parser.parse_args()
# Determine viewing mode from flags
viewing_mode = None
if args.theater:
viewing_mode = "theater"
elif args.home:
viewing_mode = "home"
print("Fetching Letterboxd RSS feed...")
try:
root = fetch_rss()
@@ -260,7 +449,7 @@ def main():
sys.exit(0)
if args.latest:
import_movie(movies[0])
import_movie(movies[0], viewing_mode)
sys.exit(0)
# Interactive mode
@@ -272,7 +461,7 @@ def main():
sys.exit(0)
idx = int(choice) - 1
if 0 <= idx < len(movies):
import_movie(movies[idx])
import_movie(movies[idx], viewing_mode)
else:
print("Invalid selection")
sys.exit(1)