cineworld_uk 2.1.6 → 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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -3
  3. data/README.md +56 -14
  4. data/Rakefile +57 -1
  5. data/cineworld_uk.gemspec +1 -2
  6. data/lib/cineworld_uk/cinema.rb +113 -182
  7. data/lib/cineworld_uk/internal/api_response.rb +74 -0
  8. data/lib/cineworld_uk/internal/parser/api/cinema_address.rb +81 -0
  9. data/lib/cineworld_uk/internal/parser/api/film.rb +46 -0
  10. data/lib/cineworld_uk/internal/parser/api/film_lookup.rb +38 -0
  11. data/lib/cineworld_uk/internal/parser/api/performance.rb +46 -0
  12. data/lib/cineworld_uk/internal/parser/api/performances_by_day.rb +50 -0
  13. data/lib/cineworld_uk/internal/title_sanitizer.rb +56 -52
  14. data/lib/cineworld_uk/performance.rb +78 -0
  15. data/lib/cineworld_uk/version.rb +2 -2
  16. data/lib/cineworld_uk.rb +11 -8
  17. data/test/fixtures/api/cinema-detail-10.json +1 -0
  18. data/test/fixtures/api/cinema-detail-21.json +1 -0
  19. data/test/fixtures/api/cinema-detail-3.json +1 -0
  20. data/test/fixtures/api/cinema-detail-96.json +1 -0
  21. data/test/fixtures/api/cinema-list.json +1 -0
  22. data/test/fixtures/api/dates-3.json +1 -0
  23. data/test/fixtures/api/film-list-comingsoon.json +1 -0
  24. data/test/fixtures/api/film-list.json +1 -0
  25. data/test/fixtures/api/performances-tomorrow-3.json +1 -0
  26. data/test/lib/cineworld_uk/cinema_test.rb +96 -197
  27. data/test/lib/cineworld_uk/internal/api_response_test.rb +85 -0
  28. data/test/lib/cineworld_uk/internal/parser/api/cinema_address_test.rb +93 -0
  29. data/test/lib/cineworld_uk/internal/parser/api/film_lookup_test.rb +30 -0
  30. data/test/lib/cineworld_uk/internal/parser/api/film_test.rb +169 -0
  31. data/test/lib/cineworld_uk/internal/parser/api/performance_test.rb +62 -0
  32. data/test/lib/cineworld_uk/internal/title_sanitizer_test.rb +1 -1
  33. data/test/lib/cineworld_uk/{screening_test.rb → performance_test.rb} +36 -48
  34. data/test/support/fixture_reader.rb +44 -0
  35. metadata +48 -59
  36. data/lib/cineworld_uk/film.rb +0 -65
  37. data/lib/cineworld_uk/internal/film_with_screenings_parser.rb +0 -69
  38. data/lib/cineworld_uk/internal/screening_parser.rb +0 -132
  39. data/lib/cineworld_uk/internal/website.rb +0 -35
  40. data/lib/cineworld_uk/internal/whatson_parser.rb +0 -36
  41. data/lib/cineworld_uk/screening.rb +0 -87
  42. data/test/fixture_updater.rb +0 -64
  43. data/test/fixtures/cinemas.html +0 -513
  44. data/test/fixtures/information/brighton.html +0 -1268
  45. data/test/fixtures/information/bristol.html +0 -1265
  46. data/test/fixtures/whatson/brighton/film_first.html +0 -207
  47. data/test/fixtures/whatson/brighton/film_last.html +0 -62
  48. data/test/fixtures/whatson/brighton/film_second.html +0 -347
  49. data/test/fixtures/whatson/brighton.html +0 -7508
  50. data/test/fixtures/whatson/glasgow-imax-at-gsc/film_first.html +0 -182
  51. data/test/fixtures/whatson/the-o2-greenwich/film_first.html +0 -167
  52. data/test/lib/cineworld_uk/film_test.rb +0 -142
  53. data/test/lib/cineworld_uk/internal/film_with_screenings_parser_test.rb +0 -101
  54. data/test/lib/cineworld_uk/internal/website_test.rb +0 -57
  55. data/test/lib/cineworld_uk/internal/whatson_parser_test.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86b00dc1901b19df84e8e682816d98ab5e9767bb
