Commit cad5285b788e1fa422b02d5e1d2f84094b54e322

Gemified, put libs into better places, added simple server
.gemified
(8 / 0)
  
1---
2:author: Marius Mathiesen
3:summary: API wrapper for Trafikanten
4:version: "0.1"
5:name: Trafikanten
6:dependencies:
7- hpricot
8:email: marius.mathiesen@gmail.com
  
1lib/trafikanten.rb
2lib/trafikanten/station.rb
3lib/trafikanten/departure.rb
4lib/string_extensions.rb
5bin/trafikanten_server
Binary files differ
  
1#!/bin/env ruby
2require 'sinatra'
3
4get '/' do
5 '<h1>Velg stoppested</h1><form method="get" action="/locations"><input name="q" type="text" /><input type="submit"/></form>'
6end
7
8
9get '/locations' do
10 result = []
11 result << '<h1>Velg stasjon</h1><ul>'
12 matches = Station.find_by_name(params[:q])
13 matches.each do |m|
14 result << "<li><a href='/departures/#{m.station_id}/#{m.name}'>#{m.name}</a></li>"
15 end
16 result << "</ul>"
17 result.join("\n")
18end
19
20get '/departures/:station_id/:station_name' do
21 result = []
22 station = Station.new(:station_id => params[:station_id], :name => params[:station_name].url_decode)
23 result << "<h1>Avganger fra #{station.name}</h1>"
24 result << "<ul>"
25 station.realtime_departures.sort{|a,b|a.departure<=>b.departure}.each do |dep|
26 result << "<li>#{dep.to_s}</li>"
27 end
28 result << "</ul>"
29 result.join("\n")
30end
  
