lothianbusestimetable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 89109e7c243f925900258b5abfaf15ccc4171fef
4
+ data.tar.gz: 8036b687f860a180f3cd8a238f5c4c1e7e64b2bb
5
+ SHA512:
6
+ metadata.gz: 2551f7e1894eb925bc324935298c91e89849e95a64e7b83570d3e5aca527190a06d7267070f98fad437b4d0908e2386dfe90afcd57bbc0fa4c06ccf435fd6dc8
7
+ data.tar.gz: ecabce83a5273642bba82590710e8b3b21c0a091676e0a42f935a5c7979fe60ba167a318d3698f4256900a00e94468fde0373e474f0206acb479c501fdaa45df
checksums.yaml.gz.sig ADDED
Binary file
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # file: lothianbusestimetable.rb
4
+
5
+ require 'time'
6
+ require 'nokorexi'
7
+
8
+ =begin
9
+
10
+ # Example usage:
11
+
12
+ lbt = LothianBusesTimetable.new
13
+ lbt.fetch_timetable '44'
14
+ lbt.timetable.keys #=> [:service, :weekday, :saturday, :sunday]
15
+ lbt.timetable[:weekday][:inbound]
16
+
17
+ # return the bus times for Juniper Green heading towards Balerno
18
+ lbt.timetable[:weekday][:outbound]["Juniper Green Post Office"]
19
+
20
+ =end
21
+
22
+
23
+ class LothianBusesTimetable
24
+
25
+ attr_reader :timetable
26
+
27
+ def initialize
28
+ super()
29
+ @base_url = 'https://lothianbuses.co.uk/timetables-and-maps/timetables/'
30
+ end
31
+
32
+ def fetch_timetable(service_number)
33
+
34
+ url = @base_url + service_number
35
+
36
+ doc = Nokorexi.new(url).to_doc
37
+
38
+ table = doc.root.element('//table')
39
+
40
+ prev_col = ''
41
+ a0 = []
42
+
43
+ # get the destinations
44
+ # inbound and outbound
45
+ table.xpath('tr').each do |tr|
46
+
47
+ # get the name
48
+ a = tr.xpath('td//text()').map(&:to_s)
49
+
50
+ col1 = a.shift.strip
51
+
52
+ if col1 =~ /Service (\w?\d+)/ then
53
+
54
+ a0 << {service: $1}
55
+
56
+ elsif col1.empty? or col1.length <= 1
57
+
58
+ if prev_col.empty? or prev_col.length <= 1 and a0.last.any? then
59
+
60
+ a0 << {}
61
+
62
+ else
63
+
64
+ prev_col = ''
65
+ end
66
+
67
+ elsif prev_col =~ /Service \w?\d+/
68
+
69
+ a0.last.merge!(timetable: col1)
70
+
71
+ else
72
+
73
+ if a.any? then
74
+
75
+ h = a0.last
76
+
77
+ if h.has_key? col1 then
78
+ h[col1].concat a
79
+ else
80
+ h[col1] = a
81
+ end
82
+
83
+ else
84
+ a0.pop if a0.last.empty?
85
+ end
86
+ end
87
+
88
+ prev_col = col1
89
+
90
+ end
91
+
92
+
93
+ master = {
94
+ service: '',
95
+ weekday: {desc: '', inbound: {}, outbound: {}},
96
+ saturday: {desc: '', inbound: {}, outbound: {}},
97
+ sunday: {desc: '', inbound: {}, outbound: {}}
98
+ }
99
+
100
+ h = a0.shift
101
+ master[:service] = h[:service]
102
+ master[:weekday][:desc] = h[:timetable]
103
+
104
+ h = a0.shift
105
+ master[:weekday][:inbound] = h
106
+ h = a0.shift
107
+ master[:weekday][:outbound] = h
108
+
109
+ h = a0.shift
110
+ h = a0.shift until h.any?
111
+ master[:saturday][:desc] = h[:timetable]
112
+ h = a0.shift
113
+ master[:saturday][:inbound] = h
114
+ h = a0.shift
115
+ master[:saturday][:outbound] = h
116
+
117
+ h = a0.shift
118
+ h = a0.shift until h.any?
119
+ master[:sunday][:desc] = h[:timetable]
120
+ h = a0.shift
121
+ master[:sunday][:inbound] = h
122
+ h = a0.shift
123
+ master[:sunday][:outbound] = h
124
+
125
+ # note: the special character looks like a space
126
+ # but is in fact " ".ord #=> 160
127
+
128
+ master.to_a[1..-1].each do |key, timetable|
129
+
130
+ timetable.to_a[1..-1].each do |direction, printed_rows|
131
+
132
+ # find the interval gaps
133
+
134
+ a = printed_rows.to_a
135
+ index = a.index a.detect {|x| x.last.grep(/^ $/).any? }
136
+ a2 = a[index].last
137
+
138
+ gaps = a2.map.with_index.select {|x,i| x == " "}.map(&:last)
139
+
140
+ gaps.delete_at -1 if gaps.last >= a2.length - 1
141
+
142
+ # sanitise the times (where short hand times are
143
+ # given i.e. minutes only)
144
+
145
+ printed_rows.each do |name, row|
146
+
147
+ prev_time = nil
148
+ printed_rows[name] = row.map.with_index do |col,i|
149
+
150
+ if gaps.include? i then
151
+ col
152
+ else
153
+ case col
154
+ when /^\d{4}$/
155
+ # record the time
156
+ prev_time = Time.strptime(col, "%H%M")
157
+ col
158
+ when /^\d{2}$/
159
+
160
+ # substitute with a time
161
+ val = "%02d%02d" % [prev_time.hour, col.to_i]
162
+
163
+ #if col is less than minutes, increment the hour
164
+ t = Time.strptime(val, "%H%M")
165
+ t = t + (60 * 60) if prev_time.min > t.min
166
+ prev_time = t
167
+ t.strftime("%H%M")
168
+ else
169
+ col
170
+ end
171
+ end
172
+ end
173
+
174
+ end
175
+
176
+ # fill in the gaps
177
+
178
+ periods = gaps.map {|i| a.map {|k,v| v[i].to_s.gsub(/\W/,'')}
179
+ .compact.join(' ').strip }
180
+
181
+ gap_times = gaps.zip(periods)
182
+
183
+
184
+ intervaltimes = gap_times.map do |i, desc|
185
+
186
+ interval = desc[/then every (\d+) mins until/,1].to_i
187
+
188
+ new_rows = printed_rows.map do |k,v|
189
+
190
+ times = []
191
+ next unless v[i-1] && v[i-1] =~ /^\d{4}$/
192
+
193
+ t = Time.strptime(v[i-1], "%H%M") #if v[i-1] =~ /^\d{4}$/
194
+
195
+ while t + (60 * interval) < Time.strptime(v[i+1], "%H%M") do
196
+ t = t + (60 * interval)
197
+ times << t.strftime("%H%M")
198
+ end
199
+
200
+ [k,times]
201
+ end.compact
202
+
203
+ [i, new_rows]
204
+ end
205
+
206
+ intervaltimes.reverse.each do |i, rows|
207
+
208
+ rows.each do |name, xtimes|
209
+
210
+ printed_rows[name].delete_at i
211
+ printed_rows[name].insert i, *xtimes
212
+
213
+ end
214
+
215
+ end
216
+ end
217
+ end
218
+
219
+ @timetable = master
220
+
221
+ end
222
+ end
223
+
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lothianbusestimetable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Robertson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDljCCAn6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBIMRIwEAYDVQQDDAlnZW1t
14
+ YXN0ZXIxHjAcBgoJkiaJk/IsZAEZFg5qYW1lc3JvYmVydHNvbjESMBAGCgmSJomT
15
+ 8ixkARkWAmV1MB4XDTE3MDgyMjEyMzg1OFoXDTE4MDgyMjEyMzg1OFowSDESMBAG
16
+ A1UEAwwJZ2VtbWFzdGVyMR4wHAYKCZImiZPyLGQBGRYOamFtZXNyb2JlcnRzb24x
17
+ EjAQBgoJkiaJk/IsZAEZFgJldTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
18
+ ggEBANn4wnsqPgnkuEmMe25DFlvzQD22UYMiPEFTfNC6WWoD/XGT/YV9hgPQ0Vxe
19
+ JdP67UjkqAT7dGceN7dBie6cjDx0koddtOOdioYQQ4i/ugCeyQPuqHbsSbDr2Dpu
20
+ wEQFUWAY3QXSuQojLwNIF9N1jwa6eTZji77VyA/+t5HO485EB4AQjBAgS1j09XRQ
21
+ 8mInZcpsDFXy+SRmKy/k5UgoO+UPl1l7frGfF7ngad6Y66hFhv/qBg4bSbyHytfL
22
+ G1BSTbsXYFw+TemSHNOZ6omP5Gi6PIMZHbc8nOgPSVJ3miMTI3HSIvArrnmsF3Dg
23
+ FtLWSyZhm09xfPQp6O+eRkRugHUCAwEAAaOBijCBhzAJBgNVHRMEAjAAMAsGA1Ud
24
+ DwQEAwIEsDAdBgNVHQ4EFgQUWWYnDtPOZj84D4zYKoL5ka1Xg/gwJgYDVR0RBB8w
25
+ HYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1h
26
+ c3RlckBqYW1lc3JvYmVydHNvbi5ldTANBgkqhkiG9w0BAQUFAAOCAQEAb8XQ6GME
27
+ ZhiRy44IrSVoTn9x+0/vXlSiR0A5pp/6l/tIhnCLRj033XA6WEYLGhhh8pYP8rbW
28
+ YPThZ/7jz2yzazCzfcvHi8dTd5RHtHZC2P5doj0yqjG+zBtq4nlmfZFSDD+m5+wJ
29
+ FNnNN1AZxxllHLxtBFvBhHMpccjU1BP/Rnmw9x9+l25eCn+GbvqvV1jurtKGWcml
30
+ DF7dZobpSzQTyh2BO/HWiJSdKHB6sB5oKWvpCDW4eltRAg/QLku5bkCK25zPVg5f
31
+ K7yWGJq+eGl34xrLaucvTbO8Ua3rHayCkBzgfx5LVcch22Axj8quw+YGsPnhuosr
32
+ BHdCmx9eUF/TKg==
33
+ -----END CERTIFICATE-----
34
+ date: 2017-08-22 00:00:00.000000000 Z
35
+ dependencies: []
36
+ description:
37
+ email: james@jamesrobertson.eu
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - lib/lothianbusestimetable.rb
43
+ homepage: https://github.com/jrobertson/lothianbusestimetable
44
+ licenses:
45
+ - MIT
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.6.8
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: lothianbusestimetable
67
+ test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ ��.6��]��<0^{�S_ݏ�]@���Y��j_� �x���eN=ہ� �#�q@���)s��i.�턍
2
+ �<��^��l�zRXB���\��WN�w��I�*N ڃܑ�/���N������ (Z 1��b�Ui�-:�0��yuC�ߡ+�2�Z����#1k~�e�>ʴ��a�3Tp���k%M��A�����$5�j��+����N��@9d����+ �Hs�T�sc�kz�3]��]���