odeon_uk 2.0.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -1
  3. data/CHANGELOG.md +6 -0
  4. data/Rakefile +29 -0
  5. data/lib/odeon_uk/api/cinema.rb +62 -0
  6. data/lib/odeon_uk/api/response.rb +55 -0
  7. data/lib/odeon_uk/api/screenings.rb +89 -0
  8. data/lib/odeon_uk/cinema.rb +53 -114
  9. data/lib/odeon_uk/configuration.rb +21 -0
  10. data/lib/odeon_uk/html/cinema.rb +101 -0
  11. data/lib/odeon_uk/html/parser/film_with_screenings.rb +160 -0
  12. data/lib/odeon_uk/html/screenings.rb +38 -0
  13. data/lib/odeon_uk/{internal → html}/website.rb +1 -1
  14. data/lib/odeon_uk/internal/title_sanitizer.rb +1 -0
  15. data/lib/odeon_uk/screening.rb +7 -15
  16. data/lib/odeon_uk/version.rb +2 -2
  17. data/lib/odeon_uk.rb +11 -4
  18. data/odeon_uk.gemspec +2 -0
  19. data/rake/fixture_creator.rb +98 -0
  20. data/test/fixtures/api/all_cinemas.plist +0 -0
  21. data/test/fixtures/api/app_init.plist +0 -0
  22. data/test/fixtures/api/film_times/71-100747.plist +0 -0
  23. data/test/fixtures/api/film_times/71-100750.plist +0 -0
  24. data/test/fixtures/api/film_times/71-100790.plist +0 -0
  25. data/test/fixtures/api/film_times/71-14646.plist +0 -0
  26. data/test/fixtures/api/film_times/71-14725.plist +0 -0
  27. data/test/fixtures/api/film_times/71-15086.plist +0 -0
  28. data/test/fixtures/api/film_times/71-15096.plist +0 -0
  29. data/test/fixtures/api/film_times/71-15122.plist +0 -0
  30. data/test/fixtures/api/film_times/71-15130.plist +0 -0
  31. data/test/fixtures/api/film_times/71-15141.plist +0 -0
  32. data/test/fixtures/api/film_times/71-15142.plist +0 -0
  33. data/test/fixtures/api/film_times/71-15143.plist +0 -0
  34. data/test/fixtures/api/film_times/71-15144.plist +0 -0
  35. data/test/fixtures/api/film_times/71-15145.plist +0 -0
  36. data/test/fixtures/api/film_times/71-15170.plist +0 -0
  37. data/test/fixtures/api/film_times/71-15172.plist +0 -0
  38. data/test/fixtures/api/film_times/71-15177.plist +0 -0
  39. data/test/fixtures/api/film_times/71-15179.plist +0 -0
  40. data/test/fixtures/api/film_times/71-15182.plist +0 -0
  41. data/test/fixtures/api/film_times/71-15286.plist +0 -0
  42. data/test/fixtures/api/film_times/71-15360.plist +0 -0
  43. data/test/fixtures/api/film_times/71-15586.plist +0 -0
  44. data/test/fixtures/api/film_times/71-15700.plist +0 -0
  45. data/test/fixtures/api/film_times/71-15718.plist +0 -0
  46. data/test/fixtures/api/film_times/71-15768.plist +0 -0
  47. data/test/fixtures/api/film_times/71-15788.plist +0 -0
  48. data/test/fixtures/api/film_times/71-15793.plist +0 -0
  49. data/test/fixtures/api/film_times/71-15794.plist +0 -0
  50. data/test/fixtures/api/film_times/71-15795.plist +0 -0
  51. data/test/fixtures/api/film_times/71-15796.plist +0 -0
  52. data/test/fixtures/api/film_times/71-15799.plist +0 -0
  53. data/test/fixtures/api/film_times/71-15802.plist +0 -0
  54. data/test/fixtures/api/film_times/71-15814.plist +0 -0
  55. data/test/fixtures/api/film_times/71-15817.plist +0 -0
  56. data/test/fixtures/api/film_times/71-15840.plist +0 -0
  57. data/test/fixtures/{cinema/leicester_square.html → html/cinema/105.html} +384 -313
  58. data/test/fixtures/{cinema/bfi_imax.html → html/cinema/211.html} +677 -355
  59. data/test/fixtures/{cinema/brighton.html → html/cinema/71.html} +899 -431
  60. data/test/fixtures/html/showtimes/11-imax.html +170 -0
  61. data/test/fixtures/html/showtimes/171-d-box.html +203 -0
  62. data/test/fixtures/html/showtimes/71-0.html +59 -0
  63. data/test/fixtures/html/showtimes/71.html +2395 -0
  64. data/test/fixtures/{sitemap.html → html/sitemap.html} +264 -352
  65. data/test/lib/odeon_uk/api/cinema_test.rb +149 -0
  66. data/test/lib/odeon_uk/api/response_test.rb +44 -0
  67. data/test/lib/odeon_uk/api/screenings_test.rb +43 -0
  68. data/test/lib/odeon_uk/cinema_test.rb +373 -148
  69. data/test/lib/odeon_uk/configuration_test.rb +29 -0
  70. data/test/lib/odeon_uk/html/cinema_test.rb +149 -0
  71. data/test/lib/odeon_uk/{internal/film_with_screenings_parser_test.rb → html/parser/film_with_screenings_test.rb} +12 -42
  72. data/test/lib/odeon_uk/html/screenings_test.rb +43 -0
  73. data/test/lib/odeon_uk/html/website_test.rb +37 -0
  74. data/test/lib/odeon_uk/screening_test.rb +17 -83
  75. data/test/support/api_fixtures_helper.rb +34 -0
  76. data/test/support/website_fixtures_helper.rb +25 -0
  77. data/test/test_helper.rb +7 -2
  78. metadata +149 -34
  79. data/lib/odeon_uk/film.rb +0 -65
  80. data/lib/odeon_uk/internal/film_with_screenings_parser.rb +0 -159
  81. data/lib/odeon_uk/internal/showtimes_page.rb +0 -36
  82. data/test/fixture_updater.rb +0 -72
  83. data/test/fixtures/showtimes/brighton/film_first.html +0 -92
  84. data/test/fixtures/showtimes/brighton/film_last.html +0 -100
  85. data/test/fixtures/showtimes/brighton.html +0 -2071
  86. data/test/fixtures/showtimes/liverpool_one/film_first_dbox.html +0 -188
  87. data/test/fixtures/showtimes/manchester/film_first_imax.html +0 -182
  88. data/test/lib/odeon_uk/film_test.rb +0 -142
  89. data/test/lib/odeon_uk/internal/showtimes_page_test.rb +0 -51
  90. data/test/lib/odeon_uk/internal/website_test.rb +0 -59
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: odeon_uk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Croll
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-18 00:00:00.000000000 Z
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest-reporters
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: webmock
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: CFPropertyList
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: nokogiri
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -96,33 +124,79 @@ files:
96
124
  - README.md
