odeon_uk 2.0.4 → 3.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.
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>