mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-11 19:47:12 +03:00
refactor(skills): drop -cli suffix from six consumer-API skills
Rename ghost-cli, jira-cli, jellyfin-cli, openlibrary-cli, tmdb-cli, and tempest-cli to ghost, jira, jellyfin, openlibrary, tmdb, and tempest via git mv. Rewrite frontmatter name fields to match new directories, rename bundled scripts preserving executable bits, update internal invocation strings and README quick-start examples, and relocate the jellyfin pytest suite to jellyfin/scripts/ with its SCRIPT constant now resolving to the renamed sibling script. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
parent
e10508b034
commit
dd97e846ec
@@ -0,0 +1,36 @@
|
||||
# TMDb — Movie & TV Discovery from the Terminal
|
||||
|
||||
Search movies and TV shows by keyword, discover by genre/certification/rating/date, check trending and upcoming releases, and browse genre lists.
|
||||
|
||||
## Why Install This Skill
|
||||
|
||||
When your agent loads this skill, it can **access the entire TMDb catalog** without a browser. That means:
|
||||
|
||||
- **Search movies and TV** — by keyword with release year and ratings
|
||||
- **Discover by taste** — genre, certification, rating threshold, date range
|
||||
- **Find trending content** — what's popular right now
|
||||
- **Check upcoming releases** — what's coming to theaters
|
||||
- **Browse certifications** — US ratings (G, PG, PG-13, R, NC-17)
|
||||
|
||||
## What You Get
|
||||
|
||||
| Directory | Purpose |
|
||||
|-----------|---------|
|
||||
| `SKILL.md` | Complete command reference with compound filter examples |
|
||||
| `scripts/tmdb` | CLI tool for TMDb v3 API |
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
export TMDB_ACCESS_TOKEN="your-tmdb-access-token"
|
||||
tmdb movie search --term "dune"
|
||||
tmdb movie discover --genre horror --certification R
|
||||
```
|
||||
|
||||
## Triggers
|
||||
|
||||
Load this for movies, TV shows, film discovery, genre browsing, or media recommendations.
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.8+ with `requests` library. Free API key from themoviedb.org.
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
---
|
||||
name: tmdb
|
||||
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 — 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 movie search --term "dune" # basic search
|
||||
tmdb movie search --term "inception" --limit 5 # top 5 results
|
||||
tmdb 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 movie discover --genre horror # horror movies
|
||||
tmdb movie discover --genre horror --certification R # horror, R-rated
|
||||
tmdb movie discover --genre comedy --rating 7 --limit 15 # highly-rated comedy
|
||||
tmdb movie discover --from 2024-01-01 --to 2024-12-31 # released in 2024
|
||||
tmdb movie discover --genre scifi --from 2026-05-01 # recent sci-fi
|
||||
tmdb movie discover --genre thriller --certification R \
|
||||
--rating 6 --from 2025-01-01 --limit 20 # compound filter
|
||||
```
|
||||
|
||||
### movie upcoming — Upcoming movie releases
|
||||
|
||||
```bash
|
||||
tmdb movie upcoming # next 10 upcoming
|
||||
tmdb movie upcoming --limit 20 # more results
|
||||
tmdb movie upcoming --json # machine-readable
|
||||
```
|
||||
|
||||
### tv search — Search TV shows by keyword
|
||||
|
||||
```bash
|
||||
tmdb tv search --term "severance" # basic TV search
|
||||
tmdb tv search --term "the expanse" --limit 5
|
||||
tmdb 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 tv discover --genre sci-fi # sci-fi shows
|
||||
tmdb tv discover --genre drama --rating 7 # critically-acclaimed drama
|
||||
tmdb tv discover --genre comedy --from 2025-01-01 # recent comedy
|
||||
```
|
||||
|
||||
### trending — Trending content across day or week
|
||||
|
||||
```bash
|
||||
tmdb trending # trending movies this week
|
||||
tmdb trending --type tv # trending TV this week
|
||||
tmdb trending --type all --window day # all media trending today
|
||||
tmdb trending --limit 20 --json # top 20 as JSON
|
||||
```
|
||||
|
||||
### genre list — Browse available genres
|
||||
|
||||
```bash
|
||||
tmdb genre list --type movie # all movie genres
|
||||
tmdb genre list --type tv # all TV genres
|
||||
tmdb genre list --type movie --json
|
||||
```
|
||||
|
||||
### certification — View US movie certification ratings
|
||||
|
||||
```bash
|
||||
tmdb certification # US certification list
|
||||
tmdb certification --json # machine-readable
|
||||
```
|
||||
|
||||
## Global Flags
|
||||
|
||||
These flags work in any position before, between, or after subcommands:
|
||||
|
||||
```bash
|
||||
tmdb --json movie search --term "dune" # JSON output
|
||||
tmdb movie search --term "dune" --json # json after subcommand
|
||||
tmdb --dry-run movie discover --genre horror # preview without API call
|
||||
tmdb --quiet trending # suppress diagnostic output
|
||||
tmdb --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](scripts/tmdb) — 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 — 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 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 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 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 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 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 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", 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