Added movie master skill

This commit is contained in:
Mathieu 2021-09-14 15:44:22 +02:00
parent 807fa16d14
commit a3798e1a2c
65 changed files with 362 additions and 2 deletions

View File

@ -4,6 +4,7 @@ from jarvis.skills import intent_manager
from jarvis.skills.daily.timer import TimerSkill
from jarvis.skills.entertainement.decide import DecideSkill
from jarvis.skills.entertainement.jokes import JokesSkill
from jarvis.skills.entertainement.moviemaster import MovieMaster
from jarvis.skills.entertainement.spotify import SpotifySkill
from jarvis.skills.entertainement.weather import WeatherSkill
from jarvis.skills.productivity.homeassistant import HomeAssistantSkill
@ -26,10 +27,10 @@ def start():
TimerSkill().register()
WeatherSkill().register()
HomeAssistantSkill().register()
MovieMaster().register()
# TODO: movies master skill
# TODO: calculator skill
# TODO: wolfram alpha skill
# TODO: google/ddg help skill
# TODO: unit converter skill

View File

@ -0,0 +1,244 @@
# 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)

View File

@ -0,0 +1 @@
I can not find any (TV|television) shows with the genre {genre}

View File

@ -0,0 +1 @@
I can not find any (TV|television) shows with the genre {genre}

View File

@ -0,0 +1 @@
Falling back to the default A P I

View File

@ -0,0 +1 @@
the movies with the genre {genre} are;

View File

@ -0,0 +1 @@
the (television|TV) shows with the genre {genre} are;

View File

@ -0,0 +1,2 @@
Here is the cast of {movie}; {actorlist} and {lastactor}
The following people (star|play|act) in the movie {movie}; {actorlist} and {lastactor}

View File

@ -0,0 +1,2 @@
the (movie|film) {movie} is about this.
here is a synopsis of the (movie|film) {movie}.

View File

@ -0,0 +1,2 @@
The (movie|film|flick) can be found in one of the genres; {genrelist} and {genrelistlast}
People consider the (movie|film) a {genrelist} or {genrelistlast}

View File

@ -0,0 +1,2 @@
The (movie|film) {movie} could be considered a {genre}
You can find the (film|flick) {movie} in the {genre} section

View File

@ -0,0 +1 @@
{movie} was released on {year}, with a budget of {budget} dollars.

View File

@ -0,0 +1,2 @@
The new popular movies out now are {popularlist}.
{popularlist} top the movie charts right now.

View File

@ -0,0 +1,2 @@
The companies {companies} and {lastcompany} produced the movie {movie}
{companies} and {lastcompany} produced the movie {movie}

View File

@ -0,0 +1 @@
The production company {company}, produced the movie {movie}

View File

@ -0,0 +1,2 @@
I recommend the movies {movielist}, if you like the (movie|flick) {movie}
The movies {movielist} are a good choice if you like the (movie|flick) {movie}

View File

@ -0,0 +1,3 @@
The (movie|film|flick) {movie}, runs for {runtime} minutes.
The (movie|film|flick) {movie} is {runtime} minutes long.
Watching {movie}; You can expect about {runtime} minutes before you can have a bathroom break.

View File

@ -0,0 +1,2 @@
These are the (top|most popular) movies (out|playing) now; {toplist}
{toplist} are the (top|most popular) movies (out|playing) now.

View File

@ -0,0 +1 @@
the (movie|film|flick) {movie} was (made|released) on {year}

View File

@ -0,0 +1 @@
You must enter your T M D B A P I key at home dot mycroft dot A I to use the movie master skill

View File

@ -0,0 +1 @@
I'm sorry. I can not find any information on the (film|movie) {movie}

View File

@ -0,0 +1 @@
I'm sorry, I can not find the list you are looking for right now; please ask again later.

View File

@ -0,0 +1 @@
The A P I key that you entered is not valid. Refer to the read me file for instructions on how to obtain one.

View File

@ -0,0 +1 @@
Je ne trouve aucune (émission) télé du genre {genre}

View File

@ -0,0 +1 @@
Je ne trouve aucune (émission) télé du genre {genre}

View File

@ -0,0 +1 @@
Retour à l'A P I par défaut

View File

@ -0,0 +1 @@
les films du genre {genre} sont;

View File

@ -0,0 +1 @@
les émissions (télé|) du genre {genre} sont;

