Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save all available forecast data, including today's #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions meteofrance/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class meteofranceError(Exception):

class meteofranceClient():
"""Client to fetch and parse data from Meteo-France"""
def __init__(self, postal_code, update=False, need_rain_forecast=True):
def __init__(self, postal_code, update=False, need_rain_forecast=True, include_today=False):
"""Initialize the client object."""
self.postal_code = postal_code
self._city_slug = False
Expand All @@ -33,6 +33,7 @@ def __init__(self, postal_code, update=False, need_rain_forecast=True):
self._rain_available = False
self._weather_html_soup = False
self.need_rain_forecast = need_rain_forecast
self.include_today = include_today
self._type = None
self._data = {}
self._init_codes()
Expand Down Expand Up @@ -223,16 +224,26 @@ def _format_data(self):

self._data["forecast"] = {}
daydatas = soup.find(class_="liste-jours").find_all("li")
for day in range(0, 5):
day = 0
for daydata in daydatas:
try:
daydata = daydatas[day+1]
forecast = {}
forecast["date"] = daydata.find("a").string
forecast["weather"] = daydata.find("dd").string.strip()
forecast["min_temp"] = int(re.sub(r"[^0-9\-]","",daydata.find(class_="min-temp").string))
forecast["max_temp"] = int(re.sub(r"[^0-9\-]","",daydata.find(class_="max-temp").string))
forecast["weather_class"] = daydata.find("dd").attrs['class'][1]
self._data["forecast"][day] = forecast
weather = daydata.find("dd").string
if weather:
forecast["weather"] = weather.strip()
min_temp = re.sub(r"[^0-9\-]","",daydata.find(class_="min-temp").string)
if min_temp != '-':
forecast["min_temp"] = int(min_temp)
max_temp = re.sub(r"[^0-9\-]","",daydata.find(class_="max-temp").string)
if max_temp != '-':
forecast["max_temp"] = int(max_temp)
forecast["weather_class"] = daydata.find("dd").attrs['class'][1]
if self.include_today:
self._data["forecast"][day] = forecast
elif day > 0 and day < 6:
self._data["forecast"][day-1] = forecast
day = day + 1
except:
raise

Expand Down
66 changes: 56 additions & 10 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,33 @@

class TestLocation(unittest.TestCase):
def test_oslo(self):
client = meteofranceClient('oslo, norvege', True)
client = meteofranceClient('oslo, norvege', True, include_today=True)
data = client.get_data()
self.assertEqual(data['name'], 'Oslo')
self.assertEqual(data['printName'], u'Oslo (Norvège)')

def test_luxembourg(self):
client = meteofranceClient('luxembourg', True)
client = meteofranceClient('luxembourg', True, include_today=True)
data = client.get_data()
self.assertEqual(data['name'], 'Luxembourg')
self.assertEqual(data['printName'], u'Luxembourg (Luxembourg )')

def test_postal_code(self):
client = meteofranceClient('80000', True)
client = meteofranceClient('80000', True, include_today=True)
data = client.get_data()
self.assertEqual(data['name'], 'Amiens')
self.assertEqual(data['dept'], '80')
self.assertEqual(data['printName'], 'Amiens (80000)')

def test_city_name(self):
client = meteofranceClient('Brest', True)
client = meteofranceClient('Brest', True, include_today=True)
data = client.get_data()
self.assertEqual(data['name'], 'Brest')
self.assertEqual(data['printName'], u'Brest (Biélorussie)')

#postal code is not correct : should return the first result which is "Ableiges"
def test_department(self):
client = meteofranceClient('95', True)
client = meteofranceClient('95', True, include_today=True)
data = client.get_data()
self.assertEqual(data['name'], 'Ableiges')
self.assertEqual(data['printName'], 'Ableiges (95450)')
Expand All @@ -44,7 +44,7 @@ def test_invalid(self):

