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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user