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

@ -14,4 +14,5 @@ wikipedia~=1.4.0
SpeechRecognition~=3.8.1 SpeechRecognition~=3.8.1
speedtest-cli~=2.1.3 speedtest-cli~=2.1.3
HomeAssistant-API~=2.2.0 HomeAssistant-API~=2.2.0
fuzzywuzzy~=0.18.0 fuzzywuzzy~=0.18.0
tmdbv3api~=1.7.6