diff --git a/DVB-Scraping.mw b/DVB-Scraping.mw index 8d242fd1..380a8526 100644 --- a/DVB-Scraping.mw +++ b/DVB-Scraping.mw @@ -1,9 +1,11 @@ [[Kategorie:Projekt]] +=Ruby= + {{Broken| Reason=Die Struktur der WAP-Seiten war nicht permanent und wurde in der Zwischenzeit geändert. Jemand muss auf die neuen URLs anpassen.|}} -=Telnet-Haltestellenmonitor= +==Telnet-Haltestellenmonitor== #!/usr/bin/env ruby require 'net/http' require 'socket' @@ -131,7 +133,7 @@ end Und dann: telnet localhost 65023 -=NCurses Monitor= +==NCurses Monitor== Der VVO stellt jetzt ja für seine Widgets eine JSON(?)-Variante der Daten zur Verfügung. @@ -245,6 +247,176 @@ if __FILE__ == $0 end +=Python= + +==CLI-Interface== + +#!/usr/bin/python + +import sys + +from urllib import urlencode, urlopen +from optparse import OptionParser + +from BeautifulSoup import BeautifulStoneSoup +import simplejson + +widgets_base_url = "http://widgets.vvo-online.de/abfahrtsmonitor/" + +def get_connections(stop=None, town=None, time=None): + """ + Get the next connections at *stop* in *town* *time* minutes from now. + """ + query_params = [] + + if stop is not None: + query_params.append(("hst", stop)) + if town is not None: + query_params.append(("ort", town)) + if time is not None: + query_params.append(("vz", time)) + + query_url = widgets_base_url + "Abfahrten.do?" + urlencode(query_params) + + page_data = urlopen(query_url).read() + connections_soup = BeautifulStoneSoup(page_data, convertEntities="html") + connections_data = connections_soup.contents[0] + + connections = simplejson.loads(connections_data) + + return connections + + +def find_stops(stop, town=None): + """ + Get stops with the given name in *town*. + """ + query_params = [("hst", stop)] + + if town is not None: + query_params.append(("ort", town)) + + query_url = widgets_base_url + "Haltestelle.do?" + urlencode(query_params) + + page_data = urlopen(query_url).read() + stops_soup = BeautifulStoneSoup(page_data, convertEntities="html") + stops_data = stops_soup.contents[0] + + towns, stops = simplejson.loads(stops_data) + + return towns, stops + + +def format_connections(connections): + """ + Format a list of connections into a nice table. Returns a generator for + table's rows. + """ + + destination_column_length = max(23, *(len(d) for _, d, _ in connections)) + line_name_column_length = max(5, *(len(l) for l, _, _ in connections)) + line_format = "%-" + str(line_name_column_length) + "s | %" \ + + str(destination_column_length) + "s | %7s" + header_line = line_format % ("line", "destination", "arrival") + + yield header_line + yield "-" * line_name_column_length + "-+-" \ + + "-" * destination_column_length + "-+-" \ + + "-" * 7 + + for line_name, destination, time in connections: + yield line_format % (line_name, destination, time) + + +def print_connections(stop, town, connections, limit=None): + """ + Print *connections* at *stop* in *town* to stdout. If a limit is given + only that many connections are printed otherwise all. + """ + + if len(connections) == 0: + print "No connections at %s in %s." % (stop, town) + sys.exit(1) + + if town is not None: + print "Next connections at %s in %s:" % (stop, town) + else: + print "Next connections at %s:" % (stop,) + + print + + if limit: + connections_table = format_connections(connections[:limit]) + else: + connections_table = format_connections(connections) + + for line in connections_table: + print line + + +def main(): + """ + Main function. + """ + + option_parser = OptionParser( + usage="%prog [options] [] ") + option_parser.add_option("-l", "--limit", + help="maximum number of connections to display", + type="int", + default=5) + option_parser.add_option("-t", "--time", + help="minimum time to departure", + type="int", + default=None) + option_parser.add_option("-k", "--no-lookup", + help="do not look up stop name", + action="store_false", + dest="lookup_stop", + default=True) + + options, args = option_parser.parse_args() + + # sanitize options + if options.limit < 0: + options.limit = None + if options.time < 0: + options.time = None + + if len(args) == 1: + stop = args[0] + town = None + elif len(args) == 2: + town, stop = args + else: + option_parser.error("Not enough arguments") + + if options.lookup_stop: + towns, stops = find_stops(stop, town) + + if len(towns) == 0: + print "No town named '%s'." % (town,) + sys.exit(1) + + if len(stops) == 0: + print "No stop named '%s' in the following towns:" % (stop,) + print "\n".join(" "+t[0] for t in towns) + sys.exit(1) + + for stop_name, town, stop_id in stops: + connections = get_connections(stop_id, time=options.time) + + print_connections(stop_name, town, connections, options.limit) + print + else: + connections = get_connections(stop, town, options.time) + print_connections(stop, town, connections, options.limit) + + +if __name__ == "__main__": + main() + + [[Kategorie:Ruby]] {{Rübÿ Spëëd Mëtäl Cödïng}}