changed get_departure, return list of Departure objects with line,
authorFlorian Schweikert <kelvan@logic.at>
Tue, 18 Oct 2011 15:07:01 +0000 (17:07 +0200)
committerFlorian Schweikert <kelvan@logic.at>
Tue, 18 Oct 2011 15:07:01 +0000 (17:07 +0200)
station, direction, departure time and lowfloor instead of list of int
added support for time objects if realtime ist unknown
fixed an silent error on startup
added lowfloor fetching (only in backend, not in an interface)

gotovienna-qml
gotovienna/realtime.py
itip
qml/MainPage.qml
qml/StationSheet.qml

index e1779e6..75e3803 100755 (executable)
@@ -93,7 +93,7 @@ class Gui(QObject):
     @Slot(str)
     def load_departures(self, url):
         def load_async():
-            self.current_departures = [str(x) for x in
+            self.current_departures = [x.get_ftime() for x in
                     self.itip.get_departures(url)]
             print self.current_departures
             self.departuresLoaded.emit()
index 3e6dd5c..0990fc1 100644 (file)
@@ -9,6 +9,35 @@ from errors import LineNotFoundError, StationNotFoundError
 
 from gotovienna import defaults
 
+class Departure:
+    def __init__(self, line, station, direction, time, lowfloor):
+        self.line = line
+        self.station = station
+        self.direction = direction
+        self.time = time
+        self.lowfloor = lowfloor
+
+    def get_departure_time(self):
+        """ return time object of departure time
+        """
+        if type(self.time) == time:
+            return self.time
+        else:
+            pass
+    def get_departure_deltatime(self):
+        """ return int representing minutes until departure
+        """
+        if type(self.time) == int:
+            return self.time
+        else:
+            pass
+
+    def get_ftime(self):
+        if type(self.time) == int:
+            return str(self.time)
+        elif type(self.time) == time:
+            return self.time.strftime('%H:%M')
+
 class ITipParser:
     def __init__(self):
         self._stations = {}
@@ -70,56 +99,76 @@ class ITipParser:
         return None
 
     def get_departures(self, url):
-        """ Get list of next departures
-        integer if time until next departure
-        time if time of next departure
+        """ Get list of next departures as Departure object
         """
 
         #TODO parse line name and direction for station site parsing
 
         if not url:
             # FIXME prevent from calling this method with None
+            print "ERROR empty url"
             return []
 
         # open url for 90 min timeslot / get departure for next 90 min
         bs = BeautifulSoup(urlopen(url + "&departureSizeTimeSlot=90"))
+        print url
+        lines = bs.findAll('table')[-2].findAll('tr')
+        if len(lines) == 1:
+            station = lines[0].span.text.replace('&nbsp;', '')
+            line = lines[0].findAll('span')[-1].text.replace('&nbsp;', '')
+        else:
+            station = lines[1].td.span.text.replace('&nbsp;', '')
+            line = '??'
+
         result_lines = bs.findAll('table')[-1].findAll('tr')
 
         dep = []
         for tr in result_lines[1:]:
+            d = {'station': station}
             th = tr.findAll('th')
             if len(th) < 2:
                 #TODO replace with logger
                 print "[DEBUG] Unable to find th in:\n%s" % str(tr)
             elif len(th) == 2:
+                # underground site looks different -.-
+                d['lowfloor'] = True
+                d['line'] = line
+                d['direction'] = th[0].text.replace('&nbsp;', '')
                 t = th[-1]
             else:
+                # all other lines
+                d['lowfloor'] = th[-1].has_key('img') and th[-1].img.has_key('alt')
+                d['line'] = th[0].text.replace('&nbsp;', '')
+                d['direction'] = th[1].text.replace('&nbsp;', '')
                 t = th[-2]
             # parse time
-            time = t.text.split(' ')
-            if len(time) < 2:
-                #print 'Invalid time: %s' % time
+            tim = t.text.split(' ')
+            if len(tim) < 2:
+                # print '[WARNING] Invalid time: %s' % time
                 # TODO: Issue a warning OR convert "HH:MM" format to countdown
-                continue
-
-            time = time[1]
+                tim = tim[0]
+            else:
+                tim = tim[1]
 
-            if time.find('rze...') >= 0:
-                    dep.append(0)
-            elif time.isdigit():
+            if tim.find('rze...') >= 0:
+                    d['time'] = 0
+            elif tim.isdigit():
                 # if time to next departure in cell convert to int
-                dep.append(int(time))
+                d['time'] = int(tim)
             else:
                 # check if time of next departue in cell
-                t = time.strip('&nbsp;').split(':')
+                t = tim.strip('&nbsp;').split(':')
                 if len(t) == 2 and all(map(lambda x: x.isdigit(), t)):
                     t = map(int, t)
-                    dep.append(time(*t))
+                    d['time'] = time(*t)
                 else:
                     # Unexpected content
                     #TODO replace with logger
                     print "[DEBUG] Invalid data:\n%s" % time
 
+            print d
+            dep.append(Departure(**d))
+
         return dep
 
 
diff --git a/itip b/itip
index 9df14fe..88046f3 100755 (executable)
--- a/itip
+++ b/itip
@@ -4,6 +4,7 @@
 from gotovienna import argparse
 from gotovienna.utils import *
 from gotovienna.realtime import *
+from datetime import time
 
 parser = argparse.ArgumentParser(description='Get realtime public transport information for Vienna')
 parser.add_argument('line', nargs='?', help='line name (e.g. 59A)')
@@ -32,7 +33,7 @@ if args.line in itip.lines:
     for stops in stations:
         # Pad station list with empty items for printing, so that
         # different-sized lists aren't truncated (with zip below)
-        stops.extend([('', '')]*(maxlength-len(stops)))
+        stops.extend([('', '')] * (maxlength - len(stops)))
 
     stations_table = zip(*stations)
     fmt = '%%-%ds' % ITEM_WIDTH
@@ -41,15 +42,15 @@ if args.line in itip.lines:
     print
     print spacer, spacer.join(inblue(fmt % ('Richtung %s' % name))
             for name in headers)
-    print spacer, spacer.join('-'*ITEM_WIDTH for name in headers)
+    print spacer, spacer.join('-' * ITEM_WIDTH for name in headers)
 
     def match_station(query, station):
         return query and station and (query.lower() in station.lower())
 
     for row in stations_table:
-        print spacer, spacer.join(ingreen(fmt%name)
+        print spacer, spacer.join(ingreen(fmt % name)
                 if match_station(args.station, name)
-                else fmt%name
+                else fmt % name
                 for name, url in row)
     print
 
@@ -64,8 +65,11 @@ if args.line in itip.lines:
         print
 
     # Format a departure time (in minutes from now) for display
-    def format_departure(minutes):
-        if minutes == 0:
+    def format_departure(departure):
+        minutes = departure.time
+        if type(minutes) == time:
+            return inblue(minutes.strftime('%H:%M'))
+        elif minutes == 0:
             return inred('now')
         elif minutes == 1:
             return inblue('1') + ' min'
@@ -86,7 +90,7 @@ if args.line in itip.lines:
 else:
     ITEMS_PER_LINE = 12
     ITEM_WIDTH = 5
-    LINE_WIDTH = (ITEMS_PER_LINE*ITEM_WIDTH + ITEMS_PER_LINE)
+    LINE_WIDTH = (ITEMS_PER_LINE * ITEM_WIDTH + ITEMS_PER_LINE)
 
     if args.line:
         print
@@ -95,10 +99,10 @@ else:
     print
     for label, remaining in categorize_lines(itip.lines):
         prefix, fill, postfix = '|== ', '=', '==- -'
-        before, after = prefix+label+' ', postfix
-        padding = LINE_WIDTH - len(before+after)
+        before, after = prefix + label + ' ', postfix
+        padding = LINE_WIDTH - len(before + after)
         before = before.replace(label, inblue(label))
-        print ''.join((before, fill*padding, after))
+        print ''.join((before, fill * padding, after))
 
         while remaining:
             this_row = [remaining.pop(0) for _ in
index e989fe4..a0f5cdf 100644 (file)
@@ -75,9 +75,10 @@ Page {
          }
     }
 
+    /*
     LineSheet {
         id: lineSheet
-    }
+    }*/
 
     Button {
         id: lineSearchButton
index 19b93f1..49c22f8 100644 (file)
@@ -8,6 +8,7 @@ Sheet {
     property string currentLine: ''
     property string currentDirection: ''
     property string currentStation: ''
+    property string currentUrl: ''
 
     acceptButtonText: 'Select'
     rejectButtonText: 'Cancel'