blinkbox_films 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 473ae721f46a03e80dcbbd541c65d5eba2b86c31
4
- data.tar.gz: e0a1422c50e3d237cdc800837789354f849dbdf2
3
+ metadata.gz: e695abee9304b0cde5c7193c45caaaba9e128104
4
+ data.tar.gz: de8ce6b1da05feb99e1b98824953d5a18601c84b
5
5
  SHA512:
6
- metadata.gz: a851e8361e2bc1e9c75cc4cb3322b1b9a5a2a1e884f9c05186a4a0a5f32a5c88fc54260c5eed808e308ec723b681e295fb85cc4511db3b61f7718f2e44a80857
7
- data.tar.gz: aa19ba80560622d0790a057767042577f0fce21f6508f3aa1e7392d082f5181bab94b7b37b9b099c25c6e1a6c1363e50d6f0c95f766a8935b9e5af7f610b3b3a
6
+ metadata.gz: 1132b4616635c34f1837e1b81428611e7e82a5282ca64949ac4ba9569e17c97532350f70b61d75d617e16d4b9e005ccf93fd0bf31c3125f8605421b91a6c5b8c
7
+ data.tar.gz: 526309666d94232b4205956ff01c9794ef890fd0fdba60295bc77e6d020b533544afc9825a29822231b8c7dafd77a377a80876da1179e3984aeb047b639f72e7
@@ -0,0 +1,26 @@
1
+ module BlinkboxFilms
2
+ class Film
3
+ def initialize(
4
+ title:,
5
+ url: nil,
6
+ image_url: nil,
7
+ certificate: nil,
8
+ release_year: nil,
9
+ running_time_in_minutes: nil,
10
+ buy_price: nil,
11
+ rental_price: nil
12
+ )
13
+ @title = title
14
+ @url = url
15
+ @image_url = image_url
16
+ @certificate = certificate
17
+ @release_year = release_year
18
+ @running_time_in_minutes = running_time_in_minutes
19
+ @buy_price = buy_price
20
+ @rental_price = rental_price
21
+ end
22
+
23
+ attr_reader :title, :url, :image_url, :certificate, :release_year,
24
+ :running_time_in_minutes, :buy_price, :rental_price
25
+ end
26
+ end
@@ -0,0 +1,69 @@
1
+ require 'uri'
2
+ require 'nokogiri'
3
+ require 'httpclient'
4
+
5
+ module BlinkboxFilms
6
+ class FilmPage
7
+ def initialize(body:, url: nil)
8
+ @body = body
9
+ @url = url
10
+ end
11
+
12
+ attr_reader :body, :url
13
+
14
+ def self.from_url(url)
15
+ response = HTTPClient.new.get(url)
16
+ FilmPage.new(body: Nokogiri::HTML(response.body), url: url)
17
+ end
18
+
19
+ def film
20
+ Film.new(
21
+ title: title,
22
+ url: url,
23
+ image_url: image_url,
24
+ release_year: release_year,
25
+ certificate: certificate,
26
+ running_time_in_minutes: running_time_in_minutes,
27
+ rental_price: rental_price,
28
+ buy_price: buy_price
29
+ )
30
+ end
31
+
32
+ def title
33
+ body.css('h1').first.content.strip
34
+ end
35
+
36
+ def image_url
37
+ body.css('.c-packShot noscript img').first.attributes['src'].value
38
+ end
39
+
40
+ def release_year
41
+ match = body.css('.g-assetInfo li').map { |n| %r{(\d{4})}.match(n.content) }.compact.first
42
+ match && match[1].to_i
43
+ end
44
+
45
+ def certificate
46
+ match = body.css('.g-assetInfo li').map { |n| %r{CERT (.*)}.match(n.content) }.compact.first
47
+ match && match[1]
48
+ end
49
+
50
+ def running_time_in_minutes
51
+ match = body.css('.g-assetInfo li').map { |n| %r{(\d+) HRS (\d+) MINS}.match(n.content) }.compact.first
52
+ match && (match[1].to_i * 60 + match[2].to_i)
53
+ end
54
+
55
+ def rental_price
56
+ select_price(body, '.c-retailButton--rental .c-retailButton__price > text()')
57
+ end
58
+
59
+ def buy_price
60
+ select_price(body, '.c-retailButton--purchase .c-retailButton__price > text()')
61
+ end
62
+
63
+ private
64
+ def select_price(body, selector)
65
+ price_tag = body.css(selector).first
66
+ price_tag && price_tag.text.strip
67
+ end
68
+ end
69
+ end
@@ -6,20 +6,20 @@ module BlinkboxFilms
6
6
  class Search
