Add preliminary station chooser UI for realtime
[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 PySide.QtCore import *
11 from PySide.QtGui import *
12 from PySide.QtDeclarative import *
13
14 from gotovienna.utils import *
15 from gotovienna.realtime import *
16
17 import urllib2
18 import os
19 import sys
20 import threading
21
22 class GotoViennaListModel(QAbstractListModel):
23     def __init__(self, objects=None):
24         QAbstractListModel.__init__(self)
25         if objects is None:
26             objects = []
27         self._objects = objects
28         self.setRoleNames({0: 'modelData'})
29
30     def set_objects(self, objects):
31         self._objects = objects
32
33     def get_objects(self):
34         return self._objects
35
36     def get_object(self, index):
37         return self._objects[index.row()]
38
39     def rowCount(self, parent=QModelIndex()):
40         return len(self._objects)
41
42     def data(self, index, role):
43         if index.isValid():
44             if role == 0:
45                 return self.get_object(index)
46         return None
47
48
49 class Gui(QObject):
50     def __init__(self):
51         QObject.__init__(self)
52         self.itip = ITipParser()
53         self.lines = []
54
55         # Read line names in categorized/sorted order
56         for _, lines in categorize_lines(self.itip.lines):
57             self.lines.extend(lines)
58
59         self.current_line = ''
60         self.current_stations = []
61
62     @Slot(int, result=str)
63     def get_direction(self, idx):
64         return self.current_stations[idx][0]
65
66     @Slot(str, str, result='QStringList')
67     def get_stations(self, line, direction):
68         print 'line:', line, 'current line:', self.current_line
69         for dx, stations in self.current_stations:
70             print 'dx:', dx, 'direction:', direction
71             if dx == direction:
72                 return [stationname for stationname, url in stations]
73
74         return ['no stations found']
75
76     directionsLoaded = Signal()
77
78     @Slot(str)
79     def load_directions(self, line):
80         def load_async():
81             stations = sorted(self.itip.get_stations(line).items())
82
83             self.current_line = line
84             self.current_stations = stations
85
86             self.directionsLoaded.emit()
87
88         threading.Thread(target=load_async).start()
89
90     @Slot(result='QStringList')
91     def get_lines(self):
92         return self.lines
93
94     @Slot(str, str)
95     def search(self, line, station):
96         line = line.upper()
97         station = station.decode('utf-8')
98         print line, station
99
100         if line not in self.lines:
101             return "Invalid line"
102
103         try:
104             stations = sorted(self.itip.get_stations(line).items())
105             print stations
106             headers, stations = zip(*stations)
107             print headers
108             print stations
109             details = [(direction, name, url) for direction, stops in stations
110                         for name, url in stops if match_station(station, name)]
111             print details
112         except urllib2.URLError as e:
113             print e.message
114             return e.message
115
116 if __name__ == '__main__':
117     app = QApplication(sys.argv)
118
119     view = QDeclarativeView()
120
121     # instantiate the Python object
122     itip = Gui()
123
124     # expose the object to QML
125     context = view.rootContext()
126     context.setContextProperty('itip', itip)
127
128     if os.path.abspath(__file__).startswith('/usr/bin/'):
129         # Assume system-wide installation, QML from /usr/share/
130         view.setSource('/usr/share/gotovienna/qml/main.qml')
131     else:
132         # Assume test from source directory, use relative path
133         view.setSource(os.path.join(os.path.dirname(__file__), 'qml/main.qml'))
134
135     view.showFullScreen()
136
137     sys.exit(app.exec_())
138