diff options
| author | 2020-02-12 20:47:17 +0200 | |
|---|---|---|
| committer | 2020-02-12 20:47:17 +0200 | |
| commit | 90dc6da4c1460a4f6c5d3ef5ea8bb8a403e28785 (patch) | |
| tree | e3ff07e03aa20bd7f3585816f823c6a1b135a7a1 /bot | |
| parent | Merge pull request #333 from python-discord/github-templates (diff) | |
Added .movie command with what when specifing genre you get random movies, depending how much movies you define. This use TMDB API.
Diffstat (limited to 'bot')
| -rw-r--r-- | bot/seasons/evergreen/movie.py | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/bot/seasons/evergreen/movie.py b/bot/seasons/evergreen/movie.py new file mode 100644 index 00000000..1256cb45 --- /dev/null +++ b/bot/seasons/evergreen/movie.py @@ -0,0 +1,481 @@ +import logging +import random +from os import environ +from typing import List, Tuple +from urllib.parse import urlencode + +from aiohttp import ClientSession +from discord import Embed +from discord.ext.commands import Bot, Cog, Context, group + +from bot.pagination import ImagePaginator + +# Get TMDB API key from .env +TMDB_API_KEY = environ.get('TMDB_API_KEY') + +# Define base URL of TMDB +BASE_URL = "https://api.themoviedb.org/3/" + +# Get logger +logger = logging.getLogger(__name__) + + +async def get_random_movies(client: ClientSession, + count: int, + genre_id: int, + genre_name: str,) \ + -> Tuple[List[Tuple[str, str]], Embed]: + """Get random movies by genre from TMDB.""" + pages = [] + + # Create embed + embed = Embed(title=f"Random {genre_name} Movies") + embed.set_footer(text='Powered by TMDB (themoviedb.org)') + + # Get random page between 1 and 600 + page = random.randint(1, 200) + + # Define TMDB request parameters + # (API key, exclusions, inclusions, sort) + params = { + "api_key": TMDB_API_KEY, + "language": "en-US", + "sort_by": "popularity.desc", + "include_adult": "false", + "include_video": "false", + "page": page, + "with_genres": str(genre_id) + } + + # Create request URL + url = BASE_URL + "discover/movie" + "?" + urlencode(params) + + # Do discover request to TMDB API and fetch information + async with client.get(url) as res: + try: + # Parse response data from JSON to dictionary + movie_list_data = await res.json() + + # Loop and fetch movies + for i in range(count): + # Get movie ID + movie_id = movie_list_data["results"][i]["id"] + + # Create movie params + movie_params = { + "api_key": TMDB_API_KEY, + "language": "en-US" + } + + # Generate URL + movie_url = BASE_URL + f"movie/{movie_id}?" + urlencode( + movie_params) + + # Fetch movie + async with client.get(movie_url) as m_res: + # Parse JSON to dict + movie_data = await m_res.json() + + # Create embed text + movie_text = "" + + # Add Title and tagline + movie_text += f"**{movie_data['title']}**\n" + if movie_data['tagline'] != "": + movie_text += movie_data['tagline'] + "\n\n" + else: + movie_text += "\n" + + # Add movie rating and release date + movie_text += f"**Rating:** {movie_data['vote_average']}/10 :star:\n" + movie_text += f"**Release Date:** {movie_data['release_date']}\n\n" + + # Add production title + movie_text += "__**Production Information**__\n" + + companies = movie_data['production_companies'] + countries = movie_data['production_countries'] + + # Add production information + movie_text += f"""**Made by:** {', '.join([comp['name'] + for comp in companies])}\n""" + movie_text += f"""**Made in:** {', '.join([country['name'] + for country in countries])}\n\n""" + + # Add Some Numbers title + movie_text += "__**Some Numbers**__\n" + + # Add Budget, Revenue and Duration + movie_text += f"**Budget:** ${movie_data['budget'] if movie_data['budget'] != 0 else '?'}\n" + movie_text += f"**Revenue:** ${movie_data['revenue'] if movie_data['revenue'] != 0 else '?'}\n" + movie_text += f"**Duration:** {movie_data['runtime']} minutes\n\n" + + # Add description + movie_text += movie_data['overview'] + + # Define Movie Image URL + movie_img_url = f"http://image.tmdb.org/t/p/w200{movie_data['poster_path']}" + + # Append this page to pages + pages.append((movie_text, movie_img_url)) + except KeyError as err: + # Create error message + msg = f"There was KeyError while executing HTTP request. API may " \ + f"down or API key may be incorrect, however, some movies " \ + f"have some missing fields, and this error will raise this " \ + f"too. Problematic Key: \n```{err}``` " + + # Create error embed + err_embed = Embed(title=":no_entry: Error :no_entry:") + + # Log error + logger.warning(msg) + + # Return error message + embed + return [(msg, "")], err_embed + + # Return all movies pages + return pages, embed + + +class Movie(Cog): + """Movie Cog contains movies command that grab random movies from TMDB.""" + + def __init__(self, bot: Bot): + self.bot = bot + self.http_session: ClientSession = bot.http_session + + @group(name='movies', invoke_without_command=True) + async def movies(self, ctx: Context) -> None: + """Get random movies by specifing genre.""" + await ctx.send_help('movies') + + @movies.command(name='action') + async def action(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Action genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 28, "Action") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='adventure') + async def adventure(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Adventure genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 12, "Adventure") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='animation') + async def animation(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Animation genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 16, "Animation") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='comedy') + async def comedy(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Comedy genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 35, "Comedy") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='crime') + async def crime(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Crime genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 80, "Crime") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='documentary') + async def documentary(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Documentary genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 99, "Documentary") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='drama') + async def drama(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Drama genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 18, "Drama") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='family') + async def family(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Drama genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 10751, "Family") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='fantasy') + async def fantasy(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Fantasy genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 14, "Fantasy") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='history') + async def history(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random History genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 36, "History") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='horror') + async def horror(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Horror genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 27, "Horror") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='music') + async def music(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Music genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 10402, "Music") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='mystery') + async def mystery(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Mystery genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 9648, "Mystery") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='romance') + async def romance(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Romance genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 10749, "Romance") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='science') + async def science(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Science Fiction genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 878, "Science Fiction") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='thriller') + async def thriller(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Thriller genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 53, + "Thriller") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + @movies.command(name='western') + async def western(self, ctx: Context, movies_amount: int = 5) -> None: + """Get random Western genre movies.""" + # Count can't be higher than 20, due one page return 20 items + # And also this can't be lower than 1, just logic + if movies_amount > 20: + await ctx.send("Max allowed amount of movies is 20.") + return + elif movies_amount < 1: + await ctx.send("You can't get less movies than 1.") + return + + # Get pages and embed + pages, embed = await get_random_movies(self.http_session, + movies_amount, 37, + "Western") + + # Paginate + await ImagePaginator.paginate(pages, ctx, embed) + + +def setup(bot: Bot) -> None: + """Load Movie Cog.""" + bot.add_cog(Movie(bot)) |