1---
2- !ruby/object:Station
3 name: Sinsenveien
4 station_id: "3012086"
5 x: "600257"
6 y: "6645423"
7- !ruby/object:Station
8 name: "Rogneskj\xE6r"
9 station_id: "2160364"
10 x: "589452"
11 y: "6626683"
12- !ruby/object:Station
13 name: Gangtunnelen
14 station_id: "3011817"
15 x: "605912"
16 y: "6648722"
17- !ruby/object:Station
18 name: Vannsbrekka
19 station_id: "6280730"
20 x: "0"
21 y: "0"
22- !ruby/object:Station
23 name: Munkerud
24 station_id: "3010862"
25 x: "601416"
26 y: "6637243"
27- !ruby/object:Station
28 name: Tjernsrud
29 station_id: "2190110"
30 x: "590029"
31 y: "6643675"
32- !ruby/object:Station
33 name: Stubberud
34 station_id: "2130224"
35 x: "608874"
36 y: "6624671"
37- !ruby/object:Station
38 name: Lillebergsvingen
39 station_id: "3011435"
40 x: "600392"
41 y: "6643696"
42- !ruby/object:Station
43 name: Volvat
44 station_id: "3012556"
45 x: "595261"
46 y: "6645131"
47- !ruby/object:Station
48 name: "Bj\xF8rnsonsgt."
49 station_id: "2310306"
50 x: "614459"
51 y: "6648815"
52- !ruby/object:Station
53 name: Rognlikrysset
54 station_id: "2390144"
55 x: "609490"
56 y: "6707331"
57- !ruby/object:Station
58 name: Johnsrudgata
59 station_id: "2190875"
60 x: "582208"
61 y: "6648676"
62- !ruby/object:Station
63 name: "Bj\xF8rnebr\xE5ten"
64 station_id: "2130125"
65 x: "608791"
66 y: "6623860"
67- !ruby/object:Station
68 name: Industriveien
69 station_id: "2130312"
70 x: "604397"
71 y: "6620861"
72- !ruby/object:Station
73 name: Kampheimveien
74 station_id: "3011336"
75 x: "603637"
76 y: "6641482"
77- !ruby/object:Station
78 name: Hauketo st.
79 station_id: "3010911"
80 x: "601043"
81 y: "6635654"
82- !ruby/object:Station
83 name: "Ellingstad\xE5sen"
84 station_id: "2160548"
85 x: "590858"
86 y: "6630604"
87- !ruby/object:Station
88 name: Hauger
89 station_id: "3012644"
90 x: "599036"
91 y: "6653667"
92- !ruby/object:Station
93 name: Vestengveien
94 station_id: "2310207"
95 x: "613474"
96 y: "6650314"
97- !ruby/object:Station
98 name: "St\xF8lsvegen"
99 station_id: "3012075"
100 x: "600929"
101 y: "6646960"
102- !ruby/object:Station
103 name: Dalsbakken
104 station_id: "2150270"
105 x: "595456"
106 y: "6624826"
107- !ruby/object:Station
108 name: Grue
109 station_id: "2370575"
110 x: "626404"
111 y: "6690660"
112- !ruby/object:Station
113 name: "Svestad g\xE5rd"
114 station_id: "2160540"
115 x: "591922"
116 y: "6626549"
117- !ruby/object:Station
118 name: Norderhovgata
119 station_id: "3010664"
120 x: "599491"
121 y: "6643112"
122- !ruby/object:Station
123 name: Skovheim
124 station_id: "3010851"
125 x: "600579"
126 y: "6637771"
127- !ruby/object:Station
128 name: Ingier bru
129 station_id: "2170059"
130 x: "599177"
131 y: "6633351"
132- !ruby/object:Station
133 name: "Sk\xE5rer\xE5sen"
134 station_id: "2300438"
135 x: "609528"
136 y: "6644264"
137- !ruby/object:Station
138 name: Langerudveien
139 station_id: "3011237"
140 x: "602433"
141 y: "6638763"
142- !ruby/object:Station
143 name: Idrettsparken
144 station_id: "2170210"
145 x: "602111"
146 y: "6630491"
147- !ruby/object:Station
148 name: Filipstad
149 station_id: "3010095"
150 x: "595578"
151 y: "6642499"
152- !ruby/object:Station
153 name: Lindeberg T
154 station_id: "3011611"
155 x: "605121"
156 y: "6645433"
157- !ruby/object:Station
158 name: Seiersten
159 station_id: "2150740"
160 x: "592297"
161 y: "6615478"
162- !ruby/object:Station
163 name: Kambo
164 station_id: "1040480"
165 x: "0"
166 y: "0"
167- !ruby/object:Station
168 name: Teisenkrysset
169 station_id: "3011458"
170 x: "601220"
171 y: "6643643"
172- !ruby/object:Station
173 name: Liakollen
174 station_id: "3010947"
175 x: "600863"
176 y: "6633774"
177- !ruby/object:Station
178 name: Hovelsrudvn.
179 station_id: "2300430"
180 x: "611721"
181 y: "6645335"
182- !ruby/object:Station
183 name: Skryta
184 station_id: "2350323"
185 x: "625818"
186 y: "6673386"
187- !ruby/object:Station
188 name: Molykkja
189 station_id: "2370289"
190 x: "623348"
191 y: "6701339"
192- !ruby/object:Station
193 name: "Kjels\xE5salleen"
194 station_id: "3012163"
195 x: "599620"
196 y: "6648649"
197- !ruby/object:Station
198 name: Haugerudveien
199 station_id: "3011534"
200 x: "603500"
201 y: "6643661"
202- !ruby/object:Station
203 name: "Solbergst\xF8a"
204 station_id: "6280620"
205 x: "0"
206 y: "0"
207- !ruby/object:Station
208 name: "Malm\xF8ysundet"
209 station_id: "3010752"
210 x: "598527"
211 y: "6638762"
212- !ruby/object:Station
213 name: "Solg\xE5rden"
214 station_id: "2200485"
215 x: "581072"
216 y: "6635513"
217- !ruby/object:Station
218 name: Ski bussterminal
219 station_id: "2130301"
220 x: "603194"
221 y: "6621446"
222- !ruby/object:Station
223 name: "Solh\xF8gda"
224 station_id: "3011325"
225 x: "603339"
226 y: "6641878"
227- !ruby/object:Station
228 name: "Tveten g\xE5rd"
229 station_id: "3011512"
230 x: "602718"
231 y: "6642946"
232- !ruby/object:Station
233 name: "R\xE6lingen r\xE5dhus"
234 station_id: "2280253"
235 x: "615526"
236 y: "6644991"
237- !ruby/object:Station
238 name: Horgen
239 station_id: "2150641"
240 x: "597593"
241 y: "6618020"
242- !ruby/object:Station
243 name: Engelsrud
244 station_id: "3012633"
245 x: "598480"
246 y: "6649717"
247- !ruby/object:Station
248 name: Brobekk
249 station_id: "3012064"
250 x: "601551"
251 y: "6646590"
252- !ruby/object:Station
253 name: Korsveien
254 station_id: "2160342"
255 x: "594974"
256 y: "6627102"
257- !ruby/object:Station
258 name: Kremlegrenda
259 station_id: "2190765"
260 x: "583763"
261 y: "6643602"
262- !ruby/object:Station
263 name: Hammerstad nord
264 station_id: "2370182"
265 x: "622334"
266 y: "6690888"
267- !ruby/object:Station
268 name: Tangenhagen
269 station_id: "2130202"
270 x: "606264"
271 y: "6629222"
272- !ruby/object:Station
273 name: Manglerud skole
274 station_id: "3011226"
275 x: "601898"
276 y: "6641030"
277- !ruby/object:Station
278 name: Haslevangen
279 station_id: "3011413"
280 x: "600329"
281 y: "6644464"
282- !ruby/object:Station
283 name: Dikemark
284 station_id: "2200760"
285 x: "576995"
286 y: "6630564"
287- !ruby/object:Station
288 name: Tanum skole
289 station_id: "2190570"
290 x: "582616"
291 y: "6639467"
292- !ruby/object:Station
293 name: Jessheim skole
294 station_id: "2350125"
295 x: "620693"
296 y: "6669725"
297- !ruby/object:Station
298 name: Bergkrystallen T
299 station_id: "3011031"
300 x: "602000"
301 y: "6637921"
302- !ruby/object:Station
303 name: Jeppedalen
304 station_id: "2390122"
305 x: "605490"
306 y: "6695093"
307- !ruby/object:Station
308 name: Vilbergvegen
309 station_id: "2350312"
310 x: "618316"
311 y: "6670329"
312- !ruby/object:Station
313 name: Grensestien
314 station_id: "3010936"
315 x: "599769"
316 y: "6633547"
317- !ruby/object:Station
318 name: Nordberg
319 station_id: "2170108"
320 x: "601302"
321 y: "6631129"
322- !ruby/object:Station
323 name: "S\xF8ndre Hallangen"
324 station_id: "2150160"
325 x: "591064"
326 y: "6619534"
327- !ruby/object:Station
328 name: Grefsenseteren
329 station_id: "3012152"
330 x: "600444"
331 y: "6647813"
332- !ruby/object:Station
333 name: Kirkebygda
334 station_id: "2370465"
335 x: "618569"
336 y: "6706886"
337- !ruby/object:Station
338 name: Grefsen stasjon
339 station_id: "3012111"
340 x: "599531"
341 y: "6646271"
342- !ruby/object:Station
343 name: Lofthus
344 station_id: "3012076"
345 x: "600735"
346 y: "6646922"
347- !ruby/object:Station
348 name: "\xC5ros fabrikker"
349 station_id: "6271460"
350 x: "0"
351 y: "0"
352- !ruby/object:Station
353 name: Holtet
354 station_id: "3010741"
355 x: "600030"
356 y: "6639511"
357- !ruby/object:Station
358 name: Jernbanetorget
359 station_id: "3010014"
360 x: "597771"
361 y: "6642697"
362- !ruby/object:Station
363 name: "Bl\xE5b\xE6rveien"
364 station_id: "2130103"
365 x: "604568"
366 y: "6626387"
367- !ruby/object:Station
368 name: Martin Linges vei
369 station_id: "3011127"
370 x: "602969"
371 y: "6639540"
372- !ruby/object:Station
373 name: Ila sikring
374 station_id: "2190097"
375 x: "588491"
376 y: "6647494"
377- !ruby/object:Station
378 name: "Kj\xF8ttmeisveien"
379 station_id: "2110446"
380 x: "595882"
381 y: "6597711"
382- !ruby/object:Station
383 name: Kitty Kiellands vei
384 station_id: "2190284"
385 x: "586422"
386 y: "6642788"
387- !ruby/object:Station
388 name: Vettre
389 station_id: "2200435"
390 x: "582493"
391 y: "6633231"
392- !ruby/object:Station
393 name: Orebakken
394 station_id: "3012435"
395 x: "592547"
396 y: "6647425"
397- !ruby/object:Station
398 name: "Gj\xF8fjell"
399 station_id: "2160526"
400 x: "590404"
401 y: "6624166"
402- !ruby/object:Station
403 name: Heer
404 station_id: "2150630"
405 x: "593532"
406 y: "6617547"
407- !ruby/object:Station
408 name: Nordre Venner
409 station_id: "3012622"
410 x: "588919"
411 y: "6654482"
412- !ruby/object:Station
413 name: Langbakk
414 station_id: "2350213"
415 x: "627217"
416 y: "6666281"
417- !ruby/object:Station
418 name: Sagveien
419 station_id: "2170009"
420 x: "599626"
421 y: "6632003"
422- !ruby/object:Station
423 name: Dokken nord
424 station_id: "2370179"
425 x: "621916"
426 y: "6694204"
427- !ruby/object:Station
428 name: "Rud g\xE5rd"
429 station_id: "2390210"
430 x: "612307"
431 y: "6696180"
432- !ruby/object:Station
433 name: Tveita
434 station_id: "3011523"
435 x: "603125"
436 y: "6643160"
437- !ruby/object:Station
438 name: Gruemyra
439 station_id: "2370553"
440 x: "625877"
441 y: "6689710"
442- !ruby/object:Station
443 name: "V\xE5lerenga"
444 station_id: "3010642"
445 x: "599950"
446 y: "6642608"
447- !ruby/object:Station
448 name: Bogen
449 station_id: "2390119"
450 x: "614408"
451 y: "6692723"
452- !ruby/object:Station
453 name: Fusdal
454 station_id: "2200375"
455 x: "580770"
456 y: "6633543"
457- !ruby/object:Station
458 name: Manglerudveien
459 station_id: "3011215"
460 x: "600880"
461 y: "6641627"
462- !ruby/object:Station
463 name: Strand
464 station_id: "2190185"
465 x: "589297"
466 y: "6641696"
467- !ruby/object:Station
468 name: Holmenhavna
469 station_id: "3012336"
470 x: "593870"
471 y: "6647117"
472- !ruby/object:Station
473 name: Enebakk kirke
474 station_id: "2290180"
475 x: "620560"
476 y: "6627075"
477- !ruby/object:Station
478 name: Arne Garborgs vei
479 station_id: "2300221"
480 x: "610131"
481 y: "6645977"
482- !ruby/object:Station
483 name: Hvile
484 station_id: "2390111"
485 x: "611804"
486 y: "6699450"
487- !ruby/object:Station
488 name: "Slore\xE5sen"
489 station_id: "3010925"
490 x: "600584"
491 y: "6635202"
492- !ruby/object:Station
493 name: Lettvinten
494 station_id: "3012141"
495 x: "599682"
496 y: "6646731"
497- !ruby/object:Station
498 name: To vest
499 station_id: "2160232"
500 x: "591864"
501 y: "6633377"
502- !ruby/object:Station
503 name: Feiring S-lag
504 station_id: "2370454"
505 x: "618586"
506 y: "6707104"
  
