[transilien] fix #938 and adapt to brower2
This commit is contained in:
parent
158d3fb627
commit
f4576b5921
8 changed files with 218 additions and 607 deletions
|
|
@ -17,14 +17,10 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from weboob.capabilities.travel import CapTravel
|
||||||
|
|
||||||
|
|
||||||
from weboob.capabilities.travel import CapTravel, Station, Departure, RoadStep
|
|
||||||
from weboob.tools.backend import BaseBackend
|
from weboob.tools.backend import BaseBackend
|
||||||
|
|
||||||
from .browser import Transilien
|
from .browser import Transilien
|
||||||
from .stations import STATIONS
|
|
||||||
|
|
||||||
|
|
||||||
class TransilienBackend(BaseBackend, CapTravel):
|
class TransilienBackend(BaseBackend, CapTravel):
|
||||||
|
|
@ -37,32 +33,10 @@ class TransilienBackend(BaseBackend, CapTravel):
|
||||||
BROWSER = Transilien
|
BROWSER = Transilien
|
||||||
|
|
||||||
def iter_station_search(self, pattern):
|
def iter_station_search(self, pattern):
|
||||||
pattern = pattern.lower()
|
return self.browser.get_stations(pattern)
|
||||||
for _id, name in STATIONS.iteritems():
|
|
||||||
if name.lower().find(pattern) >= 0:
|
|
||||||
yield Station(_id, name)
|
|
||||||
|
|
||||||
def iter_station_departures(self, station_id, arrival_id=None, date=None):
|
def iter_station_departures(self, station_id, arrival_id=None, date=None):
|
||||||
with self.browser:
|
return self.browser.get_station_departues(station_id.replace('-', ' '), arrival_id, date)
|
||||||
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
|
|
||||||
|
|
||||||
def iter_roadmap(self, departure, arrival, filters):
|
def iter_roadmap(self, departure, arrival, filters):
|
||||||
with self.browser:
|
return self.browser.get_roadmap(departure, arrival, filters)
|
||||||
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
|
|
||||||
|
|
|
||||||
|
|
@ -16,56 +16,52 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
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
|
BASEURL = 'http://www.transilien.com'
|
||||||
from .pages.roadmap import RoadmapSearchPage, RoadmapConfirmPage, RoadmapPage
|
stations_page = URL('aidesaisie/autocompletion\?saisie=(?P<pattern>.*)', StationsPage)
|
||||||
|
departures_page = URL('gare/pagegare/chargerGare\?nomGare=(?P<station>.*)',
|
||||||
|
'gare/.*', DeparturesPage)
|
||||||
|
departures_page2 = URL('fichehoraire/fichehoraire/(?P<url>.*)',
|
||||||
|
'fichehoraire/fichehoraire/.*', DeparturesPage2)
|
||||||
|
|
||||||
|
horaires_page = URL('fiche-horaire/(?P<station>.*)--(?P<arrival>.*)-(?P<station2>.*)-(?P<arrival2>)-(?P<date>)',
|
||||||
|
'fiche-horaire/.*', HorairesPage)
|
||||||
|
|
||||||
class UnavailablePage(BasePage):
|
roadmap_page = URL('itineraire/rechercheitineraire/(?P<url>.*)',
|
||||||
def on_loaded(self):
|
'itineraire/rechercheitineraire/.*', RoadMapPage)
|
||||||
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()
|
|
||||||
|
|
||||||
def get_roadmap(self, departure, arrival, filters):
|
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)
|
def get_stations(self, pattern, only_station=True):
|
||||||
self.page.search(departure, arrival, filters.departure_time, filters.arrival_time)
|
return self.stations_page.go(pattern=pattern).get_stations(only_station=only_station)
|
||||||
|
|
||||||
assert self.is_on_page(RoadmapConfirmPage)
|
def get_station_departues(self, station, arrival_id, date):
|
||||||
self.page.confirm()
|
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)
|
arrival = self.page.get_potential_arrivals().get(arrival_name)
|
||||||
roadmap = {}
|
if arrival:
|
||||||
roadmap['steps'] = list(self.page.get_steps())
|
station_id = self.page.get_station_id()
|
||||||
return roadmap
|
|
||||||
|
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)
|
||||||
|
|
|
||||||
171
modules/transilien/pages.py
Normal file
171
modules/transilien/pages.py
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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<mn>\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=(.*?)&.*?')
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
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)}
|
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
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',
|
|
||||||
}
|
|
||||||
|
|
@ -26,17 +26,20 @@ from weboob.tools.test import BackendTest
|
||||||
class TransilienTest(BackendTest):
|
class TransilienTest(BackendTest):
|
||||||
BACKEND = 'transilien'
|
BACKEND = 'transilien'
|
||||||
|
|
||||||
def test_departures(self):
|
def test_stations(self):
|
||||||
stations = list(self.backend.iter_station_search('defense'))
|
stations = list(self.backend.iter_station_search('aul'))
|
||||||
self.assertTrue(len(stations) > 0)
|
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))
|
list(self.backend.iter_station_departures(stations[0].id))
|
||||||
|
|
||||||
def test_roadmap(self):
|
def test_roadmap(self):
|
||||||
filters = RoadmapFilters()
|
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)
|
self.assertTrue(len(roadmap) > 0)
|
||||||
|
|
||||||
filters.arrival_time = datetime.datetime.now() + datetime.timedelta(days=1)
|
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)
|
self.assertTrue(len(roadmap) > 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue