Fixing some errorhandling bugs
[pywienerlinien] / gotovienna-qml
1 #!/usr/env/python
2
3 """Public transport information for Vienna"""
4
5 __author__ = 'kelvan <kelvan@logic.at>'
6 __version__ = '1.0'
7 __website__ = 'https://github.com/kelvan/gotoVienna/'
8 __license__ = 'GNU General Public License v3 or later'
9
10 from datetime import datetime
11
12 t = datetime.now()
13
14 from PySide.QtCore import QAbstractListModel, QModelIndex, QObject, Slot, Signal
15 from PySide.QtGui import QApplication
16 from PySide.QtDeclarative import QDeclarativeView
17
18 from gotovienna.utils import *
19 from gotovienna.realtime import *
20
21 import urllib2
22 import os
23 import sys
24 import threading
25
26 class GotoViennaListModel(QAbstractListModel):
27     def __init__(self, objects=None):
28         QAbstractListModel.__init__(self)
29         if objects is None:
30             objects = []
31         self._objects = objects
32         self.setRoleNames({0: 'modelData'})
33
34     def set_objects(self, objects):
35         self._objects = objects
36
37     def get_objects(self):
38         return self._objects
39
40     def get_object(self, index):
41         return self._objects[index.row()]
42
43     def rowCount(self, parent=QModelIndex()):
44         return len(self._objects)
45
46     def data(self, index, role):
47         if index.isValid():
48             if role == 0:
49                 return self.get_object(index)
50         return None
51
52
53 class Gui(QObject):
54     def __init__(self):
55         QObject.__init__(self)
56         self.itip = ITipParser()
57         self.lines = []
58
59         # Read line names in categorized/sorted order
60         for _, lines in categorize_lines(self.itip.lines):
61             self.lines.extend(lines)
62
63         self.current_line = ''
64         self.current_stations = []
65         self.current_departures = []
66
67     @Slot(int, result=str)
68     def get_direction(self, idx):
69         return self.current_stations[idx][0]
70
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
76             if dx == direction:
77                 return [stationname for stationname, url in stations]
78
79         return ['no stations found']
80
81     directionsLoaded = Signal()
82
83     @Slot(str)
84     def load_directions(self, line):
85         def load_async():
86             stations = sorted(self.itip.get_stations(line).items())
87
88             self.current_line = line
89             self.current_stations = stations
90
91             self.directionsLoaded.emit()
92
93         threading.Thread(target=load_async).start()
94
95     departuresLoaded = Signal()
96
97     @Slot(str)
98     def load_departures(self, url):
99         def load_async():
100             self.current_departures = [x.get_ftime() for x in
101                     self.itip.get_departures(url)]
102             print self.current_departures
103             self.departuresLoaded.emit()
104
105         threading.Thread(target=load_async).start()
106
107     @Slot(str, str, str, result=str)
108     def get_directions_url(self, line, direction, station):
109         return self.itip.get_url_from_direction(line, direction, station)
110
111     @Slot(result='QStringList')
112     def get_lines(self):
113         return self.lines
114
115     @Slot(result='QStringList')
116     def get_departures(self):
117         return self.current_departures
118
119     @Slot(str, str)
120     def search(self, line, station):
121         line = line.upper()
122         station = station.decode('utf-8')
123         print line, station
124
125         if line not in self.lines:
126             return "Invalid line"
127
128         try:
129             stations = sorted(self.itip.get_stations(line).items())
130             print stations
131             headers, stations = zip(*stations)
132             print headers
133             print stations
134             details = [(direction, name, url) for direction, stops in stations
135                         for name, url in stops if match_station(station, name)]
136             print details
137         except urllib2.URLError as e:
138             print e.message
139             return e.message
140
141 if __name__ == '__main__':
142     app = QApplication(sys.argv)
143
144     view = QDeclarativeView()
145
146     # instantiate the Python object
147     itip = Gui()
148
149     # expose the object to QML
150     context = view.rootContext()
151     context.setContextProperty('itip', itip)
152
153     if os.path.abspath(__file__).startswith('/usr/bin/'):
154         # Assume system-wide installation, QML from /usr/share/
155         view.setSource('/usr/share/gotovienna/qml/main.qml')
156     else:
157         # Assume test from source directory, use relative path
158         view.setSource(os.path.join(os.path.dirname(__file__), 'qml/main.qml'))
159
160     print datetime.now() - t
161
162     view.showFullScreen()
163
164     sys.exit(app.exec_())
165