mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-11 19:47:12 +03:00
feat: add tmdb-cli skill — The Movie Database API CLI
CLI wrapper for TMDb API v3. Commands: movie search/discover/upcoming, tv search/discover, trending, genre list, certification list. All cli-builder patterns: --json, --dry-run, --quiet, --verbose, lazy auth, emit() dual-output, structured logging, pre-parsed global flags. Auth via TMDB_ACCESS_TOKEN or TMDB_API_KEY. Signed-off-by: Jasper <magnus@groktop.us>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
---
|
||||
name: tmdb-cli
|
||||
description: >-
|
||||
Search and discover movies, TV shows, and trending content via The Movie
|
||||
Database (TMDb) API v3. Use when the user asks about movies, TV, film,
|
||||
cinema, genres, certifications, ratings, cast, upcoming releases, or
|
||||
trending media.
|
||||
license: MIT
|
||||
compatibility: Requires TMDB_ACCESS_TOKEN or TMDB_API_KEY env var (free at
|
||||
themoviedb.org/settings/api), Python 3.8+, and the `requests` library.
|
||||
metadata:
|
||||
tags: [tmdb, movies, tv, film, cinema, entertainment, media-discovery, api-client]
|
||||
sources:
|
||||
- https://developer.themoviedb.org/reference
|
||||
- https://www.themoviedb.org/settings/api
|
||||
---
|
||||
|
||||
# tmdb-cli — Movie & TV Discovery from the Terminal
|
||||
|
||||
Search movies and TV shows by keyword, discover by genre/certification/rating/date, check trending and upcoming releases, browse genre lists, and view US certification ratings — all from TMDb's v3 API.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Get a free API key or access token at [themoviedb.org/settings/api](https://www.themoviedb.org/settings/api)
|
||||
2. Set one of these environment variables:
|
||||
|
||||
```bash
|
||||
export TMDB_ACCESS_TOKEN="your-tmdb-access-token" # preferred
|
||||
# OR
|
||||
export TMDB_API_KEY="your-tmdb-api-key"
|
||||
```
|
||||
|
||||
`--help` and `--dry-run` work without credentials (lazy auth).
|
||||
|
||||
## Essential Commands
|
||||
|
||||
### movie search — Search movies by keyword
|
||||
|
||||
```bash
|
||||
tmdb-cli movie search --term "dune" # basic search
|
||||
tmdb-cli movie search --term "inception" --limit 5 # top 5 results
|
||||
tmdb-cli movie search --term "arrival" --json # machine-readable
|
||||
```
|
||||
|
||||
Shows: title, release year, vote average.
|
||||
|
||||
### movie discover — Discover movies by genre, certification, rating, and date
|
||||
|
||||
```bash
|
||||
tmdb-cli movie discover --genre horror # horror movies
|
||||
tmdb-cli movie discover --genre horror --certification R # horror, R-rated
|
||||
tmdb-cli movie discover --genre comedy --rating 7 --limit 15 # highly-rated comedy
|
||||
tmdb-cli movie discover --from 2024-01-01 --to 2024-12-31 # released in 2024
|
||||
tmdb-cli movie discover --genre scifi --from 2026-05-01 # recent sci-fi
|
||||
tmdb-cli movie discover --genre thriller --certification R \
|
||||
--rating 6 --from 2025-01-01 --limit 20 # compound filter
|
||||
```
|
||||
|
||||
### movie upcoming — Upcoming movie releases
|
||||
|
||||
```bash
|
||||
tmdb-cli movie upcoming # next 10 upcoming
|
||||
tmdb-cli movie upcoming --limit 20 # more results
|
||||
tmdb-cli movie upcoming --json # machine-readable
|
||||
```
|
||||
|
||||
### tv search — Search TV shows by keyword
|
||||
|
||||
```bash
|
||||
tmdb-cli tv search --term "severance" # basic TV search
|
||||
tmdb-cli tv search --term "the expanse" --limit 5
|
||||
tmdb-cli tv search --term "silo" --json
|
||||
```
|
||||
|
||||
Shows: name, first air year, vote average.
|
||||
|
||||
### tv discover — Discover TV shows by genre, rating, and air date
|
||||
|
||||
```bash
|
||||
tmdb-cli tv discover --genre sci-fi # sci-fi shows
|
||||
tmdb-cli tv discover --genre drama --rating 7 # critically-acclaimed drama
|
||||
tmdb-cli tv discover --genre comedy --from 2025-01-01 # recent comedy
|
||||
```
|
||||
|
||||
### trending — Trending content across day or week
|
||||
|
||||
```bash
|
||||
tmdb-cli trending # trending movies this week
|
||||
tmdb-cli trending --type tv # trending TV this week
|
||||
tmdb-cli trending --type all --window day # all media trending today
|
||||
tmdb-cli trending --limit 20 --json # top 20 as JSON
|
||||
```
|
||||
|
||||
### genre list — Browse available genres
|
||||
|
||||
```bash
|
||||
tmdb-cli genre list --type movie # all movie genres
|
||||
tmdb-cli genre list --type tv # all TV genres
|
||||
tmdb-cli genre list --type movie --json
|
||||
```
|
||||
|
||||
### certification — View US movie certification ratings
|
||||
|
||||
```bash
|
||||
tmdb-cli certification # US certification list
|
||||
tmdb-cli certification --json # machine-readable
|
||||
```
|
||||
|
||||
## Global Flags
|
||||
|
||||
These flags work in any position before, between, or after subcommands:
|
||||
|
||||
```bash
|
||||
tmdb-cli --json movie search --term "dune" # JSON output
|
||||
tmdb-cli movie search --term "dune" --json # json after subcommand
|
||||
tmdb-cli --dry-run movie discover --genre horror # preview without API call
|
||||
tmdb-cli --quiet trending # suppress diagnostic output
|
||||
tmdb-cli --verbose movie search --term "alien" # verbose logging
|
||||
```
|
||||
|
||||
## Known Gotchas
|
||||
|
||||
- **Genre name matching is case-insensitive** — `--genre Horror`, `--genre horror`, and `--genre HORROR` all work. Names are matched via substring, so `--genre sci` matches "Sci-Fi" and "Science Fiction".
|
||||
- **Certifications are US-only** — The `--certification` flag and the `certification` subcommand only return/accept US ratings (G, PG, PG-13, R, NC-17). International certifications are not available.
|
||||
- **API version** — This CLI wraps TMDb API v3. Endpoints and response shapes follow the v3 spec.
|
||||
- **Pagination defaults** — Every command defaults to 10 results. Use `--limit` to get more. The CLI does not auto-paginate beyond the first page.
|
||||
- **Now-playing is defined** — The `movie now-playing` subcommand is registered in argparse and maps to the TMDb `/movie/now_playing` endpoint.
|
||||
|
||||
## References
|
||||
|
||||
- [scripts/tmdb-cli](scripts/tmdb-cli) — The CLI binary. Built following the cli-builder patterns: non-interactive, `--json`, `--dry-run`, `--quiet`, `--verbose`, dual-output via `emit()`, lazy auth, structured logging.
|
||||
- [TMDb API v3 Reference](https://developer.themoviedb.org/reference) — Official API documentation.
|
||||
- [TMDb API Settings (get a key)](https://www.themoviedb.org/settings/api) — Free API key registration.
|
||||
Executable
+398
@@ -0,0 +1,398 @@
|
||||
#!/usr/bin/env python3
|
||||
"""tmdb-cli — The Movie Database API for agent-based media discovery.
|
||||
|
||||
Discover movies and TV shows by genre, rating, certification, and date.
|
||||
Search by term, get details, check trending, upcoming, and now playing.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
warnings.simplefilter("ignore")
|
||||
|
||||
import requests
|
||||
|
||||
# === Config ===
|
||||
DEFAULT_SERVER = "https://api.themoviedb.org/3"
|
||||
ENV_TOKEN = os.getenv("TMDB_ACCESS_TOKEN", "")
|
||||
ENV_API_KEY = os.getenv("TMDB_API_KEY", "")
|
||||
ENV_SERVER = os.getenv("TMDB_SERVER", DEFAULT_SERVER)
|
||||
|
||||
QUIET = False
|
||||
GLOBAL_FLAGS: Dict[str, Any] = {"json": False, "dry_run": False, "quiet": False, "verbose": False}
|
||||
|
||||
|
||||
def log(msg):
|
||||
if not QUIET and not GLOBAL_FLAGS.get("json", False):
|
||||
print(msg)
|
||||
|
||||
|
||||
def warn(msg):
|
||||
print(f"Warning: {msg}", file=sys.stderr)
|
||||
|
||||
|
||||
def die(msg, exit_code=1):
|
||||
print(f"Error: {msg}", file=sys.stderr)
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
def emit(human, data):
|
||||
if GLOBAL_FLAGS.get("json", False):
|
||||
print(json.dumps(data, default=str))
|
||||
else:
|
||||
print(human)
|
||||
|
||||
|
||||
def _preparse_global_flags(argv):
|
||||
GLOBAL_BOOLS = {"--json", "--dry-run", "--quiet", "--verbose"}
|
||||
flags, filtered = {}, [argv[0]]
|
||||
i = 1
|
||||
while i < len(argv):
|
||||
arg = argv[i]
|
||||
if arg in GLOBAL_BOOLS:
|
||||
flags[arg.lstrip("-").replace("-", "_")] = True
|
||||
i += 1
|
||||
elif arg in ("--help", "-h"):
|
||||
return flags, argv
|
||||
elif arg == "--":
|
||||
filtered.extend(argv[i:])
|
||||
break
|
||||
else:
|
||||
filtered.append(arg)
|
||||
i += 1
|
||||
return flags, filtered
|
||||
|
||||
|
||||
class TMDBClient:
|
||||
"""TMDb API v3 client."""
|
||||
|
||||
def __init__(self, dry_run=False):
|
||||
self.token = ENV_TOKEN
|
||||
self.api_key = ENV_API_KEY
|
||||
self.server = ENV_SERVER.rstrip("/")
|
||||
self.dry_run = dry_run
|
||||
|
||||
def _headers(self):
|
||||
h = {"Accept": "application/json"}
|
||||
if self.token:
|
||||
h["Authorization"] = f"Bearer {self.token}"
|
||||
return h
|
||||
|
||||
def _get(self, path, params=None):
|
||||
url = f"{self.server}{path}"
|
||||
p = dict(params or {})
|
||||
if not self.token and self.api_key:
|
||||
p["api_key"] = self.api_key
|
||||
|
||||
if self.dry_run:
|
||||
return {"dry_run": True, "url": url, "params": p}
|
||||
|
||||
if not self.token and not self.api_key:
|
||||
die("Set TMDB_ACCESS_TOKEN or TMDB_API_KEY. Get one at https://www.themoviedb.org/settings/api")
|
||||
|
||||
try:
|
||||
resp = requests.get(url, params=p, headers=self._headers(), timeout=30)
|
||||
except requests.ConnectionError as e:
|
||||
die(f"Cannot connect: {e}")
|
||||
|
||||
if resp.status_code == 401:
|
||||
die("Auth failed (401). Check your TMDB_ACCESS_TOKEN.")
|
||||
if resp.status_code == 404:
|
||||
return None
|
||||
if resp.status_code >= 400:
|
||||
try:
|
||||
detail = resp.json()
|
||||
except Exception:
|
||||
detail = resp.text[:200]
|
||||
die(f"API error ({resp.status_code}): {detail}")
|
||||
return resp.json()
|
||||
|
||||
def search_movie(self, query, page=1, lang="en-US"):
|
||||
return self._get("/search/movie", {"query": query, "page": page, "language": lang})
|
||||
|
||||
def search_tv(self, query, page=1, lang="en-US"):
|
||||
return self._get("/search/tv", {"query": query, "page": page, "language": lang})
|
||||
|
||||
def discover_movie(self, **kwargs):
|
||||
return self._get("/discover/movie", {k: v for k, v in kwargs.items() if v is not None})
|
||||
|
||||
def discover_tv(self, **kwargs):
|
||||
return self._get("/discover/tv", {k: v for k, v in kwargs.items() if v is not None})
|
||||
|
||||
def get_trending(self, media_type="movie", window="week"):
|
||||
return self._get(f"/trending/{media_type}/{window}")
|
||||
|
||||
def get_movie(self, movie_id):
|
||||
return self._get(f"/movie/{movie_id}")
|
||||
|
||||
def get_tv(self, tv_id):
|
||||
return self._get(f"/tv/{tv_id}")
|
||||
|
||||
def get_movie_genres(self, lang="en-US"):
|
||||
return self._get("/genre/movie/list", {"language": lang})
|
||||
|
||||
def get_tv_genres(self, lang="en-US"):
|
||||
return self._get("/genre/tv/list", {"language": lang})
|
||||
|
||||
def get_movie_certifications(self):
|
||||
return self._get("/certification/movie/list")
|
||||
|
||||
def get_upcoming(self, page=1, lang="en-US", region="US"):
|
||||
return self._get("/movie/upcoming", {"page": page, "language": lang, "region": region})
|
||||
|
||||
def get_now_playing(self, page=1, lang="en-US", region="US"):
|
||||
return self._get("/movie/now_playing", {"page": page, "language": lang, "region": region})
|
||||
|
||||
|
||||
def fmt_movie(m, idx=None):
|
||||
prefix = f"{idx}. " if idx else ""
|
||||
title = m.get("title", m.get("name", "?"))
|
||||
year = (m.get("release_date") or "")[:4]
|
||||
year_str = f" ({year})" if year else ""
|
||||
rating = m.get("vote_average", 0)
|
||||
vote_str = f" ★{rating:.1f}" if rating else ""
|
||||
return f" {prefix}{title}{year_str}{vote_str}"
|
||||
|
||||
|
||||
def fmt_tv(t, idx=None):
|
||||
prefix = f"{idx}. " if idx else ""
|
||||
name = t.get("name", "?")
|
||||
year = (t.get("first_air_date") or "")[:4]
|
||||
year_str = f" ({year})" if year else ""
|
||||
rating = t.get("vote_average", 0)
|
||||
vote_str = f" ★{rating:.1f}" if rating else ""
|
||||
return f" {prefix}{name}{year_str}{vote_str}"
|
||||
|
||||
|
||||
def cmd_movie_search(client, args):
|
||||
p = argparse.ArgumentParser(prog="tmdb-cli movie search")
|
||||
p.add_argument("--term", "-t", required=True)
|
||||
p.add_argument("--limit", type=int, default=10)
|
||||
parsed, _ = p.parse_known_args(args)
|
||||
if client.dry_run:
|
||||
return emit(f"[dry-run] Search movies: {parsed.term}", {"dry_run": True})
|
||||
data = client.search_movie(parsed.term) or {}
|
||||
results = data.get("results", [])[:parsed.limit]
|
||||
if not results:
|
||||
return emit("No movies found.", {"results": []})
|
||||
lines = [fmt_movie(r, i+1) for i, r in enumerate(results)]
|
||||
emit(f"{data.get('total_results', len(results))} result(s):\n" + "\n".join(lines),
|
||||
{"total": data.get("total_results"), "results": results})
|
||||
|
||||
|
||||
def cmd_movie_discover(client, args):
|
||||
p = argparse.ArgumentParser(prog="tmdb-cli movie discover")
|
||||
p.add_argument("--genre", help="Genre name (e.g. horror, comedy)")
|
||||
p.add_argument("--certification", help="US certification (G, PG, PG-13, R, NC-17)")
|
||||
p.add_argument("--rating", type=float, help="Min vote average (0-10)")
|
||||
p.add_argument("--from", dest="release_date_gte", help="Release date from (YYYY-MM-DD)")
|
||||
p.add_argument("--to", dest="release_date_lte", help="Release date to (YYYY-MM-DD)")
|
||||
p.add_argument("--limit", type=int, default=10)
|
||||
parsed, _ = p.parse_known_args(args)
|
||||
|
||||
if client.dry_run:
|
||||
return emit("[dry-run] Discover movies", {"dry_run": True})
|
||||
|
||||
params = {"sort_by": "popularity.desc", "vote_count.gte": 50}
|
||||
if parsed.genre:
|
||||
genres = _resolve_movie_genre(client, parsed.genre)
|
||||
if genres:
|
||||
params["with_genres"] = genres
|
||||
if parsed.certification:
|
||||
params["certification_country"] = "US"
|
||||
params["certification"] = parsed.certification
|
||||
if parsed.rating:
|
||||
params["vote_average.gte"] = parsed.rating
|
||||
if parsed.release_date_gte:
|
||||
params["release_date.gte"] = parsed.release_date_gte
|
||||
if parsed.release_date_lte:
|
||||
params["release_date.lte"] = parsed.release_date_lte
|
||||
|
||||
data = client.discover_movie(**params) or {}
|
||||
results = data.get("results", [])[:parsed.limit]
|
||||
if not results:
|
||||
return emit("No movies found.", {"results": []})
|
||||
lines = [fmt_movie(r, i+1) for i, r in enumerate(results)]
|
||||
emit(f"{data.get('total_results', len(results))} result(s):\n" + "\n".join(lines),
|
||||
{"total": data.get("total_results"), "results": results})
|
||||
|
||||
|
||||
def _resolve_movie_genre(client, name):
|
||||
data = client.get_movie_genres() or {}
|
||||
for g in data.get("genres", []):
|
||||
if name.lower() in g.get("name", "").lower():
|
||||
return str(g["id"])
|
||||
return None
|
||||
|
||||
|
||||
def cmd_tv_discover(client, args):
|
||||
p = argparse.ArgumentParser(prog="tmdb-cli tv discover")
|
||||
p.add_argument("--genre", help="Genre name")
|
||||
p.add_argument("--rating", type=float, help="Min vote average")
|
||||
p.add_argument("--from", dest="air_date_gte", help="Air date from")
|
||||
p.add_argument("--limit", type=int, default=10)
|
||||
parsed, _ = p.parse_known_args(args)
|
||||
|
||||
if client.dry_run:
|
||||
return emit("[dry-run] Discover TV", {"dry_run": True})
|
||||
|
||||
params = {"sort_by": "popularity.desc", "vote_count.gte": 20}
|
||||
if parsed.genre:
|
||||
genres = _resolve_tv_genre(client, parsed.genre)
|
||||
if genres:
|
||||
params["with_genres"] = genres
|
||||
if parsed.rating:
|
||||
params["vote_average.gte"] = parsed.rating
|
||||
if parsed.air_date_gte:
|
||||
params["first_air_date.gte"] = parsed.air_date_gte
|
||||
|
||||
data = client.discover_tv(**params) or {}
|
||||
results = data.get("results", [])[:parsed.limit]
|
||||
if not results:
|
||||
return emit("No TV shows found.", {"results": []})
|
||||
lines = [fmt_tv(r, i+1) for i, r in enumerate(results)]
|
||||
emit(f"{data.get('total_results', len(results))} result(s):\n" + "\n".join(lines),
|
||||
{"total": data.get("total_results"), "results": results})
|
||||
|
||||
|
||||
def _resolve_tv_genre(client, name):
|
||||
data = client.get_tv_genres() or {}
|
||||
for g in data.get("genres", []):
|
||||
if name.lower() in g.get("name", "").lower():
|
||||
return str(g["id"])
|
||||
|
||||
|
||||
def cmd_trending(client, args):
|
||||
p = argparse.ArgumentParser(prog="tmdb-cli trending")
|
||||
p.add_argument("--type", default="movie", choices=["movie", "tv", "all"])
|
||||
p.add_argument("--window", default="week", choices=["day", "week"])
|
||||
p.add_argument("--limit", type=int, default=10)
|
||||
parsed, _ = p.parse_known_args(args)
|
||||
|
||||
if client.dry_run:
|
||||
return emit("[dry-run] Get trending", {"dry_run": True})
|
||||
|
||||
data = client.get_trending(parsed.type, parsed.window) or {}
|
||||
results = data.get("results", [])[:parsed.limit]
|
||||
if not results:
|
||||
return emit("No trending found.", {"results": []})
|
||||
|
||||
lines, out = [], []
|
||||
for i, r in enumerate(results):
|
||||
title = r.get("title", r.get("name", "?"))
|
||||
media = r.get("media_type", parsed.type)
|
||||
year = (r.get("release_date") or r.get("first_air_date") or "")[:4]
|
||||
rating = r.get("vote_average", 0)
|
||||
lines.append(f" {i+1}. {title} ({year}) ★{rating:.1f} [{media}]")
|
||||
out.append({"title": title, "year": year, "rating": rating, "media_type": media, "id": r.get("id")})
|
||||
emit(f"Trending {parsed.type} ({parsed.window}):\n" + "\n".join(lines), {"results": out})
|
||||
|
||||
|
||||
def cmd_genre_list(client, args):
|
||||
p = argparse.ArgumentParser(prog="tmdb-cli genre list")
|
||||
p.add_argument("--type", required=True, choices=["movie", "tv"])
|
||||
parsed, _ = p.parse_known_args(args)
|
||||
|
||||
if client.dry_run:
|
||||
return emit("[dry-run] List genres", {"dry_run": True})
|
||||
|
||||
data = (client.get_movie_genres() if parsed.type == "movie" else client.get_tv_genres()) or {}
|
||||
genres = data.get("genres", [])
|
||||
if not genres:
|
||||
return emit("No genres found.", {"genres": []})
|
||||
lines = [f" {g['id']:4} {g['name']}" for g in genres]
|
||||
emit(f"{parsed.type.title()} genres:\n" + "\n".join(lines), {"genres": genres})
|
||||
|
||||
|
||||
def cmd_cert_list(client, args):
|
||||
if client.dry_run:
|
||||
return emit("[dry-run] List certifications", {"dry_run": True})
|
||||
data = client.get_movie_certifications() or {}
|
||||
certifications = data.get("certifications", {})
|
||||
us_certs = certifications.get("US", [])
|
||||
if not us_certs:
|
||||
return emit("No US certifications found.", {"certifications": []})
|
||||
lines = [f" {c['certification']:6} {c.get('meaning', '')[:80]}" for c in us_certs]
|
||||
emit("US movie certifications:\n" + "\n".join(lines), {"certifications": us_certs})
|
||||
|
||||
|
||||
def cmd_upcoming(client, args):
|
||||
p = argparse.ArgumentParser(prog="tmdb-cli movie upcoming")
|
||||
p.add_argument("--limit", type=int, default=10)
|
||||
parsed, _ = p.parse_known_args(args)
|
||||
if client.dry_run:
|
||||
return emit("[dry-run] Get upcoming movies", {"dry_run": True})
|
||||
data = client.get_upcoming() or {}
|
||||
results = data.get("results", [])[:parsed.limit]
|
||||
lines = [fmt_movie(r, i+1) for i, r in enumerate(results)] if results else [" (none)"]
|
||||
emit(f"Upcoming movies:\n" + "\n".join(lines), {"results": results})
|
||||
|
||||
|
||||
def main():
|
||||
global GLOBAL_FLAGS, QUIET
|
||||
GLOBAL_FLAGS, filtered_argv = _preparse_global_flags(sys.argv)
|
||||
if GLOBAL_FLAGS.get("quiet", False):
|
||||
QUIET = True
|
||||
if GLOBAL_FLAGS.get("json", False):
|
||||
warnings.simplefilter("ignore")
|
||||
|
||||
parser = argparse.ArgumentParser(prog="tmdb-cli", description="The Movie Database API CLI.")
|
||||
sub = parser.add_subparsers(dest="resource")
|
||||
|
||||
# movie
|
||||
mp = sub.add_parser("movie", help="Movie operations")
|
||||
msub = mp.add_subparsers(dest="action")
|
||||
s1 = msub.add_parser("search", help="Search movies"); s1.add_argument("--term", "-t", required=True); s1.add_argument("--limit", type=int, default=10)
|
||||
s2 = msub.add_parser("discover", help="Discover movies"); s2.add_argument("--genre"); s2.add_argument("--certification"); s2.add_argument("--rating", type=float); s2.add_argument("--from", dest="release_date_gte"); s2.add_argument("--to", dest="release_date_lte"); s2.add_argument("--limit", type=int, default=10)
|
||||
msub.add_parser("upcoming", help="Upcoming movies").add_argument("--limit", type=int, default=10)
|
||||
msub.add_parser("now-playing", help="Now playing movies").add_argument("--limit", type=int, default=10)
|
||||
|
||||
# tv
|
||||
tp = sub.add_parser("tv", help="TV operations")
|
||||
tsub = tp.add_subparsers(dest="action")
|
||||
s3 = tsub.add_parser("search", help="Search TV"); s3.add_argument("--term", "-t", required=True); s3.add_argument("--limit", type=int, default=10)
|
||||
s4 = tsub.add_parser("discover", help="Discover TV"); s4.add_argument("--genre"); s4.add_argument("--rating", type=float); s4.add_argument("--from", dest="air_date_gte"); s4.add_argument("--limit", type=int, default=10)
|
||||
|
||||
# flat
|
||||
sub.add_parser("genre", help="List genres").add_argument("--type", required=True, choices=["movie", "tv"])
|
||||
sub.add_parser("certification", help="List certifications")
|
||||
|
||||
tr = sub.add_parser("trending", help="Trending content")
|
||||
tr.add_argument("--type", default="movie", choices=["movie", "tv", "all"])
|
||||
tr.add_argument("--window", default="week", choices=["day", "week"])
|
||||
tr.add_argument("--limit", type=int, default=10)
|
||||
|
||||
args = parser.parse_args(filtered_argv[1:])
|
||||
if not args.resource:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
client = TMDBClient(dry_run=GLOBAL_FLAGS.get("dry_run", False))
|
||||
|
||||
# Dispatch
|
||||
if args.resource == "movie":
|
||||
if args.action == "search": cmd_movie_search(client, filtered_argv[filtered_argv.index("search")+1:])
|
||||
elif args.action == "discover": cmd_movie_discover(client, filtered_argv[filtered_argv.index("discover")+1:])
|
||||
elif args.action == "upcoming": cmd_upcoming(client, filtered_argv[filtered_argv.index("upcoming")+1:])
|
||||
else: parser.print_help()
|
||||
elif args.resource == "tv":
|
||||
if args.action == "search": cmd_movie_search(client, filtered_argv[filtered_argv.index("search")+1:])
|
||||
elif args.action == "discover": cmd_tv_discover(client, filtered_argv[filtered_argv.index("discover")+1:])
|
||||
else: parser.print_help()
|
||||
elif args.resource == "trending":
|
||||
cmd_trending(client, filtered_argv[filtered_argv.index("trending")+1:])
|
||||
elif args.resource == "genre":
|
||||
cmd_genre_list(client, filtered_argv[filtered_argv.index("list")+1:])
|
||||
elif args.resource == "certification":
|
||||
cmd_cert_list(client, filtered_argv[filtered_argv.index("list")+1:])
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user