world_top_movies 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,334 @@
1
+ class WorldTopMovies::CLI
2
+ attr_accessor :movie_instance, :genre, :status
3
+
4
+ @@prompt = TTY::Prompt.new
5
+ @@user = nil
6
+
7
+ def self.prompt
8
+ @@prompt
9
+ end
10
+
11
+ def self.user
12
+ @@user
13
+ end
14
+
15
+ def run
16
+ introduce
17
+ select_movies_lookup_or_fav_movies
18
+ end
19
+
20
+ private
21
+
22
+ def introduce
23
+ # Introduces the app and ask for user credentials
24
+ artii = Artii::Base.new({})
25
+ puts "-----------------------------------------------------------------------------------"
26
+ puts artii.asciify("World's Top Movies!")
27
+ puts "-----------------------------------------------------------------------------------"
28
+ puts " By Harold Torres Marino | p: +61 401 927 123 | e: haroldtm55@gmail.com".colorize(:mode => :italic)
29
+ puts "-----------------------------------------------------------------------------------"
30
+ sleep(0.5)
31
+ puts "\nWelcome to the World's Top Movies of all times, a place where you can look up for worldwide top rated movies!\n\n"
32
+ sleep(1.5)
33
+ username = self.class.prompt.ask("Please enter your username to log in or sign up: ") do |q|
34
+ q.required(true, "Oops, seems you haven't provided your username! Try again please.")
35
+ q.validate(/^[a-zA-Z0-9._-]+$/, "Oops, seems like that username is invalid. Only alphanumerical characters plus . - _ are allowed. Try again please.")
36
+ q.modify(:down)
37
+ end
38
+ @@user = WorldTopMovies::DB::User.find_or_create_by(username: username)
39
+ sleep(0.5)
40
+ puts "\nThanks #{username}. I'd like to ask you some questions, ok?"
41
+ end
42
+
43
+ def select_movies_lookup_or_fav_movies
44
+ options = [
45
+ "Top Movies Lookup",
46
+ "My Favourite Movies section",
47
+ "My Movie Notes",
48
+ "Exit app",
49
+ ]
50
+ next_action = self.class.prompt.select(
51
+ "\nPlease choose where you want to go...", options
52
+ )
53
+ next_action == options[0] && scrape_and_print_movies
54
+ next_action == options[1] && select_action_favourite_movies
55
+ next_action == options[2] && select_action_movies_with_notes
56
+ next_action == options.last && close_app
57
+ select_next_action
58
+ end
59
+
60
+ def scrape_and_print_movies
61
+ # Asks the user which genre they want to see, then scrapres and generates the instances
62
+ sleep(1.5)
63
+ puts ""
64
+ type_of_scrape = self.class.prompt.select(
65
+ "Would you like to see the list of all movies in general or by genre?",
66
+ %w(General Genre)
67
+ )
68
+ puts "\nAlright! We're going to see the top #{type_of_scrape} movies..."
69
+ puts ""
70
+ sleep(1.5)
71
+ self.genre = nil if type_of_scrape == "General"
72
+ type_of_scrape == "Genre" && (self.genre = self.class.prompt.select(
73
+ "Choose a genre:\n", WorldTopMovies::Scraper.genres
74
+ ))
75
+ WorldTopMovies::Movie.scrape_and_print_movies_compact(self.genre)
76
+ end
77
+
78
+ def select_next_action
79
+ # Ask user to select a new action and re run the app from the chosen action
80
+ puts ""
81
+ sleep(0.5)
82
+ options = [
83
+ "See more info of a movie from the last selected genre or general list",
84
+ "Add favourite movies from the last selected genre or general list",
85
+ "Start a new lookup",
86
+ "Go to My Favourite Movies section",
87
+ "Go to My Movie notes",
88
+ "Print all the movies displayed so far",
89
+ "Exit app",
90
+ ]
91
+
92
+ next_action = self.class.prompt.select(
93
+ "What would you like to do now?", options
94
+ )
95
+ if next_action == options[0]
96
+ select_and_print_specific_movie
97
+ add_fav_or_leave_note
98
+ end
99
+ next_action == options[1] && add_favourite_movies
100
+ next_action == options[2] && scrape_and_print_movies
101
+ next_action == options[3] && select_action_favourite_movies
102
+ next_action == options[4] && select_action_movies_with_notes
103
+ next_action == options[5] && WorldTopMovies::Movie.scrape_and_print_movies_compact("all")
104
+ next_action == options.last && close_app
105
+ select_next_action
106
+ end
107
+
108
+ def select_and_print_specific_movie
109
+ # Asks user to select a movie from print_movies_compact
110
+ sleep(0.5)
111
+ puts ""
112
+ movie_url = self.class.prompt.select(
113
+ "Select a movie: ", WorldTopMovies::Movie.all_titles_and_links_hash_by_genre(self.genre), enum: ")"
114
+ )
115
+ self.movie_instance = WorldTopMovies::Movie.find_by_url(movie_url)
116
+ self.movie_instance.scrape_and_print_movie
117
+ end
118
+
119
+ def add_favourite_movies
120
+ # Finds or creates a new Favourite movie instances and adds them to the database
121
+ sleep(0.5)
122
+ movie_urls = self.class.prompt.multi_select(
123
+ "\nSelect movies: ", WorldTopMovies::Movie.all_titles_and_links_hash_by_genre(self.genre), enum: ")",
124
+ )
125
+ WorldTopMovies::DB::Movie.add_movies(user: self.class.user, movie_urls: movie_urls)
126
+ movie_urls.size > 0 ? puts("\nThe movie(s) have been added to your favourites!") : puts("\nNo movies were selected.")
127
+ end
128
+
129
+ def add_fav_or_leave_note
130
+ options = [
131
+ "Add it to your favourites",
132
+ "Leave a note",
133
+ "Nothing in particular",
134
+ ]
135
+ puts ""
136
+ next_action = self.class.prompt.select(
137
+ "What would you like to do with this movie?", options
138
+ )
139
+ next_action == options[0] && add_favourite_movie
140
+ next_action == options[1] && leave_note
141
+ select_next_action
142
+ end
143
+
144
+ def leave_note
145
+ note_message = self.class.prompt.ask("Please leave your note\n\n") do |q|
146
+ q.required(true, "Oops, seems you haven't left any note! Try again please.")
147
+ end
148
+ WorldTopMovies::DB::Note.create_note(movie_url: self.movie_instance.url, note_message: note_message, user: self.class.user)
149
+ puts "\nYour note has been saved!"
150
+ sleep(1.5)
151
+ end
152
+
153
+ def add_favourite_movie
154
+ # Finds or creates a new Favourite movie instance and adds it to the database
155
+ sleep(0.5)
156
+ # add_to_favourite = self.class.prompt.yes?("\nWould you like to add this movie to your favourites?")
157
+ if self.class.user.movies.none? { |m| m.url == self.movie_instance.url }
158
+ WorldTopMovies::DB::Movie.add_movies(user: self.class.user, movie_urls: self.movie_instance.url)
159
+ puts "\n#{self.movie_instance.title} has been added to your favourite movies!"
160
+ else
161
+ puts("\nOops! #{self.movie_instance.title} is already in your favourites!")
162
+ end
163
+ end
164
+
165
+ def delete_favourite_movies
166
+ sleep(0.5)
167
+ if self.class.user.movies.empty?
168
+ puts "\nOops, you haven't favourited any movies yet!!"
169
+ else
170
+ movie_urls = self.class.prompt.multi_select(
171
+ "\nSelect movies: ", self.class.user.favourite_movie_titles, enum: ")",
172
+ )
173
+ movie_urls.each do |movie_url|
174
+ WorldTopMovies::DB::UserMovie.delete_movie_record_from_user(user: self.class.user, movie_url: movie_url)
175
+ WorldTopMovies::Movie.delete_movie_instance_from_user(user: self.class.user, movie_url: movie_url)
176
+ end
177
+ movie_urls.size > 0 ? puts("\nThe movie(s) have been successfully deleted") : puts("\nNo movies were selected.")
178
+ end
179
+ end
180
+
181
+ def print_favourite_movies
182
+ sleep(1)
183
+ if !self.class.user.movies.empty?
184
+ self.class.user.print_all_favourite_movie_titles
185
+ else
186
+ puts "\nOops, you haven't favourited any movies yet!!"
187
+ end
188
+ end
189
+
190
+ def select_and_print_specific_favourite_movie
191
+ # Asks user to select a movie from print_movies_compact
192
+ sleep(0.5)
193
+ if self.class.user.movies.empty?
194
+ puts "\nOops, you haven't favourited any movies yet!!"
195
+ else
196
+ puts ""
197
+
198
+ movie_url = self.class.prompt.select(
199
+ "Select a movie: ", self.class.user.favourite_movie_titles, enum: ")"
200
+ )
201
+ WorldTopMovies::DB::Movie.all.find { |m| m.url == movie_url }.print_movie_details
202
+ end
203
+ end
204
+
205
+ def select_action_favourite_movies
206
+ puts ""
207
+ if self.class.user.movies.empty?
208
+ puts "Oops, you haven't favourited any movies yet, let's change that!!"
209
+ scrape_and_print_movies
210
+ select_next_action
211
+ else
212
+ sleep(0.5)
213
+ options = [
214
+ "See all your favourite movies",
215
+ "See more info of any of your favourite movies",
216
+ "Delete any of your favourite movies",
217
+ "Take me to the top movies lookup",
218
+ "Exit app",
219
+ ]
220
+
221
+ next_action = self.class.prompt.select(
222
+ "What would you like to do now?", options
223
+ )
224
+ if next_action == options[0]
225
+ print_favourite_movies
226
+ select_action_favourite_movies
227
+ elsif next_action == options[1]
228
+ select_and_print_specific_favourite_movie
229
+ select_action_favourite_movies
230
+ elsif next_action == options[2]
231
+ delete_favourite_movies
232
+ select_action_favourite_movies
233
+ elsif next_action == options[3]
234
+ scrape_and_print_movies
235
+ select_next_action
236
+ else
237
+ close_app
238
+ end
239
+ end
240
+ end
241
+
242
+ def print_all_notes
243
+ if !self.class.user.notes.empty?
244
+ self.class.user.print_all_notes
245
+ else
246
+ puts "\nOops, you haven't left any notes yet!!"
247
+ end
248
+ end
249
+
250
+ def print_movies_with_notes
251
+ sleep(1)
252
+ if !self.class.user.notes.empty?
253
+ self.class.user.print_movies_with_notes
254
+ else
255
+ puts "\nOops, you haven't left any notes yet!!"
256
+ end
257
+ end
258
+
259
+ def select_and_print_specific_movie_with_notes
260
+ # Asks user to select a movie from print_movies_compact
261
+ sleep(0.5)
262
+ if self.class.user.notes.empty?
263
+ puts "\nOops, you haven't left any notes yet!!"
264
+ else
265
+ puts ""
266
+ movie_url = self.class.prompt.select(
267
+ "Select a movie: ", self.class.user.movies_with_notes_titles, enum: ")"
268
+ )
269
+ WorldTopMovies::DB::Movie.all.find { |m| m.url == movie_url }.print_movie_details
270
+ end
271
+ end
272
+
273
+ def delete_notes
274
+ sleep(0.5)
275
+ if self.class.user.movies.empty?
276
+ puts "\nOops, you haven't left any notes yet!!"
277
+ else
278
+ note_ids = self.class.prompt.multi_select(
279
+ "\nSelect notes: ", self.class.user.notes_titles, enum: ")",
280
+ )
281
+ note_ids.each do |note_id|
282
+ WorldTopMovies::DB::UserNote.delete_note_record_from_user(user: self.class.user, note_id: note_id)
283
+ WorldTopMovies::DB::Note.delete_note_instance_from_user(user: self.class.user, note_id: note_id)
284
+ end
285
+ note_ids.size > 0 ? puts("\nThe note(s) have been successfully deleted") : puts("\nNo notes were selected.")
286
+ end
287
+ end
288
+
289
+ def select_action_movies_with_notes
290
+ puts ""
291
+ if self.class.user.notes.empty?
292
+ puts "Oops, you haven't left any notes yet, let's change that!!"
293
+ scrape_and_print_movies
294
+ select_next_action
295
+ else
296
+ sleep(0.5)
297
+ options = [
298
+ "See all my notes",
299
+ "See all your movies with notes",
300
+ "Open specific movie with notes",
301
+ "Delete any of your notes",
302
+ "Take me to the top movies lookup",
303
+ "Exit app",
304
+ ]
305
+
306
+ next_action = self.class.prompt.select(
307
+ "What would you like to do now?", options
308
+ )
309
+ if next_action == options[0]
310
+ print_all_notes
311
+ select_action_movies_with_notes
312
+ elsif next_action == options[1]
313
+ print_movies_with_notes
314
+ select_action_movies_with_notes
315
+ elsif next_action == options[2]
316
+ select_and_print_specific_movie_with_notes
317
+ select_action_movies_with_notes
318
+ elsif next_action == options[3]
319
+ delete_notes
320
+ select_action_movies_with_notes
321
+ elsif next_action == options[4]
322
+ scrape_and_print_movies
323
+ select_next_action
324
+ else
325
+ close_app
326
+ end
327
+ end
328
+ end
329
+
330
+ def close_app
331
+ puts "\nOk #{self.class.user.username}, hope you enjoyed your time with me!"
332
+ exit!
333
+ end
334
+ end
@@ -0,0 +1,63 @@
1
+ class WorldTopMovies::DB::Movie < ActiveRecord::Base
2
+ has_many :user_movies
3
+ has_many :users, through: :user_movies
4
+ has_many :notes
5
+
6
+ def self.generate_attributes_from_url(movie_url)
7
+ fav_movie = WorldTopMovies::Movie.find_by_url(movie_url)
8
+ attributes = {
9
+ title: fav_movie.title,
10
+ year: fav_movie.year,
11
+ duration: fav_movie.duration,
12
+ genres: fav_movie.genres.join(" - "),
13
+ user_rating: fav_movie.user_rating,
14
+ metascore: fav_movie.metascore,
15
+ description: fav_movie.description,
16
+ director: fav_movie.director,
17
+ stars: fav_movie.stars.join(" - "),
18
+ votes: fav_movie.votes,
19
+ gross_revenue: fav_movie.gross_revenue,
20
+ url: fav_movie.url,
21
+ }
22
+ end
23
+
24
+ def self.add_movies(user:, movie_urls:)
25
+ # Finds or creates new Favourite movie instances and adds them to the given user
26
+ movie_urls.class != Array && movie_urls = movie_urls.split()
27
+ movie_urls.each do |movie_url|
28
+ if user.movies.none? { |m| m.url == movie_url }
29
+ attributes = self.generate_attributes_from_url(movie_url)
30
+ user.movies << self.find_or_create_by(attributes)
31
+ end
32
+ end
33
+ end
34
+
35
+ def print_movie_details
36
+ attributes = {
37
+ title: self.title,
38
+ year: self.year,
39
+ duration: self.duration,
40
+ genres: self.genres,
41
+ user_rating: self.user_rating,
42
+ metascore: self.metascore.to_s,
43
+ description: self.description,
44
+ director: self.director,
45
+ stars: self.stars,
46
+ votes: self.votes,
47
+ gross_revenue: self.gross_revenue,
48
+ url: self.url,
49
+ database: true,
50
+ }
51
+ movie = WorldTopMovies::Movie.new(attributes)
52
+ movie.scrape_and_print_movie
53
+ print_movie_notes
54
+ end
55
+
56
+ def print_movie_notes
57
+ logged_user = WorldTopMovies::CLI.user
58
+ notes = self.notes.select { |n| n.user && n.user.username == logged_user.username }
59
+ puts "\n----------------#{"My Own notes".bold}------------------"
60
+ notes.empty? ? puts("No notes left") : notes.each { |n| puts "\n-#{n.note_message}- on #{n.created_at.localtime}" }
61
+ puts "----------------------------------------------"
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ class WorldTopMovies::DB::Note < ActiveRecord::Base
2
+ has_one :user_note, dependent: :destroy
3
+ has_one :user, through: :user_note
4
+ belongs_to :movie
5
+
6
+ def self.create_note(movie_url:, note_message:, user:)
7
+ #Creates a note to a movie that is created if it's not in the database, and appends it to the user
8
+ attributes = WorldTopMovies::DB::Movie.generate_attributes_from_url(movie_url)
9
+ if !WorldTopMovies::DB::Movie.find_by(url: movie_url)
10
+ movie_record = WorldTopMovies::DB::Movie.create(attributes)
11
+ else
12
+ movie_record = WorldTopMovies::DB::Movie.find_by(url: movie_url)
13
+ end
14
+ note_record = self.create(note_message: note_message, movie_id: movie_record.id)
15
+ user.notes << note_record
16
+ end
17
+
18
+ def self.delete_note_instance_from_user(user:, note_id:)
19
+ user.notes.delete(user.find_note_from_id(note_id))
20
+ end
21
+ end
@@ -0,0 +1,67 @@
1
+ class WorldTopMovies::DB::User < ActiveRecord::Base
2
+ has_many :user_movies, dependent: :destroy
3
+ has_many :movies, through: :user_movies
4
+ has_many :user_notes, dependent: :destroy
5
+ has_many :notes, through: :user_notes
6
+
7
+ def print_all_favourite_movie_titles
8
+ puts "\nOk! Your favourite movies are:\n\n"
9
+ sleep(1.5)
10
+ self.movies.sort_by { |m| m.title }.each_with_index do |m, i|
11
+ sleep(0.01)
12
+ WorldTopMovies::Movie.print_movie_compact(m, i)
13
+ end
14
+ end
15
+
16
+ def favourite_movie_titles
17
+ # returns a hash with key=title, value=url of all fav movies
18
+ result = {}
19
+ self.movies.sort_by { |m| m.title }.each { |m| result[m.title] = m.url }
20
+ result
21
+ end
22
+
23
+ def find_movie_from_url(movie_url)
24
+ self.movies.find { |m| m.url == movie_url }
25
+ end
26
+
27
+ def print_movies_with_notes
28
+ puts "\nOk! Your movies with notes are:\n\n"
29
+ sleep(1.5)
30
+ self.movies_with_notes_arr.sort_by { |m| m.title }.each_with_index do |m, i|
31
+ sleep(0.01)
32
+ WorldTopMovies::Movie.print_movie_compact(m, i)
33
+ end
34
+ end
35
+
36
+ def movies_with_notes_titles
37
+ result = {}
38
+ self.movies_with_notes_arr.sort_by { |m| m.title }.each { |m| result[m.title] = m.url }
39
+ result
40
+ end
41
+
42
+ def movies_with_notes_arr
43
+ self.notes.map { |note| note.movie }.uniq
44
+ end
45
+
46
+ def print_all_notes
47
+ puts "\nPrinting #{self.notes.count} note(s):\n\n"
48
+ sleep(1.5)
49
+ self.notes.each_with_index do |n, i|
50
+ sleep(0.01)
51
+ puts "--------------------------------------------------------------"
52
+ puts "\n#{i + 1}. #{n.note_message.colorize(:color => :green).italic}, \
53
+ Movie: #{n.movie.title.colorize(:color => :light_blue).bold}, \
54
+ Date: #{n.created_at.localtime.to_s.colorize(:color => :red).bold} \n"
55
+ end
56
+ end
57
+
58
+ def notes_titles
59
+ result = {}
60
+ self.notes.each { |n| result["#{n.note_message}, #{n.movie.title}, #{n.created_at.localtime.to_s}"] = n.id }
61
+ result
62
+ end
63
+
64
+ def find_note_from_id(note_id)
65
+ self.notes.find { |n| n.id == note_id }
66
+ end
67
+ end
@@ -0,0 +1,9 @@
1
+ class WorldTopMovies::DB::UserMovie < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :movie
4
+
5
+ def self.delete_movie_record_from_user(user:, movie_url:)
6
+ self.joins(:user, :movie)
7
+ .where("movies.url" => movie_url, "users.username" => user.username).destroy_all
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class WorldTopMovies::DB::UserNote < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :note
4
+
5
+ def self.delete_note_record_from_user(user:, note_id:)
6
+ self.joins(:user, :note)
7
+ .where("notes.id" => note_id, "users.username" => user.username).destroy_all
8
+ end
9
+ end
@@ -0,0 +1,179 @@
1
+ class WorldTopMovies::Movie
2
+ attr_reader :award, :storyline, :languages, :official_site, :countries_of_orig
3
+
4
+ @@all = []
5
+
6
+ def initialize(attributes)
7
+ #Utilises metaprogramming to create new instances
8
+ attributes.each do |key, value|
9
+ self.class.attr_accessor(key)
10
+ self.send(("#{key}="), value)
11
+ end
12
+ # Add instance to @all only if it's not already there
13
+ self.class.all << self if self.class.all.none? { |m| m.url == self.url } && !self.database
14
+ end
15
+
16
+ def self.new_from_page(m)
17
+ # Creates new instance with the attributes from general page
18
+ self.new({
19
+ title: m.css("h3 a").text,
20
+ year: m.css("h3 span.lister-item-year").text[1...-1].scan(/[0-9]/).join(),
21
+ duration: m.css("span.runtime").text,
22
+ genres: m.css("span.genre").text.strip.split(", "),
23
+ user_rating: m.css("div strong").text.to_f,
24
+ metascore: m.css("div span.metascore").text.strip.to_i,
25
+ description: m.css("p.text-muted")[1].text.strip,
26
+ director: m.css("div.lister-item-content p a")[0].text.strip,
27
+ stars: m.css("div.lister-item-content p a").slice(1..-1).map { |s| s.text },
28
+ votes: m.css("p.sort-num_votes-visible span")[1].text.gsub(",", "").to_i,
29
+ gross_revenue: m.css("p.sort-num_votes-visible span")[-1].text,
30
+ url: "https://imdb.com" + m.css("h3 a").attribute("href").value,
31
+ database: false,
32
+ })
33
+ end
34
+
35
+ def self.all
36
+ @@all
37
+ end
38
+
39
+ def self.all_top_general
40
+ # Filters out the movies with rating >= 8.4
41
+ self.all.select { |m| m.user_rating >= 8.4 }.sort_by { |m| m.user_rating }.reverse
42
+ end
43
+
44
+ def self.all_by_genre(genre)
45
+ # Filters all movies from a given genre, if no genre, return general movies
46
+ return self.all_top_general if !genre
47
+ self.all.select { |m| m.genres.include?(genre) }
48
+ end
49
+
50
+ def self.reset_all
51
+ self.all.clear
52
+ end
53
+
54
+ def self.all_titles_and_links_hash
55
+ # returns a hash with key=title, value=url of all movie instances
56
+ result = {}
57
+ self.all.each do |m|
58
+ result[m.title] = m.url
59
+ end
60
+ result
61
+ end
62
+
63
+ def self.all_titles_and_links_hash_by_genre(genre)
64
+ # returns a hash with key=title, value=url of all movie instances from given genre
65
+ result = {}
66
+ counter = 1
67
+ self.all_by_genre(genre).each do |m|
68
+ if result.keys.none? { |key| key == m.title }
69
+ result[m.title] = m.url
70
+ else
71
+ result[m.title + "(#{counter + 1})"] = m.url
72
+ end
73
+ end
74
+
75
+ result
76
+ end
77
+
78
+ def self.find_by_url(url)
79
+ self.all.find { |m| m.url == url }
80
+ end
81
+
82
+ def self.delete_movie_instance_from_user(user:, movie_url:)
83
+ user.movies.delete(user.find_movie_from_url(movie_url))
84
+ end
85
+
86
+ def self.scrape_and_print_movies_compact(genre = nil)
87
+ # Looks for the movies to print depending on the arg and prints title, rating, year
88
+ if genre == "all"
89
+ movies = self.all.sort_by { |m| m.user_rating }.reverse
90
+ else
91
+ WorldTopMovies::Scraper.make_movies(genre)
92
+ movies = genre == nil ? self.all_top_general : self.all_by_genre(genre)
93
+ end
94
+ puts "I'll give you #{movies.size} top movies!"
95
+ sleep(1.5)
96
+ movies.each_with_index do |movie, index|
97
+ sleep(0.01)
98
+ self.print_movie_compact(movie, index)
99
+ end
100
+ end
101
+
102
+ def self.print_movie_compact(movie, index)
103
+ puts "--------------------------------------------------------------"
104
+ puts "\n#{index + 1}. #{movie.title.colorize(:color => :green, :mode => :bold)}, \
105
+ Rating: #{movie.user_rating.to_s.colorize(:color => :light_blue, :mode => :bold)}, \
106
+ Year: #{movie.year.colorize(:color => :red)} \n"
107
+ end
108
+
109
+ def get_awards_count
110
+ target = doc.css("li span.ipc-metadata-list-item__list-content-item")[0].text
111
+ @award || (@award = target if target.include?("nomination") || target.include?("win"))
112
+ end
113
+
114
+ def storyline
115
+ @storyline ||
116
+ @storyline = doc.css(
117
+ ".Storyline__StorylineWrapper-sc-1b58ttw-0 div.ipc-html-content.ipc-html-content--base div"
118
+ )[0].text
119
+ end
120
+
121
+ def languages
122
+ @languages ||
123
+ @languages = doc.css(
124
+ "div[data-testid=title-details-section] li[data-testid=title-details-languages]"
125
+ )
126
+ .children[1].children[0].children.map { |l| l.text }.join(" - ")
127
+ end
128
+
129
+ def official_site
130
+ target = doc.css(
131
+ "div[data-testid=title-details-section] li[data-testid=title-details-officialsites]"
132
+ )
133
+ .children
134
+ if @official_site
135
+ @official_site
136
+ else
137
+ if target.children[0] && target.children[0].text.include?("site")
138
+ @official_site = target.children[1].children[0].children[0].attribute("href").value
139
+ end
140
+ end
141
+ end
142
+
143
+ def countries_of_origin
144
+ @countries_of_origin ||
145
+ @countries_of_origin = doc.css("div[data-testid=title-details-section] li[data-testid=title-details-origin]")
146
+ .children[1].children[0].children.map { |c| c.text }.join(" - ")
147
+ end
148
+
149
+ def scrape_and_print_movie
150
+ # Prints detailed info of a selected movie from select_specific_movie, after scraping it.
151
+ description = self.description
152
+ storyline = self.storyline
153
+ puts "\n----------------------------------------------"
154
+ puts " #{self.title.upcase} - #{self.year} ".colorize(:background => :green, :color => :black).bold
155
+ puts "----------------------------------------------"
156
+ puts "\n#{"Genres:".bold} #{self.genres.class == Array && self.genres.join(" - ").green.italic || self.genres.green.italic}"
157
+ puts "#{"Duration:".bold} #{self.duration.green.italic}"
158
+ puts "#{"Stars:".bold} #{self.stars.class == Array && self.stars.join(" - ").green.italic || self.stars.green.italic}"
159
+ puts "#{"Rating:".bold} #{"#{self.user_rating} from #{self.votes} votes".green.italic}"
160
+ puts "#{"Metascore:".bold} #{self.metascore && self.metascore.to_s.green.italic || "N/A"}"
161
+ puts "#{"Directed by:".bold} #{self.director && self.director.green.italic}"
162
+ puts "#{"Total Awards:".bold} #{self.get_awards_count && self.get_awards_count.green.italic || "N/A"}"
163
+ puts "\n-----------------#{"Description".bold}-------------------"
164
+ puts "\n#{description.green.italic || "N/A"}\n"
165
+ puts "\n#{"Storyline:".bold}\n\n#{self.storyline && self.storyline.green.italic || "N/A"}\n"
166
+ puts "\n----------------#{"Other Details".bold}------------------"
167
+ puts "\n#{"Countries:".bold} #{self.countries_of_origin && self.countries_of_origin.green.italic || "N/A"}"
168
+ puts "#{"Languages:".bold} #{self.languages && self.languages.green.italic || "N/A"}"
169
+ puts "#{"IMDB URL:".bold} #{self.url.green.italic}"
170
+ puts "#{"Website:".bold} #{self.official_site && self.official_site.green.italic || "N/A"}"
171
+ puts "\nThis movie has a gross revenue of #{self.gross_revenue}".green.bold
172
+ end
173
+
174
+ private
175
+
176
+ def doc
177
+ @doc || @doc = WorldTopMovies::Scraper.get_movie_details_page(self.url)
178
+ end
179
+ end