DEV Community

Cover image for Log It Already : The movie backlog was overwhelming, so I built my friend an AI that just picks one.
Bhavy Khatod
Bhavy Khatod

Posted on AI-assisted

Log It Already : The movie backlog was overwhelming, so I built my friend an AI that just picks one.

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🀝

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend

What I Built

My friend loves movies. But watching him actually sit down to watch a movie is an exercise in frustration. The actual bottleneck is never finding a good filmβ€”it's the paradox of choice. He has over 500 movies in his Letterboxd watchlist. He scrolls, reads three reviews, checks the runtime, gets overwhelmed, and then just closes the app.

He spends 45 minutes deciding what to watch, and by the time he picks something, he's too tired to actually watch it.

So I built him Log It Already: a fast, minimalist movie selector. You paste in your Letterboxd watchlist URL, type in exactly how you are feeling today ("brain fried from work, want a sci-fi"), and it cross-references your exact mood with your existing backlog to spit out one single recommendation. No carousels. No endless scrolling. Just the movie you should watch right now.

Demo

Live Demo: Log It Already

Search box with list URL and Mood

Result with Poster

Code

GitHub logo joyboy-8509 / log-it-already

Hacktoberfest Weekend Challenge: Build for a Friend

My Current Top 4

My Current Top 4

🍿 Log It Already (Hacktoberfest Weekend Challenge: Build for a Friend)

For the cinephile with 500 movies in their watchlist and 45 minutes of decision paralysis "Log It Already" is a minimalist, AI-powered movie recommender built with a clean, high-contrast aesthetic. It scans your Letterboxd watchlist and uses AI to pick the absolute best movie for your current mood.

Features

  • Letterboxd Integration: Automatically scrapes your public watchlist.
  • Vibe Check: Tell the AI exactly what you're in the mood for.
  • Minimalist UI: Clean, high-contrast, distraction-free design.
  • Smart Fallback: Don't have a watchlist? Leave it blank and the AI will recommend a global trending movie based on your mood.

How to Run

Prerequisites

  1. Python 3.9+
  2. Ollama (If running local models) or an Ollama Cloud API Key.

Installation

  1. Clone the repository
    git clone https://github.com/joyboy-8509/log-it-already.git
    cd log-it-already
    Enter fullscreen mode Exit fullscreen mode
  2. Install the required dependencies:
    pip install -r requirements.txt
    Enter fullscreen mode Exit fullscreen mode
  3. Set your Ollama API key…

How it works

Watchlist URL ──▢ BeautifulSoup Scraper ──┐
                                              β”‚
                                              β–Ό
    Mood Input ─────▢ Streamlit UI ─────▢ Ollama API (Gemma4:31b) ──▢ 1 Perfect Movie
Enter fullscreen mode Exit fullscreen mode

How I Built It

1. The constraint that shaped everything
My first plan was obvious: just hook up to the Letterboxd API, pull his watchlist JSON, and feed it to an LLM.

That plan died immediately. Letterboxd doesn't have an open, public API for standard developers. I had to scrape the data dynamically. But scraping a modern web app isn't as simple as requests.get().

2. Gemma 4 at the core
The engine running the logic is gemma4:31b, Google's open-weight model, served through the Ollama Cloud API.

The design decision I'm happiest with: there is no complex RAG pipeline. The entire scraped watchlist easily fits into a single context window. So every query sends the user's mood and their entire watchlist array directly to the model. The system prompt does the heavy lifting:

  • Answer only from the provided watchlist array.
  • Explain why it fits their specific mood.
  • Never hallucinate a movie that isn't on the list.

3. What I got wrong on the way
I originally targeted the og:image meta tag to pull movie posters, but that returned horizontal backdrop banners that destroyed my vertical UI layout. I had to rewrite the scraper to dig into the application/ld+json script tag to regex-extract the true 2:3 vertical poster URL.

Later, I tried to speed up the app by scraping the posters directly from the watchlist page. I deployed it, and suddenly every poster broke. It turns out Letterboxd lazy-loads watchlist images, so my scraper was proudly serving a tiny 1x1 transparent empty-poster.png to the UI instead of the actual movie poster.

Why Does Open Innovation Matter?

  • Model choice is a swap. Gemma is just an API call away. If something better ships, or I want to run it completely offline on my own laptop, I change one string. Nothing else in the project knows or cares which model answers.
  • It's inspectable and honest. The closed path here would be relying on a massive recommendation algorithm like Netflix's, which is a black box optimized for watch-time. What I built is small and honest. It only looks at the movies you already curated and explicitly want to watch.

The hand-over

I sent it to him to try out. The most important question was: does this actually stop you from scrolling?

He went through his watchlist, typed in his mood, and it immediately grabbed a psychological thriller he'd added three years ago and forgotten about. He liked that it explained why it picked it.

What his feedback actually changed

All of this is live on the repo now, shipped after his feedback:

He said
What changed

"The Look Back poster is some guy in goggles, not the anime."
The AI had guessed the URL slug and hit a 1959 film with the same name. Rewrote the scraper to pull the exact slug directly from the watchlist data.

"Press enter to search is not working"
Wrapped the entire input section in an st.form so keyboard submission works natively.

"What if they don't have a watchlist?"
Made the URL input optional. If left blank, it dynamically falls back to querying global trends.

"I got a 401 Unauthorized error"
Migrated the API key infrastructure to natively check Streamlit Secrets first, fixing the cloud deployment.

The useful version of AI here isn't one that endlessly generates new content. It's the one that looks at a pile of data you already curated, points at one thing, and says "Watch this," and then gets out of the way.

Prize Categories

  • Best Use of Gemma β€” gemma4:31b is the open-weight model doing the reasoning, constrained to cross-reference the user's specific mood against a scraped array of movie titles via the Ollama API.

Credits

The project was built with AI assistance. Especially, debugging of Streamlit forms, and BeautifulSoup JSON-LD parsing were solved via a weekend pair-programming session with an AI agent.

P.S. Cover image is my top 4

Top comments (0)