TMDB Integration

A Fully Functional Personal Movie Database

Case Study

I created a fully functional personal movie database. It has access to every single film, person, and TV show ever made—1M+ movies, 500K+ people, thousands of TV shows—all without me manually logging a single piece of data. It integrates seamlessly with my Film Diary, showing my complete watch history. It connects to my Movie Lists and Targets, so I can see which curated lists feature any film. And when I text someone a link to jimmyweber.com/tmdb/550, they see a beautiful full-frame movie poster in their text message. When they click it, they get everything: what it's about, where it's streaming, the trailer, whether I've seen it, and if it's on any of my movie lists. All with my design, no ads, no distractions.

I use it constantly. It's my single source of truth for movie research, my sharing mechanism for recommendations, and my answer to "Have I seen this actor before?" As a certified movie junkie, the integration solves so many problems that it's hard to name them all. It's exactly what I needed, and now it's exactly what I have.

Timeline and Development Process

Initial TMDB Integration

May 2025

Bot Attack & Protection Phase 1-2

September 2025

Cloudflare Turnstile Implementation

October 2025

Production Ready System

Present Day

Goals

  • Create a personal movie database with access to every film, person, and TV show ever made without manual data entry
  • Build a beautiful, ad-free movie page that can be shared with family and friends via text message with rich preview images
  • Integrate seamlessly with Film Diary watch history to show "Jimmy's Seen" sections on person pages
  • Connect with Movie Lists and Targets for comprehensive film discovery and tracking
  • Design custom layouts matching JimmyWeber.com aesthetic - no external site redirects
  • Implement bulletproof bot protection while maintaining URL shareability
  • Provide instant answers to questions like "Have I seen this actor before?" and "Where is this streaming?"
  • Create a single source of truth for movie recommendations without relying on external platforms

What I Learned

The TMDB Integration taught me the importance of understanding how big systems actually work while you’re building them. I started this project as a pure vibe coder — letting my AI agents handle most of the implementation while I focused on vision and results. That worked beautifully in the beginning, but once things started breaking down, I realized how little I understood about the infrastructure underneath. When the custom API manager or routing system failed, I was completely helpless. If I had known how each piece worked — even just conceptually — I could’ve solved problems in minutes instead of hours. This was the project that taught me to stop being a passive client and start being an active director: the person who defines what’s happening, asks why, and decides what needs to happen next.

The other major lesson came from the bot attack that nearly took down my site. Moving from a managed host like Bluehost to a self-managed DigitalOcean server made me realize just how many invisible systems those platforms provide. I didn’t even know bot protection was something I had to think about — until thousands of crawlers started hammering my TMDB pages and draining my API limits. That experience forced me to learn, from the ground up, how to implement layered defenses: Apache-level blocks, PHP detection, and finally enterprise-grade Cloudflare Turnstile protection. I went from not even knowing what a bot request looked like to designing a full-scale, multi-phase defense strategy that achieved 99.5% blocking while keeping the site fully functional for users.

In the end, this project taught me that technical direction requires technical literacy. You don’t need to code every line yourself, but you need to understand the shape of the system you’re directing — what depends on what, where it can break, and how to fix it. It’s the difference between leading a project and just watching one unfold.

What I Created: Three Interconnected Systems

Solving Real Problems

"Have I Seen This Actor Before?"

This is the question that started it all. I'm watching a new film, I see a face I recognize, and I wonder: have I seen their work before?

With the TMDB integration, I can look up any actor and immediately see "Jimmy's Seen"—a complete list of every film of theirs I've watched. It cross-references their entire filmography (movies and TV) with my 7+ years of watch history automatically.

The system loads yearly JSON files from 2019-present, creates lookup maps by TMDB ID, matches against their credits, and displays the results with poster images, watch dates, and rewatch counts. No manual tagging, no guessing, instant answers.

Sharing Movies with Family

When I tell my mom "Hey, you should watch this movie," I can now send her a single link: jimmyweber.com/tmdb/#

When she receives the text message, her phone displays a beautiful full-frame movie poster with the title and description—no ads, no clutter. It looks professional.

When she clicks the link, she sees my custom-designed page with everything she needs: the overview, where to stream it, the trailer embedded right there, the MPAA rating, who directed it, and whether I've watched it.

She doesn't get redirected to IMDb with banner ads or TMDB with even more popups. She gets my site, my design, my data.

Portfolio Integration

Everything connects. In my Film Diary, every logged film has a poster image. Click it, and you're on the full TMDB movie page.

In Movie Lists and Targets, every film entry is clickable—tap the poster, see comprehensive details. Person headshots in cast lists? Clickable to their person page. Director names? Links to their page showing everything they've made.