4
- data.tar.gz: 8429f8b142b9e928e4b2527e732a6bb15a280446
3
+ metadata.gz: e16ae76d133daa488243828c8b093a3517d54baa
4
+ data.tar.gz: 580b82b0d6317205b34d506230dd9239fbdef9b5
5
5
  SHA512:
6
- metadata.gz: 73b0bccf10a7ad6ff30cc89e99bc226dcf4f5b5d774945c1aa3578af5f4f7cec38e27b95e298274c42a97fba1fdab49ff7f8bf8d51dfb1de4d4199309bfeaebe
7
- data.tar.gz: d4c2fef4ac56b1eb12e8a062029bccc94709891c6a3cac842bd3a422b77b5c2820e2fc0552809419d9fd39cf7d82a1c470363769898231b921d64d38ca4f17b9
6
+ metadata.gz: 65c6441ae400782f81c776edbf856d3c39392419d66186faf1ed183fc0692bb01509735a1e0499e38a281af84757c0cc81e22e7bf262b52233bbf8cd2d052544
7
+ data.tar.gz: 785e66d627135d40e0665fb685e6890680c17e96a1de60b0f30058c894550fb1de305f06f347c6b8d2e1b80b4015b6113c423624cc363b2ac78f9c8da08a06d9
data/CHANGELOG.md CHANGED
@@ -1,14 +1,33 @@
1
1
  # Change Log
2
-
3
2
  All notable changes to this project will be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org/).
4
+
5
+ ## 3.0.0 - 2016-02-03
6
+
7
+ The cinebase standardisation release.
8
+
9
+ ### Removed
10
+ - Remove website as data source
11
+ - Remove film concept
12
+
13
+ ### Added
14
+ - Use iOS api as a data source
15
+
16
+ ### Changed
17
+ - Parse cinema address from iOS api
18
+ - Screening becomes Performance in cinebase 2.0.0
19
+ - Parse performances & films iOS API
20
+ - Use the `cinebase` gem to fix an common API across all gems
4
21
 
5
22
  ## 2.1.6 - 2015-05-06
6
23
 
7
- - [FIXED] whats on pge is the cinema url
24
+ # Fixed
25
+ - whats on page is the cinema url
8
26
 
9
27
  ## 2.1.5 - 2015-02-18
10
28
 
11
- - [FIXED] more defensive against closing cinemas
29
+ # Fixed
30
+ - more defensive against closing cinemas
12
31
 
13
32
  ## 2.1.4 - 2015-01-03
14
33
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CineworldUk
2
2
 
