[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
|
||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -16,56 +16,52 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# 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
|
||||
from .pages.roadmap import RoadmapSearchPage, RoadmapConfirmPage, RoadmapPage
|
||||
BASEURL = 'http://www.transilien.com'
|
||||
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):
|
||||
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<url>.*)',
|
||||
'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)
|
||||
|
|
|
|||
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):
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue