[meteofrance] adapt to browser2

This commit is contained in:
Bezleputh 2014-11-03 15:24:28 +01:00 committed by Romain Bignon
commit ddbf7c1335
5 changed files with 119 additions and 141 deletions

View file

@ -17,53 +17,22 @@
# 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 urllib
from weboob.deprecated.browser import Browser
from .pages.meteo import WeatherPage, SearchCitiesPage
from weboob.capabilities.weather import CityNotFound
from weboob.browser import PagesBrowser, URL
from .pages import WeatherPage, SearchCitiesPage
__all__ = ['MeteofranceBrowser']
class MeteofranceBrowser(Browser):
DOMAIN = 'www.meteofrance.com'
PROTOCOL = 'http'
ENCODING = 'utf-8'
WEATHER_URL = '{0}://{1}/previsions-meteo-france/{{city_name}}/{{city_id}}'.format(PROTOCOL, DOMAIN)
CITY_SEARCH_URL = 'http://www.meteofrance.com/recherche/resultats'
PAGES = {
WEATHER_URL.format(city_id=".*", city_name=".*"): WeatherPage,
CITY_SEARCH_URL: SearchCitiesPage,
}
def __init__(self, *args, **kwargs):
Browser.__init__(self, *args, **kwargs)
class MeteofranceBrowser(PagesBrowser):
BASEURL = 'http://www.meteofrance.com'
cities = URL('mf3-rpc-portlet/rest/lieu/facet/previsions/search/(?P<pattern>.*)', SearchCitiesPage)
weather = URL('previsions-meteo-france/(?P<city_name>.*)/(?P<city_id>.*)', WeatherPage)
def iter_city_search(self, pattern):
datas = {'facet': 'previsions',
'search-type': 'previsions',
'query': pattern}
self.location(self.CITY_SEARCH_URL, data=urllib.urlencode(datas))
assert self.is_on_page(SearchCitiesPage)
return self.page.iter_cities()
return self.cities.go(pattern=pattern).iter_cities()
def iter_forecast(self, city_id):
mcity = self.get_city(city_id)
self.location(self.WEATHER_URL.format(city_id=mcity.id, city_name=mcity.name))
assert self.is_on_page(WeatherPage)
return self.page.iter_forecast()
def iter_forecast(self, city):
return self.weather.go(city_id=city.id, city_name=city.name).iter_forecast()
def get_current(self, city_id):
mcity = self.get_city(city_id)
self.location(self.WEATHER_URL.format(city_id=mcity.id, city_name=mcity.name))
assert self.is_on_page(WeatherPage)
return self.page.get_current()
def get_city(self, city_id):
cities = self.iter_city_search(city_id)
for city in cities:
if city_id == city.id:
return city
raise CityNotFound('Unable to find a city whose id is %s' % city_id)
def get_current(self, city):
return self.weather.go(city_id=city.id, city_name=city.name).get_current()

View file

@ -18,9 +18,9 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.capabilities.weather import CapWeather
from weboob.capabilities.weather import CapWeather, CityNotFound
from weboob.tools.backend import Module
from weboob.capabilities.base import find_object
from .browser import MeteofranceBrowser
@ -37,10 +37,13 @@ class MeteofranceModule(Module, CapWeather):
BROWSER = MeteofranceBrowser
def get_current(self, city_id):
return self.browser.get_current(city_id)
return self.browser.get_current(self.get_city(city_id))
def iter_forecast(self, city_id):
return self.browser.iter_forecast(city_id)
return self.browser.iter_forecast(self.get_city(city_id))
def iter_city_search(self, pattern):
return self.browser.iter_city_search(pattern)
def get_city(self, _id):
return find_object(self.iter_city_search(_id), id=_id, error=CityNotFound)

View file

