pax_global_header 0000666 0000000 0000000 00000000064 13414430553 0014514 g ustar 00root root 0000000 0000000 52 comment=6e2147adbb0d685e8e740a246e0c7f31465f3511
woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/ 0000775 0000000 0000000 00000000000 13414430553 0024116 5 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/ 0000775 0000000 0000000 00000000000 13414430553 0025566 5 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole/ 0000775 0000000 0000000 00000000000 13414430553 0030722 5 ustar 00root root 0000000 0000000 __init__.py 0000664 0000000 0000000 00000001525 13414430553 0032757 0 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole # -*- coding: utf-8 -*-
# Copyright(C) 2017 Vincent A
#
# 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 __future__ import unicode_literals
from .module import LameteoagricoleModule
__all__ = ['LameteoagricoleModule']
browser.py 0000664 0000000 0000000 00000004134 13414430553 0032702 0 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole # -*- coding: utf-8 -*-
# Copyright(C) 2017 Vincent A
#
# 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 __future__ import unicode_literals
from weboob.browser import PagesBrowser, URL
from .pages import CitiesPage, HourPage, Days5Page, Days10Page
class LameteoagricoleBrowser(PagesBrowser):
BASEURL = 'https://www.lameteoagricole.net'
cities = URL(r'/autocomplete/autocomplete_ajax.php\?table=meteo_communes&field=NomComMaj&search=(?P.*)', CitiesPage)
hour = URL(r'/meteo-heure-par-heure/(?P[^.]+).html',
r'/index_meteo-heure-par-heure.php\?communehome=(?P.*)',
HourPage)
day5 = URL(r'/previsions-meteo-agricole/(?P[^.]+).html',
r'/index.php\?communehome=(?P.*)',
Days5Page)
day10 = URL(r'/meteo-a-10-jours/(?P[^.]+).html',
r'/index_meteo-a-10-jours.php\?communehome=(?P.*)',
Days10Page)
def iter_cities(self, pattern):
self.cities.go(pattern=pattern)
return self.page.iter_cities()
def get_current(self, id):
self.hour.go(id=id)
assert self.hour.is_here()
return self.page.get_current()
def iter_forecast(self, id):
self.hour.go(id=id)
for f in self.page.iter_forecast():
yield f
self.day5.go(id=id)
for f in self.page.iter_forecast():
yield f
self.day10.go(id=id)
for f in self.page.iter_forecast():
yield f
favicon.png 0000664 0000000 0000000 00000002072 13414430553 0032777 0 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole PNG
IHDR L\ pHYs tIME
ą iTXtComment Created with GIMPd.e IDATxˑ0.Um
0QLMilL()3̎5zK[6_8-q.H
//>4Aova%Ȗ~9zfB5V?L%(UTL@z8ЃO$p0Lw@[(eH\
̀#\ Od?N;c
Ơ>Ϭ5pZP `* @ d @@ |k}Ɨa~d`JnY\(ced?xȒ}9}mZ{:r+&%7,@e`I8u]~>Cz?RP.`q{I=Ə)S>ЬE\;l8֣s4t2r|71ώv;FrP!cW$44
xomH@E,gss{9~ zFkU[BD_V5_ٻ b=b
nn(_t2 |;Qi`%hYiD ?{ L}[4
ƾ Pch8z@I! `UD,
d@5c~d@5 #"Ȁv$(]{0Q:̟$=V:yqtEf'X[$4*G#w1,;P $},£P`k֗v;:CpR{?ZEvXѸMA/z~Zt&cEu0`'}Xyu/bmroA|V̾KK 6 IENDB` module.py 0000664 0000000 0000000 00000002707 13414430553 0032510 0 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole # -*- coding: utf-8 -*-
# Copyright(C) 2017 Vincent A
#
# 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 __future__ import unicode_literals
from weboob.tools.backend import Module
from weboob.capabilities.weather import CapWeather
from .browser import LameteoagricoleBrowser
__all__ = ['LameteoagricoleModule']
class LameteoagricoleModule(Module, CapWeather):
NAME = 'lameteoagricole'
DESCRIPTION = u'lameteoagricole website'
MAINTAINER = u'Vincent A'
EMAIL = 'dev@indigo.re'
LICENSE = 'AGPLv3+'
VERSION = '1.4'
BROWSER = LameteoagricoleBrowser
def iter_city_search(self, pattern):
return self.browser.iter_cities(pattern)
def get_current(self, city_id):
return self.browser.get_current(city_id)
def iter_forecast(self, city_id):
return self.browser.iter_forecast(city_id)
pages.py 0000664 0000000 0000000 00000014416 13414430553 0032322 0 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole # -*- coding: utf-8 -*-
# Copyright(C) 2017 Vincent A
#
# 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 __future__ import unicode_literals
from datetime import date, time, datetime, timedelta
from weboob.browser.elements import method, ListElement, ItemElement
from weboob.browser.filters.standard import CleanText, Field
from weboob.browser.pages import HTMLPage
from weboob.capabilities.weather import City, Forecast, Temperature, Current, Direction
from weboob.tools.compat import quote
class CitiesPage(HTMLPage):
ENCODING = 'utf-8'
@method
class iter_cities(ListElement):
item_xpath = '//suggest'
class item(ItemElement):
klass = City
obj_name = CleanText('.')
def obj_id(self):
return quote(Field('name')(self))
def temp(v):
t = Temperature()
t.unit = 'C'
t.value = v
return t
class WeatherPage(HTMLPage):
def fill_base(self, obj, n):
obj.text = self.get_img_cell(self.titles['Temps sensible'], n)
if 'Humidité relative moyenne' in self.titles:
humidity = self.get_cell(self.titles['Humidité relative moyenne'], n)
else:
humidity = self.get_cell(self.titles['Humidité relative'], n)
obj.humidity = float(humidity.strip('%')) / 100
direction = self.get_cell(self.titles['Direction du vent'], n).replace('O', 'W')
obj.wind_direction = getattr(Direction, direction)
if 'Vitesse du vent' in self.titles:
speed_text = self.get_cell(self.titles['Vitesse du vent'], n)
elif 'Vitesse Moy. du vent' in self.titles:
speed_text = self.get_cell(self.titles['Vitesse Moy. du vent'], n)
else:
speed_text = self.get_cell(self.titles['Vitesse moyenne du vent'], n)
obj.wind_speed = int(speed_text.replace('km/h', '').strip())
if 'Probabilité de précipitations' in self.titles:
txt = self.get_cell(self.titles['Probabilité de précipitations'], n)
obj.precipitation_probability = float(txt.strip('<%')) / 100
if 'Nébulosité' in self.titles:
txt = self.get_cell(self.titles['Nébulosité'], n).rstrip('%')
obj.cloud = int(round(float(txt) / 100 * 8))
class HourPage(WeatherPage):
def get_cell(self, row, col):
return CleanText('//table[@id="meteoHour"]/tr[{row}]/td[{col}]'.format(row=row + 1, col=col + 1))(self.doc)
def get_img_cell(self, row, col):
return CleanText('//table[@id="meteoHour"]/tr[{row}]/td[{col}]/img/@alt'.format(row=row + 1, col=col + 1))(self.doc)
def get_current(self):
fore = next(iter(self.iter_forecast()))
ret = Current()
for f in ('date', 'text', 'wind_direction', 'wind_speed', 'humidity'):
setattr(ret, f, getattr(fore, f))
ret.temp = fore.high
return ret
def iter_forecast(self):
d = date.today()
self.titles = {}
for n, tr in enumerate(self.doc.xpath('//table[@id="meteoIntit"]/tr')):
self.titles[CleanText('.')(tr)] = n
day_str = None
for n in range(len(self.doc.xpath('//table[@id="meteoHour"]/tr[1]/td'))):
obj = Forecast()
t = time(int(self.get_cell(self.titles['Heure'], n).rstrip('h')), 0)
new_day_str = self.get_cell(self.titles['Jour'], n)
if day_str is not None and day_str != new_day_str:
d += timedelta(1)
day_str = new_day_str
obj.date = datetime.combine(d, t)
obj.low = obj.high = temp(int(self.get_cell(self.titles['T° (ressentie)'], n).split('°')[0]))
self.fill_base(obj, n)
yield obj
class Days5Page(WeatherPage):
def get_cell(self, row, col):
return CleanText('//table[@id="meteo2"]/tr[2]/td[{col}]/table/tr[{row}]/td'.format(row=row + 1, col=col + 1))(self.doc)
def get_img_cell(self, row, col):
return CleanText('//table[@id="meteo2"]/tr[2]/td[{col}]/table/tr[{row}]/td//img/@alt'.format(row=row + 1, col=col + 1))(self.doc)
def iter_forecast(self):
d = date.today()
self.titles = {}
for n, tr in enumerate(self.doc.xpath('//table[@id="meteo2"]/tr[2]/td[1]/table/tr')):
self.titles[CleanText('.')(tr)] = n
for n in range(1, len(self.doc.xpath('//table[@id="meteo2"]/tr[1]/td'))):
obj = Forecast()
obj.low = temp(int(self.get_cell(self.titles['Température Mini'], n).rstrip('°')))
obj.high = temp(int(self.get_cell(self.titles['Température Maxi'], n).rstrip('°')))
obj.date = d
self.fill_base(obj, n)
d += timedelta(1)
yield obj
class Days10Page(WeatherPage):
def get_cell(self, row, col):
return CleanText('(//table[@id="meteo2"]//td/table)[{col}]/tr[{row}]/td'.format(row=row + 1, col=col + 1))(self.doc)
def get_img_cell(self, row, col):
return CleanText('(//table[@id="meteo2"]//td/table)[{col}]/tr[{row}]/td//img/@alt'.format(row=row + 1, col=col + 1))(self.doc)
def iter_forecast(self):
d = date.today() + timedelta(5)
self.titles = {}
for n, tr in enumerate(self.doc.xpath('(//table[@id="meteo2"]//td/table)[1]/tr/td')):
self.titles[CleanText('.')(tr)] = n
cols = len(self.doc.xpath('//table[@id="meteo2"]//td/table'))
for n in range(1, cols):
obj = Forecast()
obj.low = temp(int(self.get_cell(self.titles['Température Mini'], n).rstrip('°C')))
obj.high = temp(int(self.get_cell(self.titles['Température Maxi'], n).rstrip('°C')))
obj.date = d
self.fill_base(obj, n)
d += timedelta(1)
yield obj
test.py 0000664 0000000 0000000 00000003365 13414430553 0032203 0 ustar 00root root 0000000 0000000 woob-6e2147adbb0d685e8e740a246e0c7f31465f3511-modules-lameteoagricole/modules/lameteoagricole # -*- coding: utf-8 -*-
# Copyright(C) 2017 Vincent A
#
# 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 __future__ import unicode_literals
from datetime import date
from weboob.tools.test import BackendTest
from weboob.capabilities.base import empty
from weboob.tools.date import new_datetime
class LameteoagricoleTest(BackendTest):
MODULE = 'lameteoagricole'
def test_base(self):
start = date.today()
cities = list(self.backend.iter_city_search('paris'))
assert cities
for c in cities:
assert c.id
assert c.name
c = cities[0]
cur = self.backend.get_current(c.id)
assert cur
assert cur.temp
assert cur.temp.unit
assert not empty(cur.temp.value)
assert cur.text
forecast = list(self.backend.iter_forecast(c.id))
assert forecast
for f in forecast:
assert f.date
assert new_datetime(f.date) >= new_datetime(start)
assert f.text
assert -20 < f.low.value <= f.high.value < 40
assert f.low.unit == 'C'
assert f.high.unit == 'C'