1class String
2 def url_encode
3 CGI.escape(self)
4 end
5
6 def url_decode
7 CGI.unescape(self)
8 end
9end
  
1$:.unshift File.dirname(__FILE__)
2require 'rubygems'
3require 'open-uri'
4require 'cgi'
5require 'hpricot'
6require 'yaml'
7
8require 'trafikanten/departure'
9require 'trafikanten/station'
10require 'string_extensions'
11module Trafikanten
12
13end
  
1module Trafikanten
2 class Departure
3 attr_accessor :status, :departure, :destination, :line, :from
4 def initialize(options={})
5 options.each{|k,v|send("#{k}=",v)}
6 end
7
8 def to_s
9 "Linje #{line} fra #{from} til #{destination} klokka #{departure.strftime('%H:%M (%d/%m)')}"
10 end
11 end
12
13end
  
1module Trafikanten
2 class Station
3 attr_accessor :station_id, :name, :district, :x, :y
4
5 def located?
6 !x.nil?
7 end
8 def initialize(options={})
9 options.each{|k,v|send("#{k}=",v)}
10 end
11
12 def to_s
13 "#{name} (#{station_id}) at #{x}/#{y}"
14 end
15
16 def self.find_by_name(a_name)
17 uri = "http://www8.trafikanten.no/txml?type=1&stopname=#{a_name.url_encode}"
18 data = open(uri).read
19 result = []
20 doc = Hpricot(data)
21 (doc/"//stopmatch").each do |match|
22 id = (match/"fromid").inner_html.to_i
23 name = (match/"stopname").inner_html
24 district = (match/"district").inner_html
25 x = (match/"xcoordinate").inner_html
26 y = (match/"ycoordinate").inner_html
27 result << new(:x => x, :y => y, :station_id => id, :name => name, :district => district)
28 end
29 result
30 end
31
32 def self.extract_all_stations_and_record_positions(limit=100)
33 result = []
34 doc = Hpricot(open("http://www.sis.trafikanten.no/xmlrtpi/StopPointList.xml").read)
35 (doc/"stoppoint").each do |point|
36 dsid = (point/"disid").inner_html.split(":").first.to_i.to_s # Nasty, they tend to have something like "012923:1", meaning 12923
37 name = (point/"stopname").inner_html
38 station = new(:station_id => dsid, :name => name)
39 station.guess_location
40 result << station if station.located?
41 break if result.size > limit
42 end
43 File.open("stations.yml","w"){|f|f.write(YAML::dump(result))}
44 end
45
46 # Tries to determine the coordinates, based on a lookup of the name
47 def guess_location
48 candidates = self.class.find_by_name(name)
49 puts "Checking #{candidates}"
50 match = candidates.find{|m|m.station_id.to_i == self.station_id.to_i}
51 if match
52 self.x = match.x
53 self.y = match.y
54 end
55 end
56
57 # There seem to be different data sources for subway stations and the other stations.
58 def subway_station?
59 ["03011930","03012220","03011030","03012365","02190070","02190080","02190090","03010011","03010020","03010031","03010200","03010360","03010370","03010600","03010610","03010770","03010780","03010950","03011010","03011020","03011110","03011120","03011130","03011140","03011200","03011210","03011220","03011310","03011320","03011330","03011400","03011410","03011430","03011440","03011450","03011510","03011520","03011530","03011540","03011610","03011620","03011630","03011710","03011720","03011730","03011810","03011910","03011920","03011940","03012000","03012010","03012020","03012030","03012040","03012100","03012120","03012130","03012210","03012230","03012240","03012260","03012270","03012280","03012305","03012310","03012315","03012320","03012325","03012330","03012340","03012345","03012350","03012355","03012360","03012370","03012375","03012380","03012385","03012390","03012410","03012420","03012430","03012450","03012460","03012560","03012565","03012572","03012630"].include?(station_id)
60 end
61
62 def realtime_url
63 if subway_station?
64 "http://www.sis.trafikanten.no:8088/xmlrtpi/dis/request?DISID=SN$#{station_id}"
65 else
66 "http://www.sis.trafikanten.no/xmlrtpi/dis/request?DISID=SN$#{station_id}"
67 end
68 end
69
70 def realtime_departures
71 result = []
72 doc = Hpricot(open(realtime_url).read)
73 (doc/"disdeviation").each do |m|
74 trip_status = (m/"trip_status").inner_html
75 departure_field = (trip_status == "real") ? "expecteddisdeparturetime" : "scheduleddisdeparturetime"
76 scheduled_departure = (m/departure_field).inner_html
77 destination = (m/"destinationstop").inner_html
78 line = (m/"lineid").inner_html
79 result << Departure.new(:status => trip_status, :departure => Time.parse(scheduled_departure), :destination => destination, :line => line, :from => name)
80 end
81 return result
82 end
83
84 end
85end
  
