fandango 1.0.0 → 2.0.0
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 +7 -0
- data/.gitignore +0 -1
- data/.irbrc +2 -3
- data/.ruby-version +1 -0
- data/.travis.yml +2 -2
- data/Gemfile +2 -0
- data/Gemfile.lock +37 -0
- data/README.md +45 -22
- data/Rakefile +2 -2
- data/fandango.gemspec +3 -3
- data/lib/fandango.rb +13 -35
- data/lib/fandango/api.rb +14 -0
- data/lib/fandango/api/movies_near.rb +36 -0
- data/lib/fandango/api/theater_showtimes.rb +47 -0
- data/lib/fandango/movie.rb +34 -18
- data/lib/fandango/showtime.rb +18 -0
- data/lib/fandango/theater.rb +44 -35
- data/lib/fandango/version.rb +1 -1
- data/spec/api/movies_near.spec.rb +30 -0
- data/spec/api/theater_showtimes.spec.rb +36 -0
- data/spec/movie.spec.rb +17 -18
- data/spec/showtime.spec.rb +21 -0
- data/spec/spec_helper.rb +5 -10
- data/spec/support/fixture_helpers.rb +14 -0
- data/spec/support/fixtures/movies_near_me_73142.rss +185 -1
- data/spec/support/fixtures/{movies_near_me_73142.yaml → movies_near_me_73142.yml} +70 -70
- data/spec/support/fixtures/showtimes_amcquailspringsmall24_aaktw_2016_08_01.html +7264 -0
- data/spec/support/fixtures/theater_showtimes_amcquailspringsmall24.yml +203 -0
- data/spec/support/fixtures/theater_showtimes_amcquailspringsmall24_tomorrow.yml +190 -0
- data/spec/support/minitest.rb +9 -0
- data/spec/support/vcr.rb +6 -0
- data/spec/support/vcr_cassettes/theater_showtimes_amcquailspringsmall24.yml +10974 -0
- data/spec/support/vcr_cassettes/theater_showtimes_amcquailspringsmall24_tomorrow.yml +10759 -0
- data/spec/theater.spec.rb +58 -12
- metadata +79 -48
- data/.rvmrc +0 -1
- data/lib/fandango/parser.rb +0 -39
- data/spec/fandango.spec.rb +0 -41
- data/spec/parser.spec.rb +0 -12
- data/spec/support/fixtures/item.html +0 -1
- data/spec/support/helpers.rb +0 -25
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 852bc1a00a4783ec4b36469fe7db37179dd6201c
|
4
|
+
data.tar.gz: 3c9bd3977acc1d8e629bfbf84c6bc258d138b214
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3ae6deafd0527b381e036167ff321277d8f86d4eed21fbe719ae30d2334819934e396ad0f8a2fb212a66a61457ed883a6a675d22e2b0b6c8e5db34a76d652e3
|
7
|
+
data.tar.gz: 9d6d73995bec4a0221385b667c65115e0e5cf99716f9894ea02428eb7c157d8156230bdfdda86ceca268aa9315ce2272e449d4afb6840ebc734b29058269ff20
|
data/.gitignore
CHANGED
data/.irbrc
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.3.1
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fandango (2.0.0)
|
5
|
+
nokogiri (~> 1.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
addressable (2.4.0)
|
11
|
+
awesome_print (1.7.0)
|
12
|
+
crack (0.4.3)
|
13
|
+
safe_yaml (~> 1.0.0)
|
14
|
+
mini_portile2 (2.1.0)
|
15
|
+
minitest (5.9.0)
|
16
|
+
nokogiri (1.6.8.1)
|
17
|
+
mini_portile2 (~> 2.1.0)
|
18
|
+
rake (11.2.2)
|
19
|
+
safe_yaml (1.0.4)
|
20
|
+
vcr (3.0.3)
|
21
|
+
webmock (1.9.3)
|
22
|
+
addressable (>= 2.2.7)
|
23
|
+
crack (>= 0.3.2)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
awesome_print
|
30
|
+
fandango!
|
31
|
+
minitest
|
32
|
+
rake
|
33
|
+
vcr
|
34
|
+
webmock
|
35
|
+
|
36
|
+
BUNDLED WITH
|
37
|
+
1.13.1
|
data/README.md
CHANGED
@@ -6,34 +6,57 @@ Uses Fandango's RSS moviesnearme feed. E.g. http://www.fandango.com/rss/moviesne
|
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
The movies are an array of hashes. Each hash contains title and Fandango's id.
|
13
|
-
|
14
|
-
### Example output format
|
15
|
-
|
16
|
-
```
|
9
|
+
```ruby
|
10
|
+
theaters_and_movies = Fandango.movies_near(73142)
|
11
|
+
=begin
|
17
12
|
[
|
18
13
|
[ 0] {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
:id => "123456"
|
14
|
+
:name => "AMC Quail Springs Mall 24",
|
15
|
+
:id => "aaktw",
|
16
|
+
:address => "2501 West Memorial Oklahoma City, OK 73134",
|
17
|
+
:postal_code => "73134",
|
18
|
+
:showtimes_link => "http://www.fandango.com/amcquailspringsmall24_aaktw/theaterpage?wssaffid=11836&wssac=123",
|
19
|
+
:movies => [
|
20
|
+
[ 0] {
|
21
|
+
:title => "Abraham Lincoln: Vampire Hunter",
|
22
|
+
:id => "141897"
|
29
23
|
},
|
30
|
-
#
|
24
|
+
# ...
|
31
25
|
]
|
32
26
|
},
|
33
|
-
#
|
27
|
+
# ...
|
34
28
|
]
|
29
|
+
=end
|
30
|
+
|
31
|
+
movies_and_showtimes = Fandango.theater_showtimes(theaters_and_movies.first.fetch(:showtimes_link))
|
32
|
+
=begin
|
33
|
+
[
|
34
|
+
{
|
35
|
+
:title => "Bad Moms",
|
36
|
+
:id => "191125",
|
37
|
+
:runtime => 101,
|
38
|
+
:showtimes => [
|
39
|
+
[0] {
|
40
|
+
:datetime => #<DateTime: 2016-08-02T11:30:00-05:00 ((2457603j,59400s,0n),-18000s,2299161j)>
|
41
|
+
},
|
42
|
+
# ...
|
43
|
+
]
|
44
|
+
},
|
45
|
+
# ...
|
46
|
+
=end
|
47
|
+
```
|
48
|
+
|
49
|
+
### `theaters_and_movies` with id and different date
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Fandango.theater_showtimes(
|
53
|
+
:theater_id => theaters_and_movies.first.fetch(:id),
|
54
|
+
:date => Date.tomorrow, # optional, defaults to `Date.today`
|
55
|
+
)
|
35
56
|
```
|
36
57
|
|
37
|
-
##
|
58
|
+
## Compatibility
|
38
59
|
|
39
|
-
|
60
|
+
Development of this gem will only officially support Ruby versions 2.3.0. (see `.travis.yml`)
|
61
|
+
It used to support 1.9.2. and 1.9.3, and it still may work, but it's not tested as of now.
|
62
|
+
Contributions are very welcome, and I will do what I can to help.
|
data/Rakefile
CHANGED
data/fandango.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_runtime_dependency 'nokogiri', '~> 1.0'
|
22
22
|
|
23
23
|
s.add_development_dependency 'awesome_print'
|
24
|
-
s.add_development_dependency '
|
25
|
-
s.add_development_dependency 'minitest'
|
26
|
-
s.add_development_dependency 'vcr'
|
24
|
+
s.add_development_dependency 'webmock'
|
25
|
+
s.add_development_dependency 'minitest'
|
26
|
+
s.add_development_dependency 'vcr'
|
27
27
|
end
|
data/lib/fandango.rb
CHANGED
@@ -3,47 +3,25 @@ require "fandango/version"
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'nokogiri'
|
5
5
|
|
6
|
-
require 'fandango/
|
6
|
+
require 'fandango/api'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def movies_near(postal_code)
|
13
|
-
raise ArgumentError, "postal code cannot be blank" if postal_code.nil? || postal_code == ''
|
14
|
-
response = request(postal_code)
|
15
|
-
raise BadResponse.new(response) unless response.status.first == '200'
|
16
|
-
source = response.read
|
17
|
-
parse source
|
18
|
-
end
|
19
|
-
|
20
|
-
def request(postal_code)
|
21
|
-
open(url_for_postal_code(postal_code))
|
22
|
-
end
|
8
|
+
require 'fandango/theater'
|
9
|
+
require 'fandango/movie'
|
10
|
+
require 'fandango/showtime'
|
23
11
|
|
24
|
-
|
25
|
-
# Return hash of theaters and movies playing at each..
|
26
|
-
def parse(source)
|
27
|
-
Parser.parse(source)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def url_for_postal_code(postal_code)
|
33
|
-
cleaned_postal_code = clean_postal_code(postal_code)
|
34
|
-
"http://www.fandango.com/rss/moviesnearme_#{cleaned_postal_code}.rss"
|
35
|
-
end
|
12
|
+
module Fandango
|
36
13
|
|
37
|
-
|
38
|
-
def clean_postal_code(postal_code)
|
39
|
-
postal_code.to_s.gsub(' ', '')
|
40
|
-
end
|
14
|
+
module_function
|
41
15
|
|
16
|
+
def movies_near(postal_code)
|
17
|
+
MoviesNear.(postal_code)
|
42
18
|
end
|
43
19
|
|
44
|
-
|
45
|
-
|
46
|
-
|
20
|
+
def theater_showtimes(showtimes_link_or_options)
|
21
|
+
if showtimes_link_or_options.is_a?(Hash)
|
22
|
+
TheaterShowtimes.by_id_and_date(showtimes_link_or_options)
|
23
|
+
else
|
24
|
+
TheaterShowtimes.(showtimes_link_or_options)
|
47
25
|
end
|
48
26
|
end
|
49
27
|
|
data/lib/fandango/api.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Fandango
|
2
|
+
autoload :MoviesNear, 'fandango/api/movies_near'
|
3
|
+
autoload :TheaterShowtimes, 'fandango/api/theater_showtimes'
|
4
|
+
|
5
|
+
module API
|
6
|
+
|
7
|
+
class BadResponse < StandardError
|
8
|
+
def initialize(response)
|
9
|
+
super "Bad response:\n#{response.inspect}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Fandango
|
2
|
+
module MoviesNear
|
3
|
+
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def call(postal_code)
|
7
|
+
response = request(postal_code)
|
8
|
+
raise BadResponse.new(response) unless response.status.first == '200'
|
9
|
+
|
10
|
+
xml = response.read
|
11
|
+
Parser.(xml)
|
12
|
+
end
|
13
|
+
|
14
|
+
def request(postal_code)
|
15
|
+
cleaned_postal_code = postal_code.to_s.gsub(' ', '')
|
16
|
+
url_for_postal_code = "http://www.fandango.com/rss/moviesnearme_#{cleaned_postal_code}.rss"
|
17
|
+
open(url_for_postal_code)
|
18
|
+
end
|
19
|
+
|
20
|
+
module Parser
|
21
|
+
|
22
|
+
module_function
|
23
|
+
|
24
|
+
def call(xml)
|
25
|
+
doc = Nokogiri.XML(xml)
|
26
|
+
doc.css('item').map do |item_node|
|
27
|
+
Theater.parse(item_node)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class BadResponse < API::BadResponse; end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Fandango
|
2
|
+
module TheaterShowtimes
|
3
|
+
|
4
|
+
BASE_URL = 'http://www.fandango.com/theater_%{theater_id}/theaterpage?date=%{date}'
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def call(showtimes_link)
|
9
|
+
response = request(showtimes_link)
|
10
|
+
raise BadResponse.new(response) unless response.status.first == '200'
|
11
|
+
|
12
|
+
html = response.read
|
13
|
+
Parser.(html)
|
14
|
+
end
|
15
|
+
|
16
|
+
def by_id_and_date(theater_id:, date: Date.today)
|
17
|
+
url = BASE_URL % {:theater_id => theater_id, :date => date}
|
18
|
+
call url
|
19
|
+
end
|
20
|
+
|
21
|
+
def request(showtimes_link)
|
22
|
+
open(showtimes_link)
|
23
|
+
end
|
24
|
+
|
25
|
+
module Parser
|
26
|
+
|
27
|
+
module_function
|
28
|
+
|
29
|
+
def call(html)
|
30
|
+
doc = Nokogiri.HTML(html)
|
31
|
+
doc.css('.showtimes-movie-container').map do |movie_node|
|
32
|
+
movie = Movie.parse(movie_node)
|
33
|
+
movie[:showtimes] =
|
34
|
+
movie_node.at_css('.showtimes-times').css('a').map do |showtime_node|
|
35
|
+
Showtime.parse(showtime_node)
|
36
|
+
end
|
37
|
+
movie
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class BadResponse < API::BadResponse; end
|
46
|
+
|
47
|
+
end
|
data/lib/fandango/movie.rb
CHANGED
@@ -1,29 +1,45 @@
|
|
1
1
|
module Fandango
|
2
2
|
module Movie
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
# Return array of movie attributes.
|
7
|
-
def parse(description_node)
|
8
|
-
description_node.css('li').map do |li|
|
9
|
-
{
|
10
|
-
title: parse_title(li),
|
11
|
-
id: parse_id(li),
|
12
|
-
}
|
13
|
-
end
|
14
|
-
end
|
4
|
+
module_function
|
15
5
|
|
16
|
-
|
6
|
+
def parse(node)
|
7
|
+
a_tag = node.at_css('a.showtimes-movie-title') || node.at_css('a')
|
8
|
+
hash = {
|
9
|
+
title: parse_title(a_tag),
|
10
|
+
id: parse_id(a_tag),
|
11
|
+
}
|
17
12
|
|
18
|
-
|
19
|
-
|
13
|
+
if a_tag.attr(:class)&.include?('showtimes-movie-title')
|
14
|
+
hash[:runtime] = parse_runtime(node)
|
20
15
|
end
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
hash
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_title(a_tag)
|
21
|
+
a_tag.content
|
22
|
+
end
|
23
|
+
|
24
|
+
# E.g. '141081' in fandango.com/the+adventures+of+tintin+3d_141081/movietimes
|
25
|
+
def parse_id(a_tag)
|
26
|
+
a_tag['href'].match(%r{fandango\.com/.*_(?<id>\d+)/})[:id]
|
27
|
+
end
|
26
28
|
|
29
|
+
# <div class="showtimes-movie-rating-runtime">
|
30
|
+
# <!-- Display rating -->
|
31
|
+
# R ,
|
32
|
+
# <!-- Display runtime -->
|
33
|
+
# 1 hr 41 min
|
34
|
+
# </div>
|
35
|
+
def parse_runtime(node)
|
36
|
+
rating_runtime = node.at_css('.showtimes-movie-rating-runtime')
|
37
|
+
%r{(?<hour>\d+)\s+hr\s+(?<min>\d+)} =~ rating_runtime.content
|
38
|
+
begin
|
39
|
+
Integer(hour) * 60 + Integer(min)
|
40
|
+
rescue TypeError
|
41
|
+
#puts rating_runtime
|
42
|
+
end
|
27
43
|
end
|
28
44
|
|
29
45
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fandango
|
2
|
+
module Showtime
|
3
|
+
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def parse(node)
|
7
|
+
{
|
8
|
+
datetime: parse_datetime(node),
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_datetime(node)
|
13
|
+
datetime_str = node.at_css('time').attr('datetime')
|
14
|
+
DateTime.parse(datetime_str)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/fandango/theater.rb
CHANGED
@@ -1,49 +1,58 @@
|
|
1
1
|
module Fandango
|
2
2
|
module Theater
|
3
3
|
|
4
|
-
|
4
|
+
module_function
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
end
|
6
|
+
def parse(item_node)
|
7
|
+
hash = {}
|
9
8
|
|
10
|
-
|
11
|
-
description_node ||= Fandango::Parser.parse_description(item_node)
|
12
|
-
name = parse_name(item_node)
|
13
|
-
id = parse_id(item_node)
|
14
|
-
address = parse_address(description_node)
|
15
|
-
postal_code = parse_postal_code(address)
|
16
|
-
|
17
|
-
{
|
18
|
-
name: name,
|
19
|
-
id: id,
|
20
|
-
address: address,
|
21
|
-
postal_code: postal_code,
|
22
|
-
}
|
23
|
-
end
|
9
|
+
description_node = parse_description_node(item_node)
|
24
10
|
|
25
|
-
|
11
|
+
hash[:name] = parse_name(item_node)
|
12
|
+
hash[:id] = parse_id(item_node)
|
13
|
+
hash[:address] = parse_address(description_node)
|
14
|
+
hash[:postal_code] = parse_postal_code(hash[:address])
|
15
|
+
hash[:showtimes_link] = parse_showtimes_link(item_node)
|
16
|
+
hash[:movies] = parse_movies(description_node)
|
26
17
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
18
|
+
hash
|
19
|
+
end
|
30
20
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
21
|
+
# Description content is in the form of HTML wrapped in CDATA.
|
22
|
+
# Parse it and return a parsed Nokogiri node.
|
23
|
+
def parse_description_node(item_node)
|
24
|
+
cdata = item_node.at_css('description')
|
25
|
+
Nokogiri::HTML(cdata.content)
|
26
|
+
end
|
38
27
|
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
def parse_name(item_node)
|
29
|
+
item_node.at_css('title').content.strip
|
30
|
+
end
|
42
31
|
|
43
|
-
|
44
|
-
|
45
|
-
|
32
|
+
# E.g. 'aaicu' in http://www.fandango.com/northpark7_aaicu/theaterpage
|
33
|
+
def parse_id(item_node)
|
34
|
+
item_node.
|
35
|
+
at_css('link').
|
36
|
+
content.
|
37
|
+
match(%r{fandango\.com/.*_(?<id>.*)/theaterpage})[:id]
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_address(description_node)
|
41
|
+
description_node.at_css('p').content
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_postal_code(address)
|
45
|
+
address.match(/(?<postal_code>\d+)$/)[:postal_code]
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_showtimes_link(item_node)
|
49
|
+
item_node.at_css('link').content.strip
|
50
|
+
end
|
46
51
|
|
52
|
+
def parse_movies(description_node)
|
53
|
+
description_node.css('li').map do |li|
|
54
|
+
Movie.parse(li)
|
55
|
+
end
|
47
56
|
end
|
48
57
|
|
49
58
|
end
|