3 """Public transport information for Vienna"""
5 __author__ = 'kelvan <kelvan@logic.at>'
7 __website__ = 'https://github.com/kelvan/gotoVienna/'
8 __license__ = 'GNU General Public License v3 or later'
10 from datetime import datetime
12 from PySide.QtCore import QAbstractListModel, QModelIndex, QObject, Slot, Signal
13 from PySide.QtGui import QApplication
14 from PySide.QtDeclarative import QDeclarativeView
16 from gotovienna.utils import *
17 from gotovienna.realtime import *
18 from gotovienna.gps import *
24 from datetime import time
26 class GotoViennaListModel(QAbstractListModel):
27 def __init__(self, objects=None):
28 QAbstractListModel.__init__(self)
31 self._objects = objects
32 self.setRoleNames({0: 'modelData'})
34 def set_objects(self, objects):
35 self._objects = objects
37 def get_objects(self):
40 def get_object(self, index):
41 return self._objects[index.row()]
43 def rowCount(self, parent=QModelIndex()):
44 return len(self._objects)
46 def data(self, index, role):
49 return self.get_object(index)
55 QObject.__init__(self)
56 self.itip = ITipParser()
59 # Read line names in categorized/sorted order
60 for _, lines in categorize_lines(self.itip.lines):
61 self.lines.extend(lines)
63 self.current_line = ''
64 self.current_stations = []
65 self.current_departures = []
67 @Slot(int, result=str)
68 def get_direction(self, idx):
69 return self.current_stations[idx][0]
71 @Slot(str, str, result='QStringList')
72 def get_stations(self, line, direction):
73 print 'line:', line, 'current line:', self.current_line
74 for dx, stations in self.current_stations:
75 print 'dx:', dx, 'direction:', direction
77 return [stationname for stationname, url in stations]
79 return ['no stations found']
81 directionsLoaded = Signal()
84 def load_directions(self, line):
86 stations = sorted(self.itip.get_stations(line).items())
88 self.current_line = line
89 self.current_stations = stations
91 self.directionsLoaded.emit()
93 threading.Thread(target=load_async).start()
95 def map_departure(self, dep):
96 dep['lowfloor'] = 1 if dep['lowfloor'] else 0
97 if type(dep['time']) == time:
98 dep['time'] = dep['time'].strftime('%H:%M')
101 departuresLoaded = Signal()
104 def load_departures(self, url):
106 self.current_departures = map(self.map_departure, self.itip.get_departures(url))
107 print self.current_departures
108 self.departuresLoaded.emit()
110 threading.Thread(target=load_async).start()
113 def load_station_departures(self, station):
115 self.current_departures = map(self.map_departure, self.itip.get_departures_by_station(station))
116 print self.current_departures
117 self.departuresLoaded.emit()
119 threading.Thread(target=load_async).start()
122 def load_nearby_departures(self, lat, lon):
124 self.current_departures = []
126 stations = get_nearby_stations(lat, lon)
128 for station in stations:
131 self.current_departures += map(self.map_departure, self.itip.get_departures_by_station(station))
132 except Exception as e:
134 print self.current_departures
135 except Exception as e:
139 self.departuresLoaded.emit()
141 threading.Thread(target=load_async).start()
143 @Slot(str, str, str, result=str)
144 def get_directions_url(self, line, direction, station):
145 return self.itip.get_url_from_direction(line, direction, station)
147 @Slot(result='QStringList')
151 @Slot(result='QVariant')
152 def get_departures(self):
153 return self.current_departures
155 @Slot(float, float, result='QStringList')
156 def get_nearby_stations(self, lat, lon):
158 return get_nearby_stations(lat, lon)
159 except Exception as e:
164 def search(self, line, station):
166 station = station.decode('utf-8')
169 if line not in self.lines:
170 return "Invalid line"
173 stations = sorted(self.itip.get_stations(line).items())
175 headers, stations = zip(*stations)
178 details = [(direction, name, url) for direction, stops in stations
179 for name, url in stops if match_station(station, name)]
181 except urllib2.URLError as e:
185 if __name__ == '__main__':
186 app = QApplication(sys.argv)
188 view = QDeclarativeView()
190 # instantiate the Python object
193 # expose the object to QML
194 context = view.rootContext()
195 context.setContextProperty('itip', itip)
197 if os.path.abspath(__file__).startswith('/usr/bin/'):
198 # Assume system-wide installation, QML from /usr/share/
199 view.setSource('/usr/share/gotovienna/qml/main.qml')
201 # Assume test from source directory, use relative path
202 view.setSource(os.path.join(os.path.dirname(__file__), 'qml/main.qml'))
204 view.showFullScreen()
206 sys.exit(app.exec_())