fixed loading bug
authorFlorian Schweikert <kelvan@logic.at>
Fri, 28 Oct 2011 20:40:46 +0000 (22:40 +0200)
committerFlorian Schweikert <kelvan@logic.at>
Fri, 28 Oct 2011 20:40:46 +0000 (22:40 +0200)
added departures by station method

gotovienna-qml
gotovienna/defaults.py
gotovienna/realtime.py
itip

index 06b7807..7ca6b60 100755 (executable)
@@ -97,7 +97,7 @@ class Gui(QObject):
     @Slot(str)
     def load_departures(self, url):
         def load_async():
-            self.current_departures = [x.get_ftime() for x in
+            self.current_departures = [x['ftime'] for x in
                     self.itip.get_departures(url)]
             print self.current_departures
             self.departuresLoaded.emit()
index e3170bd..5491e0d 100644 (file)
@@ -19,6 +19,8 @@ cache_stations = path.join(cache_folder, 'stations.json')
 
 line_overview = 'http://www.wienerlinien.at/itip/linienwahl/'
 stations = 'http://www.wienerlinien.at/itip/haltestelle?letter=%s'
+departures_by_station = 'http://m.qando.at/de/get_monitor.ft?stop=%s&submit=Anfordern'
+qando = 'http://m.qando.at/de/'
 
 search_post = {'language': 'de',
             'sessionID': 0,
index 553382f..3884abf 100644 (file)
@@ -2,44 +2,59 @@
 
 from gotovienna.BeautifulSoup import BeautifulSoup
 #from urllib2 import urlopen
+from urllib import quote_plus
 from UrlOpener import urlopen
-from datetime import time
+from datetime import time, datetime, timedelta
 import re
 import collections
 from errors import LineNotFoundError, StationNotFoundError
 import cache
 from cache import Stations
+from time import sleep
 
 from gotovienna import defaults
 
-class Departure:
+class Departure(dict):
     def __init__(self, line, station, direction, time, lowfloor):
-        self.line = line
-        self.station = station
-        self.direction = direction
-        self.time = time
-        self.lowfloor = lowfloor
+        self['line'] = line
+        self['station'] = station
+        self['direction'] = direction
+        self['time'] = time
+        self['lowfloor'] = lowfloor
+
+    def __getitem__(self, *args, **kwargs):
+        if args[0] == 'ftime':
+            return self.ftime
+        elif args[0] == 'deltatime':
+            return self.departure_deltatime
+        elif args[0] == 'atime':
+            return self.departure_time
+        return dict.__getitem__(self, *args, **kwargs)
 
-    def get_departure_time(self):
+    @property
+    def departure_time(self):
         """ return time object of departure time
         """
-        if type(self.time) == time:
-            return self.time
+        if type(self['time']) == time:
+            return self['time']
         else:
-            pass
-    def get_departure_deltatime(self):
+            return (datetime.now() + timedelta(self['time'])).time()
+
+    @property
+    def departure_deltatime(self):
         """ return int representing minutes until departure
         """
-        if type(self.time) == int:
-            return self.time
+        if type(self['time']) == int:
+            return self['time']
         else:
-            pass
+            raise NotImplementedError()
 
-    def get_ftime(self):
-        if type(self.time) == int:
-            return str(self.time)
-        elif type(self.time) == time:
-            return self.time.strftime('%H:%M')
+    @property
+    def 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):
@@ -99,6 +114,60 @@ class ITipParser:
 
         return None
 
+    def get_departures_by_station(self, station):
+        """ Get list of Departures for one station
+        """
+
+        # TODO 1. Error handling
+        # TODO 2. more error handling
+        # TODO 3. ultimative error handling
+
+        dep = []
+        bs = BeautifulSoup(urlopen(defaults.departures_by_station % quote_plus(station.encode('UTF-8'))))
+        try:
+            li = bs.ul.findAll('li')
+            if li[0].a:
+                # Dirty workaround for ambiguous station
+                bs = BeautifulSoup(urlopen(defaults.qando + li[0].a['href']))
+                li = bs.ul.findAll('li')
+
+            for l in li:
+                try:
+                    d = l.div.next
+                    if d.find('&raquo;') == -1:
+                        d = d.next.next
+
+                    direction = d.replace('&raquo;', '').strip()
+                    if direction.startswith('NICHT EINSTEIGEN'):
+                        continue
+
+                    line = l.img['alt']
+                    for span in l.findAll('span'):
+                        if span.text.isdigit():
+                            tim = int(span.text)
+                        elif span.text.find(':') >= 0:
+                            tim = time(*map(int, span.text.split(':')))
+                        else:
+                            print 'Warning: %s' % span.text
+                            continue
+
+                        if span['class'] == 'departureBarrierFree':
+                            lowfloor = True
+                        else:
+                            lowfloor = False
+
+                        dep.append(Departure(line, station, direction, tim, lowfloor))
+
+                except:
+                    print 'Warning: %s' % l
+                    continue
+
+        except AttributeError:
+            print 'Error while getting station %s' % station
+            return dep
+
+        return dep
+
     def get_departures(self, url):
         """ Get list of next departures as Departure object
         """
@@ -117,6 +186,8 @@ class ITipParser:
             bs = BeautifulSoup(urlopen(url + "&departureSizeTimeSlot=90"))
             try:
                 lines = bs.find('form', {'name': 'mainform'}).table.findAll('tr')[1]
+                break
+
             except AttributeError:
                 print 'FetchError'
                 msg = bs.findAll('span', {'class': 'rot fett'})
@@ -129,6 +200,8 @@ class ITipParser:
                 retry += 1
                 if retry == tries:
                     return []
+            sleep(0.5)
+
         if len(lines.findAll('td', {'class': 'info'})) > 0:
             station = lines.span.text.replace('&nbsp;', '')
             line = lines.findAll('span')[-1].text.replace('&nbsp;', '')
@@ -182,7 +255,6 @@ class ITipParser:
                     #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 88046f3..a291720 100755 (executable)
--- a/itip
+++ b/itip
@@ -66,7 +66,7 @@ if args.line in itip.lines:
 
     # Format a departure time (in minutes from now) for display
     def format_departure(departure):
-        minutes = departure.time
+        minutes = departure['time']
         if type(minutes) == time:
             return inblue(minutes.strftime('%H:%M'))
         elif minutes == 0: