This repository has been archived by the owner on Dec 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy path__init__.py
292 lines (246 loc) · 9.68 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
from datetime import datetime
import os
from mycroft import MycroftSkill, intent_file_handler
from mycroft.util.format import pronounce_number, nice_date, nice_number
from mycroft.util.log import LOG
import tmdbv3api
__author__ = "[email protected]"
__version__ = "0.2.0"
__api__= "6b064259b900f7d4fd32f3c74ac35207"
LOGGER = LOG(__name__)
TMDB = tmdbv3api.TMDb()
MOVIE = tmdbv3api.Movie()
class MovieMaster(MycroftSkill):
def __init__(self):
"""A Mycroft skill to access the free TMDb api from https://www.themoviedb.org/"""
super(MovieMaster, self).__init__(name="MovieMaster")
self._api = None
self._searchDepth = None
def initialize(self):
""" This sets some variables that do not change during the execution of the script"""
# Try and get the settings from https://account.mycroft.ai/skills
self.api = self.settings.get("apiv3")
if self.api == "Default" or self.api =="" or self.api ==None:
self.api = __api__
#else:
#TMDB.api_key = self.api
try:
# Do a quick search to verify the api_key
TMDB.api_key = self.api
p = MOVIE.popular()
except Exception:
self.speak_dialog("no.valid.api", {})
self.speak_dialog("fallback.api", {})
self.api = __api__
TMDB.api_key = self.api
# Get search depth
self.searchDepth = self.settings.get("searchDepth")
# Set the language from the default in settings
TMDB.language = self.lang
self.settings_change_callback = self.on_web_settings_change
def on_web_settings_change(self):
api = self.settings.get("apiv3")
if api == "Default" or api == "":
TMDB.api_key = __api__
else:
try:
TMDB.api_key = api
# Do a quick search to verify the api_key
p = MOVIE.popular()
except Exception:
self.speak_dialog("no.valid.api", {})
self.speak_dialog("fallback.api", {})
TMDB.api_key = __api__
# Get search depth
self.searchDepth = self.settings.get("searchDepth")
@property
def api(self):
return self._api
@api.setter
def api(self, apiNum):
self._api = apiNum
@property
def searchDepth(self):
return self._searchDepth
@searchDepth.setter
def searchDepth(self, depth):
self._searchDepth = depth
@intent_file_handler("movie.description.intent")
def handle_movie_description(self, message):
""" Gets the long version of the requested movie.
"""
movie = message.data.get("movie")
try:
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
if movieDetails.overview is not "":
self.speak_dialog("movie.description", {"movie": movie})
for sentence in movieDetails.overview.split(". "):
self.speak(sentence)
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")
def handle_movie_information(self, message):
""" Gets the short version and adds the TagLine for good measure.
"""
movie = message.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")
def handle_movie_year(self, message):
""" Gets the year the movie was released.
"""
movie = message.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")
def handle_movie_cast(self, message):
""" Gets the cast of the requested movie.
The search_depth setting is avaliable at home.mycroft.ai
"""
movie = message.data.get("movie")
try:
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
cast = movieDetails.casts["cast"][:self.searchDepth]
# 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")
def handle_movie_production(self, message):
""" Gets the production companies that made the movie.
The search_depth setting is avaliable at home.mycroft.ai
"""
movie = message.data.get("movie")
try:
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
companyList = movieDetails.production_companies[:self.searchDepth]
# 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")
def handle_movie_genre(self, message):
""" Gets the genres the movie belongs to.
The search_depth setting is avaliable at home.mycroft.ai
"""
movie = message.data.get("movie")
try:
movieDetails = MOVIE.details(MOVIE.search(movie)[:1][0].id)
genreList = movieDetails.genres[:self.searchDepth]
# 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")
def handle_movie_length(self, message):
""" Gets the runtime of the searched movie.
"""
movie = message.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")
def handle_movie_recommendations(self, message):
""" Gets the top movies that are similar to the suggested movie.
"""
try:
movie = message.data.get("movie")
# Create a list to store the dialog
movieDialog = ""
movieRecommendations = MOVIE.recommendations(MOVIE.search(movie)[:1][0].id)[:self.searchDepth]
# 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")
def handle_popular_movies(self, message):
""" Gets the daily popular movies.
The list changes daily, and are not just recent movies.
The search_depth setting is avaliable at home.mycroft.ai
"""
try:
popularMovies = MOVIE.popular()[:self.searchDepth]
# 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")
def handle_top_movies(self, message):
""" Gets the top rated movies of the day.
The list changes daily, and are not just recent movies.
The search_depth setting is avaliable at home.mycroft.ai
"""
try:
topMovies = MOVIE.top_rated()[:self.searchDepth]
# 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():
return MovieMaster()