View File

@ -0,0 +1,2 @@
Voici la distribution de {movie} ; {actorlist} et {lastactor}
Les personnes suivantes (star|play|act) dans le film {movie} ; {actorlist} et {lastactor}

View File

@ -0,0 +1,2 @@
le (filme) {movie} parle de.
voici le synopsis du (film) {movie}

View File

@ -0,0 +1,2 @@
Le (movie|film|flick) peut être trouvé dans l'un des genres; {genrelist} et {genrelistlast}.
Les gens considèrent le (movie|film) comme un {genrelist} ou un {genrelistlast}.

View File

@ -0,0 +1,2 @@
Le (movie|film) {movie} pourrait être considéré comme un {genre}.
Vous pouvez trouver le film {movie} dans la section {genre}

View File

@ -0,0 +1 @@
{movie} est sorti en {year}, avec un budget de {budget} dollars

View File

@ -0,0 +1,2 @@
Le nouveau film populaire du moment est {popularlist}
{popularlist} est en tête du classement des films en ce moment.

View File

@ -0,0 +1,2 @@
Les studio {companies} et {lastcompany} ont produit le film {movie}
{companies} et {lastcompany} ont produit le film {movie}

View File

@ -0,0 +1 @@
Le studio de production {company}, a produit le film {movie}

View File

@ -0,0 +1,2 @@
Je recommande les films {movielist}, si vous aimez le film {movie}
Les films {movielist} sont un bon choix si vous aimez le film {movie}

View File

@ -0,0 +1,3 @@
Le film {movie}, dure {runtime} minutes
Le film {movie} dure {runtime} minutes
en regardant le film {movie}; Vous pouvez (prévoir|vous attendre à) environ {runtime} minutes avant de pouvoir faire une pause pipi

View File

@ -0,0 +1,2 @@
Ce sont les film les (meilleurs|plus populaires) du moment; {toplist}
{toplist} sont (les meilleurs|les plus populaires) films du moment

View File

@ -0,0 +1 @@
Le film {movie} a été (fait|tourné|réalisé|diffusé) en {year}

View File

@ -0,0 +1 @@
Vous devez entrer votre clé A P I de T M D B sur home . mycroft . A I pour utiliser la compétence de maître de cinéma

View File

@ -0,0 +1 @@
Je suis désolé, je ne trouve aucune information sur le film {movie}

View File

@ -0,0 +1 @@
Je suis désoler, je ne peux pas trouver la liste que vous cherchez pour le moment ; veuillez la redemander plus tard.

View File

@ -0,0 +1 @@
La clé API que vous avez entré est invalide. Consultez le fichier lisez-moi pour savoir comment en obtenir une.

View File

@ -0,0 +1 @@
who (acts|plays|is) in the (movie|film|flick) {movie}

View File

@ -0,0 +1,4 @@
what is the (movie|film|flick) {movie} about
tell (me|us) about the (movie|film|flick) {movie}
(give|get) (me|us) a (description|synopsis) of the (movie|film|flick) {movie}

View File

@ -0,0 +1,3 @@
what (genres|genre) does the (movie|film|flick) {movie} belong to
what are the (genres|genre) of the (movie|film|flick) {movie}
what (genres|genre) (is|are) the (movie|film|flick) {movie}

View File

@ -0,0 +1,3 @@
(find|get|look for|is there) (information|info) (on|about) the (movie|film|flick) {movie}
(give|tell|get) (|me|us) (information|info) (on|about) the (movie|film|flick) {movie}
(do you have|can you get) (info|information) on the (movie|film|flick) {movie}

View File

@ -0,0 +1,2 @@
(list|search|search for) popular (movies|films|flicks)
what are ( |the) popular (movies|films|flicks) (playing|out) ( |now)

View File

@ -0,0 +1 @@
(who|what company) (produced|made) the movie {movie}

View File

@ -0,0 +1,3 @@
recommend (movies|films|flicks) (similar to|like) {movie}
what (movies|films|flicks) (would|do) you recommend (similar to|like) {movie}
(list|get) (|good) (movies|films|flicks) (similar to|like) {movie}

View File

@ -0,0 +1,3 @@
How long is the (movie|film|flick) {movie}
What is the (runtime|length) of the (movie|film|flick) {movie}
Get the (runtime|length) of the (movie|film|flick) {movie}

