diff --git a/modules/vlille/backend.py b/modules/vlille/backend.py index c03a32b5..64b8e9e9 100644 --- a/modules/vlille/backend.py +++ b/modules/vlille/backend.py @@ -19,6 +19,7 @@ import re from weboob.tools.backend import BaseBackend +from weboob.capabilities.base import find_object from weboob.capabilities.gauge import ICapGauge, GaugeSensor, Gauge, SensorNotFound from .browser import VlilleBrowser @@ -47,11 +48,9 @@ class VlilleBackend(BaseBackend, ICapGauge): def iter_sensors(self, gauge, pattern=None): if not isinstance(gauge, Gauge): - gauge = self._get_gauge_by_id(gauge) - if gauge is None: - raise SensorNotFound() + gauge = find_object(self.iter_gauges(), id=gauge, error=SensorNotFound) - gauge.sensors = self.browser.get_station_infos(gauge) + gauge = self.browser.get_station_infos(gauge).next() if pattern is None: for sensor in gauge.sensors: yield sensor @@ -68,11 +67,13 @@ class VlilleBackend(BaseBackend, ICapGauge): raise SensorNotFound() return sensor.lastvalue + """ def _get_gauge_by_id(self, id): for gauge in self.browser.get_station_list(): if id == gauge.id: return gauge return None + """ def _get_sensor_by_id(self, id): reSensorId = re.search('(\d+)-((bikes|attach|status))', id, re.IGNORECASE) diff --git a/modules/vlille/browser.py b/modules/vlille/browser.py index 0083c2fd..13a58dd7 100644 --- a/modules/vlille/browser.py +++ b/modules/vlille/browser.py @@ -18,7 +18,7 @@ # along with weboob. If not, see . -from weboob.tools.browser import BaseBrowser +from weboob.tools.browser2 import PagesBrowser, URL from .pages import ListStationsPage, InfoStationPage @@ -26,23 +26,14 @@ from .pages import ListStationsPage, InfoStationPage __all__ = ['VlilleBrowser'] -class VlilleBrowser(BaseBrowser): - PROTOCOL = 'http' - DOMAIN = 'www.vlille.fr/stations' - ENCODING = None +class VlilleBrowser(PagesBrowser): - PAGES = { - '%s://%s/les-stations-vlille.aspx' % (PROTOCOL, DOMAIN): ListStationsPage, - '%s://%s/xml-station.aspx\?borne=.*' % (PROTOCOL, DOMAIN): InfoStationPage, - '%s://%s/xml-stations.aspx' % (PROTOCOL, DOMAIN): ListStationsPage, - } + BASEURL = 'http://www.vlille.fr' + list_page = URL('/stations/les-stations-vlille.aspx', ListStationsPage) + info_page = URL('/stations/xml-station.aspx\?borne=(?P.*)', InfoStationPage) def get_station_list(self): - if not self.is_on_page(ListStationsPage): - self.location('%s://%s/les-stations-vlille.aspx' % (self.PROTOCOL, self.DOMAIN)) - #self.location(u'%s://%s/xml-stations.aspx' % (self.PROTOCOL, self.DOMAIN)) - return self.page.get_station_list() + return self.list_page.go().get_station_list() def get_station_infos(self, gauge): - self.location('%s://%s/xml-station.aspx?borne=%s' % (self.PROTOCOL, self.DOMAIN, gauge.id)) - return self.page.get_station_infos(gauge.id) + return self.info_page.go(idgauge=gauge.id).get_station_infos(obj=gauge) diff --git a/modules/vlille/pages.py b/modules/vlille/pages.py index 225b9cd1..afab9dc0 100644 --- a/modules/vlille/pages.py +++ b/modules/vlille/pages.py @@ -18,7 +18,9 @@ # along with weboob. If not, see . -from weboob.tools.browser import BasePage +from weboob.tools.browser2.page import HTMLPage, XMLPage, method, ListElement, ItemElement, TableElement +from weboob.tools.browser2.filters import CleanText, TableCell, Filter + from weboob.capabilities.gauge import Gauge, GaugeMeasure, GaugeSensor from weboob.capabilities.base import NotLoaded import datetime @@ -27,86 +29,100 @@ import re __all__ = ['InfoStationPage', 'ListStationsPage'] -class InfoStationPage(BasePage): - def _create_bikes_sensor(self, value, gauge_id, last_update, adresse): - levelbikes = GaugeSensor(gauge_id + '-bikes') - levelbikes.name = u'Bikes' - levelbikes.address = u'%s' % adresse - lastvalue = GaugeMeasure() - lastvalue.level = float(value) - lastvalue.date = last_update - if lastvalue.level < 1: - lastvalue.alarm = u'Empty station' - levelbikes.lastvalue = lastvalue - levelbikes.history = NotLoaded - levelbikes.gaugeid = gauge_id - return levelbikes - - def _create_attach_sensor(self, value, gauge_id, last_update, adresse): - levelattach = GaugeSensor(gauge_id + '-attach') - levelattach.name = u'Attach' - levelattach.address = u'%s' % adresse - lastvalue = GaugeMeasure() - if lastvalue.level < 1: - lastvalue.alarm = u'Full station' - lastvalue.level = float(value) - lastvalue.date = last_update - levelattach.lastvalue = lastvalue - levelattach.history = NotLoaded - levelattach.gaugeid = gauge_id - return levelattach - - def _create_status_sensor(self, value, gauge_id, last_update, adresse): - levelstatus = GaugeSensor(gauge_id + '-status') - levelstatus.name = u'Status' - levelstatus.address = u'%s' % adresse - lastvalue = GaugeMeasure() - status = float(value) - if status == 0: - status = 1 - else: - status = -1 - if lastvalue.level < 1: - lastvalue.alarm = u'Not available station' - lastvalue.level = float(status) - lastvalue.date = last_update - levelstatus.lastvalue = lastvalue - levelstatus.history = NotLoaded - levelstatus.gaugeid = gauge_id - return levelstatus - - def _get_last_update(self, last_update): +class LastDateFilter(Filter): + def filter(self, last_update): return datetime.datetime.now() - datetime.timedelta(seconds=int(re.match(r'\d+', last_update).group(0))) - def get_station_infos(self, gauge_id): - last_update = self._get_last_update(self.parser.select(self.document.getroot(), 'lastupd', 1).text) - sensors = [] +class InfoStationPage(XMLPage): + @method + class get_station_infos(ListElement): + item_xpath = "." - adresse = self.parser.select(self.document.getroot(), 'adress', 1).text + class item(ItemElement): + klass = Gauge - sensors.append(self._create_bikes_sensor(self.parser.select(self.document.getroot(), 'bikes', 1).text, gauge_id, last_update, adresse)) + def _create_bikes_sensor(self, value, gauge_id, last_update, adresse): + levelbikes = GaugeSensor(gauge_id + '-bikes') + levelbikes.name = u'Bikes' + levelbikes.address = u'%s' % adresse + lastvalue = GaugeMeasure() + lastvalue.level = float(value) + lastvalue.date = last_update + if lastvalue.level < 1: + lastvalue.alarm = u'Empty station' + levelbikes.lastvalue = lastvalue + levelbikes.history = NotLoaded + levelbikes.gaugeid = gauge_id + return levelbikes - sensors.append(self._create_attach_sensor(self.parser.select(self.document.getroot(), 'attachs', 1).text, gauge_id, last_update, adresse)) + def _create_attach_sensor(self, value, gauge_id, last_update, adresse): + levelattach = GaugeSensor(gauge_id + '-attach') + levelattach.name = u'Attach' + levelattach.address = u'%s' % adresse + lastvalue = GaugeMeasure() + if lastvalue.level < 1: + lastvalue.alarm = u'Full station' + lastvalue.level = float(value) + lastvalue.date = last_update + levelattach.lastvalue = lastvalue + levelattach.history = NotLoaded + levelattach.gaugeid = gauge_id + return levelattach - sensors.append(self._create_status_sensor(self.parser.select(self.document.getroot(), 'status', 1).text, gauge_id, last_update, adresse)) + def _create_status_sensor(self, value, gauge_id, last_update, adresse): + levelstatus = GaugeSensor(gauge_id + '-status') + levelstatus.name = u'Status' + levelstatus.address = u'%s' % adresse + lastvalue = GaugeMeasure() + status = float(value) + if status == 0: + status = 1 + else: + status = -1 + if lastvalue.level < 1: + lastvalue.alarm = u'Not available station' + lastvalue.level = float(status) + lastvalue.date = last_update + levelstatus.lastvalue = lastvalue + levelstatus.history = NotLoaded + levelstatus.gaugeid = gauge_id + return levelstatus - return sensors + def parse(self, el): + self.obj = self.env['obj'] + + def obj_sensors(self): + sensors = [] + last_update = LastDateFilter(CleanText('lastupd'))(self) + adresse = CleanText('adress')(self) + sensors.append(self._create_bikes_sensor(CleanText('bikes')(self), + self.env['idgauge'], + last_update, adresse)) + sensors.append(self._create_attach_sensor(CleanText('attachs')(self), + self.env['idgauge'], + last_update, adresse)) + sensors.append(self._create_status_sensor(CleanText('status')(self), + self.env['idgauge'], + last_update, adresse)) + return sensors -class ListStationsPage(BasePage): - def get_station_list(self): - gauges = [] +class ListStationsPage(HTMLPage): + @method + class get_station_list(TableElement): + item_xpath = "//table[@id='ctl00_Contenu_ListeStations1_ListViewStations_itemPlaceholderContainer']/tr" + head_xpath = "//table[@id='ctl00_Contenu_ListeStations1_ListViewStations_itemPlaceholderContainer']/tr/th/@id" - trs = self.document.getroot().xpath('//table[@id="ctl00_Contenu_ListeStations1_ListViewStations_itemPlaceholderContainer"]/tr') + col_id = 'ctl00_Contenu_ListeStations1_ListViewStations_Th1' + col_name = 'ctl00_Contenu_ListeStations1_ListViewStations_Th2' + col_city = 'ctl00_Contenu_ListeStations1_ListViewStations_Th9' - for tr in trs: - if not ('id' in tr.attrib): - tds = self.parser.select(tr, 'td/span', method='xpath') - if len(tds) > 4: - gauge = Gauge(int(tds[0].text)) - gauge.name = u'%s' % tds[1].text - gauge.city = u'%s' % tds[3].text - gauge.object = u'vLille' - gauges.append(gauge) - return gauges + class item(ItemElement): + klass = Gauge + condition = lambda self: (len(self.el.xpath('td/span')) > 4 and not ('id' in self.el.attrib)) + + obj_id = CleanText(TableCell('id')) + obj_name = CleanText(TableCell('name')) + obj_city = CleanText(TableCell('city')) + obj_object = u'vLille'