picturehouse_uk 1.0.2 → 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 +2 -1
- data/CHANGELOG.md +18 -0
- data/README.md +7 -10
- data/Rakefile +20 -7
- data/lib/picturehouse_uk.rb +4 -1
- data/lib/picturehouse_uk/cinema.rb +51 -100
- data/lib/picturehouse_uk/film.rb +22 -8
- data/lib/picturehouse_uk/internal/address_parser.rb +72 -0
- data/lib/picturehouse_uk/internal/cinema_page.rb +35 -0
- data/lib/picturehouse_uk/internal/film_with_screenings_parser.rb +87 -37
- data/lib/picturehouse_uk/internal/title_sanitizer.rb +49 -0
- data/lib/picturehouse_uk/internal/website.rb +39 -0
- data/lib/picturehouse_uk/screening.rb +63 -19
- data/lib/picturehouse_uk/version.rb +2 -2
- data/picturehouse_uk.gemspec +11 -11
- data/test/fixture_updater.rb +43 -0
- data/test/fixtures/address-fragments/duke-of-yorks.html +39 -0
- data/test/fixtures/address-fragments/hackney-picturehouse.html +12 -0
- data/test/fixtures/cinema/Duke_Of_Yorks.html +4370 -0
- data/test/fixtures/cinema/Duke_Of_Yorks/film_last.html +45 -0
- data/test/fixtures/cinema/Duke_Of_Yorks/film_second.html +37 -0
- data/test/fixtures/{abbeygate-contact-us.html → contact_us/Duke_Of_Yorks.html} +635 -156
- data/test/fixtures/{dukes-at-komedia-contact-us.html → contact_us/Dukes_At_Komedia.html} +582 -98
- data/test/fixtures/{picturehouses-homepage.html → home.html} +642 -146
- data/test/lib/picturehouse_uk/cinema_test.rb +127 -307
- data/test/lib/picturehouse_uk/film_test.rb +65 -16
- data/test/lib/picturehouse_uk/internal/address_parser_test.rb +55 -0
- data/test/lib/picturehouse_uk/internal/cinema_page_test.rb +51 -0
- data/test/lib/picturehouse_uk/internal/film_with_screenings_parser_test.rb +44 -151
- data/test/lib/picturehouse_uk/internal/title_sanitizer_test.rb +131 -0
- data/test/lib/picturehouse_uk/internal/website_test.rb +64 -0
- data/test/lib/picturehouse_uk/screening_test.rb +149 -21
- data/test/live/integration_test.rb +68 -0
- data/test/test_helper.rb +3 -1
- metadata +40 -43
- data/test/fixtures/dukes-at-komedia-cinema.html +0 -7148
- data/test/fixtures/film_node/blue-jasmine-done.html +0 -53
- data/test/fixtures/film_node/blue-jasmine-future.html +0 -55
- data/test/fixtures/film_node/bolshoi-spartacus.html +0 -26
- data/test/fixtures/film_node/captain-phillips-with-silver-screen-and-subtitles.html +0 -103
- data/test/fixtures/film_node/fifth-estate-with-big-scream.html +0 -73
- data/test/fixtures/film_node/london-film-festival-with-toddler-time.html +0 -46
- data/test/fixtures/film_node/met-encore-rusalka-as-live.html +0 -26
- data/test/fixtures/film_node/nt-encore-hamlet.html +0 -26
- data/test/fixtures/film_node/planes-with-kids-club.html +0 -77
- data/test/fixtures/film_node/royal-opera-house-don-quixote.html +0 -26
- data/test/fixtures/film_node/rsc-encore-richard-ii.html +0 -28
- data/test/fixtures/film_node/rsc-live-richard-ii.html +0 -41
- data/test/fixtures/film_node/rsc-live-the-two-gentlemen-of-verona-zero-cert.html +0 -19
- data/test/fixtures/hackney-contact-us.html +0 -998
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 852cffd41d42e302152ccedd703e8f265b48015f
|
|
4
|
+
data.tar.gz: a2cfd6c6dbb93d841cc2d7c22423d9228363d342
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5da4c31df5e98af0f65e4261eca2de02da13e6f5f80ab5a75171c7b393537e801bab7740cffdfee6ce39caa6994165c3ddc4c91e28ba3f26367590c31863de3
|
|
7
|
+
data.tar.gz: 36e769a6373c03914f241ca65babc5e878552902627d53b6123bdc99918a605009ba0dcc41815933139c918925d7d84be828496f2dfb0853c051e9efcde3f429
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
## 2.0.0 - 2014-10-16
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
- Live testing rake task
|
|
8
|
+
- Ruby 2.1.3 on Travis
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Internal structure of parsers
|
|
12
|
+
- Title sanitization
|
|
13
|
+
- Broke up monolith of Cinema class
|
|
14
|
+
- Fixture update
|
|
15
|
+
- Rubocop
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
- Only the badness
|
data/README.md
CHANGED
|
@@ -5,6 +5,7 @@ A simple gem to parse the [Picturehouse Cinemas UK website](http://picturehouses
|
|
|
5
5
|
[](http://badge.fury.io/rb/picturehouse_uk)
|
|
6
6
|
[](https://codeclimate.com/github/andycroll/picturehouse_uk)
|
|
7
7
|
[](https://travis-ci.org/andycroll/picturehouse_uk)
|
|
8
|
+
[](http://inch-ci.org/github/andycroll/picturehouse_uk)
|
|
8
9
|
|
|
9
10
|
## Installation
|
|
10
11
|
|
|
@@ -26,12 +27,13 @@ Or install it yourself as:
|
|
|
26
27
|
|
|
27
28
|
``` ruby
|
|
28
29
|
PicturehouseUK::Cinema.all
|
|
29
|
-
#=> [
|
|
30
|
+
#=> [
|
|
31
|
+
<PicturehouseUK::Cinema brand="Picturehouse" name="Duke's at Komedia" slug="dukes-at-komedia" chain_id="Dukes_At_Komedia" url="...">,
|
|
32
|
+
<PicturehouseUK::Cinema brand="Picturehouse" name="Duke of York's" slug="duke-of-yorks" chain_id="Duke_Of_Yorks" url="...">,
|
|
33
|
+
...
|
|
34
|
+
]
|
|
30
35
|
|
|
31
|
-
PicturehouseUK::Cinema.
|
|
32
|
-
#=> <PicturehouseUK::Cinema brand="Picturehouse" name="Duke_Of_Yorks" slug="duke-of-yorks" address="..." chain_id="Duke_Of_Yorks" url="...">
|
|
33
|
-
|
|
34
|
-
cinema = PicturehouseUK::Cinema.find_by_slug('duke-of-yorks')
|
|
36
|
+
PicturehouseUK::Cinema.find('Duke_Of_Yorks')
|
|
35
37
|
#=> <PicturehouseUK::Cinema brand="Picturehouse" name="Duke_Of_Yorks" slug="duke-of-yorks" address="..." chain_id="Duke_Of_Yorks" url="...">
|
|
36
38
|
|
|
37
39
|
cinema.brand
|
|
@@ -49,11 +51,6 @@ cinema.films
|
|
|
49
51
|
cinema.screenings
|
|
50
52
|
#=> [<PicturehouseUK::Screening film="About Time" when="2013-09-09 11:00 UTC" varient="3d">, <PicturehouseUK::Screening film="Iron Man 3" when="2013-09-09 13:50 UTC" varient="kids">, <PicturehouseUK::Screening ..>, <PicturehouseUK::Screening ...>]
|
|
51
53
|
|
|
52
|
-
cinema.screenings_of 'Iron Man 3'
|
|
53
|
-
#=> [<PicturehouseUK::Screening film="Iron Man 3" when="2013-09-09 11:00 UTC" varient="3d">, <PicturehouseUK::Screening film="Iron Man 3" when="2013-09-09 13:50 UTC" varient="kids">]
|
|
54
|
-
|
|
55
|
-
cinema.screenings_of <PicturehouseUK::Film name="Iron Man 3">
|
|
56
|
-
#=> [<PicturehouseUK::Screening film="Iron Man 3" when="2013-09-09 11:00 UTC" varient="3d">, <PicturehouseUK::Screening film="Iron Man 3" when="2013-09-09 13:50 UTC" varient="kids">]
|
|
57
54
|
```
|
|
58
55
|
|
|
59
56
|
## Contributing
|
data/Rakefile
CHANGED
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
-
require
|
|
2
|
+
require 'bundler/gem_tasks'
|
|
3
3
|
|
|
4
4
|
require 'rake/testtask'
|
|
5
5
|
|
|
6
6
|
Rake::TestTask.new do |t|
|
|
7
7
|
t.libs << 'lib/picturehouse_uk'
|
|
8
|
-
t.test_files = FileList[
|
|
8
|
+
t.test_files = FileList[
|
|
9
|
+
'test/lib/picturehouse_uk/*_test.rb',
|
|
10
|
+
'test/lib/picturehouse_uk/internal/*_test.rb'
|
|
11
|
+
]
|
|
9
12
|
t.verbose = true
|
|
10
13
|
end
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
Rake::TestTask.new do |t|
|
|
16
|
+
t.libs << 'lib/picturehouse_uk'
|
|
17
|
+
t.name = :live
|
|
18
|
+
t.test_files = FileList[
|
|
19
|
+
'test/live/*_test.rb'
|
|
20
|
+
]
|
|
21
|
+
t.verbose = true
|
|
14
22
|
end
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
# http://erniemiller.org/2014/02/05/7-lines-every-gems-rakefile-should-have/
|
|
25
|
+
task :console do
|
|
26
|
+
require 'irb'
|
|
27
|
+
require 'irb/completion'
|
|
28
|
+
require 'picturehouse_uk'
|
|
29
|
+
ARGV.clear
|
|
30
|
+
IRB.start
|
|
18
31
|
end
|
|
19
32
|
|
|
20
|
-
task :
|
|
33
|
+
task default: :test
|
data/lib/picturehouse_uk.rb
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
require 'httparty'
|
|
2
1
|
require 'nokogiri'
|
|
3
2
|
require 'tzinfo'
|
|
4
3
|
require 'tzinfo/data'
|
|
5
4
|
|
|
6
5
|
require_relative './picturehouse_uk/version'
|
|
7
6
|
|
|
7
|
+
require_relative './picturehouse_uk/internal/address_parser'
|
|
8
|
+
require_relative './picturehouse_uk/internal/cinema_page'
|
|
8
9
|
require_relative './picturehouse_uk/internal/film_with_screenings_parser'
|
|
10
|
+
require_relative './picturehouse_uk/internal/title_sanitizer'
|
|
11
|
+
require_relative './picturehouse_uk/internal/website'
|
|
9
12
|
|
|
10
13
|
require_relative './picturehouse_uk/cinema'
|
|
11
14
|
require_relative './picturehouse_uk/film'
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
module PicturehouseUk
|
|
2
|
-
|
|
3
2
|
# The object representing a cinema on the Picturehouse UK website
|
|
4
3
|
class Cinema
|
|
4
|
+
# address css
|
|
5
|
+
ADDRESS_CSS = '.box6 .txt6'
|
|
6
|
+
# cinema link css
|
|
7
|
+
CINEMA_LINKS_CSS = '#cinemalisthome .cinemas a'
|
|
5
8
|
|
|
6
9
|
# @return [String] the brand of the cinema
|
|
7
10
|
attr_reader :brand
|
|
@@ -14,27 +17,27 @@ module PicturehouseUk
|
|
|
14
17
|
# @return [String] the url of the cinema on the Picturehouse website
|
|
15
18
|
attr_reader :url
|
|
16
19
|
|
|
17
|
-
# @param [
|
|
18
|
-
# @param [String] name cinema name
|
|
19
|
-
# @param [String] url url on Picturehouse website
|
|
20
|
+
# @param [Hash] options id, name and url of the cinemas
|
|
20
21
|
# @return [PicturehouseUk::Cinema]
|
|
21
|
-
def initialize(
|
|
22
|
+
def initialize(options)
|
|
22
23
|
@brand = 'Picturehouse'
|
|
23
|
-
@id = id
|
|
24
|
-
@name = name
|
|
25
|
-
@slug = name.downcase.gsub(/[^0-9a-z ]/,'').gsub(/\s+/, '-')
|
|
26
|
-
@url =
|
|
24
|
+
@id = options[:id]
|
|
25
|
+
@name = options[:name]
|
|
26
|
+
@slug = @name.downcase.gsub(/[^0-9a-z ]/, '').gsub(/\s+/, '-')
|
|
27
|
+
@url = if options[:url][0] == '/'
|
|
28
|
+
"http://www.picturehouses.co.uk#{options[:url]}"
|
|
29
|
+
else
|
|
30
|
+
options[:url]
|
|
31
|
+
end
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
# Return basic cinema information for all cinemas
|
|
30
35
|
# @return [Array<PicturehouseUk::Cinema>]
|
|
31
36
|
# @example
|
|
32
37
|
# PicturehouseUk::Cinema.all
|
|
33
|
-
# # => [<PicturehouseUK::Cinema
|
|
38
|
+
# # => [<PicturehouseUK::Cinema ...>, <PicturehouseUK::Cinema ...>, ...]
|
|
34
39
|
def self.all
|
|
35
|
-
cinema_links.map
|
|
36
|
-
new_from_link link
|
|
37
|
-
end
|
|
40
|
+
cinema_links.map { |link| new_from_link(link) }
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
# Find a single cinema
|
|
@@ -42,9 +45,9 @@ module PicturehouseUk
|
|
|
42
45
|
# @return [PicturehouseUk::Cinema, nil]
|
|
43
46
|
# @example
|
|
44
47
|
# PicturehouseUk::Cinema.find('Dukes_At_Komedia')
|
|
45
|
-
# # => <PicturehouseUK::Cinema
|
|
48
|
+
# # => <PicturehouseUK::Cinema ...>
|
|
46
49
|
def self.find(id)
|
|
47
|
-
all.
|
|
50
|
+
all.find { |cinema| cinema.id == id }
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
# Address of the cinema
|
|
@@ -52,16 +55,16 @@ module PicturehouseUk
|
|
|
52
55
|
# @example
|
|
53
56
|
# cinema = PicturehouseUk::Cinema.find('Dukes_At_Komedia')
|
|
54
57
|
# cinema.adr
|
|
55
|
-
# #=> {
|
|
56
|
-
#
|
|
58
|
+
# #=> {
|
|
59
|
+
# street_address: '44-47 Gardner Street',
|
|
60
|
+
# extended_address: 'North Laine',
|
|
61
|
+
# locality: 'Brighton',
|
|
62
|
+
# postal_code: 'BN1 1UN',
|
|
63
|
+
# country_name: 'United Kingdom'
|
|
64
|
+
# }
|
|
65
|
+
# @note Uses method naming as at http://microformats.org/wiki/adr
|
|
57
66
|
def adr
|
|
58
|
-
|
|
59
|
-
street_address: street_address,
|
|
60
|
-
extended_address: extended_address,
|
|
61
|
-
locality: locality,
|
|
62
|
-
postal_code: postal_code,
|
|
63
|
-
country: 'United Kingdom'
|
|
64
|
-
}
|
|
67
|
+
PicturehouseUk::Internal::AddressParser.new(address_node.to_s).address
|
|
65
68
|
end
|
|
66
69
|
alias_method :address, :adr
|
|
67
70
|
|
|
@@ -71,9 +74,9 @@ module PicturehouseUk
|
|
|
71
74
|
# cinema = PicturehouseUk::Cinema.find('Dukes_At_Komedia')
|
|
72
75
|
# cinema.extended_address
|
|
73
76
|
# #=> 'North Laine'
|
|
74
|
-
# @note Uses
|
|
77
|
+
# @note Uses method naming as at http://microformats.org/wiki/adr
|
|
75
78
|
def extended_address
|
|
76
|
-
|
|
79
|
+
address[:extended_address]
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
# Films with showings scheduled at this cinema
|
|
@@ -81,12 +84,9 @@ module PicturehouseUk
|
|
|
81
84
|
# @example
|
|
82
85
|
# cinema = PicturehouseUk::Cinema.find('Dukes_At_Komedia')
|
|
83
86
|
# cinema.films
|
|
84
|
-
# # => [<PicturehouseUk::Film
|
|
87
|
+
# # => [<PicturehouseUk::Film ...>, <PicturehouseUk::Film ...>, ...]
|
|
85
88
|
def films
|
|
86
|
-
|
|
87
|
-
parser = PicturehouseUk::Internal::FilmWithScreeningsParser.new node.to_s
|
|
88
|
-
PicturehouseUk::Film.new parser.film_name
|
|
89
|
-
end.uniq
|
|
89
|
+
PicturehouseUk::Film.at(@id)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
# The name of the cinema (might include brand)
|
|
@@ -107,7 +107,7 @@ module PicturehouseUk
|
|
|
107
107
|
# #=> 'Brighton'
|
|
108
108
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
|
109
109
|
def locality
|
|
110
|
-
|
|
110
|
+
address[:locality]
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
# Post code of the cinema
|
|
@@ -118,7 +118,7 @@ module PicturehouseUk
|
|
|
118
118
|
# #=> 'BN1 1UN'
|
|
119
119
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
|
120
120
|
def postal_code
|
|
121
|
-
|
|
121
|
+
address[:postal_code]
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# All planned screenings
|
|
@@ -126,17 +126,9 @@ module PicturehouseUk
|
|
|
126
126
|
# @example
|
|
127
127
|
# cinema = PicturehouseUk::Cinema.find('Dukes_At_Komedia')
|
|
128
128
|
# cinema.screenings
|
|
129
|
-
# # => [<PicturehouseUk::Screening
|
|
129
|
+
# # => [<PicturehouseUk::Screening ...>, <PicturehouseUk::Screening ...>]
|
|
130
130
|
def screenings
|
|
131
|
-
|
|
132
|
-
parser = PicturehouseUk::Internal::FilmWithScreeningsParser.new node.to_s
|
|
133
|
-
parser.showings.map do |screening_type, times|
|
|
134
|
-
times.map do |time|
|
|
135
|
-
variant = screening_type == '2d' ? nil : screening_type
|
|
136
|
-
PicturehouseUk::Screening.new parser.film_name, self.name, time, variant
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
end.flatten
|
|
131
|
+
PicturehouseUk::Screening.at(@id)
|
|
140
132
|
end
|
|
141
133
|
|
|
142
134
|
# The street adress of the cinema
|
|
@@ -147,79 +139,38 @@ module PicturehouseUk
|
|
|
147
139
|
# #=> '44-47 Gardner Street'
|
|
148
140
|
# @note Uses the standard method naming as at http://microformats.org/wiki/adr
|
|
149
141
|
def street_address
|
|
150
|
-
|
|
142
|
+
address[:street_address]
|
|
151
143
|
end
|
|
152
144
|
|
|
153
145
|
private
|
|
154
146
|
|
|
155
147
|
def self.cinema_links
|
|
156
|
-
|
|
148
|
+
home_doc.css(CINEMA_LINKS_CSS)
|
|
157
149
|
end
|
|
158
150
|
|
|
159
|
-
def self.
|
|
160
|
-
@
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def self.new_from_link(link)
|
|
164
|
-
url = link.get_attribute('href')
|
|
165
|
-
id = url.match(/\/cinema\/(.+)\/$/)[1]
|
|
166
|
-
name = link.css('span:nth-child(2)').text
|
|
167
|
-
new id, name, url
|
|
151
|
+
def self.home_doc
|
|
152
|
+
@home_doc ||= Nokogiri::HTML(website.home)
|
|
168
153
|
end
|
|
169
154
|
|
|
170
|
-
def self.
|
|
171
|
-
|
|
155
|
+
def self.website
|
|
156
|
+
@website ||= PicturehouseUk::Internal::Website.new
|
|
172
157
|
end
|
|
173
158
|
|
|
174
|
-
def
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def address_strings
|
|
183
|
-
if address_parts && address_parts.length > 0
|
|
184
|
-
address_parts[0..post_code_index]
|
|
185
|
-
else
|
|
186
|
-
# this is a horrendous hack for Hackney Picturehouse
|
|
187
|
-
address_node.css('p').to_s.split('Box Office')[0].split('<br> ')[1..-1]
|
|
188
|
-
end
|
|
159
|
+
def self.new_from_link(link)
|
|
160
|
+
url = link.get_attribute('href')
|
|
161
|
+
new(
|
|
162
|
+
id: url.match(%r{/cinema/(.+)/$})[1],
|
|
163
|
+
name: link.css('span:nth-child(2)').text,
|
|
164
|
+
url: url
|
|
165
|
+
)
|
|
189
166
|
end
|
|
190
167
|
|
|
191
168
|
def address_node
|
|
192
|
-
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def contact_us_response
|
|
196
|
-
@contact_us_response ||= HTTParty.get("#{@url}Hires_Info/Contact_Us/")
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def cinema_response
|
|
200
|
-
@cinema_response ||= HTTParty.get(@url)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def film_nodes
|
|
204
|
-
parsed_cinema.css('.box8_content .largelist .item')
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def parsed_cinema
|
|
208
|
-
Nokogiri::HTML(cinema_response)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def parsed_contact_us
|
|
212
|
-
Nokogiri::HTML(contact_us_response)
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def post_code_index
|
|
216
|
-
address_parts.index { |e| e.match /[A-Z]{1,2}\d{1,2}[A-Z]?\s\d{1,2}[A-Z]{1,2}/ }
|
|
169
|
+
@address_node ||= contact_us_doc.css(ADDRESS_CSS)
|
|
217
170
|
end
|
|
218
171
|
|
|
219
|
-
def
|
|
220
|
-
@
|
|
221
|
-
e.children[0].to_s
|
|
222
|
-
end.select { |e| e != '' }
|
|
172
|
+
def contact_us_doc
|
|
173
|
+
@contact_us_doc ||= Nokogiri::HTML(self.class.website.contact_us(id))
|
|
223
174
|
end
|
|
224
175
|
end
|
|
225
176
|
end
|
data/lib/picturehouse_uk/film.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
module PicturehouseUk
|
|
2
|
-
|
|
3
2
|
# A film on the Picturehouse UK website
|
|
4
3
|
class Film
|
|
5
4
|
include Comparable
|
|
@@ -13,14 +12,23 @@ module PicturehouseUk
|
|
|
13
12
|
# @return [PicturehouseUk::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
|
+
# Films at a single cinema
|
|
19
|
+
# @param [String] cinema_id the id of the cinema
|
|
20
|
+
# @return [Array<PicturehouseUk::Film>]
|
|
21
|
+
def self.at(cinema_id)
|
|
22
|
+
cinema_page(cinema_id).film_html.map do |html|
|
|
23
|
+
new(Internal::FilmWithScreeningsParser.new(html).film_name)
|
|
24
|
+
end.uniq
|
|
17
25
|
end
|
|
18
26
|
|
|
19
27
|
# Allows sort on objects
|
|
20
28
|
# @param [PicturehouseUk::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,26 @@ module PicturehouseUk
|
|
|
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
|
-
# [ Film.new('
|
|
39
|
-
# #=> [ Film.new('
|
|
46
|
+
# [ Film.new('AB'), Film.new('EF') ] & [ Film.new('EF'), Film.new('GH') ]
|
|
47
|
+
# #=> [ Film.new('EF') ]
|
|
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.cinema_page(cinema_id)
|
|
58
|
+
@cinema_page ||= PicturehouseUk::Internal::CinemaPage.new(cinema_id)
|
|
45
59
|
end
|
|
46
60
|
end
|
|
47
61
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module PicturehouseUk
|
|
2
|
+
# @api private
|
|
3
|
+
module Internal
|
|
4
|
+
# Parses a chunk of HTML to derive address
|
|
5
|
+
class AddressParser
|
|
6
|
+
# CSS for address lines
|
|
7
|
+
ADDRESS_LINES_CSS = '.cinemaListBox'
|
|
8
|
+
|
|
9
|
+
# regular expression for postal code
|
|
10
|
+
POSTCODE_REGEX = /[A-Z]{1,2}\d{1,2}[A-Z]?\s\d{1,2}[A-Z]{1,2}/
|
|
11
|
+
|
|
12
|
+
# @param [String] node the HTML to parse into an address
|
|
13
|
+
# @return [PicturehouseUk::Internal::AddressParser]
|
|
14
|
+
def initialize(html)
|
|
15
|
+
@html = html
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Hash] contains :street_address, :extended_address, :locality,
|
|
19
|
+
# :postal_code, :country
|
|
20
|
+
# @note Uses the address naming from http://microformats.org/wiki/adr
|
|
21
|
+
def address
|
|
22
|
+
{
|
|
23
|
+
street_address: array[0],
|
|
24
|
+
extended_address: array.length > 3 ? array[1] : nil,
|
|
25
|
+
locality: array[-2],
|
|
26
|
+
postal_code: array[-1],
|
|
27
|
+
country: 'United Kingdom'
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def array
|
|
34
|
+
@array ||= begin
|
|
35
|
+
if standard?
|
|
36
|
+
lines[0..postal_code_index(lines)]
|
|
37
|
+
else
|
|
38
|
+
# this is a horrendous hack for Hackney Picturehouse
|
|
39
|
+
doc.css('p').to_s.split('Box Office')[0].split('<br> ')[1..-1]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def doc
|
|
45
|
+
@doc ||= Nokogiri::HTML(@html)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def matched_lines
|
|
49
|
+
@matched_lines ||= begin
|
|
50
|
+
matched = doc.css(ADDRESS_LINES_CSS).map { |n| n.children[0].to_s }
|
|
51
|
+
matched.reject { |e| e == '' }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def postal_code_index(array)
|
|
56
|
+
array.index { |element| element.match(POSTCODE_REGEX) }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def lines
|
|
60
|
+
if matched_lines.length > 0 && matched_lines[0].match(/\d+\Z/) # komedia
|
|
61
|
+
["#{matched_lines[0]} #{matched_lines[1]}"] + matched_lines[2..-1]
|
|
62
|
+
else
|
|
63
|
+
matched_lines
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def standard?
|
|
68
|
+
lines && lines.length > 0
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|