97
125
  - Rakefile
98
126
  - lib/odeon_uk.rb
127
+ - lib/odeon_uk/api/cinema.rb
128
+ - lib/odeon_uk/api/response.rb
129
+ - lib/odeon_uk/api/screenings.rb
99
130
  - lib/odeon_uk/cinema.rb
100
- - lib/odeon_uk/film.rb
101
- - lib/odeon_uk/internal/film_with_screenings_parser.rb
102
- - lib/odeon_uk/internal/showtimes_page.rb
131
+ - lib/odeon_uk/configuration.rb
132
+ - lib/odeon_uk/html/cinema.rb
133
+ - lib/odeon_uk/html/parser/film_with_screenings.rb
134
+ - lib/odeon_uk/html/screenings.rb
135
+ - lib/odeon_uk/html/website.rb
103
136
  - lib/odeon_uk/internal/title_sanitizer.rb
104
- - lib/odeon_uk/internal/website.rb
105
137
  - lib/odeon_uk/screening.rb
106
138
  - lib/odeon_uk/version.rb
107
139
  - odeon_uk.gemspec
108
- - test/fixture_updater.rb
109
- - test/fixtures/cinema/bfi_imax.html
110
- - test/fixtures/cinema/brighton.html
111
- - test/fixtures/cinema/leicester_square.html
112
- - test/fixtures/showtimes/brighton.html
113
- - test/fixtures/showtimes/brighton/film_first.html
114
- - test/fixtures/showtimes/brighton/film_last.html
115
- - test/fixtures/showtimes/liverpool_one/film_first_dbox.html
116
- - test/fixtures/showtimes/manchester/film_first_imax.html
117
- - test/fixtures/sitemap.html
140
+ - rake/fixture_creator.rb
141
+ - test/fixtures/api/all_cinemas.plist
142
+ - test/fixtures/api/app_init.plist
143
+ - test/fixtures/api/film_times/71-100747.plist
144
+ - test/fixtures/api/film_times/71-100750.plist
145
+ - test/fixtures/api/film_times/71-100790.plist
146
+ - test/fixtures/api/film_times/71-14646.plist
147
+ - test/fixtures/api/film_times/71-14725.plist
148
+ - test/fixtures/api/film_times/71-15086.plist
149
+ - test/fixtures/api/film_times/71-15096.plist
150
+ - test/fixtures/api/film_times/71-15122.plist
151
+ - test/fixtures/api/film_times/71-15130.plist
152
+ - test/fixtures/api/film_times/71-15141.plist
153
+ - test/fixtures/api/film_times/71-15142.plist
154
+ - test/fixtures/api/film_times/71-15143.plist
155
+ - test/fixtures/api/film_times/71-15144.plist
156
+ - test/fixtures/api/film_times/71-15145.plist
157
+ - test/fixtures/api/film_times/71-15170.plist
158
+ - test/fixtures/api/film_times/71-15172.plist
159
+ - test/fixtures/api/film_times/71-15177.plist
160
+ - test/fixtures/api/film_times/71-15179.plist
161
+ - test/fixtures/api/film_times/71-15182.plist
162
+ - test/fixtures/api/film_times/71-15286.plist
163
+ - test/fixtures/api/film_times/71-15360.plist
164
+ - test/fixtures/api/film_times/71-15586.plist
165
+ - test/fixtures/api/film_times/71-15700.plist
166
+ - test/fixtures/api/film_times/71-15718.plist
167
+ - test/fixtures/api/film_times/71-15768.plist
168
+ - test/fixtures/api/film_times/71-15788.plist
169
+ - test/fixtures/api/film_times/71-15793.plist
170
+ - test/fixtures/api/film_times/71-15794.plist
171
+ - test/fixtures/api/film_times/71-15795.plist
172
+ - test/fixtures/api/film_times/71-15796.plist
173
+ - test/fixtures/api/film_times/71-15799.plist
174
+ - test/fixtures/api/film_times/71-15802.plist
175
+ - test/fixtures/api/film_times/71-15814.plist
176
+ - test/fixtures/api/film_times/71-15817.plist
177
+ - test/fixtures/api/film_times/71-15840.plist
178
+ - test/fixtures/html/cinema/105.html
179
+ - test/fixtures/html/cinema/211.html
180
+ - test/fixtures/html/cinema/71.html
181
+ - test/fixtures/html/showtimes/11-imax.html
182
+ - test/fixtures/html/showtimes/171-d-box.html
183
+ - test/fixtures/html/showtimes/71-0.html
184
+ - test/fixtures/html/showtimes/71.html
185
+ - test/fixtures/html/sitemap.html
186
+ - test/lib/odeon_uk/api/cinema_test.rb
187
+ - test/lib/odeon_uk/api/response_test.rb
188
+ - test/lib/odeon_uk/api/screenings_test.rb
118
189
  - test/lib/odeon_uk/cinema_test.rb
