lcbo 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ Version 1.2.1
2
+
3
+ * Updated `StorePage` to deal with changes made on LCBO.com.
4
+
1
5
  Version 1.2.0
2
6
 
3
7
  * Updated dependencies.
@@ -7,28 +7,18 @@ module LCBO
7
7
 
8
8
  uri 'http://www.lcbo.com/lcbo-ear/jsp/storeinfo.jsp?STORE={id}&language=EN'
9
9
 
10
- DAY_NAMES = %w[
11
- monday
12
- tuesday
13
- wednesday
14
- thursday
15
- friday
16
- saturday
17
- sunday ]
18
-
19
- DETAIL_FIELDS = {
10
+ FEATURE_FIELDS = {
20
11
  :has_wheelchair_accessability => 'wheelchair',
21
12
  :has_bilingual_services => 'bilingual',
22
13
  :has_product_consultant => 'consultant',
23
14
  :has_tasting_bar => 'tasting',
24
15
  :has_beer_cold_room => 'cold',
25
16
  :has_special_occasion_permits => 'permits',
26
- :has_vintages_corner => 'vintages',
17
+ :has_vintages_corner => 'corner',
27
18
  :has_parking => 'parking',
28
19
  :has_transit_access => 'transit' }
29
20
 
30
21
  on :before_parse, :verify_store_returned
31
- on :after_parse, :verify_node_count
32
22
  on :after_parse, :verify_telephone_number
33
23
 
34
24
  emits :id do
@@ -36,7 +26,7 @@ module LCBO
36
26
  end
37
27
 
38
28
  emits :name do
39
- CrawlKit::TitleCaseHelper[info_nodes[1].content.strip]
29
+ CrawlKit::TitleCaseHelper[doc.css('.infoWindowTitle')[0].content.strip]
40
30
  end
41
31
 
42
32
  emits :tags do
@@ -50,7 +40,7 @@ module LCBO
50
40
  end
51
41
 
52
42
  emits :address_line_1 do
53
- data = info_nodes[2].content.strip.split(',')[0]
43
+ data = info_nodes[2].content.strip
54
44
  unless data
55
45
  raise CrawlKit::MalformedError,
56
46
  "unable to locate address for store #{idid}"
@@ -59,134 +49,116 @@ module LCBO
59
49
  end
60
50
 
61
51
  emits :address_line_2 do
62
- data = info_nodes[2].content.strip.split(',')[1]
63
- CrawlKit::TitleCaseHelper[data.gsub(/[\n\r\t]+/, ' ').strip] if data
52
+ data = info_nodes[3].content.strip
53
+ CrawlKit::TitleCaseHelper[data] if data != ''
64
54
  end
65
55
 
66
56
  emits :city do
67
- data = info_nodes[3].content.strip.split(',')[0]
68
- CrawlKit::TitleCaseHelper[data.gsub(/[\n\r\t]+/, ' ').strip] if data
57
+ pos = get_info_node_offset(4)
58
+ data = info_nodes[pos].content.strip.split(',')[0]
59
+ CrawlKit::TitleCaseHelper[data.strip] if data
69
60
  end
70
61
 
71
62
  emits :postal_code do
72
- data = info_nodes[3].content.strip.split(',')[1]
63
+ pos = get_info_node_offset(4)
64
+ data = info_nodes[pos].content.strip.split(',')[1]
73
65
  unless data
74
66
  raise CrawlKit::MalformedError,
75
67
  "unable to locate postal code for store #{id}"
76
68
  end
77
- data.gsub(/[\n\r\t]+/, ' ').strip.upcase
69
+ data.strip.upcase
78
70
  end
79
71
 
80
72
  emits :telephone do
73
+ pos = get_info_node_offset(6)
81
74
  CrawlKit::PhoneHelper[
82
- info_nodes[4].content.
83
- gsub(/[\n\r\t]+/, ' ').
84
- gsub('Telephone:', '').
85
- strip
75
+ info_nodes[pos].content.sub('Telephone:', '').strip
86
76
  ]
87
77
  end
88
78
 
89
79
  emits :fax do
90
80
  if has_fax?
81
+ pos = (info_nodes_count - 1)
91
82
  CrawlKit::PhoneHelper[
92
- info_nodes[5].content.gsub(/[\n\r\t]+/, ' ').gsub('Fax:', '').strip
83
+ info_nodes[pos].content.sub('Fax:', '').strip
93
84
  ]
94
85
  end
95
86
  end
96
87
 
97
88
  emits :latitude do
98
- location[0].to_f
89
+ node = doc.css('#latitude').first
90
+ node ? node[:value].to_f : nil
99
91
  end
100
92
 
101
93
  emits :longitude do
102
- location[1].to_f
94
+ node = doc.css('#longitude').first
95
+ node ? node[:value].to_f : nil
103
96
  end
104
97
 
105
- DAY_NAMES.each do |day|
98
+ Date::DAYNAMES.map { |d| d.downcase }.each do |day|
106
99
  emits :"#{day}_open" do
107
- time_open_close(day)[0]
100
+ open_close_times[day.downcase][0]
108
101
  end
109
102
 
110
103
  emits :"#{day}_close" do
111
- time_open_close(day)[1]
104
+ open_close_times[day.downcase][1]
112
105
  end
113
106
  end
114
107
 
115
- DETAIL_FIELDS.keys.each do |field|
116
- emits(field) { details[field] }
108
+ FEATURE_FIELDS.keys.each do |field|
109
+ emits(field) { features[field] }
117
110
  end
118
111
 
119
- def detail_rows
120
- @detail_rows ||= begin
121
- doc.css('input[type="checkbox"]').map { |e| e.parent.parent.inner_html }
122
- end
123
- end
124
-
125
- def details
126
- @details ||= begin
127
- DETAIL_FIELDS.reduce({}) do |hsh, (field, term)|
128
- row = detail_rows.detect { |row| row.include?(term) }
129
- value = row.include?('checked')
130
- hsh.merge(field => value)
131
- end
132
- end
112
+ def get_info_node_offset(index)
113
+ pos = (info_nodes_count == 9 ? index : index + 1)
114
+ pos += (info_nodes_count == 9 ? 1 : -1) unless has_fax?
115
+ pos
133
116
  end
134
117
 
135
- def map_anchor_href
136
- @map_anchor_href ||= begin
137
- info_nodes[has_fax? ? 6 : 5].css('a').first.attributes['href'].to_s
118
+ def feature_cells
119
+ @feature_cells ||= begin
120
+ doc.css('input[type="checkbox"]').map { |el| el.parent.inner_html }
138
121
  end
139
122
  end
140
123
 
141
- def location
142
- @location ||= begin
143
- CGI.parse(URI.parse(map_anchor_href).query)['q'][0].to_s.split(',')
124
+ def features
125
+ @details ||= begin
126
+ Hash[FEATURE_FIELDS.map { |field, term|
127
+ cell = feature_cells.detect { |cell| cell.include?(term) }
128
+ value = cell.include?('checked')
129
+ [field, value]
130
+ }]
144
131
  end
145
132
  end
146
133
 
147
134
  def has_fax?
148
- info_nodes.to_s.include?('Fax: ')
149
- end
150
-
151
- def time_open_close(day)
152
- open_close_times[day.to_s.downcase]
135
+ info_nodes.to_s.include?('Fax:')
153
136
  end
154
137
 
155
138
  def open_close_times
156
139
  @open_close_times ||= begin
157
- time_cells.inject({}) do |hsh, td|
158
- text = td.text.gsub(/\s+/, ' ')
159
- day = text.match(/[MTWTFS]{1}[a-z]+/).to_s.downcase
160
- times = text.scan(/[0-9]{1,2}:[0-9]{2}/)
140
+ days = Date::DAYNAMES.map { |d| d.downcase }
141
+ Hash[days.each_with_index.map { |day, idx|
142
+ text = doc.css("#row#{idx}Time.hours")[0].content
143
+ next [day, [nil, nil]] if text.include?('Closed')
144
+ times = text.split('-')
161
145
  open, close = *times.map { |time|
162
- hour, min = *time.split(':').map { |t| t.to_i }
146
+ ord = time.include?('PM') ? 12 : 0
147
+ hour, min = *time.sub(/AM|PM/, '').strip.split(':').map { |t| t.to_i }
148
+ hour += ord
163
149
  (hour * 60) + min
164
150
  }
165
- hsh.merge(day => (open == close ? [nil, nil] : [open, close]))
166
- end
151
+ [day, (open == close ? [nil, nil] : [open, close])]
152
+ }]
167
153
  end
168
154
  end
169
155
 
170
- def container_table
171
- @doc.css('table.border[width="478"]')
172
- end
173
-
174
- def hours_table
175
- container_table.css('table[width="100%"]')
156
+ def info_nodes_count
157
+ info_nodes.size
176
158
  end
177
159
 
178
160
  def info_nodes
179
- container_table.css('td[width="48%"]')
180
- end
181
-
182
- def time_cells
183
- hours_table.
184
- css('td[width="50%"] tr').
185
- select { |td| td.to_s =~ /[MTWTFS]{1}[onuesdhriat]{2,5}day/ }
186
- end
187
-
188
- def expected_node_count
189
- has_fax? ? 8 : 7
161
+ doc.css('#storeDetails td.main_font')
190
162
  end
191
163
 
192
164
  def verify_store_returned
@@ -200,12 +172,5 @@ module LCBO
200
172
  "unable to locate telephone number for store #{id}"
201
173
  end
202
174
 
203
- def verify_node_count
204
- return if expected_node_count == info_nodes.size
205
- raise CrawlKit::MalformedError,
206
- "Expected #{expected_node_count} nodes for store #{id} but found " \
207
- "#{info_nodes.size} instead."
208
- end
209
-
210
175
  end
211
176
  end
data/lib/lcbo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LCBO
2
- VERSION = '1.2.0'
2
+ VERSION = '1.2.1'
3
3
  end