1require 'rubygems'
2require 'open-uri'
3require 'cgi'
4require 'hpricot'
5require 'yaml'
6
7class String
8 def url_encode
9 CGI.escape(self)
10 end
11
12 def url_decode
13 CGI.unescape(self)
14 end
15end
16
17class Station
18 attr_accessor :station_id, :name, :district, :x, :y
19
20 def located?
21 !x.nil?
22 end
23 def initialize(options={})
24 options.each{|k,v|send("#{k}=",v)}
25 end
26
27 def to_s
28 "#{name} (#{station_id}) at #{x}/#{y}"
29 end
30
31 def self.find_by_name(a_name)
32 uri = "http://www8.trafikanten.no/txml?type=1&stopname=#{a_name.url_encode}"
33 data = open(uri).read
34 result = []
35 doc = Hpricot(data)
36 (doc/"//stopmatch").each do |match|
37 id = (match/"fromid").inner_html.to_i
38 name = (match/"stopname").inner_html
39 district = (match/"district").inner_html
40 x = (match/"xcoordinate").inner_html
41 y = (match/"ycoordinate").inner_html
42 result << new(:x => x, :y => y, :station_id => id, :name => name, :district => district)
43 end
44 result
45 end
46
47 def self.extract_all_stations_and_record_positions(limit=100)
48 result = []
49 doc = Hpricot(open("http://www.sis.trafikanten.no/xmlrtpi/StopPointList.xml").read)
50 (doc/"stoppoint").each do |point|
51 dsid = (point/"disid").inner_html.split(":").first.to_i.to_s # Nasty, they tend to have something like "012923:1", meaning 12923
52 name = (point/"stopname").inner_html
53 station = new(:station_id => dsid, :name => name)
54 station.guess_location
55 result << station if station.located?
56 break if result.size > limit
57 end
58 File.open("stations.yml","w"){|f|f.write(YAML::dump(result))}
59 end
60
61 # Tries to determine the coordinates, based on a lookup of the name
62 def guess_location
63 candidates = self.class.find_by_name(name)
64 puts "Checking #{candidates}"
65 match = candidates.find{|m|m.station_id.to_i == self.station_id.to_i}
66 if match
67 self.x = match.x
68 self.y = match.y
69 end
70 end
71
72 # There seem to be different data sources for subway stations and the other stations.
73 def subway_station?
74 ["03011930","03012220","03011030","03012365","02190070","02190080","02190090","03010011","03010020","03010031","03010200","03010360","03010370","03010600","03010610","03010770","03010780","03010950","03011010","03011020","03011110","03011120","03011130","03011140","03011200","03011210","03011220","03011310","03011320","03011330","03011400","03011410","03011430","03011440","03011450","03011510","03011520","03011530","03011540","03011610","03011620","03011630","03011710","03011720","03011730","03011810","03011910","03011920","03011940","03012000","03012010","03012020","03012030","03012040","03012100","03012120","03012130","03012210","03012230","03012240","03012260","03012270","03012280","03012305","03012310","03012315","03012320","03012325","03012330","03012340","03012345","03012350","03012355","03012360","03012370","03012375","03012380","03012385","03012390","03012410","03012420","03012430","03012450","03012460","03012560","03012565","03012572","03012630"].include?(station_id)
75 end
76
77 def realtime_url
78 if subway_station?
79 "http://www.sis.trafikanten.no:8088/xmlrtpi/dis/request?DISID=SN$#{station_id}"
80 else
81 "http://www.sis.trafikanten.no/xmlrtpi/dis/request?DISID=SN$#{station_id}"
82 end
83 end
84
85 def realtime_departures
86 result = []
87 doc = Hpricot(open(realtime_url).read)
88 (doc/"disdeviation").each do |m|
89 trip_status = (m/"trip_status").inner_html
90 departure_field = (trip_status == "real") ? "expecteddisdeparturetime" : "scheduleddisdeparturetime"
91 scheduled_departure = (m/departure_field).inner_html
92 destination = (m/"destinationstop").inner_html
93 line = (m/"lineid").inner_html
94 result << Departure.new(:status => trip_status, :departure => Time.parse(scheduled_departure), :destination => destination, :line => line, :from => name)
95 end
96 return result
97 end
98
99end
100
101class Departure
102 attr_accessor :status, :departure, :destination, :line, :from
103 def initialize(options={})
104 options.each{|k,v|send("#{k}=",v)}
105 end
106
107 def to_s
108 "Linje #{line} fra #{from} til #{destination} klokka #{departure.strftime('%H:%M (%d/%m)')}"
109 end
110end
111
112# Just to play nice, let's embed a webserver
113# if __FILE__ == $0
114 require 'sinatra'
115
116 get '/' do
117 '<h1>Velg stoppested</h1><form method="get" action="/locations"><input name="q" type="text" /><input type="submit"/></form>'
118 end
119
120
121 get '/locations' do
122 result = []
123 result << '<h1>Velg stasjon</h1><ul>'
124 matches = Station.find_by_name(params[:q])
125 matches.each do |m|
126 result << "<li><a href='/departures/#{m.station_id}/#{m.name}'>#{m.name}</a></li>"
127 end
128 result << "</ul>"
129 result.join("\n")
130 end
131
132 get '/departures/:station_id/:station_name' do
133 result = []
134 station = Station.new(:station_id => params[:station_id], :name => params[:station_name].url_decode)
135 result << "<h1>Avganger fra #{station.name}</h1>"
136 result << "<ul>"
137 station.realtime_departures.sort{|a,b|a.departure<=>b.departure}.each do |dep|
138 result << "<li>#{dep.to_s}</li>"
139 end
140 result << "</ul>"
141 result.join("\n")
142 end
143# end