spotlite 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +5 -5
  4. data/Rakefile +1 -1
  5. data/lib/spotlite.rb +2 -1
  6. data/lib/spotlite/http_client.rb +18 -0
  7. data/lib/spotlite/movie.rb +92 -83
  8. data/lib/spotlite/person.rb +32 -34
  9. data/lib/spotlite/string_extensions.rb +13 -13
  10. data/lib/spotlite/version.rb +1 -1
  11. data/spec/fixtures/movie_find_conan +248 -213
  12. data/spec/fixtures/movie_find_no_results +246 -212
  13. data/spec/fixtures/nm0000233/index +2139 -1374
  14. data/spec/fixtures/nm0005132/index +1081 -698
  15. data/spec/fixtures/nm0864666/index +393 -329
  16. data/spec/fixtures/nm1659547/index +1065 -686
  17. data/spec/fixtures/person_find_conan +247 -212
  18. data/spec/fixtures/person_find_no_results +246 -212
  19. data/spec/fixtures/search_name_count_50 +178 -180
  20. data/spec/fixtures/search_title_count_50 +251 -251
  21. data/spec/fixtures/tt0002186/index +2439 -492
  22. data/spec/fixtures/tt0047396/releaseinfo +583 -411
  23. data/spec/fixtures/tt0112873/index +1157 -864
  24. data/spec/fixtures/tt0120338/technical +353 -283
  25. data/spec/fixtures/tt0133093/criticreviews +329 -269
  26. data/spec/fixtures/tt0133093/fullcredits +1610 -893
  27. data/spec/fixtures/tt0133093/index +1360 -949
  28. data/spec/fixtures/tt0133093/keywords +5134 -1015
  29. data/spec/fixtures/tt0133093/mediaindex_still_frame +323 -250
  30. data/spec/fixtures/tt0133093/releaseinfo +579 -410
  31. data/spec/fixtures/tt0133093/trivia +1974 -1447
  32. data/spec/fixtures/tt0169547/index +1296 -901
  33. data/spec/fixtures/tt0317248/index +1308 -888
  34. data/spec/fixtures/tt1134629/fullcredits +1022 -598
  35. data/spec/spec_helper.rb +4 -4
  36. data/spec/spotlite/find_spec.rb +3 -3
  37. data/spec/spotlite/movie_spec.rb +48 -51
  38. data/spec/spotlite/person_spec.rb +25 -25
  39. data/spotlite.gemspec +3 -1
  40. metadata +32 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42b6d7da0103a2f748b6ae6538dff22250514052
4
- data.tar.gz: d85ae3e8043976bd0cffb516a76b2b1018588555
3
+ metadata.gz: c105673d29a0a0bae4ea7c336e5fdaedd5cc6340
4
+ data.tar.gz: 284715b2189e721d3355e905a02e7ac88ea5abf1
5
5
  SHA512:
6
- metadata.gz: aa3593e02c8f945dc50da2f092ea92da9346fea75792561dba6677633b6498cae7c87c5135d2ddfa92c080f1fc8555559aac59058742f1fcb11660938e24b562
7
- data.tar.gz: 5f058b249fa75382094d3e3a3429f14322611d699a21c40f2d9fe3f5640e9425f497ea8b41907c0677fe6d0da1a5b9edbece1c305eb97a714af7c08c8227a686
6
+ metadata.gz: bc9057597d1da13f16e58af1261c32952b5182ed11a125b9f85e85b9201cc624076bf358f3549ab09011cd2872e01ee14284f48174810cb30c28c99b63bb9125
7
+ data.tar.gz: 0125f5259dd412008c7ad8b22b48fca6f1c3cdf9c63d6ea3262a975d81b57f18f24ceb126c38e638dbec869a8f198b2223798d4f3915946c5e083e9ff6772ef9
@@ -1,3 +1,9 @@
1
+ ## v0.8.3 14-Dec-2014
2
+
3
+ * Spotlite now uses HTTParty as HTTP client, adding `response` attribute to Movie instance
4
+ * Fixed #parse_crew method failing when crew category was missing
5
+ * Recommended movies will now include only feature films
6
+
1
7
  ## v0.8.2 18-Jul-2014
2
8
 
3
9
  * Clean some junk from credits text (particularly writers credits)
