#!/usr/bin/env python """Public transport information for Vienna""" __author__ = 'kelvan ' __version__ = '0.9.0' __website__ = 'https://github.com/kelvan/gotoVienna/' __license__ = 'GNU General Public License v3 or later' from datetime import datetime from PySide.QtCore import QAbstractListModel, QModelIndex, QObject, Slot, Signal from PySide.QtGui import QApplication from PySide.QtDeclarative import QDeclarativeView from gotovienna.utils import * from gotovienna.realtime import * from gotovienna.gps import * import urllib2 import os import sys import threading from datetime import time class GotoViennaListModel(QAbstractListModel): def __init__(self, objects=None): QAbstractListModel.__init__(self) if objects is None: objects = [] self._objects = objects self.setRoleNames({0: 'modelData'}) def set_objects(self, objects): self._objects = objects def get_objects(self): return self._objects def get_object(self, index): return self._objects[index.row()] def rowCount(self, parent=QModelIndex()): return len(self._objects) def data(self, index, role): if index.isValid(): if role == 0: return self.get_object(index) return None class Gui(QObject): def __init__(self): QObject.__init__(self) self.itip = ITipParser() self.lines = [] # Read line names in categorized/sorted order for _, lines in categorize_lines(self.itip.lines): self.lines.extend(lines) self.current_line = '' self.current_stations = [] self.current_departures = [] @Slot(int, result=str) def get_direction(self, idx): return self.current_stations[idx][0] @Slot(str, str, result='QStringList') def get_stations(self, line, direction): print 'line:', line, 'current line:', self.current_line for dx, stations in self.current_stations: print 'dx:', dx, 'direction:', direction if dx == direction: return [stationname for stationname, url in stations] return ['no stations found'] directionsLoaded = Signal() @Slot(str) def load_directions(self, line): def load_async(): stations = sorted(self.itip.get_stations(line).items()) self.current_line = line self.current_stations = stations self.directionsLoaded.emit() threading.Thread(target=load_async).start() def map_departure(self, dep): dep['lowfloor'] = 1 if dep['lowfloor'] else 0 if type(dep['time']) == time: dep['time'] = dep['time'].strftime('%H:%M') return dep departuresLoaded = Signal() @Slot(str) def load_departures(self, url): def load_async(): self.current_departures = map(self.map_departure, \ self.itip.get_departures(url)) #print self.current_departures self.departuresLoaded.emit() threading.Thread(target=load_async).start() @Slot(str) def load_station_departures(self, station): def load_async(): self.current_departures = map(self.map_departure, \ sort_departures(self.itip.get_departures_by_station(station))) #print self.current_departures self.departuresLoaded.emit() threading.Thread(target=load_async).start() @Slot(float, float) def load_nearby_departures(self, lat, lon): def load_async(): self.current_departures = [] try: stations = get_nearby_stations(lat, lon) print stations for station in stations: print station try: self.current_departures += self.itip.get_departures_by_station(station) except Exception as e: print e.message self.current_departures = map(self.map_departure, \ sort_departures(self.current_departures)) #print self.current_departures except Exception as e: print e.message print 'loaded' self.departuresLoaded.emit() threading.Thread(target=load_async).start() @Slot(str, str, str, result=str) def get_directions_url(self, line, direction, station): return self.itip.get_url_from_direction(line, direction, station) @Slot(result='QStringList') def get_lines(self): return self.lines @Slot(result='QVariant') def get_departures(self): return self.current_departures @Slot(float, float, result='QStringList') def get_nearby_stations(self, lat, lon): try: return get_nearby_stations(lat, lon) except Exception as e: print e.message return [] @Slot(str, str) def search(self, line, station): line = line.upper() station = station.decode('utf-8') print line, station if line not in self.lines: return "Invalid line" try: stations = sorted(self.itip.get_stations(line).items()) print stations headers, stations = zip(*stations) print headers print stations details = [(direction, name, url) for direction, stops in stations for name, url in stops if match_station(station, name)] print details except urllib2.URLError as e: print e.message return e.message if __name__ == '__main__': app = QApplication(sys.argv) view = QDeclarativeView() # instantiate the Python object itip = Gui() # expose the object to QML context = view.rootContext() context.setContextProperty('itip', itip) if os.path.abspath(__file__).startswith('/usr/bin/'): # Assume system-wide installation, QML from /usr/share/ view.setSource('/usr/share/gotovienna/qml/main.qml') else: # Assume test from source directory, use relative path view.setSource(os.path.join(os.path.dirname(__file__), 'qml/main.qml')) view.showFullScreen() sys.exit(app.exec_())