View File

@ -0,0 +1 @@
(list|what are|search for) the (top|most popular|highest rated) (movies|films|flicks) (playing|out) (|now)

View File

@ -0,0 +1 @@
(what year|when|what date) was the (movie|film|flick) {movie} (made|released)

View File

@ -0,0 +1,3 @@
Quels acteurs (qui|) (sont présents|joues) dans (le|la) (film|série) {movie}
Qui (est-ce qui|) (est présent|joue) dans (le|la) (film|série) {movie}
On retrouve quels acteurs dans (le|la) (film|série) {movie}

View File

@ -0,0 +1,2 @@
De quoi parle (le|la) (film|série) {movie} ?
(Parle|Donne|Fait) (moi|nous) ((une|la) description|le synoptique|) (du|de|de la) (film|série) {movie}

View File

@ -0,0 +1,3 @@
A (quel genre|quels genres) (la|le) (film|série) {movie} appartient-il?
De (quels genres|quel genre) (est|sont) (la|le) (film|série) {movie}
(Quels sont les genres|C'est quel genre) (de|du|de la) (film|série) {movie}

View File

@ -0,0 +1,3 @@
(trouve|récupère|recherche|cherche|y a t-il) des (informations|info) (sur|à propos) (le|du|de|de la) (film|série) {movie}
(donne|dit|donne|récupère) (moi|nous) des (informations|infos) (sur|à propos) (le|du|de|de la) (film|série) {movie}
(est-ce que tu as|peux-tu récupérer|récupère) des (informations|infos) (sur|à propos) (le|du|de|de la) (film|série) {movie}

View File

@ -0,0 +1,2 @@
(liste|récupère|recherche|donne moi) (des|les) (films|séries) (populaire|) (du moment|)
(Quels sont|C'est quoi) les (films|séries) (populaire|) (du moment|)

View File

@ -0,0 +1,2 @@
(qui|quel studio) a (produit|réalisé|fait) (le|la) (film|série) {movie}
(qui|quel studio) a (produit|réalisé|fait) {movie}

View File

@ -0,0 +1,4 @@
Recommande des (films|séries) (similaire (à|au) (la série|film)|comme (le|la) (film|série)|comme) {movie}
quels sont les (films|séries) que (tu|vous) (recommande|recommandiez) (similaire (à|au) (la série|film)|comme (le|la) (film|série)|comme) {movie}
(liste|récupère) (les|des) (|bons) (films|séries) (similaire (à|au) (la série|film)|comme (le|la) (film|série)|comme) {movie}
Recommande moi (un|une|des) (film(s|)|série(s|) (televisée|)) (similaire (à|au) (la série|film)|comme (le|la) (film|série)|comme) {movie}

View File

@ -0,0 +1,4 @@
Combien (de temps|) dure (du|de|de la) (film|série) {movie}
Quelle est (la durée|la longueur) (du|de|de la) (film|série) {movie}
(Donne|Obtiens|Dis) (moi|) la (durée|longueur) (du|de|de la) (film|série) {movie}
(Le|La) (film|série) dure (combien de temps|longtemps)

View File

@ -0,0 +1,2 @@
(donne moi|c'est quoi|quel est|liste|quels sont|recherche) (des|du|le|la) (meilleur (film|série)|(film|série) le plus populaire|le (film|série) le mieux noté) du moment
(Donne moi|Recherche|Quels sont|C'est quoi|Quel est) (les|la) (film|série) le mieux notés du moment

View File

@ -0,0 +1,5 @@
(en quelle année|quand est-ce que|a quel date) (le|la) (film|série) {movie} a été (fait|faite|réalisé|realisée|diffusé|diffusée)
(en quelle année|quand est-ce que|a quel date) est (sorti|sortie) (le|la) (film|série) {movie}
(en quelle année|quand est-ce que|a quel date) (le|la) (film|série) {movie} est (sorti|sortie)
(le|la) (film|série) {movie} est (sorti|apparu) quand ?
(le|la) (film|série) {movie} à été (fait|faite|réalisé|realisée|diffusé|diffusée) quand ?

View File

@ -15,3 +15,4 @@ SpeechRecognition~=3.8.1
speedtest-cli~=2.1.3
HomeAssistant-API~=2.2.0
fuzzywuzzy~=0.18.0
tmdbv3api~=1.7.6