3
- A simple gem to parse the [Cineworld UK website](http://cineworld.co.uk) and spit out useful formatted info.
3
+ A simple gem to parse the [Cineworld UK](http://cineworld.co.uk) cinema times (using their iOS API) and spit out useful formatted info.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/cineworld_uk.svg)](http://badge.fury.io/rb/cineworld_uk)
6
6
  [![Code Climate](https://codeclimate.com/github/andycroll/cineworld_uk.png)](https://codeclimate.com/github/andycroll/cineworld_uk)
@@ -23,32 +23,74 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
+ The gem conforms to the API set down in the `cinebase` gem, [andycroll/cinebase](https://github.com/andycroll/cinebase), which provides a lot of useful base vocabulary and repetitive code for this series of cinema focussed gems.
27
+
28
+ Performance titles are sanitized as much as possible, removing 'screening type' information and 'dimension' as well as standardising all the theatre/cultural event naming (NT Live, Royal Opera House etc).
29
+
26
30
  ### Cinema
27
31
 
28
32
  ``` ruby
29
- CineworldUK::Cinema.all
30
- #=> [<CineworldUK::Cinema brand="Cineworld" name="Duke's At Komedia" slug="dukes-at-komedia" chain_id="Dukes_At_Komedia" url="...">, #=> <CineworldUK::Cinema brand="Cineworld" name="Duke o York's" slug="duke-of-yorks" chain_id="Brighton" url="...">, ...]
31
-
32
- CineworldUK::Cinema.find('3')
33
- #=> <CineworldUK::Cinema brand="Cineworld" name="Brighton" slug="duke-of-yorks" address="..." chain_id="Brighton" url="...">
33
+ CineworldUk::Cinema.all
34
+ #=> [<CineworldUK::Cinema ...>, <CineworldUK::Cinema ...>, ...]
35
+
36
+ cinema = CineworldUk::Cinema.new(3)
37
+ #=> <CineworldUK::Cinema ...>
38
+
39
+ cinema.adr
40
+ #=> {
41
+ street_address: 'Brighton Marina Village',
42
+ extended_address: nil,
43
+ locality: 'Brighton',
44
+ region: nil,
45
+ postal_code: 'BN2 5UF',
46
+ country: 'United Kingdom'
47
+ }
34
48
 
35
49
  cinema.brand
36
50
  #=> 'Cineworld'
37
51
 
52
+ cinema.full_name
53
+ #=> 'Cineworld Brighton'
54
+
38
55
  cinema.id
39
56
  #=> '3'
40
57
 
41
- cinema.films
42
- #=> [<CineworldUK::Film name="Iron Man 3">, <CineworldUK::Film name="Star Trek: Into Darkness">]
58
+ cinema.postal_code
59
+ #=> 'BN2 5UF'
60
+ ```
61
+
62
+ ### Performances
63
+
64
+ ``` ruby
65
+ CineworldUk::Performance.at(3)
66
+ #=> [<CineworldUK::Performance ...>, <CineworldUK::Performance ...>, ...]
67
+
68
+ performance = CineworldUk::Performance.at(3).first
69
+ #=> <CineworldUK::Performance ...>
70
+
71
+ performance.film_name
72
+ #=> 'Star Wars: The Force Awakens'
73
+
74
+ performance.dimension
75
+ #=> '2d'
76
+
77
+ performance.variant
78
+ #=> ['imax', 'kids']
79
+
80
+ performance.starting_at
81
+ #=> 2016-02-04 13:00:20 UTC
82
+
83
+ performance.showing_on
84
+ #=> #<Date: 2016-02-04 ((2457423j,0s,0n),+0s,2299161j)>
43
85
 
44
- cinema.screenings
45
- #=> [<CineworldUK::Screening film="About Time" when="2013-09-09 11:00 UTC" variant="3d">, <CineworldUK::Screening film="Iron Man 3" when="2013-09-09 13:50 UTC" variant="kids">, <CineworldUK::Screening ..>, <CineworldUK::Screening ...>]
86
+ performance.booking_url
87
+ #=> "http://www.cineworld.co.uk/booking?performance=..."
46
88
 
47
- cinema.screenings_of 'Iron Man 3'
48
- #=> [<CineworldUK::Screening film="Iron Man 3" when="2013-09-09 11:00 UTC" variant="3d">, <CineworldUK::Screening film="Iron Man 3" when="2013-09-09 13:50 UTC" variant="kids">]
89
+ performance.cinema_name
90
+ #=> 'Brighton'
49
91
 
50
- cinema.screenings_of <CineworldUK::Film name="Iron Man 3">
51
- #=> [<CineworldUK::Screening film="Iron Man 3" when="2013-09-09 11:00 UTC" variant="3d">, <CineworldUK::Screening film="Iron Man 3" when="2013-09-09 13:50 UTC" variant="kids">]
92
+ performance.cinema_id
93
+ #=> 3
52
94
  ```
53
95
 
54
96
  ## Contributing
data/Rakefile CHANGED
@@ -7,7 +7,8 @@ Rake::TestTask.new do |t|
7
7
  t.libs << 'lib/cineworld_uk'
8
8
  t.test_files = FileList[
9
9
  'test/lib/cineworld_uk/*_test.rb',
10
- 'test/lib/cineworld_uk/internal/*_test.rb'
10
+ 'test/lib/cineworld_uk/internal/*_test.rb',
11
+ 'test/lib/cineworld_uk/internal/parser/api/*_test.rb'
11
12
  ]
12
13
  t.verbose = true
13
14
  end
@@ -21,4 +22,59 @@ task :console do
21
22
  IRB.start
22
23
  end
23
24
 
25
+ task :fixtures do
26
+ require 'cineworld_uk'
27
+
28
+ def js_fixture(name)
29
+ File.expand_path("../test/fixtures/#{name}.json", __FILE__)
30
+ end
31
+
32
+ api = CineworldUk::Internal::ApiResponse.new
33
+
34
+ File.open(js_fixture('api/cinema-list'), 'w') do |file|
35
+ puts '* API Cinema List'
36
+ file.write api.cinema_list
37
+ end
38
+
39
+ File.open(js_fixture('api/cinema-detail-3'), 'w') do |file|
40
+ puts '* API Cinema Detail Brighton'
41
+ file.write api.cinema_detail(3)
42
+ end
43
+
44
+ File.open(js_fixture('api/cinema-detail-96'), 'w') do |file|
45
+ puts '* API Cinema Detail Birmingham NEC'
46
+ file.write api.cinema_detail(96)
47
+ end
48
+
49
+ File.open(js_fixture('api/cinema-detail-21'), 'w') do |file|
50
+ puts '* API Cinema Detail Edinburgh'
51
+ file.write api.cinema_detail(21)
52
+ end
53
+
54
+ File.open(js_fixture('api/cinema-detail-10'), 'w') do |file|
55
+ puts '* API Cinema Detail Chelsea'
56
+ file.write api.cinema_detail(10)
57
+ end
58
+
59
+ File.open(js_fixture('api/film-list'), 'w') do |file|
60
+ puts '* API Film List'
61
+ file.write api.film_list
62
+ end
63
+
64
+ File.open(js_fixture('api/film-list-comingsoon'), 'w') do |file|
65
+ puts '* API Film List Coming Soon'
66
+ file.write api.film_list_comingsoon
67
+ end
68
+
69
+ File.open(js_fixture('api/performances-tomorrow-3'), 'w') do |file|
70
+ puts '* API Performances in Brighton Tomorrow'
71
+ file.write api.performances(3, Date.today + 1)
72
+ end
73
+
74
+ File.open(js_fixture('api/dates-3'), 'w') do |file|
75
+ puts '* API Dates Brighton Tomorrow'
76
+ file.write api.dates(3)
77
+ end
78
+ end
79
+
24
80
  task :default => :test
data/cineworld_uk.gemspec CHANGED
@@ -23,7 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'rake'
24
24
  spec.add_development_dependency 'webmock'
25
25
 
26
+ spec.add_runtime_dependency 'cinebase', '~> 3.0.0'
26
27
  spec.add_runtime_dependency 'nokogiri'
27
- spec.add_runtime_dependency 'tzinfo'
28
- spec.add_runtime_dependency 'tzinfo-data'
29
28
  end
@@ -1,27 +1,12 @@
1
1
  module CineworldUk
2
2
  # The object representing a cinema on the Cineworld UK website
3
- class Cinema
4
- # @return [String] the brand of the cinema
5
- attr_reader :brand
6
- # @return [Integer] the numeric id of the cinema on the Cineworld website
7
- attr_reader :id
8
- # @return [String] the name of the cinema
9
- attr_reader :name
10
- # @return [String] the slug of the cinema
11
- attr_reader :slug
12
- # @return [String] the url of the cinema on the Cineworld website
13
- attr_reader :url
14
-
15
- # @param [Integer, String] id cinema id
16
- # @param [String] name cinema name
17
- # @return [CineworldUk::Cinema]
18
- def initialize(id, name)
19
- @brand = 'Cineworld'
20
- @id = id.to_i
21
- @name = name.gsub('London - ', '').gsub(' - ', ': ')
22
- @slug = @name.downcase.gsub(/[^0-9a-z ]/, '').gsub(/\s+/, '-')
23
- @url = "http://www.cineworld.co.uk/whatson?cinema=#{@id}"
24
- end
3
+ class Cinema < Cinebase::Cinema
4
+ # @!attribute [r] id
5
+ # @return [Integer] the numeric id of the cinema on the Cineworld website
6
+
7
+ # @!method initialize(id)
8
+ # @param [Integer, String] id cinema id
9
+ # @return [CineworldUk::Cinema]
25
10
 
26
11
  # Return basic cinema information for all cinemas
27
12
  # @return [Array<CineworldUk::Cinema>]
@@ -29,29 +14,18 @@ module CineworldUk
29
14
  # CineworldUk::Cinema.all
30
15
  # #=> [<CineworldUk::Cinema>, <CineworldUk::Cinema>, ...]
31
16
  def self.all
32
- cinemas_doc.css('#cinemaId option[value]').map do |option|
33
- new option['value'], option.text
34
- end[1..-1]
17
+ id_names_hash.map { |id, _| new id }
35
18
  end
36
19
 
37
- # Find a single cinema
38
- # @param [Integer, String] id the cinema id as used on the website
39
- # @return [CineworldUk::Cinema, nil]
40
- # @example
41
- # CineworldUk::Cinema.find('3')
42
- # #=> <CineworldUk::Cinema brand="Cineworld"
43
- # name="Brighton"
44
- # slug="brighton"
45
- # id=3
46
- # url="...">
47
- def self.find(id)
48
- all.select { |cinema| cinema.id == id.to_i }[0]
49
- end
20
+ # @!method address
21
+ # Address of the cinema
22
+ # @return [Hash] of different address parts
23
+ # @see #adr
50
24
 
51
25
  # Address of the cinema
52
26
  # @return [Hash] of different address parts
53
27
  # @example
54
- # cinema = CineworldUk::Cinema.find(3)
28
+ # cinema = CineworldUk::Cinema.new(3)
55
29
  # cinema.adr
56
30
  # #=> {
57
31
  # street_address: '44-47 Gardner Street',
@@ -62,165 +36,122 @@ module CineworldUk
62
36
  # }
63
37
  # @note Uses the standard method naming as at http://microformats.org/wiki/adr
64
38
  def adr
65
- {
66
- street_address: street_address,
67
- extended_address: extended_address,
68
- locality: locality,
69
- region: region,
70
- postal_code: postal_code,
71
- country: 'United Kingdom'
72
- }
39
+ CineworldUk::Internal::Parser::Api::CinemaAddress.new(@id).to_hash
73
40
  end
74
- alias_method :address, :adr
75
41
 
76
- # The second address line of the cinema
77
- # @return [String, nil]
42
+ # Brand of the cinema
43
+ # @return [String] which will always be 'Cineworld'
78
44
  # @example
79
- # cinema = CineworldUk::Cinema.find(10)
80
- # cinema.extended_address
81
- # #=> 'Chelsea'
45
+ # cinema = CineworldUk::Cinema.new(3)
46
+ # cinema.brand
47
+ # #=> 'Cineworld'
48
+ def brand
49
+ 'Cineworld'.freeze
50
+ end
51
+
52
+ # @!method country_name
53
+ # Country of the cinema
54
+ # @return [String] which will always be 'United Kingdom'
55
+ # @example
56
+ # cinema = CineworldUk::Cinema.new(3)
57
+ # cinema.country_name
58
+ # #=> 'United Kingdom'
59
+
60
+ # @!method extended_address
61
+ # The second address line of the cinema
62
+ # @return [String]
63
+ # @example
64
+ # cinema = CineworldUk::Cinema.new(10)
65
+ # cinema.extended_address
66
+ # #=> 'Chelsea'
82
67
  #
83
- # cinema = CineworldUk::Cinema.find(3)
84
- # cinema.extended_address
85
- # #=> nil
86
- # @note Uses the standard method naming as at http://microformats.org/wiki/adr
87
- def extended_address
88
- remaining_address * ', ' unless remaining_address.empty?
89
- end
90
-
91
- # Films with showings scheduled at this cinema
92
- # @return [Array<CineworldUk::Film>]
93
- # @example
94
- # cinema = CineworldUk::Cinema.find('71')
95
- # cinema.films
96
- # #=> [<CineworldUk::Film>, <CineworldUk::Film>, ...]
97
- def films
98
- Film.at(id)
99
- end
100
-
101
- # The name of the cinema including the brand
68
+ # cinema = CineworldUk::Cinema.new(3)
69
+ # cinema.extended_address
70
+ # #=> ''
71
+
72
+ # @!method full_name
73
+ # The name of the cinema including the brand
74
+ # @return [String]
75
+ # @example
76
+ # cinema = CineworldUk::Cinema.new(88)
77
+ # cinema.full_name
78
+ # #=> 'Cineworld Glasgow: IMAX at GSC'
79
+
80
+ # @!method locality
81
+ # The locality (town) of the cinema
82
+ # @return [String]
83
+ # @example
84
+ # cinema = CineworldUk::Cinema.new(3)
85
+ # cinema.locality
86
+ # #=> 'Brighton'
87
+
88
+ # The name of the cinema
102
89
  # @return [String]
103
90
  # @example
104
- # cinema = CineworldUk::Cinema.find(88)
105
- # cinema.full_name
106
- # #=> 'Cineworld Glasgow: IMAX at GSC'
107
- def full_name
108
- "#{brand} #{name}"
109
- end
110
-
111
- # The locality (town) of the cinema
112
- # @return [String]
113
- # @example
114
- # cinema = CineworldUk::Cinema.find(3)
115
- # cinema.locality
91
+ # cinema = CineworldUk::Cinema.new(3)
92
+ # cinema.name
116
93
  # #=> 'Brighton'
117
- # @note Uses the standard method naming as at http://microformats.org/wiki/adr
118
- def locality
119
- if adr_has_region? && !adr_in_london?
120
- adr_array[-2]
121
- else
122
- adr_array[-1]
123
- end
124
- end
125
-
126
- # Post code of the cinema
94
+ def name
95
+ @name ||= self.class.id_names_hash[id]
96
+ end
97
+
98
+ # @!method postal_code
99
+ # Post code of the cinema
100
+ # @return [String]
101
+ # @example
102
+ # cinema = CineworldUk::Cinema.new(3)
103
+ # cinema.postal_code
104
+ # #=> 'BN2 5UF'
105
+
106
+ # @!method region
107
+ # The region (county) of the cinema if provided
108
+ # @return [String]
109
+ # @example
110
+ # cinema = CineworldUk::Cinema.new(3)
111
+ # cinema.region
112
+ # #=> 'East Sussex'
113
+
114
+ # @!method slug
115
+ # The URL-able slug of the cinema
116
+ # @return [String]
117
+ # @example
118
+ # cinema = CineworldUk::Cinema.new(3)
119
+ # cinema.slug
120
+ # #=> 'odeon-brighton'
121
+
122
+ # @!method street_address
123
+ # The street address of the cinema
124
+ # @return [String]
125
+ # @example
126
+ # cinema = CineworldUk::Cinema.new(3)
127
+ # cinema.street_address
128
+ # #=> 'Brighton Marina'
129
+ # @note Uses the standard method naming as at http://microformats.org/wiki/adr
130
+
131
+ # The url of the cinema on the Cineworld website
127
132
  # @return [String]
128
- # @example
129
- # cinema = CineworldUk::Cinema.find(3)
130
- # cinema.postal_code
131
- # #=> 'BN2 5UF'
132
- # @note Uses the standard method naming as at http://microformats.org/wiki/adr
133
- def postal_code
134
- return unless last_adr_line_array[-2..-1]
135
- last_adr_line_array[-2..-1] * ' '
136
- end
137
-
138
- # The region (county) of the cinema if provided
139
- # @return [String, nil]
140
- # @example
141
- # cinema = CineworldUk::Cinema.find(3)
142
- # cinema.region
143
- # #=> 'East Sussex'
144
- # @note Uses the standard method naming as at http://microformats.org/wiki/adr
145
- def region
146
- last_adr_line_non_postal_code if adr_has_region? && !adr_in_london?
147
- end
148
-
149
- # All planned screenings
150
- # @return [Array<CineworldUk::Screening>]
151
- # @example
152
- # cinema = CineworldUk::Cinema.find(3)
153
- # cinema.screenings
154
- # # => [<CineworldUk::Screening>, <CineworldUk::Screening>, ...]
155
- def screenings
156
- Screening.at(id)
157
- end
158
-
159
- # The street adress of the cinema
160
- # @return a String
161
- # @example
162
- # cinema = CineworldUk::Cinema.find(3)
163
- # cinema.street_address
164
- # #=> 'Brighton Marina'
165
- # @note Uses the standard method naming as at http://microformats.org/wiki/adr
166
- def street_address
167
- adr_parts[0]
133
+ def url
134
+ "http://www.cineworld.co.uk/cinemas/#{@id}/information"
168
135
  end
169
136
 
170
137
  private
171
138
 
172
- def self.cinemas_doc
173
- @cinemas_doc ||= Nokogiri::HTML(website.cinemas)
174
- end
175
-
176
- def self.website
177
- @website ||= CineworldUk::Internal::Website.new
178
- end
179
-
180
- def adr_array
181
- adr_parts[0..-2] << last_adr_line_non_postal_code
182
- end
183
-
184
- def adr_content
185
- information_doc.css('address.marker').to_s
139
+ # @api private
140
+ def self.api
141
+ @api ||= CineworldUk::Internal::ApiResponse.new
186
142
  end
187
143
 
188
- def adr_parts
189
- @parts ||= begin
190
- return [] unless adr_content
191
- out = adr_content.split('<br>')[-2]
192
- return [] unless out
193
- out.split(',').map(&:strip)
194
- end
195
- end
196
-
197
- def adr_in_london?
198
- last_adr_line_non_postal_code == 'London'
199
- end
200
-
201
- def adr_has_region?
202
- last_adr_line_non_postal_code != name
203
- end
204
-
205
- def last_adr_line_array
206
- return [] unless adr_parts[-1]
207
- adr_parts[-1].split(' ')
208
- end
209
-
210
- def last_adr_line_non_postal_code
211
- last_adr_line_array[0..-3] * ' '
212
- end
213
-
214
- def information_doc
215
- @information_doc ||= begin
216
- info = CineworldUk::Internal::Website.new.cinema_information(@id)
217
- Nokogiri::HTML(info)
218
- end
144
+ # @api private
145
+ def self.cinema_list_json
146
+ @cinema_list_json ||=
147
+ JSON.parse(api.cinema_list)['cinemas']
219
148
  end
220
149
 
221
- def remaining_address
222
- adr_array.delete_if do |e|
223
- e == street_address || e == locality || e == region
150
+ # @api private
151
+ def self.id_names_hash
152
+ @id_names_hash ||= cinema_list_json.each_with_object({}) do |hash, result|
153
+ result[hash['id']] =
154
+ hash['name'].gsub('London - ', '').gsub(' - ', ': ')
224
155
  end
225
156
  end
226
157
  end
@@ -0,0 +1,74 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+
4
+ module CineworldUk
5
+ # @api private
6
+ module Internal
7
+ # @api private
8
+ class ApiResponse
9
+ # Basic cinema list of ids/names
10
+ # @return [String] JSON encoded
11
+ def cinema_list
12
+ response('cinema/list', full: true)
13
+ end
14
+
15
+ # List of dates on which there are screening for this cinema id
16
+ # @param [Fixnum] id the id of the cinema
17
+ # @return [String] JSON encoded
18
+ def dates(id)
19
+ response('dates', cinema: id)
20
+ end
21
+
22
+ # Detail about a specific cinema
23
+ # @param [Fixnum] id the id of the cinema
24
+ # @return [String] JSON encoded
25
+ def cinema_detail(id)
26
+ response('cinema/detail', cinema: id)
27
+ end
28
+
29
+ # List of all currently showing films
30
+ # @return [String] JSON encoded
31
+ def film_list
32
+ response('film/list', full: true)
33
+ end
34
+
35
+ # List of all upcoming films
36
+ # @return [String] JSON encoded
37
+ def film_list_comingsoon
38
+ response('film/list/comingsoon', full: true)
39
+ end
40
+
41
+ # All screenings from a specific cinema on a specific date
42
+ # @param [Fixnum] cinema_id the id of the cinema
43
+ # @param [Date] date a single date in the future
44
+ # @return [String] JSON encoded
45
+ def performances(cinema_id, date)
46
+ response('performances', cinema: cinema_id,
47
+ date: date.strftime('%Y%m%d'))
48
+ end
49
+
50
+ private
51
+
52
+ # @api private
53
+ # mixin the default hash
54
+ DEFAULTS = { key: 'ios', territory: 'GB' }
55
+
56
+ def fetch(uri, limit = 10)
57
+ fail ArgumentError, 'too many HTTP redirects' if limit == 0
58
+
59
+ case response = Net::HTTP.get_response(URI(uri))
60
+ when Net::HTTPSuccess then response.body
61
+ when Net::HTTPRedirection then fetch(response['location'], limit - 1)
62
+ else response.code
63
+ end
64
+ end
65
+
66
+ def response(path, hash)
67
+ uri = URI::HTTP.build(host: 'www2.cineworld.co.uk',
68
+ path: "/api/#{path}",
69
+ query: URI.encode_www_form(hash.merge(DEFAULTS)))
70
+ fetch(uri)
71
+ end
72
+ end
73
+ end
74
+ end