cineworld_uk 1.0.5 → 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 +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +64 -0
- data/README.md +2 -1
- data/cineworld_uk.gemspec +3 -3
- data/lib/cineworld_uk/cinema.rb +60 -69
- data/lib/cineworld_uk/film.rb +25 -7
- data/lib/cineworld_uk/internal/film_with_screenings_parser.rb +29 -71
- data/lib/cineworld_uk/internal/name_parser.rb +20 -18
- data/lib/cineworld_uk/internal/screening_parser.rb +132 -0
- data/lib/cineworld_uk/internal/titleize.rb +19 -19
- data/lib/cineworld_uk/internal/website.rb +33 -0
- data/lib/cineworld_uk/internal/whatson_parser.rb +44 -0
- data/lib/cineworld_uk/screening.rb +65 -20
- data/lib/cineworld_uk/version.rb +2 -2
- data/lib/cineworld_uk.rb +4 -0
- data/test/fixture_updater.rb +64 -0
- data/test/fixtures/cinemas.html +134 -41
- data/test/fixtures/{cinemas/bury-st-edmunds.html → information/brighton.html} +488 -437
- data/test/fixtures/{cinemas → information}/bristol.html +463 -410
- data/test/fixtures/whatson/brighton/film_first.html +775 -0
- data/test/fixtures/whatson/brighton/film_last.html +52 -0
- data/test/fixtures/whatson/brighton/film_second.html +645 -0
- data/test/fixtures/whatson/brighton.html +3564 -2690
- data/test/fixtures/whatson/glasgow-imax-at-gsc/film_first.html +140 -0
- data/test/fixtures/whatson/the-o2-greenwich/film_first.html +1242 -0
- data/test/lib/cineworld_uk/cinema_test.rb +104 -301
- data/test/lib/cineworld_uk/film_test.rb +49 -2
- data/test/lib/cineworld_uk/internal/film_with_screenings_parser_test.rb +83 -81
- data/test/lib/cineworld_uk/internal/titleize_test.rb +12 -5
- data/test/lib/cineworld_uk/internal/website_test.rb +57 -0
- data/test/lib/cineworld_uk/internal/whatson_parser_test.rb +58 -0
- data/test/lib/cineworld_uk/screening_test.rb +155 -23
- data/test/lib/cineworld_uk/version_test.rb +1 -1
- data/test/test_helper.rb +3 -1
- metadata +30 -33
- data/test/fixtures/cinemas/brighton.html +0 -8
- data/test/fixtures/cinemas/chelsea.html +0 -1030
- data/test/fixtures/cinemas/glasgow-imax-at-gsc.html +0 -916
- data/test/fixtures/cinemas/the-o2-grenwich.html +0 -1191
- data/test/fixtures/whatson/brighton/gravity.html +0 -2129
- data/test/fixtures/whatson/glasgow-imax-at-gsc/the-hunger-games-catching-fire.html +0 -498
- data/test/fixtures/whatson/glasgow-imax-at-gsc-cinema.html +0 -3160
- data/test/fixtures/whatson/the-o2-greenwich/gravity.html +0 -784
- data/test/fixtures/whatson/the-o2-greenwich/the-hobbit-desolation-of-smaug.html +0 -764
- data/test/fixtures/whatson/the-o2-greenwich.html +0 -6854
- data/test/fixtures/whatson/wandsworth.html +0 -13729
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edcee9dcbbce90d73acbbb0ccc5650811bb7f931
|
4
|
+
data.tar.gz: 8454e532aa948af962692ce9d1add716b79dd405
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55369938b4df8ad874982a708dccb985b48f1514d2a6210e24371bcdf66f575dde627456cb4567fda757d37759bb9b0d7d6cccb8e2ed1865e2f70d7134ebefcf
|
7
|
+
data.tar.gz: 9d79dc209c5091269612dc732388d5160876defdaeef29ec7820656e5c1c3f32203144194dd5cfbc44b85ef5a1c041456a2a7974ff132941e79e9a894f6a3fd7
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,67 @@
|
|
1
|
+
## 2.0.0 _25th July 2014_
|
2
|
+
|
3
|
+
Bugfix
|
4
|
+
|
5
|
+
- Cineworld changed their markup
|
6
|
+
|
7
|
+
Features
|
8
|
+
|
9
|
+
- Less logic in the Cinema class. Moved to `Film` and `Screening`.
|
10
|
+
- Introduce `Internal::Website` class for all website comms
|
11
|
+
- Rewrite Parsers and tests to be less exact but less fragile
|
12
|
+
- Screening now uses the `FilmWithScreeningsParser`
|
13
|
+
- Build `WhatsonParser` to break into 'films with screenings'
|
14
|
+
- `FilmWithScreenings` then uses `ScreeningParser` class to get individual screening info
|
15
|
+
- `ruby test/fixture_updator.rb` produces new fixtures from the live website
|
16
|
+
- it will break a few tests when run and committed but most should be ok
|
17
|
+
- documentation
|
18
|
+
|
19
|
+
Under the hood
|
20
|
+
|
21
|
+
- Remove dependancy on HTTParty
|
22
|
+
- Travis gets Ruby 2.1.2
|
23
|
+
- General Rubocop improvements
|
24
|
+
|
25
|
+
## 1.0.6 _28th Feb 2014_
|
26
|
+
|
27
|
+
Bugfix
|
28
|
+
|
29
|
+
- UTF encoding in Titleize internal class for ruby 1.9.3
|
30
|
+
|
31
|
+
## 1.0.5 _28th Feb 2014_
|
32
|
+
|
33
|
+
Bugfix
|
34
|
+
|
35
|
+
- Vestigal require of titleize gem
|
36
|
+
|
37
|
+
## 1.0.4 _27th Feb 2014_
|
38
|
+
|
39
|
+
Under the hood
|
40
|
+
|
41
|
+
- Standardizing film names using modified titlecase from `titlecase` gem
|
42
|
+
- Film name parsing now moved to seperate class
|
43
|
+
- rake console task added
|
44
|
+
- MRI 2.1.0 support on Travis CI
|
45
|
+
|
46
|
+
## 1.0.3, _16th Jan 2014_
|
47
|
+
|
48
|
+
Additional methods
|
49
|
+
|
50
|
+
- cinema#full_name including cinema brand
|
51
|
+
- tidy up cinema naming to use colons
|
52
|
+
|
53
|
+
## 1.0.2, _3rd Jan 2014_
|
54
|
+
|
55
|
+
Under the hood
|
56
|
+
|
57
|
+
- deal with HFR screenings, bloody hobbitses
|
58
|
+
|
59
|
+
## 1.0.1, _3rd Jan 2014_
|
60
|
+
|
61
|
+
External interface
|
62
|
+
|
63
|
+
- screening#variant for spelling win, #varient maintained for compatability
|
64
|
+
|
1
65
|
## 1.0.0, _6th Dec 2013_
|
2
66
|
|
3
67
|
First ready-for-public release
|
data/README.md
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
A simple gem to parse the [Cineworld UK website](http://cineworld.co.uk) and spit out useful formatted info.
|
4
4
|
|
5
|
-
[](http://badge.fury.io/rb/cineworld_uk)
|
6
6
|
[](https://codeclimate.com/github/andycroll/cineworld_uk)
|
7
7
|
[](https://travis-ci.org/andycroll/cineworld_uk)
|
8
|
+
[](http://inch-ci.org/github/andycroll/cineworld_uk)
|
8
9
|
|
9
10
|
## Installation
|
10
11
|
|
data/cineworld_uk.gemspec
CHANGED
@@ -18,11 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'minitest-reporters'
|
23
|
+
spec.add_development_dependency 'rake'
|
23
24
|
spec.add_development_dependency 'webmock'
|
24
25
|
|
25
|
-
spec.add_runtime_dependency 'httparty'
|
26
26
|
spec.add_runtime_dependency 'nokogiri'
|
27
27
|
spec.add_runtime_dependency 'tzinfo'
|
28
28
|
spec.add_runtime_dependency 'tzinfo-data'
|
data/lib/cineworld_uk/cinema.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
module CineworldUk
|
2
|
-
|
3
2
|
# The object representing a cinema on the Cineworld UK website
|
4
3
|
class Cinema
|
5
|
-
|
6
4
|
# @return [String] the brand of the cinema
|
7
5
|
attr_reader :brand
|
8
|
-
# @return [Integer] the numeric id of the cinema on the
|
6
|
+
# @return [Integer] the numeric id of the cinema on the Cineworld website
|
9
7
|
attr_reader :id
|
10
8
|
# @return [String] the name of the cinema
|
11
9
|
attr_reader :name
|
@@ -20,8 +18,8 @@ module CineworldUk
|
|
20
18
|
def initialize(id, name)
|
21
19
|
@brand = 'Cineworld'
|
22
20
|
@id = id.to_i
|
23
|
-
@name = name.gsub('London - ','').gsub(' - ', ': ')
|
24
|
-
@slug = @name.downcase.gsub(/[^0-9a-z ]/,'').gsub(/\s+/, '-')
|
21
|
+
@name = name.gsub('London - ', '').gsub(' - ', ': ')
|
22
|
+
@slug = @name.downcase.gsub(/[^0-9a-z ]/, '').gsub(/\s+/, '-')
|
25
23
|
@url = "http://www.cineworld.co.uk/cinemas/#{@id}/information"
|
26
24
|
end
|
27
25
|
|
@@ -29,32 +27,39 @@ module CineworldUk
|
|
29
27
|
# @return [Array<CineworldUk::Cinema>]
|
30
28
|
# @example
|
31
29
|
# CineworldUk::Cinema.all
|
32
|
-
# #=> [<CineworldUk::Cinema
|
30
|
+
# #=> [<CineworldUk::Cinema>, <CineworldUk::Cinema>, ...]
|
33
31
|
def self.all
|
34
|
-
|
32
|
+
cinemas_doc.css('#cinemaId option[value]').map do |option|
|
35
33
|
new option['value'], option.text
|
36
34
|
end[1..-1]
|
37
35
|
end
|
38
36
|
|
39
37
|
# Find a single cinema
|
40
|
-
# @param [Integer, String] id the cinema id
|
38
|
+
# @param [Integer, String] id the cinema id as used on the website
|
41
39
|
# @return [CineworldUk::Cinema, nil]
|
42
40
|
# @example
|
43
41
|
# CineworldUk::Cinema.find('3')
|
44
|
-
# #=> <CineworldUk::Cinema brand="Cineworld"
|
42
|
+
# #=> <CineworldUk::Cinema brand="Cineworld"
|
43
|
+
# name="Brighton"
|
44
|
+
# slug="brighton"
|
45
|
+
# id=3
|
46
|
+
# url="...">
|
45
47
|
def self.find(id)
|
46
|
-
id
|
47
|
-
return nil unless id > 0
|
48
|
-
|
49
|
-
all.select { |cinema| cinema.id == id }[0]
|
48
|
+
all.select { |cinema| cinema.id == id.to_i }[0]
|
50
49
|
end
|
51
50
|
|
52
51
|
# Address of the cinema
|
53
52
|
# @return [Hash] of different address parts
|
54
53
|
# @example
|
55
|
-
# cinema = CineworldUk::Cinema.find(
|
54
|
+
# cinema = CineworldUk::Cinema.find(3)
|
56
55
|
# cinema.adr
|
57
|
-
# #=> {
|
56
|
+
# #=> {
|
57
|
+
# street_address: '44-47 Gardner Street',
|
58
|
+
# extended_address: 'North Laine',
|
59
|
+
# locality: 'Brighton',
|
60
|
+
# postal_code: 'BN1 1UN',
|
61
|
+
# country_name: 'United Kingdom'
|
62
|
+
# }
|
58
63
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
59
64
|
def adr
|
60
65
|
{
|
@@ -80,20 +85,17 @@ module CineworldUk
|
|
80
85
|
# #=> nil
|
81
86
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
82
87
|
def extended_address
|
83
|
-
|
88
|
+
remaining_address * ', ' unless remaining_address.empty?
|
84
89
|
end
|
85
90
|
|
86
91
|
# Films with showings scheduled at this cinema
|
87
|
-
# @return [Array<
|
92
|
+
# @return [Array<CineworldUk::Film>]
|
88
93
|
# @example
|
89
|
-
# cinema =
|
94
|
+
# cinema = CineworldUk::Cinema.find('71')
|
90
95
|
# cinema.films
|
91
|
-
# #=> [<
|
96
|
+
# #=> [<CineworldUk::Film>, <CineworldUk::Film>, ...]
|
92
97
|
def films
|
93
|
-
|
94
|
-
parser = CineworldUk::Internal::FilmWithScreeningsParser.new node.to_s
|
95
|
-
parser.film_name.length > 0 ? CineworldUk::Film.new(parser.film_name) : nil
|
96
|
-
end.compact.uniq
|
98
|
+
Film.at(id)
|
97
99
|
end
|
98
100
|
|
99
101
|
# The name of the cinema including the brand
|
@@ -114,7 +116,11 @@ module CineworldUk
|
|
114
116
|
# #=> 'Brighton'
|
115
117
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
116
118
|
def locality
|
117
|
-
adr_has_region? && !adr_in_london?
|
119
|
+
if adr_has_region? && !adr_in_london?
|
120
|
+
adr_array[-2]
|
121
|
+
else
|
122
|
+
adr_array[-1]
|
123
|
+
end
|
118
124
|
end
|
119
125
|
|
120
126
|
# Post code of the cinema
|
@@ -125,7 +131,7 @@ module CineworldUk
|
|
125
131
|
# #=> 'BN2 5UF'
|
126
132
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
127
133
|
def postal_code
|
128
|
-
|
134
|
+
last_adr_line_array[-2..-1] * ' '
|
129
135
|
end
|
130
136
|
|
131
137
|
# The region (county) of the cinema if provided
|
@@ -136,7 +142,7 @@ module CineworldUk
|
|
136
142
|
# #=> 'East Sussex'
|
137
143
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
138
144
|
def region
|
139
|
-
|
145
|
+
last_adr_line_non_postal_code if adr_has_region? && !adr_in_london?
|
140
146
|
end
|
141
147
|
|
142
148
|
# All planned screenings
|
@@ -144,16 +150,9 @@ module CineworldUk
|
|
144
150
|
# @example
|
145
151
|
# cinema = CineworldUk::Cinema.find(3)
|
146
152
|
# cinema.screenings
|
147
|
-
# # => [<CineworldUk::Screening
|
153
|
+
# # => [<CineworldUk::Screening>, <CineworldUk::Screening>, ...]
|
148
154
|
def screenings
|
149
|
-
|
150
|
-
parser = CineworldUk::Internal::FilmWithScreeningsParser.new node.to_s
|
151
|
-
parser.showings.map do |screening_type, times|
|
152
|
-
times.map do |array|
|
153
|
-
CineworldUk::Screening.new parser.film_name, self.name, array[0], array[1], screening_type
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end.flatten
|
155
|
+
Screening.at(id)
|
157
156
|
end
|
158
157
|
|
159
158
|
# The street adress of the cinema
|
@@ -164,65 +163,57 @@ module CineworldUk
|
|
164
163
|
# #=> 'Brighton Marina'
|
165
164
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
166
165
|
def street_address
|
167
|
-
|
166
|
+
adr_parts[0]
|
168
167
|
end
|
169
168
|
|
170
169
|
private
|
171
170
|
|
172
|
-
def self.
|
173
|
-
@
|
174
|
-
end
|
175
|
-
|
176
|
-
def self.cinemas_response
|
177
|
-
@cinemas_response ||= HTTParty.get('http://www.cineworld.co.uk/cinemas')
|
178
|
-
end
|
179
|
-
|
180
|
-
def address_parts
|
181
|
-
@address_parts ||= parsed_information.css('address.marker').to_s.split('<br>')[-2].split(',').map(&:strip)
|
171
|
+
def self.cinemas_doc
|
172
|
+
@cinemas_doc ||= Nokogiri::HTML(website.cinemas)
|
182
173
|
end
|
183
174
|
|
184
|
-
def
|
185
|
-
|
175
|
+
def self.website
|
176
|
+
@website ||= CineworldUk::Internal::Website.new
|
186
177
|
end
|
187
178
|
|
188
|
-
def
|
189
|
-
|
179
|
+
def adr_array
|
180
|
+
adr_parts[0..-2] << last_adr_line_non_postal_code
|
190
181
|
end
|
191
182
|
|
192
|
-
def
|
193
|
-
|
183
|
+
def adr_content
|
184
|
+
information_doc.css('address.marker').to_s
|
194
185
|
end
|
195
186
|
|
196
|
-
def
|
197
|
-
|
187
|
+
def adr_parts
|
188
|
+
@parts ||= adr_content.split('<br>')[-2].split(',').map(&:strip)
|
198
189
|
end
|
199
190
|
|
200
|
-
def
|
201
|
-
|
191
|
+
def adr_in_london?
|
192
|
+
last_adr_line_non_postal_code == 'London'
|
202
193
|
end
|
203
194
|
|
204
|
-
def
|
205
|
-
|
195
|
+
def adr_has_region?
|
196
|
+
last_adr_line_non_postal_code != name
|
206
197
|
end
|
207
198
|
|
208
|
-
def
|
209
|
-
|
199
|
+
def last_adr_line_array
|
200
|
+
adr_parts[-1].split(' ')
|
210
201
|
end
|
211
202
|
|
212
|
-
def
|
213
|
-
|
203
|
+
def last_adr_line_non_postal_code
|
204
|
+
last_adr_line_array[0..-3] * ' '
|
214
205
|
end
|
215
206
|
|
216
|
-
def
|
217
|
-
@
|
207
|
+
def information_doc
|
208
|
+
@information_doc ||= begin
|
209
|
+
Nokogiri::HTML(CineworldUk::Internal::Website.new.information(@id))
|
210
|
+
end
|
218
211
|
end
|
219
212
|
|
220
213
|
def remaining_address
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
def whatson_response
|
225
|
-
@whatson_response ||= HTTParty.get("http://www.cineworld.co.uk/whatson?cinema=#{@id}")
|
214
|
+
adr_array.delete_if do |e|
|
215
|
+
e == street_address || e == locality || e == region
|
216
|
+
end
|
226
217
|
end
|
227
218
|
end
|
228
219
|
end
|
data/lib/cineworld_uk/film.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module CineworldUk
|
2
|
-
|
3
2
|
# The object representing a film on the Cineworld UK website
|
4
3
|
class Film
|
5
4
|
include Comparable
|
@@ -13,14 +12,23 @@ module CineworldUk
|
|
13
12
|
# @return [CineworldUk::Film]
|
14
13
|
def initialize(name)
|
15
14
|
@name = name
|
16
|
-
@slug = name.downcase.gsub(/[^0-9a-z ]/,'').gsub(/\s+/, '-')
|
15
|
+
@slug = name.downcase.gsub(/[^0-9a-z ]/, '').gsub(/\s+/, '-')
|
16
|
+
end
|
17
|
+
|
18
|
+
# All currently listed films showing at a cinema
|
19
|
+
# @param [Integer] cinema_id id of the cinema on the website
|
20
|
+
# @return [Array<CineworldUk::Film>]
|
21
|
+
def self.at(cinema_id)
|
22
|
+
whatson_parser(cinema_id).films_with_screenings.map do |html|
|
23
|
+
new(screenings_parser(html).film_name)
|
24
|
+
end
|
17
25
|
end
|
18
26
|
|
19
27
|
# Allows sort on objects
|
20
28
|
# @param [CineworldUk::Film] other another film object
|
21
29
|
# @return [Integer] -1, 0 or 1
|
22
|
-
def <=>
|
23
|
-
|
30
|
+
def <=>(other)
|
31
|
+
slug <=> other.slug
|
24
32
|
end
|
25
33
|
|
26
34
|
# Check an object is the same as another object.
|
@@ -28,20 +36,30 @@ module CineworldUk
|
|
28
36
|
# @return [Boolean] True if both objects are the same exact object, or if
|
29
37
|
# they are of the same type and share an equal slug
|
30
38
|
# @note Guided by http://woss.name/2011/01/20/equality-comparison-and-ordering-in-ruby/
|
31
|
-
def eql?
|
39
|
+
def eql?(other)
|
32
40
|
self.class == other.class && self == other
|
33
41
|
end
|
34
42
|
|
35
43
|
# Generates hash of slug in order to allow two records of the same type and
|
36
44
|
# id to work with something like:
|
37
45
|
#
|
38
|
-
# [
|
46
|
+
# [Film.new('ABC'), Film.new('DEF')] & [Film.new('DEF'), Film.new('GHI')]
|
39
47
|
# #=> [ Film.new('DEF') ]
|
40
48
|
#
|
41
49
|
# @return [Integer] hash of slug
|
42
50
|
# @note Guided by http://woss.name/2011/01/20/equality-comparison-and-ordering-in-ruby/
|
43
51
|
def hash
|
44
|
-
|
52
|
+
slug.hash
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def self.screenings_parser(html)
|
58
|
+
CineworldUk::Internal::FilmWithScreeningsParser.new(html)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.whatson_parser(id)
|
62
|
+
CineworldUk::Internal::WhatsonParser.new(id)
|
45
63
|
end
|
46
64
|
end
|
47
65
|
end
|
@@ -1,102 +1,60 @@
|
|
1
1
|
module CineworldUk
|
2
|
-
|
3
2
|
# Internal utility classes: Do not use
|
4
3
|
# @api private
|
5
4
|
module Internal
|
6
|
-
|
7
5
|
# Parses a chunk of HTML to derive movie showing data
|
8
6
|
class FilmWithScreeningsParser
|
7
|
+
# css selector for film name
|
8
|
+
FILM_NAME_CSS = 'h3.h1 a[href*=whatson]'
|
9
|
+
# css selector for performances
|
10
|
+
PERFORMANCES_CSS = '.schedule .performances > li'
|
9
11
|
|
10
12
|
# @param [String] film_html a chunk of html
|
11
13
|
def initialize(film_html)
|
12
|
-
@
|
14
|
+
@film_html = film_html.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
# The cinema id
|
18
|
+
# @return [String]
|
19
|
+
def cinema_id
|
20
|
+
name_doc.to_s.match(/cinema=(\d+)/)[1].to_i
|
13
21
|
end
|
14
22
|
|
15
23
|
# The film name
|
16
24
|
# @return [String]
|
17
25
|
def film_name
|
18
|
-
|
26
|
+
name_doc.children[0].to_s
|
19
27
|
end
|
20
28
|
|
21
|
-
#
|
22
|
-
# @return [Hash]
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
tz = TZInfo::Timezone.get('Europe/London')
|
29
|
-
@nokogiri_html.css('.schedule .performances > li').inject({}) do |result, li|
|
30
|
-
key = performance_variant(li)
|
31
|
-
|
32
|
-
if has_bookable_link_node?(li)
|
33
|
-
time_array = performance_date_array(li) + performance_time_array(li)
|
34
|
-
time = tz.local_to_utc(Time.utc(*time_array))
|
35
|
-
result.merge(key => (result[key] || []) << [time, booking_url(li)])
|
36
|
-
else
|
37
|
-
result
|
38
|
-
end
|
39
|
-
end
|
29
|
+
# attributes of all the screenings
|
30
|
+
# @return [Array<Hash>]
|
31
|
+
def to_a
|
32
|
+
performances_doc.map do |node|
|
33
|
+
next unless screening_parser_hash(node)
|
34
|
+
screening_parser_hash(node).merge(film_hash)
|
35
|
+
end.compact
|
40
36
|
end
|
41
37
|
|
42
38
|
private
|
43
39
|
|
44
|
-
def
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
def dbox?(node)
|
49
|
-
node.css('.tooltip-box .icon-service-dbox').count > 0
|
50
|
-
end
|
51
|
-
|
52
|
-
def dimension(node)
|
53
|
-
node.css('.tooltip-box .icon-service-twod, .tooltip-box .icon-service-thrd').text
|
54
|
-
end
|
55
|
-
|
56
|
-
def has_bookable_link_node?(node)
|
57
|
-
performance_link(node) != nil
|
58
|
-
end
|
59
|
-
|
60
|
-
def imax?(node)
|
61
|
-
node.css('.tooltip-box .icon-service-imax').count > 0
|
62
|
-
end
|
63
|
-
|
64
|
-
def hfr?(node)
|
65
|
-
node.css('.tooltip-box .icon-service-hfr').count > 0
|
66
|
-
end
|
67
|
-
|
68
|
-
def original_name
|
69
|
-
@original_name ||= @nokogiri_html.css('.span5 h1 a,.span7 h1 a, .span7 h1').children[0].to_s
|
70
|
-
end
|
71
|
-
|
72
|
-
def performance_date_array(node)
|
73
|
-
if has_bookable_link_node?(node)
|
74
|
-
match = performance_link_text(node).match(/date\=(\d{4})(\d{2})(\d{2})/)
|
75
|
-
[match[1], match[2], match[3]]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def performance_link(node)
|
80
|
-
node.css('a.performance').first
|
40
|
+
def doc
|
41
|
+
@doc ||= Nokogiri::HTML(@film_html)
|
81
42
|
end
|
82
43
|
|
83
|
-
def
|
84
|
-
|
44
|
+
def film_hash
|
45
|
+
@film_hash ||= { cinema_id: cinema_id, film_name: film_name }
|
85
46
|
end
|
86
47
|
|
87
|
-
def
|
88
|
-
|
48
|
+
def name_doc
|
49
|
+
@name_doc ||= doc.css(FILM_NAME_CSS)
|
89
50
|
end
|
90
51
|
|
91
|
-
def
|
92
|
-
|
93
|
-
match = performance_link_text(node).match(/time\=(\d{2})\:(\d{2})/)
|
94
|
-
[match[1], match[2]]
|
95
|
-
end
|
52
|
+
def performances_doc
|
53
|
+
@performances_doc ||= doc.css(PERFORMANCES_CSS)
|
96
54
|
end
|
97
55
|
|
98
|
-
def
|
99
|
-
|
56
|
+
def screening_parser_hash(node)
|
57
|
+
ScreeningParser.new(node).to_hash
|
100
58
|
end
|
101
59
|
end
|
102
60
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
module CineworldUk
|
2
|
-
|
3
2
|
# Internal utility classes: Do not use
|
4
3
|
# @api private
|
5
4
|
module Internal
|
6
|
-
|
7
5
|
# Parses a string to derive a standardized movie title
|
8
6
|
class NameParser
|
9
|
-
|
7
|
+
# @return [String] the original name
|
10
8
|
attr_reader :original_name
|
11
9
|
|
10
|
+
# @param [String] name original film name
|
12
11
|
def initialize(name)
|
13
12
|
@original_name = name
|
14
13
|
@name = name
|
@@ -17,15 +16,15 @@ module CineworldUk
|
|
17
16
|
# Process the name and return the final string
|
18
17
|
# @return [String]
|
19
18
|
def standardize
|
20
|
-
strip_and_squeeze
|
21
|
-
ampersands_into_text
|
22
|
-
into_ampersand_if_second_to_last
|
23
|
-
remove_indian_languages
|
24
|
-
remove_screening_details
|
25
|
-
replace_non_film_prefix
|
26
|
-
remove_newlines
|
27
|
-
remove_dates
|
28
|
-
title_case
|
19
|
+
strip_and_squeeze
|
20
|
+
.ampersands_into_text
|
21
|
+
.into_ampersand_if_second_to_last
|
22
|
+
.remove_indian_languages
|
23
|
+
.remove_screening_details
|
24
|
+
.replace_non_film_prefix
|
25
|
+
.remove_newlines
|
26
|
+
.remove_dates
|
27
|
+
.title_case
|
29
28
|
to_s
|
30
29
|
end
|
31
30
|
|
@@ -48,9 +47,9 @@ module CineworldUk
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def remove_indian_languages
|
51
|
-
languages =
|
50
|
+
languages = %w(Malayalam Tamil)
|
52
51
|
|
53
|
-
_remove(/\((#{languages*'|'})\)/i)
|
52
|
+
_remove(/\((#{languages * '|'})\)/i)
|
54
53
|
self
|
55
54
|
end
|
56
55
|
|
@@ -61,7 +60,7 @@ module CineworldUk
|
|
61
60
|
end
|
62
61
|
|
63
62
|
def remove_dates
|
64
|
-
_remove(
|
63
|
+
_remove(%r(-? \d{1,2}/\d{1,2}/\d{2,4}))
|
65
64
|
self
|
66
65
|
end
|
67
66
|
|
@@ -73,15 +72,18 @@ module CineworldUk
|
|
73
72
|
def replace_non_film_prefix
|
74
73
|
_replace 'Bolshoi Ballet Live -', 'Bolshoi:'
|
75
74
|
|
76
|
-
|
75
|
+
if @name.match(/\- NT .+ encore/)
|
76
|
+
@name = 'National Theatre: ' + @name.gsub(/\- NT .+ encore/, '')
|
77
|
+
end
|
78
|
+
|
77
79
|
_replace 'NT Live:', 'National Theatre:'
|
78
80
|
|
79
81
|
_replace 'MET Opera -', 'Met Opera:'
|
80
82
|
_replace 'Royal Ballet Live:', 'Royal Ballet:'
|
81
83
|
|
82
84
|
# fill out Royal Opera House
|
83
|
-
|
84
|
-
@name = 'Royal Opera House: ' +
|
85
|
+
@name.match(/Royal Opera Live\: (.+) \-.+/) do |match|
|
86
|
+
@name = 'Royal Opera House: ' + match[1]
|
85
87
|
end
|
86
88
|
_replace 'Royal Opera Live:', 'Royal Opera House:'
|
87
89
|
|