c3d2-wiki/DVB-Scraping.mw

251 lines
5.7 KiB
Plaintext
Raw Normal View History

2006-11-27 05:58:52 +01:00
[[Kategorie:Projekt]]
2007-07-16 14:53:49 +02:00
{{Broken|
Reason=Die Struktur der WAP-Seiten war nicht permanent und wurde in der Zwischenzeit geändert. Jemand muss auf die neuen URLs anpassen.|}}
2006-07-25 19:06:14 +02:00
=Telnet-Haltestellenmonitor=
2007-06-05 14:22:00 +02:00
<source lang="ruby">#!/usr/bin/env ruby
2006-07-25 19:06:14 +02:00
require 'net/http'
require 'socket'
require 'rexml/document'
class MultipleStations < RuntimeError
def initialize(stations)
@stations = stations
end
def to_s
"Mehrere mögliche Haltestellen: " + @stations.join(', ')
end
end
class StationResult
def initialize(card)
strong_n = 0
card.each_element('p/strong') { |e|
case strong_n
when 0
@name = e.text
when 1
@time = e.text
end
strong_n += 1
}
@trams = []
card.to_s.scan(/br\/>(\d+:\d+\*?) (.+?)<br\/>-> (.+?)</) { |time,tram,direction|
@trams << [time, tram, direction]
}
end
def to_s
column_widths = [4, 5, 4]
@trams.each { |a|
a.each_with_index { |b,i|
column_widths[i] = b.size if b.size > column_widths[i]
}
}
"\n\n#{@name}, #{@time}:\n\n" +
'Zeit'.ljust(column_widths[0]) + ' | ' +
'Linie'.ljust(column_widths[1]) + ' | ' +
'Ziel'.ljust(column_widths[2]) + "\n" +
('-' * column_widths[0]) + '-+-' +
('-' * column_widths[1]) + '-+-' +
('-' * column_widths[2]) + "\n" +
@trams.collect { |time,tram,direction|
time.ljust(column_widths[0]) + ' | ' +
tram.ljust(column_widths[1]) + ' | ' +
direction.ljust(column_widths[2])
}.join("\n")
end
end
class ClientHandler
def initialize(socket)
@socket = socket
puts "#{address} connected"
Thread.new {
begin
handle
rescue Exception => e
@socket.puts("Fehler: #{e}")
ensure
@socket.close
end
}
end
def address
if @socket.peeraddr[0] == 'AF_INET6'
"[#{@socket.peeraddr[3]}]"
else
"#{@socket.peeraddr[3]}"
end +
":#{@socket.peeraddr[1]}"
end
def ask_haltestellenmonitor(station)
param = { :station => station,
:action => :check,
:time => Time.new.strftime('%H:%M'),
:date => Time.new.strftime('%d.%m.%Y')
}
param_s = param.collect { |k,v| "#{k}=#{v}" }.join('&')
param_s.gsub!(/ /, '+')
res = Net::HTTP.start('wap.dvbag.de') { |http|
http.get('/wapVVO/wap-rbl.php?' + param_s)
}
if res.kind_of? Net::HTTPSuccess
wml = REXML::Document.new(res.body).root
card = nil
wml.each_element('/wml/card') { |c| card = c }
if card
if card.attributes['id'] == 'liste'
stations = []
card.each_element('p/select/option') { |option|
stations << option.text
}
raise MultipleStations.new(stations)
elsif card.attributes['id'] == 'result'
StationResult.new(card).to_s
else
raise "Unexpected card/@id: #{card.attributes['id']}"
end
else
raise "No card found in result document"
end
else
raise "#{res.class}"
end
end
def handle
@socket.print "Hallo #{address}\n\nHaltestelle: "
@socket.flush
haltestelle = @socket.gets
if haltestelle
haltestelle.strip!
puts "#{address} asks for #{haltestelle.inspect}"
@socket.puts "Anfrage nach #{haltestelle}..."
@socket.puts ask_haltestellenmonitor(haltestelle)
end
end
end
serv = TCPServer.new('0.0.0.0', 65023)
while client = serv.accept
ClientHandler.new(client)
end
2007-06-05 14:22:00 +02:00
</source>
2006-07-25 19:06:14 +02:00
Und dann:
telnet localhost 65023
2006-07-25 19:07:06 +02:00
2008-02-29 15:28:33 +01:00
=NCurses Monitor=
Der VVO stellt jetzt ja für seine Widgets eine JSON(?)-Variante der Daten zur Verfügung.
<source lang="ruby">
require 'net/http'
require 'ncurses'
class DvbAbfahrt
def initialize
@BASEURI = "http://widgets.vvo-online.de/abfahrtsmonitor/Abfahrten.do?ort=ORT&hst=HST&vz=VZ"
end
def fetch(ort, hst, vz=0)
# TODO exceptionhandling: timeout
vz = vz.to_s
ort = URI.escape ort
hst = URI.escape hst
uri = @BASEURI.gsub(/ORT/, ort).gsub(/HST/,hst).gsub(/VZ/, vz)
res = Net::HTTP.get(URI.parse(uri))
res = umlauts_hack res
arr = res.scan(/(\d+),([^,]{1,}),(\d+)/)
end
def umlauts_hack(s)
repl = [
["&quot;", ''],
["&#252;", "ü"],
["&#246;", "ö"],
["&#223;", "ß"]
]
repl.each do |r|
s.gsub!(r[0], r[1])
end
return s
end
end
class Monitor
def initialize(ort, hst, vz=0)
Ncurses::initscr
Ncurses::start_color
Ncurses::init_pair(1, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK);
Ncurses::attron(Ncurses::COLOR_PAIR(1));
Ncurses::curs_set(0)
Ncurses::move(0,0)
Ncurses::printw "Loading..."
Ncurses::refresh
@sep = "|"
@timeout = 30
@wlno = 3
@wlname = 20
@weta = 3
@ort = ort
@hst = hst
@vz = vz
@dvb = DvbAbfahrt.new
@lines = 0
end
def print_title
Ncurses::attron(Ncurses::A_REVERSE | Ncurses::A_BOLD);
Ncurses::mvprintw(0,0, @hst.center(@wlno+@wlname+@weta+2)) # +2 seperators
Ncurses::attroff(Ncurses::A_REVERSE | Ncurses::A_BOLD);
end
def mainloop
print_title
while true
info = @dvb.fetch(@ort, @hst, @vz)
# clearing old lines if needed
if @lines > info.size
Ncurses::clear
print_title
end
@lines = info.size
info.each_index do |i|
Ncurses::mvprintw(i+1, 0, info[i][0].rjust(@wlno) + @sep + info[i][1][0..@wlname].center(@wlname) + @sep + info[i][2].rjust(@weta))
end
Ncurses::refresh
Ncurses::move(0,0)
sleep @timeout
end
end
end
if __FILE__ == $0
begin
if !ARGV.empty?
m = Monitor.new("Dresden", ARGV[0])
m.mainloop
else
puts "USAGE #{$0} <HALTESTELLENNAME>"
end
ensure
Ncurses::attroff(Ncurses::COLOR_PAIR(1));
Ncurses::endwin
end
end
</source>
2006-07-25 19:07:06 +02:00
2007-06-05 14:22:00 +02:00
[[Kategorie:Ruby]]
{{Rübÿ Spëëd Mëtäl Cödïng}}