diff --git a/modules/vlille/__init__.py b/modules/vlille/__init__.py new file mode 100644 index 00000000..95e4ca19 --- /dev/null +++ b/modules/vlille/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Bezleputh +# +# 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 . + + +from .backend import VlilleBackend + + +__all__ = ['VlilleBackend'] diff --git a/modules/vlille/backend.py b/modules/vlille/backend.py new file mode 100644 index 00000000..139d2195 --- /dev/null +++ b/modules/vlille/backend.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Bezleputh +# +# 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 . + + +from weboob.tools.backend import BaseBackend +from weboob.capabilities.gauge import ICapGauge,GaugeSensor, Gauge, SensorNotFound + +from .browser import VlilleBrowser + +__all__ = ['VlilleBackend'] + +class VlilleBackend(BaseBackend, ICapGauge): + NAME = 'vlille' + DESCRIPTION = u'accès aux données vlille' + MAINTAINER = u'Bezleputh' + EMAIL = 'carton_ben@yahoo.fr' + VERSION = '0.f' + + BROWSER = VlilleBrowser + + def iter_gauges(self, pattern=None): + if pattern is None: + for gauge in self.browser.get_station_list(): + yield gauge + else: + lowpattern = pattern.lower() + for gauge in self.browser.get_station_list(): + if lowpattern in gauge.name.lower(): + yield gauge + + 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.sensors = self.browser.get_station_infos(gauge) + if pattern is None: + for sensor in gauge.sensors: + yield sensor + else: + lowpattern = pattern.lower() + for sensor in gauge.sensors: + if lowpattern in sensor.name.lower(): + yield sensor + + def get_last_measure(self, sensor): + if not isinstance(sensor, GaugeSensor): + sensor = self._get_sensor_by_id(sensor) + if sensor is None: + 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): + for gauge in self.browser.get_station_list(): + for sensor in self.browser.get_station_infos(gauge): + if id == sensor.id: + return sensor + return None diff --git a/modules/vlille/browser.py b/modules/vlille/browser.py new file mode 100644 index 00000000..d7fe69ee --- /dev/null +++ b/modules/vlille/browser.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Bezleputh +# +# 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 . + + +from weboob.tools.browser import BaseBrowser + +from .pages import ListStationsPage, InfoStationPage + + +__all__ = ['VlilleBrowser'] + + +class VlilleBrowser(BaseBrowser): + PROTOCOL = 'http' + DOMAIN = 'www.vlille.fr/stations' + ENCODING = None + + PAGES = { + '%s://%s/xml-station.aspx\?borne=.*' % (PROTOCOL, DOMAIN): InfoStationPage, + '%s://%s/xml-stations.aspx' % (PROTOCOL, DOMAIN): ListStationsPage, + } + + def get_station_list(self): + if not self.is_on_page(ListStationsPage): + self.location(u'%s://%s/xml-stations.aspx' % (self.PROTOCOL, self.DOMAIN)) + return self.page.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) diff --git a/modules/vlille/pages.py b/modules/vlille/pages.py new file mode 100644 index 00000000..08a7b18c --- /dev/null +++ b/modules/vlille/pages.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Bezleputh +# +# 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 . + + +from weboob.tools.browser import BasePage +from weboob.capabilities.gauge import Gauge, GaugeMeasure, GaugeSensor +from weboob.capabilities.base import NotAvailable, NotLoaded +import datetime, 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.forecast = u'%s' %adresse + lastvalue = GaugeMeasure() + lastvalue.level = float(value) + lastvalue.date = last_update + lastvalue.alarm = u'0' + 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.forecast = u'%s' %adresse + lastvalue = GaugeMeasure() + lastvalue.level = float(value) + lastvalue.date = last_update + lastvalue.alarm = u'0' + 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.forecast = u'%s' %adresse + lastvalue = GaugeMeasure() + status = float(value) + if status == 0: + status = 1 + else: + status = -1 + lastvalue.level = float(status) + lastvalue.date = last_update + lastvalue.alarm = u'-1' + levelstatus.lastvalue = lastvalue + levelstatus.history = NotLoaded + levelstatus.gaugeid = gauge_id + return levelstatus + + def _get_last_update(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 = [] + + adresse = self.parser.select(self.document.getroot(),'adress',1).text + + sensors.append(self._create_bikes_sensor(self.parser.select(self.document.getroot(),'bikes',1).text, gauge_id, last_update, adresse)) + + sensors.append(self._create_attach_sensor(self.parser.select(self.document.getroot(),'attachs',1).text, gauge_id, last_update, adresse)) + + sensors.append(self._create_status_sensor(self.parser.select(self.document.getroot(),'status',1).text, gauge_id, last_update, adresse)) + + #print self.parser.select(self.document.getroot(),'paiement',1).text + + return sensors + +class ListStationsPage(BasePage): + def get_station_list(self): + gauges = [] + for marker in self.parser.select(self.document.getroot(), 'marker'): + gauge = Gauge(int(marker.get('id'))) + gauge.name = unicode(marker.get('name')) + gauge.city = gauge.name + gauge.object = u'vLille' + gauges.append(gauge) + return gauges diff --git a/modules/vlille/test.py b/modules/vlille/test.py new file mode 100644 index 00000000..cd78ebde --- /dev/null +++ b/modules/vlille/test.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2013 Bezleputh +# +# 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 . + +from weboob.tools.test import BackendTest + +class VlilleTest(BackendTest): + BACKEND = 'vlille' + + def test_vlille(self): + l = list(self.backend.iter_gauges()) + self.assertTrue(len(l) > 0) + + gauge = l[0] + s = list(self.backend.iter_sensors(gauge)) + self.assertTrue(len(s) > 0) + + sensor = s[0] + self.assertTrue(self.backend.get_last_measure(sensor.id) is not None)