119
- - test/lib/odeon_uk/film_test.rb
120
- - test/lib/odeon_uk/internal/film_with_screenings_parser_test.rb
121
- - test/lib/odeon_uk/internal/showtimes_page_test.rb
190
+ - test/lib/odeon_uk/configuration_test.rb
191
+ - test/lib/odeon_uk/html/cinema_test.rb
192
+ - test/lib/odeon_uk/html/parser/film_with_screenings_test.rb
193
+ - test/lib/odeon_uk/html/screenings_test.rb
194
+ - test/lib/odeon_uk/html/website_test.rb
122
195
  - test/lib/odeon_uk/internal/title_sanitizer_test.rb
123
- - test/lib/odeon_uk/internal/website_test.rb
124
196
  - test/lib/odeon_uk/screening_test.rb
125
197
  - test/lib/odeon_uk/version_test.rb
198
+ - test/support/api_fixtures_helper.rb
199
+ - test/support/website_fixtures_helper.rb
126
200
  - test/test_helper.rb
127
201
  homepage: http://github.com/andycroll/odeon_uk
128
202
  licenses:
@@ -149,23 +223,64 @@ signing_key:
149
223
  specification_version: 4
150
224
  summary: It's a scraper, but a nice one
151
225
  test_files:
152
- - test/fixture_updater.rb
153
- - test/fixtures/cinema/bfi_imax.html
154
- - test/fixtures/cinema/brighton.html
155
- - test/fixtures/cinema/leicester_square.html
156
- - test/fixtures/showtimes/brighton.html
157
- - test/fixtures/showtimes/brighton/film_first.html
158
- - test/fixtures/showtimes/brighton/film_last.html
159
- - test/fixtures/showtimes/liverpool_one/film_first_dbox.html
160
- - test/fixtures/showtimes/manchester/film_first_imax.html
161
- - test/fixtures/sitemap.html
226
+ - test/fixtures/api/all_cinemas.plist
227
+ - test/fixtures/api/app_init.plist
228
+ - test/fixtures/api/film_times/71-100747.plist
229
+ - test/fixtures/api/film_times/71-100750.plist
230
+ - test/fixtures/api/film_times/71-100790.plist
231
+ - test/fixtures/api/film_times/71-14646.plist
232
+ - test/fixtures/api/film_times/71-14725.plist
233
+ - test/fixtures/api/film_times/71-15086.plist
234
+ - test/fixtures/api/film_times/71-15096.plist
235
+ - test/fixtures/api/film_times/71-15122.plist
236
+ - test/fixtures/api/film_times/71-15130.plist
237
+ - test/fixtures/api/film_times/71-15141.plist
238
+ - test/fixtures/api/film_times/71-15142.plist
239
+ - test/fixtures/api/film_times/71-15143.plist
240
+ - test/fixtures/api/film_times/71-15144.plist
241
+ - test/fixtures/api/film_times/71-15145.plist
242
+ - test/fixtures/api/film_times/71-15170.plist
243
+ - test/fixtures/api/film_times/71-15172.plist
244
+ - test/fixtures/api/film_times/71-15177.plist
245
+ - test/fixtures/api/film_times/71-15179.plist
246
+ - test/fixtures/api/film_times/71-15182.plist
247
+ - test/fixtures/api/film_times/71-15286.plist
248
+ - test/fixtures/api/film_times/71-15360.plist
249
+ - test/fixtures/api/film_times/71-15586.plist
250
+ - test/fixtures/api/film_times/71-15700.plist
251
+ - test/fixtures/api/film_times/71-15718.plist
252
+ - test/fixtures/api/film_times/71-15768.plist
253
+ - test/fixtures/api/film_times/71-15788.plist
254
+ - test/fixtures/api/film_times/71-15793.plist
255
+ - test/fixtures/api/film_times/71-15794.plist
256
+ - test/fixtures/api/film_times/71-15795.plist
257
+ - test/fixtures/api/film_times/71-15796.plist
258
+ - test/fixtures/api/film_times/71-15799.plist
259
+ - test/fixtures/api/film_times/71-15802.plist
260
+ - test/fixtures/api/film_times/71-15814.plist
261
+ - test/fixtures/api/film_times/71-15817.plist
262
+ - test/fixtures/api/film_times/71-15840.plist
263
+ - test/fixtures/html/cinema/105.html
264
+ - test/fixtures/html/cinema/211.html
265
+ - test/fixtures/html/cinema/71.html
266
+ - test/fixtures/html/showtimes/11-imax.html
267
+ - test/fixtures/html/showtimes/171-d-box.html
268
+ - test/fixtures/html/showtimes/71-0.html
269
+ - test/fixtures/html/showtimes/71.html
270
+ - test/fixtures/html/sitemap.html
271
+ - test/lib/odeon_uk/api/cinema_test.rb
272
+ - test/lib/odeon_uk/api/response_test.rb
273
+ - test/lib/odeon_uk/api/screenings_test.rb
162
274
  - test/lib/odeon_uk/cinema_test.rb