The entire ecosystem is interconnected. No dead ends, no external redirects, no jumping to other websites. It's all mine, all integrated, all working together as one cohesive system.

How It Works: API to Interface

Centralized API Management

The heart of the system is a centralized API manager that handles all TMDB requests. Every page uses a simple fetch_tmdb() function that routes through /includes/api-manager.php with 1-hour response caching.

For a single movie page, the system makes 8 separate API calls—movie details, credits, videos, release dates, streaming providers, keywords, recommendations, and similar films—but the user never waits because cached responses return instantly.

The API manager handles rate limiting, error logging, and JSON decoding automatically. One function, one pattern, complete control.

Watch History Cross-Reference

The "Jimmy's Seen" feature required solving a complex data matching problem. My watch history is stored in yearly JSON files (2019-tmdb-data.json through 2025-tmdb-data.json), each containing arrays of films with TMDB IDs and watch dates.

A person's filmography comes from TMDB's combined_credits endpoint with different structure and IDs.

The solution:

  • Load all watch history files into memory
  • Create a lookup map indexed by TMDB ID
  • Iterate through the person's complete acting/directing/writing credits
  • Match IDs and build the "Jimmy's Seen" array
  • Display with titles, posters, dates watched, and rewatch counts

It happens server-side in PHP, runs in milliseconds, and displays automatically on every person page.

Movie Lists Integration

I maintain a database of 1,200+ curated movie lists in movie-list-database.json—a 2MB file with two main sections: movies (each with TMDB ID and comma-separated list appearances) and lists (metadata about each list).

When a movie page loads, it finds the movie in the database, parses the comma-separated entries (format: "listId-position"), matches against the lists metadata, and groups appearances by category.

The result: "Fight Club appears on 12 curated movie lists" with links to each list showing the film's position. All from a single JSON lookup.

Jimmy's Seen Section

"Jimmy's Seen" Section

Every person page shows which of their films I've watched, how many times, and when. It cross-references their complete filmography with my 7-year watch history automatically. No manual tagging required. This is the feature that answers "Have I seen this actor before?" instantly.

The Tech Stack

  • Backend: PHP with centralized API manager handling all TMDB requests with 1-hour response caching
  • Frontend: Vanilla JavaScript with custom search (combined-search.js), watch info module, modal controls, and expandable sections
  • APIs: The Movie Database (TMDB) API for 1M+ movies, 500K+ people, thousands of TV shows
  • Data Storage: JSON files for watch history (yearly), movie lists database, Star Stocks portfolio
  • Bot Protection: Three-layer defense (Apache .htaccess, PHP User-Agent detection, Cloudflare Turnstile)
  • Styling: Custom CSS with dark mode support, responsive layouts, poster modals, and icon integrations

The Bot Protection Battle: A Progressive Defense Strategy

When I first launched the TMDB pages, everything worked perfectly . . . for about two weeks.

Then search engine bots discovered my site. Google, Bing, Facebook's crawler, ChatGPT-User, and dozens of others started indexing thousands of pages. Each page made multiple external API calls to TMDB overwhelming the server.

API calls were failing, page loads were timing out, and my hosting provider sent "red alerts" in my dashboard. I watched it happen in real-time through Apache logs: bot after bot, crawling hundreds of pages per hour, each triggering 8+ API requests per second.

I shut everything down completely.

But I didn't want to give up. I needed these pages functional AND shareable. Plus, I just really liked using it.

The solution was a progressive three-phase defense strategy:

Phase 1: PHP bot detector with 44+ pattern signatures caught 70% of bots, returning 403 responses with X-Robots-Tag headers.

Phase 2: Apache-level .htaccess rules blocked bots before PHP even loaded, reaching 90% total protection with zero server resource waste.

Phase 3: Cloudflare Turnstile invisible CAPTCHA completed the defense, achieving 99.5% bot blocking while maintaining seamless user experience—real users see a 0.5-second verification, then full access.

I watched bots get blocked in real-time through Apache logs: Meta-webindexer, ChatGPT-User, and multiple Cloudflare IPs all denied. Zero API calls made to TMDB. The three layers worked in perfect harmony, protecting the system while preserving URL shareability for family and friends.

shield

Apache .htaccess

First Line of Defense

Blocks bots before they reach PHP with RewriteCond rules checking User-Agent patterns. Instant 403 responses with zero server resources consumed.

Protection Details

  • Blocks: 70% of all bot traffic
  • Speed: Instant denial before PHP loads
  • Targets: Search engines, empty User-Agents
  • Paths: /tmdb/, /person/, /tv/
code

PHP Bot Detector

Secondary Detection Layer

Sophisticated pattern matching against 44+ bot signatures including AI scrapers, social crawlers, and headless browsers. Returns 403 with X-Robots-Tag headers.