class TestClientData(unittest.TestCase):
def test_beynost(self):
client = meteofranceClient('01700')
client = meteofranceClient('01700', include_today=True)
client.need_rain_forecast = False
client.update()
data = client.get_data()
Expand All @@ -67,10 +67,11 @@ def test_beynost(self):
self.assertNotIn('next_rain_datetime', data)
self.assertNotIn('rain_forecast_text', data)
self.assertNotIn('rain_forecast', data)
self.assertEqual(len(data['forecast']), 14)

# pointe-a-pitre : result from meteo-france is different and it returns less data
def test_pointe_a_pitre(self):
client = meteofranceClient('97110')
client = meteofranceClient('97110', include_today=True)
client.need_rain_forecast = False
client.update()
data = client.get_data()
Expand All @@ -93,10 +94,37 @@ def test_pointe_a_pitre(self):
self.assertNotIn('next_rain_datetime', data)
self.assertNotIn('rain_forecast_text', data)
self.assertNotIn('rain_forecast', data)
self.assertGreaterEqual(len(data['forecast']), 9)

# Same with world data
def test_pointe_a_pitre(self):
client = meteofranceClient('Tokyo', include_today=True)
client.need_rain_forecast = False
client.update()
data = client.get_data()
self.assertIn('name', data)
self.assertNotIn('dept', data)
self.assertIn('fetched_at', data)
self.assertIn('forecast', data)
self.assertNotIn('freeze_chance', data)
self.assertNotIn('rain_chance', data)
self.assertNotIn('snow_chance', data)
self.assertIn('temperature', data)
self.assertNotIn('thunder_chance', data)
self.assertNotIn('uv', data)
self.assertIn('weather_class', data)
self.assertIn('weather', data)
self.assertIn('wind_bearing', data)
self.assertIn('wind_speed', data)
self.assertNotIn('next_rain_intervals', data)
self.assertNotIn('next_rain', data)
self.assertNotIn('rain_forecast_text', data)
self.assertNotIn('rain_forecast', data)
self.assertGreaterEqual(len(data['forecast']), 9)

class TestRainForecast(unittest.TestCase):
def test_rain_forecast_is_updated(self):
client = meteofranceClient('01700')
client = meteofranceClient('01700', include_today=True)
client.need_rain_forecast = False
client.update()
self.assertEqual(client.need_rain_forecast, False)
Expand All @@ -118,7 +146,7 @@ def test_rain_forecast_is_updated(self):

#marseille : no rain forecast
def test_marseille(self):
client = meteofranceClient(13000, True)
client = meteofranceClient(13000, True, include_today=True)
data = client.get_data()
self.assertNotIn('next_rain_intervals', data)
self.assertNotIn('next_rain', data)
Expand All @@ -128,13 +156,31 @@ def test_marseille(self):

#Rouen : rain forecast available
def test_rouen(self):
client = meteofranceClient(76000, True)
client = meteofranceClient(76000, True, include_today=True)
data = client.get_data()
self.assertIn('next_rain_intervals', data)
self.assertIn('next_rain', data)
self.assertIn('next_rain_datetime', data)
self.assertIn('rain_forecast_text', data)
self.assertIn('rain_forecast', data)

class TestOldAPI(unittest.TestCase):
def test_beynost(self):
new_client = meteofranceClient('01700', include_today=True)
new_client.need_rain_forecast = False
old_client = meteofranceClient('01700', include_today=False)
old_client.need_rain_forecast = False
new_client.update()
old_client.update()
new_data = new_client.get_data()
self.assertEqual(len(new_data['forecast']), 14)
old_data = old_client.get_data()
self.assertEqual(len(old_data['forecast']), 5)
self.assertEqual(new_data['forecast'][1], old_data['forecast'][0])
self.assertEqual(new_data['forecast'][2], old_data['forecast'][1])
self.assertEqual(new_data['forecast'][3], old_data['forecast'][2])
self.assertEqual(new_data['forecast'][4], old_data['forecast'][3])
self.assertEqual(new_data['forecast'][5], old_data['forecast'][4])

if __name__ == '__main__':
unittest.main()