3 """Public transport information for Vienna"""
5 __author__ = 'kelvan <kelvan@logic.at>'
7 __website__ = 'http://tinyurl.com/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 AboutInfo(QObject):
28 QObject.__init__(self)
32 return u'gotoVienna %s' % __version__
35 def getWebsiteURL(self):
39 def getCopyright(self):
40 return 'Copyright 2011, 2012 %s' % __author__
46 class GotoViennaListModel(QAbstractListModel):
47 def __init__(self, objects=None):
48 QAbstractListModel.__init__(self)
51 self._objects = objects
52 self.setRoleNames({0: 'modelData'})
54 def set_objects(self, objects):
55 self._objects = objects
57 def get_objects(self):
60 def get_object(self, index):
61 return self._objects[index.row()]
63 def rowCount(self, parent=QModelIndex()):
64 return len(self._objects)
66 def data(self, index, role):
69 return self.get_object(index)
75 QObject.__init__(self)
76 self.itip = ITipParser()
79 # Read line names in categorized/sorted order
80 for _, lines in categorize_lines(self.itip.lines):
81 self.lines.extend(lines)
83 self.current_line = ''
84 self.current_stations = []
85 self.current_departures = []
87 @Slot(int, result=str)
88 def get_direction(self, idx):
89 return self.current_stations[idx][0]
91 @Slot(str, str, result='QStringList')
92 def get_stations(self, line, direction):
93 print 'line:', line, 'current line:', self.current_line
94 for dx, stations in self.current_stations:
95 print 'dx:', dx, 'direction:', direction
97 return [stationname for stationname, url in stations]
99 return ['no stations found']
101 directionsLoaded = Signal()
104 def load_directions(self, line):
106 stations = sorted(self.itip.get_stations(line).items())
108 self.current_line = line
109 self.current_stations = stations
111 self.directionsLoaded.emit()
113 threading.Thread(target=load_async).start()
115 def map_departure(self, dep):
116 dep['lowfloor'] = 1 if dep['lowfloor'] else 0
117 if type(dep['time']) == time:
118 dep['time'] = dep['time'].strftime('%H:%M')
121 departuresLoaded = Signal()
124 def load_departures(self, url):
126 self.current_departures = map(self.map_departure, \
127 self.itip.get_departures(url))
128 #print self.current_departures
129 self.departuresLoaded.emit()
131 threading.Thread(target=load_async).start()
134 def load_station_departures(self, station):
136 self.current_departures = map(self.map_departure, \
137 sort_departures(self.itip.get_departures_by_station(station)))
138 #print self.current_departures
139 self.departuresLoaded.emit()
141 threading.Thread(target=load_async).start()
144 def load_nearby_departures(self, lat, lon):
146 self.current_departures = []
148 stations = get_nearby_stations(lat, lon)
150 for station in stations:
153 self.current_departures += self.itip.get_departures_by_station(station)
154 except Exception as e:
156 self.current_departures = map(self.map_departure, \
157 sort_departures(self.current_departures))
158 #print self.current_departures
159 except Exception as e:
163 self.departuresLoaded.emit()
165 threading.Thread(target=load_async).start()
167 @Slot(str, str, str, result=str)
168 def get_directions_url(self, line, direction, station):
169 return self.itip.get_url_from_direction(line, direction, station)
171 @Slot(result='QStringList')
175 @Slot(result='QVariant')
176 def get_departures(self):
177 return self.current_departures
179 @Slot(float, float, result='QStringList')
180 def get_nearby_stations(self, lat, lon):
182 return get_nearby_stations(lat, lon)
183 except Exception as e:
188 def search(self, line, station):
190 station = station.decode('utf-8')
193 if line not in self.lines:
194 return "Invalid line"
197 stations = sorted(self.itip.get_stations(line).items())
199 headers, stations = zip(*stations)
202 details = [(direction, name, url) for direction, stops in stations
203 for name, url in stops if match_station(station, name)]
205 except urllib2.URLError as e:
209 if __name__ == '__main__':
210 app = QApplication(sys.argv)
212 view = QDeclarativeView()
214 aboutInfo = AboutInfo()
216 # instantiate the Python object
219 # expose the object to QML
220 context = view.rootContext()
221 context.setContextProperty('itip', itip)
222 context.setContextProperty('aboutInfo', aboutInfo)
224 if os.path.abspath(__file__).startswith('/usr/bin/'):
225 # Assume system-wide installation, QML from /usr/share/
226 view.setSource('/usr/share/gotovienna/qml/main.qml')
228 # Assume test from source directory, use relative path
229 view.setSource(os.path.join(os.path.dirname(__file__), 'qml/main.qml'))
231 view.showFullScreen()
233 sys.exit(app.exec_())