@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010-2011 Cedric Defortis
#
# 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/>.
from datetime import date
from weboob.browser.pages import JsonPage, HTMLPage
from weboob.browser.elements import ItemElement, ListElement, method
from weboob.capabilities.weather import Forecast, Current, City, Temperature
from weboob.browser.filters.json import Dict
from weboob.browser.filters.html import CleanHTML
from weboob.browser.filters.standard import CleanText, CleanDecimal, Regexp, Format
class DictElement(ListElement):
def find_elements(self):
if self.item_xpath is not None:
for el in self.el:
yield el
else:
yield self.el
class SearchCitiesPage(JsonPage):
@method
class iter_cities(DictElement):
item_xpath = '.'
ignore_duplicate = True
class item(ItemElement):
klass = City
def condition(self):
return Dict('type')(self) == "VILLE_FRANCE"
obj_id = Dict('codePostal')
obj_name = Dict('slug')
class WeatherPage(HTMLPage):
@method
class iter_forecast(ListElement):
item_xpath = '//div[@class="group-days-summary"]/div'
class item(ItemElement):
klass = Forecast
obj_id = CleanText('./div/div/h3[@class="day-summary-title"]')
obj_date = CleanText('./div/div/h3[@class="day-summary-title"]')
def obj_low(self):
temp = CleanDecimal(Regexp(CleanText('./div/div/div[@class="day-summary-temperature"]'),
'(.*)\|.*'))(self)
unit = Regexp(CleanText('./div/div/div[@class="day-summary-temperature"]'), u'.*\xb0(\w) \|.*')(self)
return Temperature(float(temp), unit)
def obj_high(self):
temp = CleanDecimal(Regexp(CleanText('./div/div/div[@class="day-summary-temperature"]'),
'.*\|(.*)'))(self)
unit = Regexp(CleanText('./div/div/div[@class="day-summary-temperature"]'), u'.*\|.*\xb0(\w).*')(self)
return Temperature(float(temp), unit)
obj_text = Format('%s %s %s %s', CleanHTML('./div/div/div[@class="day-summary-broad"]'),
CleanHTML('./div/div/div[@class="day-summary-wind"]'),
CleanHTML('./div/div/div[@class="day-summary-uv"]'),
CleanHTML('./div/div/div[@class="day-summary-indice"]/img/@title'))
@method
class get_current(ItemElement):
klass = Current
obj_id = date.today()
obj_date = date.today()
obj_text = Format('%s %s %s %s',
CleanHTML('(//div[@class="group-days-summary"])[1]/div[1]/div/div/div[@class="day-summary-broad"]'),
CleanHTML('(//div[@class="group-days-summary"])[1]/div[1]/div/div/div[@class="day-summary-wind"]'),
CleanHTML('(//div[@class="group-days-summary"])[1]/div[1]/div/div/div[@class="day-summary-uv"]'),
CleanHTML('(//div[@class="group-days-summary"])[1]/div[1]/div/div/div[@class="day-summary-indice"]/img/@title'))
def obj_temp(self):
temp = CleanDecimal(Regexp(CleanText('(//div[@class="group-days-summary"])[1]/div[1]/div/div/div[@class="day-summary-temperature"]'),
'(.*)\|.*'))(self)
unit = Regexp(CleanText('(//div[@class="group-days-summary"])[1]/div[1]/div/div/div[@class="day-summary-temperature"]'),
u'.*\xb0(\w) \|.*')(self)
return Temperature(float(temp), unit)

View file

@ -1,18 +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/>.

View file

@ -1,77 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010-2011 Cedric Defortis
#
# 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/>.
from weboob.deprecated.browser import Page
from weboob.capabilities.weather import Forecast, Current, City
import datetime
import re
class SearchCitiesPage(Page):
def iter_cities(self):
list = self.document.getroot().xpath('//ul[@class="list-style-1"]/li/a')
for a in list:
m = re.search('/.*/(.*)/(\d{5})', a.attrib.get('href'))
if m:
mcity = City(int(m.group(2)), u'%s' % m.group(1))
yield mcity
class WeatherPage(Page):
def get_temp_without_unit(self, temp_str):
# It seems that the mechanize module give us some old style
# ISO character
return float(temp_str.replace(u"\xb0C", "").strip())
def iter_forecast(self):
lis = self.document.getroot().xpath('//ul[@class="list-days-summary slides"]/li')
for li in lis:
divs = self.parser.select(li, 'div[@class="group-days-summary"]', 1, method='xpath')
for div in divs:
day_div = self.parser.select(div, 'div[@class="box"]', 1, method='xpath')
date = self.parser.select(day_div, 'div[@class="box-header"]/h3', 1, method='xpath').text
temp = self.parser.select(div, 'div/div/div[@class="day-summary-temperature"]',
1, method='xpath').text_content()
low = self.get_temp_without_unit(temp.split('|')[0])
high = self.get_temp_without_unit(temp.split('|')[1])
broad = self.parser.select(div, 'div/div/div[@class="day-summary-broad"]',
1, method='xpath').text_content().strip()
uvs = self.parser.select(div, 'div/div/div[@class="day-summary-uv"]',
method='xpath')
uv = u''
if uvs is not None and len(uvs) > 0:
uv = u'%s' % uvs[0].text_content()
wind = self.parser.select(div, 'div/div/div[@class="day-summary-wind"]',
1, method='xpath').text_content()
text = u'%s %s %s' % (broad, uv, wind)
yield Forecast(date, low, high, text, u'C')
def get_current(self):
div = self.document.getroot().xpath('//div[@class="bloc-day-summary"]')[0]
mdate = datetime.datetime.now()
temp = self.parser.select(div, 'div/div/div[@class="day-summary-temperature"]',
1, method='xpath').text_content()
temperature = self.get_temp_without_unit(temp.split('|')[0])
broad = self.parser.select(div, 'div/div/div[@class="day-summary-broad"]', 1, method='xpath').text_content()
wind = self.parser.select(div, 'div/div/div[@class="day-summary-wind"]', 1, method='xpath').text_content()
mtxt = u'%s %s' % (broad, wind)
return Current(mdate, temperature, mtxt, u'C')