Protection Details

  • Blocks: 20% additional traffic
  • Patterns: 44+ bot signatures detected
  • Targets: GPTBot, ClaudeBot, SEO tools
  • Function: isBot() utility check
verified_user

Cloudflare Turnstile

Enterprise-Grade Final Layer

Invisible CAPTCHA system that real users pass in ~0.5 seconds while bots cannot complete. Content hidden until challenge passes, then displayed via callback.

Protection Details

  • Blocks: 9.5% remaining traffic
  • User Experience: 0.5 second verification
  • Method: Invisible challenge widget
  • Result: 99.5% total protection

Custom Features and Innovations

Intelligent "Known For" Algorithm

Person pages use a sophisticated algorithm to determine which 5 works to highlight in the "Known For" section.

The algorithm:

  • Determines primary department (actor, director, or writer)
  • Analyzes movie vs TV distribution
  • Filters out talk show appearances and single episodes
  • Removes "Self" credits (award shows, documentaries)
  • Uses database of 50+ long-running shows with episode thresholds
  • Sorts by TMDB popularity score
  • Selects top 5 most significant works

For example, if someone appeared once on Saturday Night Live (1,000+ total episodes), that's not significant enough for "Known For." The result: every person page highlights their most representative work instead of random guest appearances.

Dynamic Writing Credits System

Movie pages needed to show writing credits properly—not just list names, but explain their roles with correct labels.

I orchestrated a system that directs AI to parse the Writing department from TMDB's crew credits and group people by job type: Screenplay, Story, Writer, Characters, Novel, etc.

It automatically pluralizes labels based on count and links each person's name to their person page. The system builds complete HTML blocks like "Screenplay by Aaron Sorkin and William Goldman" with both names linked.

All dynamic, all automatic, all properly formatted.

Watch History Time Machine

The "Jimmy's Seen" feature required building a time machine through my viewing history.

How it works:

  • Loads 7 yearly JSON files (2019-2025)
  • Creates in-memory lookup map indexed by TMDB ID
  • Fetches person's complete filmography from TMDB
  • Iterates through every acting/directing/writing credit
  • Checks if TMDB ID exists in watch history map
  • Builds "Jimmy's Seen" array with full metadata

The entire process happens server-side in PHP, runs in milliseconds, and displays automatically—no manual tagging, no database queries, just pure data cross-referencing.

My Role

Responsibilities

  • Architected and directed the build of three complete page systems (movies, people, TV) with full TMDB API integration
  • Architected centralized API management with 1-hour caching to optimize performance and rate limits
  • Implemented progressive bot protection strategy from basic detection to enterprise Cloudflare Turnstile
  • Created cross-referencing systems for watch history, movie lists, and Star Stocks portfolio
  • Directed the development and integration of custom algorithms for "Known For" selection and writing credits parsing
  • Directed AI execution of a responsive UI with dark mode support, poster modals, expandable sections, and global search

Beautiful Link Sharing

This is what makes it special. When I text my mom "Hey, you should watch this movie" with a link to jimmyweber.com/tmdb/550, her phone shows a beautiful full-frame movie poster with the title and description.

No ads, no clutter. It looks like I sent her a professional movie recommendation, not a random internet link.

When she clicks, she sees everything: what it's about, where to stream it, the trailer embedded right there, whether I've seen it, if it's on any of my curated movie lists. She gets my custom-designed page with my data, my layout, my aesthetic—not IMDb's cluttered interface or TMDB's generic design.

How It Works

It's achieved through Open Graph and Twitter Card meta tags. Every movie, person, and TV page includes:

  • og:image with the poster URL (TMDB's high-quality image)
  • og:title with the movie title and year
  • og:description with the overview

When you share these links via text message, iMessage, WhatsApp, Slack, or any social platform, they parse these meta tags and render rich previews automatically.

The result: professional-looking movie recommendations that actually get watched because they feel real, personal, and trustworthy—not like spam or random links.

Key Challenges Solved

  • Bot Overwhelm: 99.5% blocking rate through progressive three-layer defense
  • Data Cross-Reference: In-memory lookup maps for instant "Jimmy's Seen" matching
  • Scale Performance: Pre-built JSON database for 1,200+ movie lists with instant lookups
  • Shareability Balance: Bot protection without breaking link sharing for family/friends

Next Steps

  • Build recommendation engine based on watch history patterns and list appearances to suggest films I'd actually enjoy
  • Implement advanced filtering on person pages (by year, by role, by rating) so I can find "all Christopher Nolan films from 2010-2020" instantly
  • Continue monitoring bot activity and refine patterns as new threats emerge—the bot landscape evolves, protection must too