data/README.md CHANGED
@@ -38,7 +38,7 @@ Or install it yourself as:
38
38
  => [#<Spotlite::Person:0x007f96a092be70 @imdb_id="0905152", @name="Andy Wachowski", @url="http://www.imdb.com/name/nm0905152/", @credits_category="Directed by", @credits_text="(as The Wachowski Brothers)">, #<Spotlite::Person:0x007f96a092bda8 @imdb_id="0905154", @name="Lana Wachowski", @url="http://www.imdb.com/name/nm0905154/", @credits_category="Directed by", @credits_text="(as The Wachowski Brothers)">]
39
39
  > movie.cast[0..2]
40
40
  => [#<Spotlite::Person:0x007f96a19521a0 @imdb_id="0000206", @name="Keanu Reeves", @url="http://www.imdb.com/name/nm0000206/", @credits_category="Cast", @credits_text="Neo">, #<Spotlite::Person:0x007f96a1951c28 @imdb_id="0000401", @name="Laurence Fishburne", @url="http://www.imdb.com/name/nm0000401/", @credits_category="Cast", @credits_text="Morpheus">, #<Spotlite::Person:0x007f96a1951a70 @imdb_id="0005251", @name="Carrie-Anne Moss", @url="http://www.imdb.com/name/nm0005251/", @credits_category="Cast", @credits_text="Trinity">]
41
-
41
+
42
42
  ## Important notice
43
43
 
44
44
  Movie titles will be localized if movie has an alternative title specific to your country.
@@ -60,11 +60,11 @@ Sorry, there is nothing I can do about it at the moment.
60
60
  Spotlite uses RSpec as a test framework. So, first make sure you have it installed
61
61
 
62
62
  $ gem install rspec
63
-
63
+
64
64
  Run the tests
65
65
 
66
66
  $ rake
67
-
67
+
68
68
  Spotlite uses gem FakeWeb in order to stub out HTTP responses from IMDb. These
69
69
  stubs are located in `spec/fixtures` directory.
70
70
 
@@ -76,7 +76,7 @@ If you want to make a new feature that uses data from a page which is not stubbe
76
76
 
77
77
  $ cd spotlite
78
78
  $ curl -isH "Accept-Language: en-us" http://www.imdb.com/title/tt[IMDB_ID]/ > spec/fixtures/tt[IMDB_ID]/index
79
-
79
+
80
80
  or, for example:
81
81
 
82
82
  $ curl -isH "Accept-Language: en-us" http://www.imdb.com/title/tt[IMDB_ID]/fullcredits > spec/fixtures/tt[IMDB_ID]/fullcredits
@@ -89,7 +89,7 @@ expected data, or more likely, methods will return nil or empty arrays.
89
89
  First, run tests with `LIVE_TEST=true` environment variable:
90
90
 
91
91
  $ LIVE_TEST=true rake
92
-
92
+
93
93
  Adjust methods that are failing, according to the new layout. And refresh fixtures:
94
94
 
95
95
  $ rake refresh_fixtures
data/Rakefile CHANGED
@@ -19,7 +19,7 @@ task :refresh_fixtures do
19
19
 
20
20
  IMDB_SAMPLES.each_pair do |url, fixture|
21
21
  page = `curl -isH "Accept-Language: en-us" '#{url}'`
22
-
22
+
23
23
  File.open(File.expand_path(File.dirname(__FILE__) + "/spec/fixtures/#{fixture}"), 'w') do |f|
24
24
  f.write(page)
25
25
  end
@@ -2,10 +2,11 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  require "rubygems"
5
- require "open-uri"
5
+ require "httparty"
6
6
  require "nokogiri"
7
7
 
8
8
  require "spotlite/version"
9
+ require "spotlite/http_client"
9
10
  require "spotlite/movie"
10
11
  require "spotlite/person"
11
12
  require "spotlite/string_extensions"
@@ -0,0 +1,18 @@
1
+ class HtmlParserIncluded < HTTParty::Parser
2
+ SupportedFormats.merge!('text/html' => :html)
3
+
4
+ def html
5
+ Nokogiri::HTML(body)
6
+ end
7
+ end
8
+
9
+ module Spotlite
10
+ class Client
11
+ include HTTParty
12
+ parser HtmlParserIncluded
13
+
14
+ USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.77.4 (KHTML, like Gecko) Version/7.0.5 Safari/537.77.4'
15
+
16
+ headers 'Accept-Language' => 'en-US,en;q=0.5', 'User-Agent' => USER_AGENT
17
+ end
18
+ end
@@ -1,10 +1,8 @@
1
- require 'cgi'
2
-
3
1
  module Spotlite
4
2
  # Represents a movie on IMDb.com
5
3
  class Movie
6
- attr_accessor :imdb_id, :url
7
-
4
+ attr_accessor :imdb_id, :url, :response
5
+
8
6
  # Initialize a new movie object by its IMDb ID as a string
9
7
  #
10
8
  # movie = Spotlite::Movie.new('0133093')
@@ -20,96 +18,97 @@ module Spotlite
20
18
  @year = year
21
19
  @url = "http://www.imdb.com/title/tt#{@imdb_id}/"
22
20
  end
23
-
21
+
24
22
  # Returns a list of movies as an array of +Spotlite::Movie+ objects
25
23
  # Takes single parameter and searches for movies by title and alternative titles
26
24
  def self.find(query)
27
- results = Nokogiri::HTML open("http://www.imdb.com/find?q=#{CGI::escape(query)}&s=tt&ttype=ft", 'Accept-Language' => 'en-us')
25
+ results = Spotlite::Client.get 'http://www.imdb.com/find', query: {q: query, s: 'tt', ttype: 'ft'}
28
26
  results.css('.result_text').map do |result|
29
27
  imdb_id = result.at('a')['href'].parse_imdb_id
30
28
  title = result.at('a').text.strip
31
29
  year = result.children.take(3).last.text.parse_year
32
-
30
+
33
31
  [imdb_id, title, year]
34
32
  end.map do |values|
35
33
  self.new(*values)
36
34
  end
37
35
  end
38
-
36
+
39
37
  # Returns a list of movies as an array of +Spotlite::Movie+ objects
40
38
  # Takes optional parameters as a hash
41
39
  # See https://github.com/defeed/spotlite/wiki/Advanced-movie-search for details
42
40
  def self.search(params = {})
43
41
  defaults = {
44
- :title_type => 'feature',
45
- :view => 'simple',
46
- :count => 250,
47
- :start => 1,
48
- :sort => 'moviemeter,asc'
42
+ title_type: 'feature',
43
+ view: 'simple',
44
+ count: 250,
45
+ start: 1,
46
+ sort: 'moviemeter,asc'
49
47
  }
50
- params = defaults.merge(params).map{ |k, v| "#{k}=#{v}" }.join('&')
51
- results = Nokogiri::HTML open("http://www.imdb.com/search/title?#{params}", 'Accept-Language' => 'en-us')
48
+ params = defaults.merge(params)
49
+ results = Spotlite::Client.get 'http://www.imdb.com/search/title', query: params
52
50
  results.css('td.title').map do |result|
53
51
  imdb_id = result.at('a')['href'].parse_imdb_id
54
52
  title = result.at('a').text.strip
55
53
  year = result.at('.year_type').text.parse_year
56
-
54
+
57
55
  [imdb_id, title, year]
58
56
  end.map do |values|
59
57
  self.new(*values)
60
58
  end
61
59
  end
62
-
60
+
63
61
  # Returns title as a string
64
62
  def title
65
- @title ||= details.at("h1.header span[itemprop='name']").text.strip
63
+ @title ||= details.at("h1.header span[itemprop='name']").text.strip rescue nil
66
64
  end
67
-
65
+
68
66
  # Returns original non-english title as a string
69
67
  def original_title
70
68
  details.at("h1.header span.title-extra[itemprop='name']").children.first.text.gsub('"', '').strip rescue nil
71
69
  end
72
-
70
+
73
71
  # Returns year of original release as an integer
74
72
  def year
75
73
  @year ||= details.at("h1.header a[href^='/year/']").text.parse_year rescue nil
76
74
  end
77
-
75
+
78
76
  # Returns IMDb rating as a float
79
77
  def rating
80
78
  details.at("div.star-box-details span[itemprop='ratingValue']").text.to_f rescue nil
81
79
  end
82
-
80
+
83
81
  # Returns Metascore rating as an integer
84
82
  def metascore
85
83
  details.at("div.star-box-details a[href^=criticreviews]").text.strip.split('/').first.to_i rescue nil
86
84
  end
87
-
85
+
88
86
  # Returns number of votes as an integer
89
87
  def votes
90
88
  details.at("div.star-box-details span[itemprop='ratingCount']").text.gsub(/[^\d+]/, '').to_i rescue nil
91
89
  end
92
-
90
+
93
91
  # Returns short description as a string
94
92
  def description
95
- details.at("p[itemprop='description']").text.strip.clean_description rescue nil
93
+ desc = details.at("p[itemprop='description']").text.strip.clean_description rescue nil
94
+ (desc.nil? || desc.empty?) ? nil : desc
96
95
  end
97
-
96
+
98
97
  # Returns storyline as a string. Often is the same as description
99
98
  def storyline
100
99
  details.at("#titleStoryLine div[itemprop='description'] p").text.strip.clean_description rescue nil
101
100
  end
102
-
101
+
103
102
  # Returns content rating as a string
104
103
  def content_rating
105
104
  details.at(".infobar span[itemprop='contentRating']")['title'] rescue nil
106
105
  end
107
-
106
+
108
107
  # Returns a list of genres as an array of strings
109
108
  def genres
110
109
  details.css("div.infobar a[href^='/genre/']").map { |genre| genre.text } rescue []
111
110
  end
112
-
111
+
113
112
  # Returns a list of countries as an array of hashes
114
113
  # with keys: +code+ (string) and +name+ (string)
115
114
  def countries
@@ -117,10 +116,10 @@ module Spotlite
117
116
  details.css("div.txt-block a[href^='/country/']").each do |node|
118
117
  array << {:code => node['href'].clean_href, :name => node.text.strip}
119
118
  end
120
-
119
+
121
120
  array
122
121
  end
123
-
122
+
124
123
  # Returns a list of languages as an array of hashes
125
124
  # with keys: +code+ (string) and +name+ (string)
126
125
  def languages
@@ -128,47 +127,54 @@ module Spotlite
128
127
  details.css("div.txt-block a[href^='/language/']").each do |node|
129
128
  array << {:code => node['href'].clean_href, :name => node.text.strip}
130
129
  end
131
-
130
+
132
131
  array
133
132
  end
134
-
133
+
135
134
  # Returns runtime (length) in minutes as an integer
136
135
  def runtime
137
136
  details.at("time[itemprop='duration']").text.gsub(',', '').to_i rescue nil
138
137
  end
139
-
138
+
140
139
  # Returns primary poster URL as a string
141
140
  def poster_url
142
141
  src = details.at('#img_primary img')['src'] rescue nil
143
-
142
+
144
143
  if src =~ /^(http:.+@@)/ || src =~ /^(http:.+?)\.[^\/]+$/
145
144
  $1 + '.jpg'
146
145
  end
147
146
  end
148
-
147
+
149
148
  # Returns an array of recommended movies as an array of initialized objects of +Movie+ class
150
149
  def recommended_movies
151
- details.css('.rec-title').map do |node|
150
+ details.css('.rec-title').reject do |node|
151
+ # reject movies that don't have a release year yet
152
+ node.at('span').nil?
153
+ end.reject do |node|
154
+ # reject everything other than featured film
155
+ /\d{4}-\d{4}/.match(node.at('span').text) ||
156
+ /Series|Episode|Video|Documentary|Movie|Special|Short|Game|Unknown/.match(node.at('span').text)
157
+ end.map do |node|
152
158
  imdb_id = node.at("a[href^='/title/tt']")['href'].parse_imdb_id
153
159
  title = node.at('a').text.strip
154
160
  year = node.at('span').text.parse_year
155
-
161
+
156
162
  [imdb_id, title, year]
157
163
  end.map do |values|
158
164
  Spotlite::Movie.new(*values)
159
165
  end
160
166
  end
161
-
167
+
162
168
  # Returns a list of keywords as an array of strings
163
169
  def keywords
164
170
  plot_keywords.css("a[href^='/keyword/']").map { |keyword| keyword.text.strip } rescue []
165
171
  end
166
-
172
+
167
173
  # Returns a list of trivia facts as an array of strings
168
174
  def trivia
169
175
  movie_trivia.css("div.sodatext").map { |node| node.text.strip } rescue []
170
176
  end
171
-
177
+
172
178
  # Returns a list of movie alternative titles as an array of hashes
173
179
  # with keys +title+ (string) and +comment+ (string)
174
180
  def alternative_titles
@@ -177,37 +183,37 @@ module Spotlite
177
183
  cells = row.css('td')
178
184
  array << { :title => cells.last.text.strip, :comment => cells.first.text.strip }
179
185
  end
180
-
186
+
181
187
  array
182
188
  end
183
-
189
+
184
190
  # Returns a list of directors as an array of +Spotlite::Person+ objects
185
191
  def directors
186
192
  parse_crew('Directed by')
187
193
  end
188
-
194
+
189
195
  # Returns a list of writers as an array of +Spotlite::Person+ objects
190
196
  def writers
191
197
  parse_crew('Writing Credits')
192
198
  end
193
-
199
+
194
200
  # Returns a list of producers as an array of +Spotlite::Person+ objects
195
201
  def producers
196
202
  parse_crew('Produced by')
197
203
  end
198
-
204
+
199
205
  # Returns a list of starred actors as an array of +Spotlite::Person+ objects
200
206
  def stars
201
207
  details.css("td#overview-top div[itemprop='actors'] a[href^='/name/nm']").map do |node|
202
208
  imdb_id = node['href'].parse_imdb_id
203
209
  name = node.text.strip
204
-
210
+
205
211
  [imdb_id, name]
206
212
  end.map do |values|
207
213
  Spotlite::Person.new(*values)
208
214
  end
209
215
  end
210
-
216
+
211
217
  # Returns a list of actors as an array +Spotlite::Person+ objects
212
218
  def cast
213
219
  full_credits.css('table.cast_list tr').reject do |row|
@@ -217,16 +223,16 @@ module Spotlite
217
223
  imdb_id = row.at('td:nth-child(2) a')['href'].parse_imdb_id
218
224
  name = row.at('td:nth-child(2) a').text.strip_whitespace
219
225
  credits_text = row.last_element_child.text.strip_whitespace
220
-
226
+
221
227
  [imdb_id, name, 'Cast', credits_text]
222
228
  end.map do |values|
223
229
  Spotlite::Person.new(*values)
224
230
  end
225
231
  end
226
-
232
+
227
233
  # Returns a list of crew members of a certain category as an array +Spotlite::Person+ objects
228
234
  def parse_crew(category)
229
- table = full_credits.search("[text()^='#{category}']").first.next_element rescue []
235
+ table = full_credits.search("[text()^='#{category}']").first.next_element rescue nil
230
236
  if table && table.name == 'table'
231
237
  table.css('tr').reject do |row|
232
238
  # Skip empty table rows with one non-braking space
@@ -235,34 +241,36 @@ module Spotlite
235
241
  imdb_id = row.first_element_child.at('a')['href'].parse_imdb_id
236
242
  name = row.first_element_child.at('a').text.strip_whitespace
237
243
  credits_text = row.last_element_child.text.strip_whitespace.clean_credits_text
238
-
244
+
239
245
  [imdb_id, name, category, credits_text]
240
246
  end.map do |values|
241
247
  Spotlite::Person.new(*values)
242
248
  end
249
+ else
250
+ []
243
251
  end
244
252
  end
245
-
253
+
246
254
  # Combines all crew categories and returns an array of +Spotlite::Person+ objects
247
255
  def crew
248
256
  crew_categories.map{ |category| parse_crew(category) }.flatten
249
257
  end
250
-
258
+
251
259
  # Returns combined `cast` and `crew` as an array of +Spotlite::Person+ objects
252
260
  def credits
253
261
  cast + crew
254
262
  end
255
-
263
+
256
264
  # Returns available crew categories, e.g. "Art Department", "Writing Credits", or "Stunts", as an array of strings
257
265
  def crew_categories
258
266
  array = []
259
267
  full_credits.css('h4.dataHeaderWithBorder').reject{ |h| h['id'] == 'cast' }.map do |node|
260
268
  array << (node.children.size > 1 ? node.children.first.text.strip_whitespace : node.children.text.strip_whitespace)
261
269
  end
262
-
270
+
263
271
  array
264
272
  end
265
-
273
+
266
274
  # Returns a list of regions and corresponding release dates
267
275
  # as an array of hashes with keys:
268
276
  # region +code+ (string), +region+ name (string), +date+ (date), and +comment+ (string)
@@ -278,18 +286,18 @@ module Spotlite
278
286
  date = cells.at('.release_date').text.strip.parse_date
279
287
  comment = cells.last.text.strip.clean_release_comment
280
288
  comment = nil if comment.empty?
281
-
289
+
282
290
  array << {:code => code, :region => region, :date => date, :comment => comment}
283
291
  end unless table.nil?
284
-
292
+
285
293
  array
286
294
  end
287
-
295
+
288
296
  # Returns original release date as a date
289
297
  def release_date
290
298
  release_dates.first[:date] rescue nil
291
299
  end
292
-
300
+
293
301
  # Returns a list of critic reviews as an array of hashes
294
302
  # with keys: +source+ (string), +author+ (string), +excerpt+ (string), and +score+ (integer)
295
303
  def critic_reviews
@@ -299,32 +307,32 @@ module Spotlite
299
307
  author = review.at("span[itemprop='author'] span[itemprop='name']").text
300
308
  excerpt = review.at("div[itemprop='reviewbody']").text.strip
301
309
  score = review.at("span[itemprop='ratingValue']").text.to_i
302
-
310
+
303
311
  array << {:source => source, :author => author, :excerpt => excerpt, :score => score}
304
312
  end
305
-
313
+
306
314
  array
307
315
  end
308
-
316
+
309
317
  # Returns URLs of movie still frames as an array of strings
310
318
  def images
311
319
  array = []
312
320
  still_frames.css('#media_index_thumbnail_grid img').map do |image|
313
321
  src = image['src'] rescue nil
314
-
322
+
315
323
  if src =~ /^(http:.+@@)/ || src =~ /^(http:.+?)\.[^\/]+$/
316
324
  array << $1 + '.jpg'
317
325
  end
318
326
  end
319
-
327
+
320
328
  array
321
329
  end
322
-
330
+
323
331
  # Returns technical information like film length, aspect ratio, cameras, etc. as a hash of arrays of strings
324
332
  def technical
325
333
  hash = {}
326
334
  table = technical_info.at_css('#technical_content table') rescue nil
327
-
335
+
328
336
  table.css('tr').map do |row|
329
337
  hash[row.css('td').first.text.strip] = row.css('td').last.children.
330
338
  map(&:text).
@@ -334,46 +342,47 @@ module Spotlite
334
342
  slice_before{|i| /^[^\(]/.match i}.
335
343
  map{|i| i.join(' ')}
336
344
  end unless table.nil?
337
-
345
+
338
346
  hash
339
347
  end
340
-
348
+
341
349
  private
342
-
350
+
343
351
  def details # :nodoc:
344
352
  @details ||= open_page
345
353
  end
346
-
354
+
347
355
  def release_info # :nodoc:
348
356
  @release_info ||= open_page('releaseinfo')
349
357
  end
350
-
358
+
351
359
  def full_credits # :nodoc:
352
360
  @full_credits ||= open_page('fullcredits')
353
361
  end
354
-
362
+
355
363
  def plot_keywords # :nodoc:
356
364
  @plot_keywords ||= open_page('keywords')
357
365
  end
358
-
366
+
359
367
  def movie_trivia # :nodoc:
360
368
  @movie_trivia ||= open_page('trivia')
361
369
  end
362
-
370
+
363
371
  def reviews
364
372
  @reviews ||= open_page('criticreviews')
365
373
  end
366
-
374
+
367
375
  def still_frames # :nodoc:
368
- @still_frames ||= open_page('mediaindex?refine=still_frame')
376
+ @still_frames ||= open_page('mediaindex', {refine: 'still_frame'})
369
377
  end
370
-
371
- def technical_info
378
+
379
+ def technical_info # :nodoc:
372
380
  @technical_info ||= open_page('technical')
373
381
  end
374
-
375
- def open_page(page = nil) # :nodoc:
376
- Nokogiri::HTML open("#{@url}#{page}", 'Accept-Language' => 'en-us')
382
+
383
+ def open_page(page = nil, query = {}) # :nodoc:
384
+ response = Spotlite::Client.get "#{@url}#{page}", query: query
385
+ @response = { code: response.code, message: response.message } and response
377
386
  end
378
387
  end
379
388