7
7
  def search(query)
8
8
  r = response(query)
9
- rentals = rental_fragments(r.body).map { |f|
10
- {
11
- :title => rental_title(f),
12
- :url => rental_url(f),
13
- :image_url => rental_image_url(f),
14
- :certificate => rental_certificate(f),
15
- :running_time_in_minutes => rental_running_time_in_minutes(f)
16
- }
9
+ films = film_fragments(r.body).map { |f|
10
+ Film.new(
11
+ title: film_title(f),
12
+ url: film_url(f),
13
+ image_url: film_image_url(f),
14
+ certificate: film_certificate(f),
15
+ running_time_in_minutes: film_running_time_in_minutes(f)
16
+ )
17
17
  }
18
18
 
19
- if rentals.empty? & !no_results_page?(r.body)
19
+ if films.empty? & !no_results_page?(r.body)
20
20
  raise BlinkboxFilms::SearchResultsPageNotRecognised
21
21
  else
22
- rentals
22
+ films
23
23
  end
24
24
  end
25
25
 
@@ -32,35 +32,35 @@ module BlinkboxFilms
32
32
  HTTPClient.new.get('http://www.blinkbox.com/search', { 'Search' => query })
33
33
  end
34
34
 
35
- def rental_fragments(page)
35
+ def film_fragments(page)
36
36
  Nokogiri::HTML(page).css('.p-searchResults li.b-assetCollection__item')
37
37
  end
38
38
 
39
- def rental_title(fragment)
39
+ def film_title(fragment)
40
40
  fragment.css('h3').first.content.strip
41
41
  end
42
42
 
43
- def rental_url(fragment)
44
- u = URI.parse(extract_rental_path_or_url(fragment))
43
+ def film_url(fragment)
44
+ u = URI.parse(extract_film_path_or_url(fragment))
45
45
  u.host ||= 'www.blinkbox.com'
46
46
  u.scheme ||= 'http'
47
47
  u.to_s
48
48
  end
49
49
 
50
- def extract_rental_path_or_url(fragment)
50
+ def extract_film_path_or_url(fragment)
51
51
  fragment.css('h3 a').first.attributes['href'].value
52
52
  end
53
53
 
54
- def rental_image_url(fragment)
54
+ def film_image_url(fragment)
55
55
  fragment.css('noscript img').first.attributes['src'].value
56
56
  end
57
57
 
58
- def rental_certificate(fragment)
58
+ def film_certificate(fragment)
59
59
  match = fragment.css('.c-assetCollectionItem__metaDataItem').map { |n| %r{CERT (\S+)}.match(n.content) }.compact.first
60
60
  match && match[1]
61
61
  end
62
62
 
63
- def rental_running_time_in_minutes(fragment)
63
+ def film_running_time_in_minutes(fragment)
64
64
  match = fragment.css('.c-assetCollectionItem__metaDataItem').map { |n| %r{(\d+) HRS? (\d+) MINS?}.match(n.content) }.compact.first
65
65
  match && (match[1].to_i * 60 + match[2].to_i)
66
66
  end
@@ -1,3 +1,4 @@
1
+ require 'blinkbox_films/film'
2
+ require 'blinkbox_films/film_page' || raise
1
3
  require 'blinkbox_films/search_results_page_not_recognised'
2
4
  require 'blinkbox_films/search'
3
-
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'blinkbox_films'
3
+
4
+ describe 'A film page', :vcr do
5
+ subject { BlinkboxFilms::FilmPage.from_url('http://www.blinkbox.com/movies/the-dark-knight-(28710)').film }
6
+
7
+ it { expect(subject.title).to eq('The Dark Knight') }
8
+ it { expect(subject.url).to eq('http://www.blinkbox.com/movies/the-dark-knight-(28710)') }
9
+ it { expect(subject.image_url).to match(%r{http://cdn\d+.blinkboxmedia.com/i/contentasset3/000/028/710/gl0lloqf/v=317/w=215;h=306;rm=Crop;q=85/image.jpg}) }
10
+ it { expect(subject.release_year).to eq(2008) }
11
+ it { expect(subject.certificate).to eq('12') }
12
+ it { expect(subject.running_time_in_minutes).to eq(152) }
13
+ it { expect(subject.rental_price).to eq('£2.49') }
14
+ it { expect(subject.buy_price).to eq('£6.99') }
15
+ end
16
+
@@ -10,11 +10,11 @@ describe 'A search' do
10
10
  subject { BlinkboxFilms::Search.new.search('dark knight') }
11
11
 
12
12
  it { expect(subject).to_not be_empty }
13
- it { expect(subject.first[:title]).to eq('The Dark Knight') }
14
- it { expect(subject.first[:url]).to eq('http://www.blinkbox.com/movies/the-dark-knight-(28710)') }
15
- it { expect(subject.first[:image_url]).to eq('http://cdn2.blinkboxmedia.com/i/contentasset31/000/028/710/1gkiab4e/v=316/w=234;h=132;rm=Crop;q=85/image.jpg') }
16
- it { expect(subject.first[:certificate]).to eq('12') }
17
- it { expect(subject.first[:running_time_in_minutes]).to eq(152) }
13
+ it { expect(subject.first.title).to eq('The Dark Knight') }
14
+ it { expect(subject.first.url).to eq('http://www.blinkbox.com/movies/the-dark-knight-(28710)') }
15
+ it { expect(subject.first.image_url).to eq('http://cdn2.blinkboxmedia.com/i/contentasset31/000/028/710/1gkiab4e/v=316/w=234;h=132;rm=Crop;q=85/image.jpg') }
16
+ it { expect(subject.first.certificate).to eq('12') }
17
+ it { expect(subject.first.running_time_in_minutes).to eq(152) }
18
18
  end
19
19
 
20
20
  context 'with unrecognised page format returned' do
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe BlinkboxFilms::FilmPage do
4
+ describe '#buy_price' do
5
+ subject { BlinkboxFilms::FilmPage.new(body: body) }
6
+
7
+ context 'standard price' do
8
+ let(:body) {
9
+ Nokogiri::HTML('<button type="submit" class="c-retailButton c-retailButton--purchase">
10
+ BUY
11
+ <span class="c-retailButton__price">
12
+ £6.99
13
+ </span>
14
+ </button>')
15
+ }
16
+
17
+ it { expect(subject.buy_price).to eq('£6.99') }
18
+ end
19
+
20
+ context 'discount price' do
21
+ let(:body) {
22
+ Nokogiri::HTML('<button type="submit" class="c-retailButton c-retailButton--purchase">
23
+ BUY
24
+ <span class="c-retailButton__price">
25
+ £3.99
26
+ <span class="c-retailButton__saving c-retailButton__saving--purchase">
27
+ £6.99
28
+ </span>
29
+ </span>
30
+ </button>')
31
+ }
32
+
33
+ it { expect(subject.buy_price).to eq('£3.99') }
34
+ end
35
+ end
36
+ end
37
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blinkbox_films
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Chippindale
@@ -103,9 +103,13 @@ files:
103
103
  - LICENSE.txt
104
104
  - Rakefile
105
105
  - lib/blinkbox_films.rb
106
+ - lib/blinkbox_films/film.rb
107
+ - lib/blinkbox_films/film_page.rb
106
108
  - lib/blinkbox_films/search.rb
107
109
  - lib/blinkbox_films/search_results_page_not_recognised.rb
110
+ - spec/feature/film_page_spec.rb
108
111
  - spec/feature/search_spec.rb
112
+ - spec/lib/blinkbox_films/film_page_spec.rb
109
113
  - spec/spec_helper.rb
110
114
  homepage: https://github.com/mocoso/blinkbox_films
111
115
  licenses: