245 lines
10 KiB
Python
245 lines
10 KiB
Python
# Important : Thanks to @builderjer for their work on the "moviemaster" repo, the code below is based on their code as of Sep 2021.
|
|
# Source : https://github.com/builderjer/moviemaster
|
|
|
|
from datetime import datetime
|
|
|
|
import tmdbv3api
|
|
from lingua_franca.format import nice_date, nice_number
|
|
|
|
from jarvis.skills import Skill, SkillRegistering
|
|
from jarvis.skills.decorators import intent_file_handler
|
|
from jarvis.utils import config_utils, languages_utils
|
|
|
|
TMDB = tmdbv3api.TMDb()
|
|
MOVIE = tmdbv3api.Movie()
|
|
|
|
|
|
class MovieMaster(Skill, metaclass=SkillRegistering):
|
|
|
|
def __init__(self, data=dict):
|
|
super().__init__("MovieMaster", data)
|
|
|
|
def on_load(self):
|
|
""" This sets some variables that do not change during the execution of the script"""
|
|
TMDB.api_key = config_utils.get_in_secret("TMDB_API_KEY")
|
|
|
|
# Do a quick search to verify the api_key
|
|
try:
|
|
p = MOVIE.popular()
|
|
except Exception:
|
|
print("[WARN] Specified API KEY not valid, defaulting to generic one.")
|
|
|
|
# Default key, might get deactivated at any time.
|
|
TMDB.api_key = '6b064259b900f7d4fd32f3c74ac35207'
|
|
|
|
# Set the language
|
|
TMDB.language = languages_utils.get_language_only_country()
|
|
|
|
@intent_file_handler("movie.description.intent", "MovieDescriptionIntent")
|
|
def handle_movie_description(self, data):
|
|
""" Gets the long version of the requested movie.
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movie_details = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
if movie_details.overview != "":
|
|
self.speak_dialog("movie.description", {"movie": movie})
|
|
self.speak(movie_details.overview)
|
|
else:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.information.intent", "MovieInformationIntent")
|
|
def handle_movie_information(self, data):
|
|
""" Gets the short version and adds the TagLine for good measure.
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
self.speak_dialog("movie.info.response", {"movie": movieDetails.title, "year": nice_date(
|
|
datetime.strptime(movieDetails.release_date.replace("-", " "), "%Y %m %d")),
|
|
"budget": nice_number(movieDetails.budget)})
|
|
self.speak(movieDetails.tagline)
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.year.intent", "MovieYearIntent")
|
|
def handle_movie_year(self, data):
|
|
""" Gets the year the movie was released.
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
self.speak_dialog("movie.year", {"movie": movieDetails.title, "year": nice_date(
|
|
datetime.strptime(movieDetails.release_date.replace("-", " "), "%Y %m %d"))})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.cast.intent", "MovieCastIntent")
|
|
def handle_movie_cast(self, data):
|
|
""" Gets the cast of the requested movie.
|
|
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
cast = movieDetails.casts["cast"][:5]
|
|
|
|
# Create a list to store the cast to be included in the dialog
|
|
actorList = ""
|
|
# Get the last actor in the list so that the dialog can say it properly
|
|
lastInList = cast.pop()
|
|
lastActor = " {} as {}".format(lastInList["name"], lastInList["character"])
|
|
# Format the rest of the list for the dialog
|
|
for person in cast:
|
|
actor = " {} as {},".format(person["name"], person["character"])
|
|
# Add the formated sentence to the actor list
|
|
actorList = actorList + actor
|
|
|
|
self.speak_dialog("movie.cast", {"movie": movie, "actorlist": actorList, "lastactor": lastActor})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.production.intent", "MovieProductionIntent")
|
|
def handle_movie_production(self, data):
|
|
""" Gets the production companies that made the movie.
|
|
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
companyList = movieDetails.production_companies[:5]
|
|
|
|
# If there is only one production company, say the dialog differently
|
|
if len(companyList) == 1:
|
|
self.speak_dialog("movie.production.single", {"movie": movie, "company": companyList[0]["name"]})
|
|
# If there is more, get the last in the list and set up the dialog
|
|
if len(companyList) > 1:
|
|
companies = ""
|
|
lastCompany = companyList.pop()["name"]
|
|
for company in companyList:
|
|
companies = companies + company["name"] + ", "
|
|
self.speak_dialog("movie.production.multiple",
|
|
{"companies": companies, "movie": movie, "lastcompany": lastCompany})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.genres.intent", "MovieGenresIntent")
|
|
def handle_movie_genre(self, data):
|
|
""" Gets the genres the movie belongs to.
|
|
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
genreList = movieDetails.genres[:5]
|
|
# Set up dialog AGAIN just like above. Is there a better way?
|
|
if len(genreList) == 1:
|
|
self.speak_dialog("movie.genre.single", {"movie": movie, "genre": genreList[0]["name"]})
|
|
if len(genreList) > 1:
|
|
genreDialog = ""
|
|
lastGenre = genreList.pop()["name"]
|
|
for genre in genreList:
|
|
genreDialog = genreDialog + genre["name"] + ", "
|
|
self.speak_dialog("movie.genre.multiple", {"genrelist": genreDialog, "genrelistlast": lastGenre})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.runtime.intent", "MovieRuntimeIntent")
|
|
def handle_movie_length(self, data):
|
|
""" Gets the runtime of the searched movie.
|
|
"""
|
|
movie = data.get("movie")
|
|
try:
|
|
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
|
|
self.speak_dialog("movie.runtime", {"movie": movie, "runtime": movieDetails.runtime})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie})
|
|
|
|
@intent_file_handler("movie.recommendations.intent", "MovieRecommendationsIntent")
|
|
def handle_movie_recommendations(self, data):
|
|
""" Gets the top movies that are similar to the suggested movie.
|
|
"""
|
|
try:
|
|
movie = data.get("movie")
|
|
# Create a list to store the dialog
|
|
movieDialog = ""
|
|
movieRecommendations = MOVIE.recommendations(MOVIE.search(movie)[:1][0].id)[:5]
|
|
# Get the last movie
|
|
lastMovie = movieRecommendations.pop()
|
|
for film in movieRecommendations:
|
|
if movieDialog == "":
|
|
movieDialog = film.title
|
|
else:
|
|
movieDialog = movieDialog + ", " + film.title
|
|
movieDialog = movieDialog + " and {}".format(lastMovie.title)
|
|
self.speak_dialog("movie.recommendations", {"movielist": movieDialog, "movie": movie})
|
|
|
|
# If the title can not be found, it creates an IndexError
|
|
except IndexError:
|
|
self.speak_dialog("no.info", {"movie": movie.title})
|
|
|
|
@intent_file_handler("movie.popular.intent", "MoviePopularIntent")
|
|
def handle_popular_movies(self, data):
|
|
""" Gets the daily popular movies.
|
|
|
|
The list changes daily, and are not just recent movies.
|
|
|
|
"""
|
|
try:
|
|
popularMovies = MOVIE.popular()[:5]
|
|
# Lets see...I think we will set up the dialog again.
|
|
lastMovie = popularMovies.pop()
|
|
popularDialog = ""
|
|
for movie in popularMovies:
|
|
if popularDialog == "":
|
|
popularDialog = movie.title
|
|
else:
|
|
popularDialog = popularDialog + ", " + movie.title
|
|
popularDialog = popularDialog + " and {}".format(lastMovie.title)
|
|
self.speak_dialog("movie.popular", {"popularlist": popularDialog})
|
|
|
|
except:
|
|
pass
|
|
|
|
@intent_file_handler("movie.top.intent", "MovieTopIntent")
|
|
def handle_top_movies(self, data):
|
|
""" Gets the top rated movies of the day.
|
|
The list changes daily, and are not just recent movies.
|
|
|
|
"""
|
|
try:
|
|
topMovies = MOVIE.top_rated()[:5]
|
|
# Set up the dialog
|
|
lastMovie = topMovies.pop()
|
|
topDialog = ""
|
|
for movie in topMovies:
|
|
if topDialog == "":
|
|
topDialog = movie.title
|
|
else:
|
|
topDialog = topDialog + ", {}".format(movie.title)
|
|
topDialog = topDialog + " and {}".format(lastMovie.title)
|
|
self.speak_dialog("movie.top", {"toplist": topDialog})
|
|
|
|
except:
|
|
pass
|
|
|
|
|
|
def create_skill(data):
|
|
return MovieMaster(data)
|