diff --git a/modules/transilien/backend.py b/modules/transilien/backend.py index 089600e1..eb6a9f0d 100644 --- a/modules/transilien/backend.py +++ b/modules/transilien/backend.py @@ -17,14 +17,10 @@ # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . - - - -from weboob.capabilities.travel import CapTravel, Station, Departure, RoadStep +from weboob.capabilities.travel import CapTravel from weboob.tools.backend import BaseBackend from .browser import Transilien -from .stations import STATIONS class TransilienBackend(BaseBackend, CapTravel): @@ -37,32 +33,10 @@ class TransilienBackend(BaseBackend, CapTravel): BROWSER = Transilien def iter_station_search(self, pattern): - pattern = pattern.lower() - for _id, name in STATIONS.iteritems(): - if name.lower().find(pattern) >= 0: - yield Station(_id, name) + return self.browser.get_stations(pattern) def iter_station_departures(self, station_id, arrival_id=None, date=None): - with self.browser: - for i, d in enumerate(self.browser.iter_station_departures(station_id, arrival_id)): - departure = Departure(i, d['type'], d['time']) - departure.departure_station = d['departure'] - departure.arrival_station = d['arrival'] - departure.late = d['late'] - departure.information = d['late_reason'] - departure.plateform = d['plateform'] - yield departure + return self.browser.get_station_departues(station_id.replace('-', ' '), arrival_id, date) def iter_roadmap(self, departure, arrival, filters): - with self.browser: - roadmap = self.browser.get_roadmap(departure, arrival, filters) - - for s in roadmap['steps']: - step = RoadStep(s['id']) - step.line = s['line'] - step.start_time = s['start_time'] - step.end_time = s['end_time'] - step.departure = s['departure'] - step.arrival = s['arrival'] - step.duration = s['duration'] - yield step + return self.browser.get_roadmap(departure, arrival, filters) diff --git a/modules/transilien/browser.py b/modules/transilien/browser.py index a4ad867d..5f638110 100644 --- a/modules/transilien/browser.py +++ b/modules/transilien/browser.py @@ -16,56 +16,52 @@ # # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . +from datetime import datetime + +from weboob.tools.browser2 import PagesBrowser, URL +from .pages import StationsPage, DeparturesPage, DeparturesPage2, HorairesPage, RoadMapPage -from weboob.tools.browser import BaseBrowser, BasePage, BrowserUnavailable +class Transilien(PagesBrowser): -from .pages.departures import DeparturesPage -from .pages.roadmap import RoadmapSearchPage, RoadmapConfirmPage, RoadmapPage + BASEURL = 'http://www.transilien.com' + stations_page = URL('aidesaisie/autocompletion\?saisie=(?P.*)', StationsPage) + departures_page = URL('gare/pagegare/chargerGare\?nomGare=(?P.*)', + 'gare/.*', DeparturesPage) + departures_page2 = URL('fichehoraire/fichehoraire/(?P.*)', + 'fichehoraire/fichehoraire/.*', DeparturesPage2) + horaires_page = URL('fiche-horaire/(?P.*)--(?P.*)-(?P.*)-(?P)-(?P)', + 'fiche-horaire/.*', HorairesPage) -class UnavailablePage(BasePage): - def on_loaded(self): - raise BrowserUnavailable('Website is currently unavailable') - - -class Transilien(BaseBrowser): - DOMAIN = 'www.transilien.com' - PROTOCOL = 'https' - USER_AGENT = BaseBrowser.USER_AGENTS['microb'] - PAGES = {'https://www\.transilien\.com/web/ITProchainsTrainsAvecDest\.do\?.*': DeparturesPage, - 'https://www\.transilien\.com/web/ITProchainsTrains\.do\?.*': DeparturesPage, - 'https://www\.transilien\.com/web/site.*': RoadmapSearchPage, - 'https://www\.transilien\.com/web/RedirectHI.do.*': RoadmapConfirmPage, - 'https://www\.transilien\.com/web/RedirectHIIntermediaire.do.*': RoadmapPage, - 'https://www\.transilien\.com/transilien_sncf_maintenance_en_cours.htm': UnavailablePage, - } - - def is_logged(self): - """ Do not need to be logged """ - return True - - def iter_station_search(self, pattern): - pass - - def iter_station_departures(self, station_id, arrival_id=None): - if arrival_id: - self.location('https://www.transilien.com/web/ITProchainsTrainsAvecDest.do?codeTr3aDepart=%s&codeTr3aDest=%s&urlModule=/site/pid/184&gareAcc=true' % (station_id, arrival_id)) - else: - self.location('https://www.transilien.com/web/ITProchainsTrains.do?tr3a=%s&urlModule=/site/pid/184' % station_id) - - return self.page.iter_routes() + roadmap_page = URL('itineraire/rechercheitineraire/(?P.*)', + 'itineraire/rechercheitineraire/.*', RoadMapPage) def get_roadmap(self, departure, arrival, filters): - self.location('/web/site/accueil/etat-trafic/chercher-itineraire/lang/en') + dep = self.get_stations(departure, False).next().name + arr = self.get_stations(arrival, False).next().name + self.roadmap_page.go(url='init').request_roadmap(dep, arr, filters.arrival_time) + return self.page.get_roadmap() - assert self.is_on_page(RoadmapSearchPage) - self.page.search(departure, arrival, filters.departure_time, filters.arrival_time) + def get_stations(self, pattern, only_station=True): + return self.stations_page.go(pattern=pattern).get_stations(only_station=only_station) - assert self.is_on_page(RoadmapConfirmPage) - self.page.confirm() + def get_station_departues(self, station, arrival_id, date): + if arrival_id is not None: + arrival_name = arrival_id.replace('-', ' ') + self.departures_page2.go(url='init').init_departure(station) - assert self.is_on_page(RoadmapPage) - roadmap = {} - roadmap['steps'] = list(self.page.get_steps()) - return roadmap + arrival = self.page.get_potential_arrivals().get(arrival_name) + if arrival: + station_id = self.page.get_station_id() + + if date is None: + date = datetime.now() + + _date = datetime.strftime(date, "%d/%m/%Y-%H:%M") + + self.horaires_page.go(station=station.replace(' ', '-'), arrival=arrival_id, station2=station_id, arrival2=arrival, date=_date) + return self.page.get_departures(station, arrival_name, date) + return [] + else: + return self.departures_page.go(station=station).get_departures(station=station) diff --git a/modules/transilien/pages.py b/modules/transilien/pages.py new file mode 100644 index 00000000..38c34133 --- /dev/null +++ b/modules/transilien/pages.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2011 Julien Hébert, Romain Bignon +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + +import re + +from weboob.tools.browser2.page import JsonPage, HTMLPage, method +from weboob.tools.browser2.elements import TableElement, ItemElement, ListElement +from weboob.capabilities.travel import Station, Departure, RoadStep +from weboob.tools.browser2.filters import Dict, CleanText, TableCell, Filter, DateTime, Env, Link, Regexp, Duration +from weboob.tools.date import LinearDateGuesser + +__all__ = ['StationsPage', 'DeparturesPage', 'DeparturesPage2', 'HorairesPage', 'RoadMapPage'] + + +class DictElement(ListElement): + def find_elements(self): + if self.item_xpath is not None: + for el in self.el.get(self.item_xpath): + yield el + else: + yield self.el + + +class RoadMapDuration(Duration): + regexp = re.compile(r'(?P\d+)') + kwargs = {'minutes': 'mn'} + + +class DepartureTypeFilter(Filter): + def filter(self, el): + result = [] + for img in el[0].getiterator(tag='img'): + result.append(img.attrib['alt']) + return u' '.join(result) + + +class Child(Filter): + def filter(self, el): + return list(el[0].iterchildren()) + + +class RoadMapPage(HTMLPage): + def request_roadmap(self, station, arrival, arrival_date): + form = self.get_form('//form[@id="cRechercheItineraire"]') + form['depart'] = station + form['arrivee'] = arrival + form.submit() + + def get_roadmap(self): + for step in self.doc.xpath('//table[@class="trajet_etapes"]/tr[@class="etape"]'): + roadstep = RoadStep() + roadstep.line = '%s %s' % (DepartureTypeFilter(step.xpath('./td[@class="moyen"]'))(self), + CleanText('./td[@class="moyen"]')(step)) + roadstep.start_time = DateTime(CleanText('./th/span[@class="depart"]'), + LinearDateGuesser())(step) + roadstep.end_time = DateTime(CleanText('./th/span[@class="depart"]/following-sibling::span'), + LinearDateGuesser())(step) + roadstep.departure = CleanText('./td[@class="arret"]/p/strong')(step) + roadstep.arrival = CleanText('./td[@class="arret"]/p/following-sibling::p/strong')(step) + roadstep.duration = RoadMapDuration(CleanText('./td[@class="time"]'))(step) + yield roadstep + + +class HorairesPage(HTMLPage): + def get_departures(self, station, arrival, date): + for table in self.doc.xpath('//table[@class="trajet_horaires trajet_etapes"]'): + lignes = table.xpath('./tr[@class="ligne"]/th') + arrives = table.xpath('./tr[@class="arrivee"]/td') + departs = table.xpath('./tr[@class="depart"]/td') + + items = zip(lignes, arrives, departs) + for item in items: + departure = Departure() + departure.id = Regexp(Link('./div/a'), '.*?vehicleJourneyExternalCode=(.*?)&.*?')(item[1]) + departure.departure_station = station + departure.arrival_station = arrival + hour, minute = CleanText('./div/a')(item[1]).split('h') + departure.time = date.replace(hour=int(hour), minute=int(minute)) + hour, minute = CleanText('./div/a')(item[2]).split('h') + departure.arrival_time = date.replace(hour=int(hour), minute=int(minute)) + departure.information = CleanText('.')(item[0]) + departure.type = DepartureTypeFilter(item)(self) + yield departure + + +class StationsPage(JsonPage): + + @method + class get_stations(DictElement): + item_xpath = 'gares' + + class item(ItemElement): + klass = Station + + def condition(self): + if self.env['only_station']: + return Dict('entryPointType')(self.el) == 'StopArea' and Dict('reseau')(self.el)[0] + return True + + obj_name = CleanText(Dict('gare')) + obj_id = CleanText(Dict('gare'), replace=[(' ', '-')]) + + +class DeparturesPage2(HTMLPage): + def get_potential_arrivals(self): + arrivals = {} + for el in self.doc.xpath('//select[@id="gare_arrive_ambigu"]/option'): + arrivals[el.text] = el.attrib['value'] + return arrivals + + def get_station_id(self): + form = self.get_form('//form[@id="cfichehoraire"]') + return form['departExternalCode'] + + def init_departure(self, station): + form = self.get_form('//form[@id="cfichehoraire"]') + form['depart'] = station + form.submit() + + def get_departures(self, arrival, date): + form = self.get_form('//form[@id="cfichehoraire"]') + form['arrive'] = arrival + if date: + form['jourHoraire'] = date.day + form['moiHoraire'] = '%s|%s' % (date.month, date.year) + form['heureHoraire'] = date.hour + form['minuteHoraire'] = date.minute + print form + form.submit() + + +class DeparturesPage(HTMLPage): + + @method + class get_departures(TableElement): + head_xpath = u'//table[@class="etat_trafic"]/thead/tr/th[@scope="col"]/text()' + item_xpath = u'//table[@class="etat_trafic"]/tr' + + col_type = u'Ligne' + col_info = u'Nom du train' + col_time = u'Heure de départ' + col_arrival = u'Destination' + col_plateform = u'Voie/quai' + col_id = u'Gares desservies' + + class item(ItemElement): + klass = Departure + + obj_time = DateTime(CleanText(TableCell('time')), LinearDateGuesser()) + obj_type = DepartureTypeFilter(TableCell('type')) + obj_departure_station = CleanText(Env('station')) + obj_arrival_station = CleanText(TableCell('arrival')) + obj_information = CleanText(TableCell('info')) + obj_plateform = CleanText(TableCell('plateform')) + obj_id = Regexp(Link(Child(TableCell('id'))), '.*?numeroTrain=(.*?)&.*?') diff --git a/modules/transilien/pages/__init__.py b/modules/transilien/pages/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/modules/transilien/pages/departures.py b/modules/transilien/pages/departures.py deleted file mode 100644 index 5a24c18b..00000000 --- a/modules/transilien/pages/departures.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright(C) 2010-2011 Julien Hébert, Romain Bignon -# -# This file is part of weboob. -# -# weboob is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# weboob is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with weboob. If not, see . - -import datetime - -from weboob.capabilities import UserError -from weboob.tools.misc import to_unicode -from weboob.tools.browser import BasePage, BrokenPageError - - -__all__ = ['StationNotFound', 'DeparturesPage'] - - -class StationNotFound(UserError): - pass - - -class DeparturesPage(BasePage): - def iter_routes(self): - try: - table = self.parser.select(self.document.getroot(), 'table.horaires3', 1) - except BrokenPageError: - raise StationNotFound('Station not found') - - departure = self.parser.select(table, 'td.caption strong', 1).text - for tr in table.findall('tr'): - if len(tr.findall('td')) != 4: - continue - - code_mission = self.parser.select(tr, 'td[headers=Code_de_mission] a', 1).text.strip() - time_s = self.parser.select(tr, 'td[headers=Heure_de_passage]', 1).text.strip().rstrip(u'\xa0*') - destination = self.parser.select(tr, 'td[headers=Destination]', 1).text.strip() - plateform = self.parser.select(tr, 'td[headers=Voie]', 1).text.strip() - - late_reason = None - time = None - try : - time = datetime.datetime.combine(datetime.date.today(), datetime.time(*[int(x) for x in time_s.split(':')])) - except ValueError: - late_reason = time_s - self.logger.warning('Unable to parse datetime "%s"' % time_s) - - yield {'type': to_unicode(code_mission), - 'time': time, - 'departure': to_unicode(departure), - 'arrival': to_unicode(destination), - 'late': datetime.time(), - 'late_reason': late_reason, - 'plateform': to_unicode(plateform)} diff --git a/modules/transilien/pages/roadmap.py b/modules/transilien/pages/roadmap.py deleted file mode 100644 index 43088936..00000000 --- a/modules/transilien/pages/roadmap.py +++ /dev/null @@ -1,122 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright(C) 2010-2011 Romain Bignon -# -# This file is part of weboob. -# -# weboob is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# weboob is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with weboob. If not, see . - - -import re -import datetime - -from weboob.capabilities.travel import RoadmapError -from weboob.tools.browser import BasePage -from weboob.tools.misc import to_unicode -from weboob.tools.mech import ClientForm - - -__all__ = ['RoadmapPage'] - - -class RoadmapSearchPage(BasePage): - def search(self, departure, arrival, departure_time, arrival_time): - self.browser.select_form('formHiRecherche') - self.browser['lieuDepart'] = departure.encode('utf-8') - self.browser['lieuArrivee'] = arrival.encode('utf-8') - - time = None - if departure_time: - self.browser['typeHeure'] = ['1'] - time = departure_time - elif arrival_time: - self.browser['typeHeure'] = ['-1'] - time = arrival_time - - if time: - try: - self.browser['jour'] = ['%d' % time.day] - self.browser['mois'] = ['%02d/%d' % (time.month, time.year)] - self.browser['heure'] = ['%02d' % time.hour] - self.browser['minutes'] = ['%02d' % (time.minute - (time.minute%5))] - except ClientForm.ItemNotFoundError: - raise RoadmapError('Unable to establish a roadmap with %s time at "%s"' % ('departure' if departure_time else 'arrival', time)) - self.browser.submit() - - -class RoadmapPage(BasePage): - def get_steps(self): - errors = [] - for p in self.parser.select(self.document.getroot(), 'p.errors'): - if p.text: - errors.append(p.text.strip()) - - if len(errors) > 0: - raise RoadmapError('Unable to establish a roadmap: %s' % ', '.join(errors)) - - current_step = None - i = 0 - for tr in self.parser.select(self.document.getroot(), 'table.horaires2 tbody tr'): - if not 'class' in tr.attrib: - continue - elif tr.attrib['class'] == 'trHautTroncon': - current_step = {} - current_step['id'] = i - i += 1 - current_step['start_time'] = self.parse_time(self.parser.select(tr, 'td.formattedHeureDepart p', 1).text.strip()) - current_step['line'] = to_unicode(self.parser.select(tr, 'td.rechercheResultatColumnMode img')[-1].attrib['alt']) - current_step['departure'] = to_unicode(self.parser.select(tr, 'td.descDepart p strong', 1).text.strip()) - current_step['duration'] = self.parse_duration(self.parser.select(tr, 'td.rechercheResultatVertAlign', 1).text.strip()) - elif tr.attrib['class'] == 'trBasTroncon': - current_step['end_time'] = self.parse_time(self.parser.select(tr, 'td.formattedHeureArrivee p', 1).text.strip()) - current_step['arrival'] = to_unicode(self.parser.select(tr, 'td.descArrivee p strong', 1).text.strip()) - yield current_step - - def parse_time(self, time): - h, m = time.split('h') - return datetime.time(int(h), int(m)) - - def parse_duration(self, dur): - m = re.match('(\d+)min.', dur) - if m: - return datetime.timedelta(minutes=int(m.group(1))) - m = re.match('(\d+)h(\d+)', dur) - if m: - return datetime.timedelta(hours=int(m.group(1)), - minutes=int(m.group(2))) - - -class RoadmapConfirmPage(RoadmapPage): - def select(self, name, num): - try: - self.browser[name] = str(num) - except TypeError: - self.browser[name] = [str(num)] - - def confirm(self): - self.browser.select_form('form1') - self.browser.set_all_readonly(False) - try: - self.select('idDepart', 1) - self.select('idArrivee', 1) - self.browser['modeTransport'] = ['0'] - self.browser['trainRer'] = 'true' - self.browser['bus'] = 'false' - self.browser['tramway'] = 'true' - self.browser['bateau'] = 'false' - except ClientForm.ControlNotFoundError: - # We are already on the result page - return - else: - self.browser.submit() diff --git a/modules/transilien/stations.py b/modules/transilien/stations.py deleted file mode 100644 index 5c30c440..00000000 --- a/modules/transilien/stations.py +++ /dev/null @@ -1,346 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright(C) 2010-2011 Julien Hébert, Romain Bignon -# -# This file is part of weboob. -# -# weboob is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# weboob is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with weboob. If not, see . - - -STATIONS = { - 'BXN': u'BAGNEAUX SUR LOING', - 'BJR': u'BOIS LE ROI', - 'BOM': u'BOURRON MARLOTTE GREZ', - 'BXI': u'BOUSSY ST ANTOINE', - 'BNY': u'BRUNOY', - 'CES': u'CESSON', - 'CLY': u'CHANTILLY GOUVIEUX', - 'CLX': u'CHATELET LES HALLES', - 'CBV': u'COMBS LA VILLE QUINCY', - 'COE': u'CORBEIL ESSONNES', - 'CL': u'CREIL', - 'DDI': u'DORDIVES', - 'EVR': u'EVRY', - 'EVC': u'EVRY COURCOURONNES', - 'FFY': u'FERRIERES FONTENAY', - 'FON': u'FONTAINEBLEAU AVON', - 'GDS': u'GARE DU NORD', - 'GAJ': u'GARGES SARCELLES', - 'GOU': u'GOUSSAINVILLE', - 'GBG': u'GRAND BOURG', - 'GGG': u'GRIGNY CENTRE', - 'JY': u'JUVISY', - 'BBN': u'LA BORNE BLANCHE', - 'BFX': u'LE BRAS DE FER', - 'WEE': u'LE MEE', - 'VD': u'LE VERT DE MAISONS', - 'LNX': u'LES NOUES', - 'LIU': u'LIEUSAINT MOISSY', - 'LOV': u'LOUVRES', - 'MFA': u'MAISONS ALFORT ALFORTVILLE', - 'MEL': u'MELUN', - 'MS': u'MONTARGIS', - 'MTU': u'MONTEREAU', - 'KRW': u'MONTGERON CROSNE', - 'MKN': u'MONTIGNY SUR LOING', - 'MOR': u'MORET VENEUX LES SABLONS', - 'NSP': u'NEMOURS ST PIERRE', - 'OBP': u'ORANGIS BOIS DE L EPINE', - 'ORY': u'ORRY LA VILLE COYE LA FORET', - 'PRF': u'PIERREFITTE STAINS', - 'RIS': u'RIS ORANGIS', - 'ZTN': u'SAVIGNY LE TEMPLE NANDY', - 'SPP': u'SOUPPES CHÂTEAU LANDON', - 'SDE': u'ST DENIS', - 'SF': u'ST MAMMES', - 'SFD': u'STADE DE FRANCE ST DENIS', - 'SUR': u'SURVILLIERS FOSSES', - 'TMR': u'THOMERY', - 'VGS': u'VIGNEUX SUR SEINE', - 'VP': u'VILLENEUVE PRAIRIE', - 'VSG': u'VILLENEUVE ST GEORGES', - 'VTV': u'VILLENEUVE TRIAGE', - 'VIB': u'VILLIERS LE BEL GONESSE ARNOUVILLE', - 'VWC': u'VIRY CHATILLON', - 'YES': u'YERRES', - 'ARW': u'ARGENTEUIL', - 'AEH': u'AUBERGENVILLE ELISABETHVILLE', - 'BEC': u'BECON LES BRUYERES', - 'BCO': u'BOIS COLOMBES', - 'CWJ': u'CHAVILLE RIVE DROITE', - 'CLL': u'CLICHY LEVALLOIS', - 'CBK': u'COLOMBES', - 'CSH': u'CONFLANS SAINTE HONORINE', - 'CPA': u'CORMEILLES EN PARISIS', - 'KOU': u'COURBEVOIE', - 'EPO': u'EPONE MEZIERES', - 'ERA': u'ERAGNY NEUVILLE', - 'ERE': u'ERMONT EAUBONNE', - 'PSL': u'GARE ST LAZARE', - 'HRY': u'HERBLAY', - 'HAR': u'HOUILLES CARRIERES SUR SEINE', - 'LDU': u'LA DEFENSE GARE SNCF', - 'FMY': u'LA FRETTE MONTIGNY', - 'LGK': u'LA GARENNE COLOMBES', - 'LSD': u'LE STADE', - 'VDO': u'LE VAL D OR', - 'KVE': u'LES CLAIRIERES DE VERNEUIL', - 'LMU': u'LES MUREAUX', - 'LWA': u'LES VALLEES', - 'MLF': u'MAISONS LAFFITTE', - 'MTE': u'MANTES LA JOLIE', - 'MTQ': u'MANTES STATION', - 'MFL': u'MONTREUIL', - 'NUN': u'NANTERRE UNIVERSITE', - 'PSY': u'POISSY', - 'PTC': u'PONT CARDINET', - 'PSE': u'PONTOISE', - 'PTX': u'PUTEAUX', - 'SNN': u'SANNOIS', - 'SVL': u'SARTROUVILLE', - 'VDV': u'SEVRES VILLE D AVRAY', - 'SCD': u'ST CLOUD', - 'XOA': u'ST OUEN L AUMONE QUARTIER DE L EGLIS', - 'MVH': u'SURESNES MONT VALERIEN', - 'VDA': u'VAL D ARGENTEUIL', - 'VET': u'VERNOUILLET VERNEUIL', - 'VRD': u'VERSAILLES RIVE DROITE', - 'VSW': u'VILLENNES SUR SEINE', - 'VFD': u'VIROFLAY RIVE DROITE', - 'ABL': u'ABLON', - 'ARP': u'ARPAJON', - 'ATH': u'ATHIS MONS', - 'BFM': u'BIBLIOTHEQUE F. MITTERRAND', - 'BIS': u'BIEVRES', - 'BVI': u'BOULEVARD VICTOR', - 'BY': u'BRETIGNY', - 'BIH': u'BREUILLET BRUYERES LE CHATEL', - 'BRW': u'BREUILLET VILLAGE', - 'CPM': u'CHAMP DE MARS TOUR EIFFEL', - 'CHV': u'CHAVILLE VELIZY', - 'CAZ': u'CHILLY MAZARIN', - 'CLR': u'CHOISY LE ROI', - 'D': u'DOURDAN', - 'ELY': u'EGLY', - 'EYO': u'EPINAY SUR ORGE', - 'GBI': u'GRAVIGNY BALIZY', - 'IGY': u'IGNY', - 'INV': u'INVALIDES', - 'ISY': u'ISSY', - 'ISP': u'ISSY VAL DE SEINE', - 'IV': u'IVRY SUR SEINE', - 'JVL': u'JAVEL', - 'JAS': u'JOUY EN JOSAS', - 'NG': u'LA NORVILLE ST GERMAIN LES ARPAJON', - 'LAD': u'LES ARDOINES', - 'LJU': u'LONGJUMEAU', - 'MPU': u'MASSY PALAISEAU RER C', - 'MFY': u'MEUDON VAL FLEURY', - 'MDS': u'MUSEE D ORSAY', - 'PJ': u'PETIT JOUY LES LOGES', - 'PV': u'PETIT VAUX', - 'PDM': u'PONT DE L ALMA', - 'POA': u'PORCHEFONTAINE', - 'SAO': u'SAVIGNY SUR ORGE', - 'SXE': u'SERMAISE', - 'SCW': u'ST CHERON', - 'SHL': u'ST MICHEL NOTRE DAME', - 'SHO': u'ST MICHEL SUR ORGE', - 'SXG': u'STE GENEVIEVE DES BOIS', - 'VBO': u'VAUBOYEN', - 'VC': u'VERSAILLES CHANTIERS', - 'VRG': u'VERSAILLES R G CHATEAU DE VERSAILLES', - 'VRI': u'VILLENEUVE LE ROI', - 'VFG': u'VIROFLAY RIVE GAUCHE', - 'VY': u'VITRY SUR SEINE', - 'BSO': u'BOURAY', - 'CHK': u'CHAMARANDE', - 'ETP': u'ETAMPES', - 'ETY': u'ETRECHY', - 'PZB': u'GARE D\'AUSTERLITZ', - 'LYO': u'LARDY', - 'MSX': u'MAROLLES EN HUREPOIX', - 'SME': u'ST MARTIN D ETAMPES', - 'CME': u'CHAMPAGNE SUR SEINE', - 'CJR': u'CHARTRETTES', - 'HER': u'HERICY', - 'GPA': u'LA GRANDE PAROISSE', - 'LYQ': u'LIVRY SUR SEINE', - 'VSS': u'VERNOU SUR SEINE', - 'VUN': u'VULAINES SUR SEINE SAMOREAU', - 'PLY': u'GARE DE LYON', - 'FPO': u'FONTAINE LE PORT', - 'CJN': u'CHANGIS ST JEAN', - 'CTH': u'CHATEAU THIERRY', - 'CSG': u'CHELLES GOURNAY', - 'CYZ': u'CHEZY SUR MARNE', - 'CO': u'COULOMMIERS', - 'EY': u'ESBLY', - 'FMP': u'FAREMOUTIERS POMMEUSE', - 'GCM': u'GUERARD LA CELLE SUR MORIN', - 'LFJ': u'LA FERTE SOUS JOUARRE', - 'LGY': u'LAGNY THORIGNY', - 'MLB': u'MARLES EN BRIE', - 'MEA': u'MEAUX', - 'MOF': u'MORTCERF', - 'MXK': u'MOUROUX', - 'NAU': u'NANTEUIL SAACY', - 'NAA': u'NOGENT L ARTAUD CHARLY', - 'TOU': u'TOURNAN', - 'TLP': u'TRILPORT', - 'VAI': u'VAIRES TORCY', - 'AEE': u'ASNIERES', - 'AUU': u'AUBER', - 'BQA': u'BRY SUR MARNE', - 'BXG': u'BUSSY ST GEORGES', - 'CGP': u'CHARLES DE GAULLE-ETOILE', - 'GYN': u'GARE DE LYON', - 'GAW': u'LA DEFENSE RER A', - 'LQN': u'LOGNES', - 'MVC': u'MARNE LA VALLEE CHESSY', - 'NAF': u'NANTERRE PREFECTURE SNCF', - 'NTN': u'NATION', - 'NYP': u'NEUILLY PLAISANCE', - 'NSL': u'NOISIEL', - 'NYC': u'NOISY CHAMPS', - 'NYG': u'NOISY LE GRAND MONT D EST', - 'TOC': u'TORCY MARNE LA VALLEE', - 'VDE': u'VAL D EUROPE', - 'VFR': u'VAL DE FONTENAY RER A', - 'VNC': u'VINCENNES', - 'CJV': u'CERGY LE HAUT', - 'CYP': u'CERGY PREFECTURE', - 'CYC': u'CERGY ST CHRISTOPHE', - 'CFD': u'CONFLANS FIN D OISE', - 'NUE': u'NEUVILLE UNIVERSITE', - 'RYR': u'AEROPORT CDG 2 TGV', - 'ATW': u'ANTONY', - 'ALC': u'AUBERVILLIERS LA COURNEUVE', - 'AB': u'AULNAY SOUS BOIS', - 'BAM': u'BLANC MESNIL', - 'BQQ': u'BOURG LA REINE', - 'BVJ': u'BURES SUR YVETTE', - 'CUF': u'CITE UNIVERSITAIRE', - 'CVW': u'COURCELLE SUR YVETTE', - 'DFR': u'DENFERT ROCHEREAU', - 'DRN': u'DRANCY', - 'FMN': u'FONTAINE MICHALON', - 'GIF': u'GIF SUR YVETTE', - 'XBY': u'LA CROIX DE BERNY', - 'HAQ': u'LA HACQUINIERE', - 'LPN': u'LA PLAINE STADE DE FRANCE', - 'LBT': u'LE BOURGET', - 'GUW': u'LE GUICHET', - 'BQC': u'LES BACONNETS', - 'LZV': u'LOZERE', - 'LXJ': u'LUXEMBOURG', - 'MP': u'MASSY PALAISEAU RER B', - 'MVP': u'MASSY VERRIERES RER B', - 'ORS': u'ORSAY VILLE', - 'PAX': u'PALAISEAU', - 'PAW': u'PALAISEAU VILLEBON', - 'PCX': u'PARC DE SCEAUX', - 'PEX': u'PARC DES EXPOSITIONS', - 'PWR': u'PORT ROYAL', - 'BDE': u'SEVRAN BEAUDOTTES', - 'XND': u'ST MICHEL NOTRE DAME', - 'SNM': u'ST REMY LES CHEVREUSE', - 'VPN': u'VILLEPINTE', - 'RSY': u'AEROPORT CDG 1', - 'ARK': u'ARCUEIL CACHAN', - 'BGK': u'BAGNEUX', - 'GTL': u'GENTILLY', - 'LJA': u'LAPLACE', - 'CVF': u'CHANTELOUP LES VIGNES', - 'GGV': u'GARGENVILLE', - 'IPO': u'ISSOU PORCHEVILLE', - 'JUZ': u'JUZIERS', - 'LIM': u'LIMAY', - 'MHD': u'MEULAN HARDRICOURT', - 'TPA': u'THUN LE PARADIS', - 'TSS': u'TRIEL SUR SEINE', - 'VXS': u'VAUX SUR SEINE', - 'FNR': u'FONTENAY AUX ROSES', - 'MY': u'MITRY CLAYE', - 'RNS': u'ROBINSON', - 'SKX': u'SCEAUX', - 'SEV': u'SEVRAN LIVRY', - 'VGL': u'VERT GALANT', - 'VII': u'VILLEPARISIS MITRY LE NEUF', - 'BOF': u'BOUFFEMONT MOISSELLES', - 'DEU': u'DEUIL MONTMAGNY', - 'DMO': u'DOMONT', - 'ECZ': u'ECOUEN EZANVILLE', - 'EPV': u'EPINAY VILLETANEUSE', - 'PNB': u'GARE DU NORD', - 'GRL': u'GROSLAY', - 'LUZ': u'LUZARCHES', - 'MSO': u'MONTSOULT MAFFLIERS', - 'SLL': u'SARCELLES ST BRICE', - 'SWY': u'SEUGY', - 'VMS': u'VIARMES', - 'VW': u'VILLAINES', - 'CH': u'CHARTRES', - 'CVI': u'CHAVILLE RIVE GAUCHE', - 'CMA': u'CLAMART', - 'CGW': u'COIGNIERES', - 'DX': u'DREUX', - 'EPN': u'EPERNON', - 'FAF': u'FONTENAY LE FLEURY', - 'GAQ': u'GARANCIERES LA QUEUE', - 'GZA': u'GAZERAN', - 'HOA': u'HOUDAN', - 'JOY': u'JOUY', - 'VYL': u'LA VERRIERE', - 'LPE': u'LE PERRAY', - 'LSI': u'LES ESSARTS LE ROI', - 'MTN': u'MAINTENON', - 'MBR': u'MARCHEZAIS BROUE', - 'MDN': u'MEUDON', - 'MLM': u'MONTFORT L AMAURY MERE', - 'OGB': u'ORGERUS BEHOUST', - 'PMP': u'PARIS MONTPARNASSE', - 'PG': u'PLAISIR GRIGNON', - 'PIE': u'PLAISIR LES CLAYES', - 'RBT': u'RAMBOUILLET', - 'SVR': u'SEVRES RIVE GAUCHE', - 'SCR': u'ST CYR', - 'SPI': u'ST PIAT', - 'SQY': u'ST QUENTIN EN YVELINES', - 'TAE': u'TACOIGNIERES RICHEBOURG', - 'TVO': u'TRAPPES', - 'VMK': u'VANVES MALAKOFF', - 'VEP': u'VILLEPREUX LES CLAYES', - 'VEH': u'VILLIERS NEAUPHLE PONTCHARTRAIN', - 'CEG': u'CHAMP DE COURSES D ENGHIEN', - 'CPO': u'CHAMPAGNE SUR OISE', - 'EN': u'ENGHIEN LES BAINS', - 'ERT': u'ERMONT EAUBONNE', - 'ERM': u'ERMONT HALTE', - 'FPN': u'FREPILLON', - 'GNX': u'GROS NOYER ST PRIX', - 'IAP': u'L ISLE ADAM PARMAIN', - 'LBJ': u'LA BARRE ORMESSON', - 'MLV': u'MERIEL', - 'MWO': u'MERY SUR OISE', - 'PEB': u'PERSAN BEAUMONT', - 'SLF': u'ST LEU LA FORET', - 'TVY': u'TAVERNY', - 'VMD': u'VALMONDOIS', - 'VCX': u'VAUCELLES', - 'MJM': u'MAREIL SUR MAULDRE', - 'MAE': u'MAULE', - 'NZL': u'NEZEL AULNAY', - 'PAA': u'GARE DE LYON', -} diff --git a/modules/transilien/test.py b/modules/transilien/test.py index 6d90efba..48610e77 100644 --- a/modules/transilien/test.py +++ b/modules/transilien/test.py @@ -26,17 +26,20 @@ from weboob.tools.test import BackendTest class TransilienTest(BackendTest): BACKEND = 'transilien' - def test_departures(self): - stations = list(self.backend.iter_station_search('defense')) + def test_stations(self): + stations = list(self.backend.iter_station_search('aul')) self.assertTrue(len(stations) > 0) + def test_departures(self): + stations = list(self.backend.iter_station_search('aul')) + self.assertTrue(len(stations) > 0) list(self.backend.iter_station_departures(stations[0].id)) def test_roadmap(self): filters = RoadmapFilters() - roadmap = list(self.backend.iter_roadmap('Puteaux', u'École Militaire', filters)) + roadmap = list(self.backend.iter_roadmap('aul', u'aub', filters)) self.assertTrue(len(roadmap) > 0) filters.arrival_time = datetime.datetime.now() + datetime.timedelta(days=1) - roadmap = list(self.backend.iter_roadmap('Puteaux', u'Aulnay-sous-Bois', filters)) + roadmap = list(self.backend.iter_roadmap('aul', u'bag', filters)) self.assertTrue(len(roadmap) > 0)