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, \
107 self.itip.get_departures(url))
108 #print self.current_departures
109 self.departuresLoaded.emit()
111 threading.Thread(target=load_async).start()
114 def load_station_departures(self, station):
116 self.current_departures = map(self.map_departure, \
117 sort_departures(self.itip.get_departures_by_station(station)))
118 #print self.current_departures
119 self.departuresLoaded.emit()
121 threading.Thread(target=load_async).start()
124 def load_nearby_departures(self, lat, lon):
126 self.current_departures = []
128 stations = get_nearby_stations(lat, lon)
130 for station in stations:
133 self.current_departures += self.itip.get_departures_by_station(station)
134 except Exception as e:
136 self.current_departures = map(self.map_departure, \
137 sort_departures(self.current_departures))
138 #print self.current_departures
139 except Exception as e:
143 self.departuresLoaded.emit()
145 threading.Thread(target=load_async).start()
147 stationsLoaded = Signal()
149 @Slot(float, float, result='QStringList')
150 def get_nearby_stations(self, lat, lon):
151 return get_nearby_stations(lat, lon)
153 @Slot(str, str, str, result=str)
154 def get_directions_url(self, line, direction, station):
155 return self.itip.get_url_from_direction(line, direction, station)
157 @Slot(result='QStringList')
161 @Slot(result='QVariant')
162 def get_departures(self):
163 return self.current_departures
165 @Slot(float, float, result='QStringList')
166 def get_nearby_stations(self, lat, lon):
168 return get_nearby_stations(lat, lon)
169 except Exception as e:
174 def search(self, line, station):
176 station = station.decode('utf-8')
179 if line not in self.lines:
180 return "Invalid line"
183 stations = sorted(self.itip.get_stations(line).items())
185 headers, stations = zip(*stations)
188 details = [(direction, name, url) for direction, stops in stations
189 for name, url in stops if match_station(station, name)]
191 except urllib2.URLError as e:
195 if __name__ == '__main__':
196 app = QApplication(sys.argv)
198 view = QDeclarativeView()
200 # instantiate the Python object
203 # expose the object to QML
204 context = view.rootContext()
205 context.setContextProperty('itip', itip)
207 if os.path.abspath(__file__).startswith('/usr/bin/'):
208 # Assume system-wide installation, QML from /usr/share/
209 view.setSource('/usr/share/gotovienna/qml/main.qml')
211 # Assume test from source directory, use relative path
212 view.setSource(os.path.join(os.path.dirname(__file__), 'qml/main.qml'))
214 view.showFullScreen()
216 sys.exit(app.exec_())