163
- - test/lib/odeon_uk/film_test.rb
164
- - test/lib/odeon_uk/internal/film_with_screenings_parser_test.rb
165
- - test/lib/odeon_uk/internal/showtimes_page_test.rb
275
+ - test/lib/odeon_uk/configuration_test.rb
276
+ - test/lib/odeon_uk/html/cinema_test.rb
277
+ - test/lib/odeon_uk/html/parser/film_with_screenings_test.rb
278
+ - test/lib/odeon_uk/html/screenings_test.rb
279
+ - test/lib/odeon_uk/html/website_test.rb
166
280
  - test/lib/odeon_uk/internal/title_sanitizer_test.rb
167
- - test/lib/odeon_uk/internal/website_test.rb
168
281
  - test/lib/odeon_uk/screening_test.rb
169
282
  - test/lib/odeon_uk/version_test.rb
283
+ - test/support/api_fixtures_helper.rb
284
+ - test/support/website_fixtures_helper.rb
170
285
  - test/test_helper.rb
171
286
  has_rdoc:
data/lib/odeon_uk/film.rb DELETED
@@ -1,65 +0,0 @@
1
- module OdeonUk
2
- # The object representing a film on the Odeon UK website
3
- class Film
4
- include Comparable
5
-
6
- # @return [String] the name of the film
7
- attr_reader :name
8
- # @return [String] the normalized slug derived from the film name
9
- attr_reader :slug
10
-
11
- # @param [String] name the film name
12
- # @return [OdeonUk::Film]
13
- def initialize(name)
14
- @name = name
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<OdeonUk::Film>]
21
- def self.at(cinema_id)
22
- showtimes_page(cinema_id).to_a.map do |html|
23
- new(screenings_parser(html).film_name)
24
- end
25
- end
26
-
27
- # Allows sort on objects
28
- # @param [OdeonUk::Film] other another film object
29
- # @return [Integer] -1, 0 or 1
30
- def <=>(other)
31
- slug <=> other.slug
32
- end
33
-
34
- # Check an object is the same as another object.
35
- # @param [OdeonUk::Film] other another film
36
- # @return [Boolean] True if both objects are the same exact object, or if
37
- # they are of the same type and share an equal slug
38
- # @note Guided by http://woss.name/2011/01/20/equality-comparison-and-ordering-in-ruby/
39
- def eql?(other)
40
- self.class == other.class && self == other
41
- end
42
-
43
- # Generates hash of slug in order to allow two records of the same type and
44
- # id to work with something like:
45
- #
46
- # [ Film.new('ABC'), Film.new('DEF') ] & [ Film.new('DEF'), Film.new('GHI') ]
47
- # #=> [ Film.new('DEF') ]
48
- #
49
- # @return [Integer] hash of slug
50
- # @note Guided by http://woss.name/2011/01/20/equality-comparison-and-ordering-in-ruby/
51
- def hash
52
- slug.hash
53
- end
54
-
55
- private
56
-
57
- def self.screenings_parser(html)
58
- OdeonUk::Internal::FilmWithScreeningsParser.new(html)
59
- end
60
-
61
- def self.showtimes_page(cinema_id)
62
- OdeonUk::Internal::ShowtimesPage.new(cinema_id)
63
- end
64
- end
65
- end
@@ -1,159 +0,0 @@
1
- module OdeonUk
2
- # Internal utility classes: Do not use
3
- # @api private
4
- module Internal
5
- # Parses a chunk of HTML to derive movie showing data
6
- class FilmWithScreeningsParser
7
- # CSS selector for a film title inside an individual film HTML
8
- NAME_CSS = '.presentation-info h4 a'
9
- # CSS selector for a group of showtimes inside an individual film HTML
10
- SHOWTIMES_CSS = '.times-all.accordion-group'
11
-
12
- # @param [String] html a chunk of html
13
- def initialize(html)
14
- @html = html
15
- end
16
-
17
- # The film name
18
- # @return [String]
19
- def film_name
20
- @film_name ||= TitleSanitizer.new(raw_film_name).sanitized
21
- end
22
-
23
- # array containing hashes of screening attributes
24
- # @return [Array<Hash>]
25
- def to_a
26
- doc.css(SHOWTIMES_CSS).map do |node|
27
- dimension_parser(node).to_a.map do |hash|
28
- hash.merge(film_name: film_name)
29
- end
30
- end.flatten
31
- end
32
-
33
- private
34
-
35
- def doc
36
- @doc ||= Nokogiri::HTML(@html)
37
- end
38
-
39
- def raw_film_name
40
- @raw_film_name ||= doc.css(NAME_CSS).children.first.to_s
41
- end
42
-
43
- def dimension_parser(node)
44
- DimensionNodeParser.new(node)
45
- end
46
- end
47
-
48
- # parses chunk of screenings for a particular screening dimension
49
- class DimensionNodeParser
50
- # CSS selector for a single screening inside a 'group of showtimes' HTML
51
- SCREENING_CSS = '.show'
52
- # CSS selector for showing technology for a 'group of showtimes' HTML
53
- TECH_CSS = '.tech a'
54
-
55
- # @param [Nokigiri::Node] node a Nokogiri node object
56
- def initialize(node)
57
- @node = node
58
- end
59
-
60
- # array containing hashes of screening attributes for dimension
61
- # @return [Array<Hash>]
62
- def to_a
63
- screening_hashes.map do |hash|
64
- hash.merge(
65
- dimension: dimension,
66
- variant: add_imax(hash[:variant])
67
- )
68
- end
69
- end
70
-
71
- private
72
-
73
- def add_imax(original)
74
- imax? ? "#{original} imax".strip : original
75
- end
76
-
77
- def dimension
78
- dimension_from_tech || '2d'
79
- end
80
-
81
- def dimension_from_tech
82
- tech.match(/[23]d/i) { |data| data[0] }
83
- end
84
-
85
- def imax?
86
- !!tech.match(/imax/)
87
- end
88
-
89
- def screening_hashes
90
- screening_nodes.map { |node| ScreeningNodeParser.new(node).to_hash }
91
- end
92
-
93
- def screening_nodes
94
- @node.css(SCREENING_CSS)
95
- end
96
-
97
- def tech
98
- @tech ||= @node.css(TECH_CSS).text.gsub('in ', '').downcase
99
- end
100
- end
101
-
102
- # parses a single screening
103
- class ScreeningNodeParser
104
- # regex for time format
105
- TIME_REGEX = %r(\d+/\d+/\d+ \d{2}\:\d{2})
106
- # regex for D-Box screenings
107
- DBOX_REGEX = /D-Box/
108
-
109
- # @param [Nokigiri::Node] node a Nokogiri node object
110
- def initialize(node)
111
- @node = node
112
- end
113
-
114
- # hashes of screening attributes
115
- # @return [Hash]
116
- def to_hash
117
- {
118
- booking_url: booking_url,
119
- time: utc_time,
120
- variant: variant
121
- }
122
- end
123
-
124
- private
125
-
126
- def booking_url
127
- link_attr('href').to_s
128
- end
129
-
130
- def link_attr(attribute)
131
- @node.css('a').attribute(attribute)
132
- end
133
-
134
- def info
135
- @node.css('i').to_s
136
- end
137
-
138
- def time
139
- Time.parse(time_string)
140
- end
141
-
142
- def time_string
143
- link_attr('title').to_s.match(TIME_REGEX).to_s + ' UTC'
144
- end
145
-
146
- def tz
147
- @tz ||= TZInfo::Timezone.get('Europe/London')
148
- end
149
-
150
- def utc_time
151
- tz.local_to_utc(time)
152
- end
153
-
154
- def variant
155
- info.match(DBOX_REGEX) ? 'd-box' : ''
156
- end
157
- end
158
- end
159
- end
@@ -1,36 +0,0 @@
1
- module OdeonUk
2
- # Internal utility classes: Do not use
3
- # @api private
4
- module Internal
5
- # Parses a chunk of HTML to derive showing data for a single films
6
- class ShowtimesPage
7
- # css selector for film html chunks
8
- FILM_CSS = '.film-detail'
9
-
10
- # @param [Integer] cinema_id cineworld cinema id
11
- def initialize(cinema_id)
12
- @cinema_id = cinema_id
13
- end
14
-
15
- # break up the showtimes page into individual chunks for each film
16
- # @return [Array<String>] html chunks for a film and it's screenings
17
- def to_a
18
- film_nodes.map { |node| node.to_s.gsub(/^\s+/, '') }
19
- end
20
-
21
- private
22
-
23
- def film_nodes
24
- @film_nodes ||= showtimes_doc.css(FILM_CSS)
25
- end
26
-
27
- def showtimes
28
- @showtimes ||= OdeonUk::Internal::Website.new.showtimes(@cinema_id)
29
- end
30
-
31
- def showtimes_doc
32
- @showtimes_doc ||= Nokogiri::HTML(showtimes)
33
- end
34
- end
35
- end
36
- end
@@ -1,72 +0,0 @@
1
- require File.expand_path('../../lib/odeon_uk.rb', __FILE__)
2
-
3
- def fixture(name)
4
- File.expand_path("../fixtures/#{name}.html", __FILE__)
5
- end
6
-
7
- File.open(fixture('sitemap'), 'w+') do |file|
8
- puts '* Sitemap'
9
- file.write OdeonUk::Internal::Website.new.sitemap
10
- end
11
-
12
- # BRIGHTON
13
-
14
- File.open(fixture('cinema/brighton'), 'w+') do |file|
15
- puts '* Brighton Cinema'
16
- file.write OdeonUk::Internal::Website.new.cinema(71)
17
- end
18
-
19
- File.open(fixture('showtimes/brighton'), 'w+') do |file|
20
- puts '* Brighton Showtimes'
21
- file.write OdeonUk::Internal::Website.new.showtimes(71)
22
- end
23
-
24
- parser = OdeonUk::Internal::ShowtimesParser.new(71)
25
-
26
- File.open(fixture('showtimes/brighton/film_first'), 'w+') do |file|
27
- puts '* Brighton Film First'
28
- file.write parser.films_with_screenings_html[0]
29
- end
30
-
31
- File.open(fixture('showtimes/brighton/film_last'), 'w+') do |file|
32
- puts '* Brighton Film Last'
33
- file.write parser.films_with_screenings_html[-1]
34
- end
35
-
36
- # Manchester IMAX
37
-
38
- parser = OdeonUk::Internal::ShowtimesParser.new(11)
39
- imax_screenings = parser.films_with_screenings_html.select do |text|
40
- text.match 'imax'
41
- end
42
-
43
- File.open(fixture('showtimes/manchester/film_first_imax'), 'w+') do |file|
44
- puts '* Manchester Film First IMAX'
45
- file.write imax_screenings[0]
46
- end
47
-
48
- # Liverpool ONE
49
-
50
- parser = OdeonUk::Internal::ShowtimesParser.new(171)
51
- dbox_screenings = parser.films_with_screenings_html.select do |text|
52
- text.match 'D-Box'
53
- end
54
-
55
- File.open(fixture('showtimes/liverpool_one/film_first_dbox'), 'w+') do |file|
56
- puts '* Liverpool ONE Film First D-BOX'
57
- file.write dbox_screenings[0]
58
- end
59
-
60
- # London BFI IMAX
61
-
62
- File.open(fixture('cinema/bfi_imax'), 'w+') do |file|
63
- puts '* BFI IMAX Cinema'
64
- file.write OdeonUk::Internal::Website.new.cinema(211)
65
- end
66
-
67
- # London Leicester Square
68
-
69
- File.open(fixture('cinema/leicester_square'), 'w+') do |file|
70
- puts '* Leceister Square Cinema'
71
- file.write OdeonUk::Internal::Website.new.cinema(105)
72
- end
@@ -1,92 +0,0 @@
1
- <div id="23231" class="film-detail WEEK">
2
- <div class="content-container film _WEEK" id="film-23231">
3
- <div class="grad-hor">
4
- <a href="/films/a_most_wanted_man/14578/"><img src="http://m.odeon.co.uk/_uploads/asset_management/70x108_5c90831931ced559e84af38f832a6343.jpg"></a>
5
- <div class="presentation-info">
6
- <h4><a href="/films/a_most_wanted_man/14578/">A Most Wanted Man</a></h4>
7
- <a href="/film-classifications/" alt="15" title="More about film classifications"><div class="cert-icon-uk-15-small"></div></a> <span class="description">
8
- ID may be required </span>
9
- </div>
10
- <p><strong>A spy thriller examining contemporary counter-terrorism policies </strong></p>
11
- <div class="presentation-info">
12
- <div data-rating-master-id="14578" data-return-to="/showtimes/week/71/" class="star-rating-container star-rating rating-icon-star-light-small-inactive">
13
- <div class="rating-icon-star-small-active s6" data-rating="6">
14
- <div class="rate-over s1"></div>
15
- <div class="rate-over s2"></div>
16
- <div class="rate-over s3"></div>
17
- <div class="rate-over s4"></div>
18
- <div class="rate-over s5"></div>
19
- </div>
20
- </div>
21
- <span class="description"><strong>Film length: 122 mins</strong></span>
22
- </div>
23
- <p class="description">Strong language.</p>
24
- </div>
25
- <div class="info-corner">
26
- <div class="img-bundle">
27
- <div class="film-icon-WEEK feature-icon-light-2d-medium WEEK_2D" data-schedule="2D" data-film="23231"></div> </div>
28
- <div class="btn-group">
29
- <a href="http://odeon.trailer.cineweb.de/a_most_wanted_man.mp4" class="btn btn-primary trailer kkvideo-trigger" data-return-to="/showtimes/week/71/" data-film-id="14578" data-showbooknowbutton="false"><i class="film-icon-btn-play"></i>Trailer</a>
30
- <button class="btn btn-primary trailer dropdown-toggle" data-toggle="dropdown">
31
- <span class="caret"></span>
32
- </button>
33
- <ul class="dropdown-menu">
34
- <li><a href="#">Add to Playlist</a></li>
35
- </ul>
36
- </div> </div>
37
- </div>
38
- <div id="performances-WEEK-23231" class="content-container times-all _WEEK">
39
- <div class="accordion-group times-all performances-WEEK _23231" id="tech-23231-0">
40
- <div class="content-container tech accordion-heading _WEEK">
41
- <a data-toggle="collapse" data-parent="#tech-23231-0-WEEK" class="accordion-toggle" href="#collapse-23231-0-WEEK">in 2D</a><a href="#" class="icon-info-blue info-icon-form-info-small" data-toggle="popover" title="" data-placement="bottom" data-content="2D means two dimensional. No 3D glasses required. Sit back, relax and enjoy."></a>
42
- </div>
43
- <div id="collapse-23231-0-WEEK" class="accordion-body in collapse" style="height: auto;">
44
- <div class="accordion-inner">
45
- <div class="content-container times containerWEEK">
46
- <div class="presentation-info week">
47
- <strong>Wednesday</strong><br>17 Sep</div>
48
- <ul class="unstyled inline">
49
- <li class="WEEK WEEK_WHEELCHAIR performance-lightblue WEEK_ISSUPERSAVER WEEK_15 WEEK_AFTERNOON WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/NDQxMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Super Saver - book A Most Wanted Man on 17/09/2014 15:00" data-popup="popup" data-duration="122" data-start="15:00" data-end="17:02" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 6 (Wheelchair Accessible)" data-is-online="1">15:00</a></li>
50
- <li class="WEEK WEEK_WHEELCHAIR performance-blue WEEK_ISPEAK WEEK_15 WEEK_EVENING WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/QTQxMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Peak - book A Most Wanted Man on 17/09/2014 17:50" data-popup="popup" data-duration="122" data-start="17:50" data-end="19:52" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 6 (Wheelchair Accessible)" data-is-online="1">17:50</a></li>
51
- <li class="WEEK WEEK_WHEELCHAIR performance-blue WEEK_ISPEAK WEEK_15 WEEK_EVENING WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/MDUxMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Peak - book A Most Wanted Man on 17/09/2014 20:40" data-popup="popup" data-duration="122" data-start="20:40" data-end="22:42" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 6 (Wheelchair Accessible)" data-is-online="1">20:40</a></li> </ul>
52
- </div>
53
- <div class="content-container times containerWEEK">
54
- <div class="presentation-info week">
55
- <strong>Thursday</strong><br>18 Sep</div>
56
- <ul class="unstyled inline">
57
- <li class="WEEK WEEK_WHEELCHAIR performance-lightblue WEEK_ISSUPERSAVER WEEK_15 WEEK_AFTERNOON WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/NTQxMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Super Saver - book A Most Wanted Man on 18/09/2014 15:00" data-popup="popup" data-duration="122" data-start="15:00" data-end="17:02" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 6 (Wheelchair Accessible)" data-is-online="1">15:00</a></li>
58
- <li class="WEEK WEEK_WHEELCHAIR performance-blue WEEK_ISPEAK WEEK_15 WEEK_EVENING WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/QjQxMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Peak - book A Most Wanted Man on 18/09/2014 17:50" data-popup="popup" data-duration="122" data-start="17:50" data-end="19:52" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 6 (Wheelchair Accessible)" data-is-online="1">17:50</a></li>
59
- <li class="WEEK WEEK_WHEELCHAIR performance-blue WEEK_ISPEAK WEEK_15 WEEK_EVENING WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/MTUxMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Peak - book A Most Wanted Man on 18/09/2014 20:40" data-popup="popup" data-duration="122" data-start="20:40" data-end="22:42" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 6 (Wheelchair Accessible)" data-is-online="1">20:40</a></li> </ul>
60
- </div>
61
- <div class="content-container times containerWEEK">
62
- <div class="presentation-info week">
63
- <strong>Saturday</strong><br>20 Sep</div>
64
- <ul class="unstyled inline">
65
- <li class="WEEK WEEK_WHEELCHAIR performance-blue WEEK_ISPEAK WEEK_15 WEEK_AFTERNOON WEEK_AUDIODESCRIBED WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/QzQyMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Peak - book A Most Wanted Man on 20/09/2014 16:40" data-popup="popup" data-duration="122" data-start="16:40" data-end="18:42" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 8 (Wheelchair Accessible)" data-is-online="1">16:40</a></li> </ul>
66
- </div>
67
- <div class="content-container times containerWEEK">
68
- <div class="presentation-info week">
69
- <strong>Sunday</strong><br>21 Sep</div>
70
- <ul class="unstyled inline">
71
- <li class="WEEK WEEK_WHEELCHAIR performance-blue WEEK_ISPEAK WEEK_15 WEEK_AFTERNOON WEEK_AUDIODESCRIBED WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/RjQyMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Peak - book A Most Wanted Man on 21/09/2014 16:40" data-popup="popup" data-duration="122" data-start="16:40" data-end="18:42" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 8 (Wheelchair Accessible)" data-is-online="1">16:40</a></li> </ul>
72
- </div>
73
- <div class="content-container times containerWEEK">
74
- <div class="presentation-info week">
75
- <strong>Monday</strong><br>22 Sep</div>
76
- <ul class="unstyled inline">
77
- <li class="WEEK WEEK_WHEELCHAIR performance-lightblue WEEK_ISSUPERSAVER WEEK_15 WEEK_AFTERNOON WEEK_AUDIODESCRIBED WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/MDUyMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Super Saver - book A Most Wanted Man on 22/09/2014 16:40" data-popup="popup" data-duration="122" data-start="16:40" data-end="18:42" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 8 (Wheelchair Accessible)" data-is-online="1">16:40</a></li> </ul>
78
- </div>
79
- <div class="content-container times containerWEEK">
80
- <div class="presentation-info week">
81
- <strong>Tuesday</strong><br>23 Sep</div>
82
- <ul class="unstyled inline">
83
- <li class="WEEK WEEK_WHEELCHAIR performance-lightgreen WEEK_ISBARGIN WEEK_15 WEEK_AFTERNOON WEEK_AUDIODESCRIBED WEEK_2D WEEK_GENRE_7 WEEK_GENRE_15 show"><a href="https://www.odeon.co.uk/booking/init/MTUyMzEwMDAwMjNVRFBETVhHIzcxIzE0NTc4/" class="performance-detail" title="Bargain - book A Most Wanted Man on 23/09/2014 16:40" data-popup="popup" data-duration="122" data-start="16:40" data-end="18:42" data-status="normal" data-type="WEEK" data-auditorium-info="Screen 8 (Wheelchair Accessible)" data-is-online="1">16:40</a></li> </ul>
84
- </div>
85
- <div class="content-container times stopper performances-WEEK _23231"></div>
86
- </div>
87
- </div>
88
- </div>
89
- <!-- <div class="content-container times stopper performances-WEEK _23231"></div>-->
90
- <div class="content-container white performances-WEEK _23231"></div>
91
- </div>
92
- </div>