def test_update_weather_data(self): """Testing that new weather data is loaded correctly""" forecast1 = forecastio.manual(os.path.join('fixtures', 'us.json')) wd1 = models.WeatherData(forecast1, self.location) forecast2 = forecastio.manual( os.path.join('fixtures', 'us_cincinnati.json')) wd2 = models.WeatherData(forecast2, self.location) wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd1) self.assertEqual(50.84, wbs.weather_data.apparentTemperature) self.assertIn('51', wbs.normal()) self.assertIn('66ºF', wbs.forecast()) self.assertEqual('normal', wbs.special().type) self.assertEqual(0, len(wd1.alerts)) wbs.set_weather(wd2) self.assertEqual(73.09, wbs.weather_data.apparentTemperature) self.assertIn('73', wbs.normal()) self.assertIn('78ºF', wbs.forecast()) self.assertEqual('moderate-rain', wbs.special().type) alert = wbs.alert(wd2.alerts[0], wd2.timezone) self.assertIn('Severe Thunderstorm Warning', alert) self.assertIn('Wed, Oct 19 at 19:30:00 EDT', alert) self.assertIn( 'https://alerts.weather.gov/cap/wwacapget.php?x=OH12561A63BE38.SevereThunderstormWarning.' '12561A63C2E8OH.ILNSVSILN.f17bc0b3ead1db18bf60532894d9925e', alert)
def persist_weather(data, weather_data): for d in data['observation']['hours']: weather_data['period'] = 'hour' weather_data_hour = add_observation(d, weather_data) weather_data_hour['data_type'] = 'observation' weather_data_db = models.WeatherData(**weather_data_hour) db_tool.store_weather_data(weather_data_db) for d in data['observation']['days']: weather_data['period'] = 'day' weather_data_day = add_observation(d, weather_data) weather_data['data_type'] = 'observation' weather_data_db = models.WeatherData(**weather_data_hour) db_tool.store_weather_data(weather_data_db) for d in data['forecast']['days']: weather_data['period'] = 'day' weather_data_hour = add_observation(d, weather_data) weather_data_hour['data_type'] = 'forecast' weather_data_db = models.WeatherData(**weather_data_hour) db_tool.store_weather_data(weather_data_db) for d in data['forecast']['hours']: weather_data['period'] = 'hour' weather_data_hour = add_observation(d, weather_data) weather_data_hour['data_type'] = 'forecast' weather_data_db = models.WeatherData(**weather_data_hour) db_tool.store_weather_data(weather_data_db)
def test_update_weather_data(self, mock_get): """Testing that new weather data is loaded correctly""" forecast1 = forecastio.manual(os.path.join('fixtures', 'us.json')) wd1 = models.WeatherData(forecast1, self.location) forecast2 = forecastio.manual(os.path.join('fixtures', 'us_cincinnati.json')) wd2 = models.WeatherData(forecast2, self.location) wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd1) self.assertEqual(50.84, wbs.weather_data.apparentTemperature) self.assertIn('51', wbs.normal()) self.assertIn('66ºF', wbs.forecast()) self.assertEqual('normal', wbs.special().type) dt = datetime.datetime.utcfromtimestamp(1475129665) # datetime.datetime(2016, 9, 29, 6, 14, 25) alert = wbs.alert(title='test1', expires=pytz.utc.localize(dt), uri='test.uri1') self.assertIn('test1', alert) self.assertIn('Thu, Sep 29 at 06:14:25 UTC', alert) self.assertIn('test.uri1', alert) wbs.set_weather(wd2) self.assertEqual(73.09, wbs.weather_data.apparentTemperature) self.assertIn('73', wbs.normal()) self.assertIn('78ºF', wbs.forecast()) self.assertEqual('moderate-rain', wbs.special().type) dt = datetime.datetime.utcfromtimestamp(1475129666) # datetime.datetime(2016, 9, 29, 6, 14, 26) alert = wbs.alert(title='test2', expires=pytz.utc.localize(dt), uri='test.uri2') self.assertIn('test2', alert) self.assertIn('Thu, Sep 29 at 06:14:26 UTC', alert) self.assertIn('test.uri2', alert)
def test_bad_data(self): """Testing that bad data will gracefully fail""" forecast = forecastio.manual(os.path.join('fixtures', 'bad_data_unavailable.json')) wd = models.WeatherData(forecast, self.location) self.assertFalse(wd.valid) forecast = forecastio.manual(os.path.join('fixtures', 'bad_data_temperature.json')) wd = models.WeatherData(forecast, self.location) self.assertFalse(wd.valid) forecast = forecastio.manual(os.path.join('fixtures', 'bad_data_summary.json')) wd = models.WeatherData(forecast, self.location) self.assertFalse(wd.valid)
def test_optional_fields(self): """Testing that bad data will gracefully fail""" forecast = forecastio.manual( os.path.join('fixtures', 'optional_fields.json')) wd = models.WeatherData(forecast, self.location) self.assertEqual(wd.precipType, 'rain') self.assertEqual(wd.windBearing, 'unknown direction')
def test_normal(self): """Testing that normal events are formatted""" forecast = forecastio.manual(os.path.join('fixtures', 'us.json')) wd = models.WeatherData(forecast, self.location) wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) normal_string = wbs.normal() self.assertIn(normal_string, wbs.normal_conditions)
def test_alerts(self): """Testing that alerts are loaded correctly into a list""" location = models.WeatherLocation(34.2, -118.36, 'Los Angeles, CA') forecast = forecastio.manual(os.path.join('fixtures', 'us_alert.json')) wd = models.WeatherData(forecast, location) self.assertEqual(wd.alerts[0].title, 'Wind Advisory') self.assertEqual(wd.alerts[1].title, 'Beach Hazards Statement') self.assertEqual(wd.alerts[2].title, 'Red Flag Warning')
def transform(values): return models.WeatherData( datetime=datetime.datetime.fromtimestamp(values['dt']), temperature=math.ceil(float(values['main']['temp']) - 273.15), humidity=values['main']['humidity'], pressure=values['main']['pressure'], description=", ".join(x['description'] for x in values['weather']))
def test_precipitation(self): """Testing that precipitation conditions are met""" wbs = models.WeatherBotString(self.weatherbot_strings) forecast_us = forecastio.manual(os.path.join('fixtures', 'us.json')) wd = models.WeatherData(forecast_us, self.location) wbs.set_weather(wd) self.assertEqual(wbs.precipitation(), models.Condition(type='none', text='')) wd.precipIntensity = 0.3 wd.precipProbability = 0.5 wd.precipType = 'rain' wbs.set_weather(wd) self.assertEqual(wbs.precipitation(), models.Condition(type='none', text='')) wd.precipIntensity = 0.3 wd.precipProbability = 1 wd.precipType = 'none' wbs.set_weather(wd) self.assertEqual(wbs.precipitation(), models.Condition(type='none', text='')) wd.precipIntensity = 0 wd.precipProbability = 1 wd.precipType = 'rain' wbs.set_weather(wd) self.assertEqual(wbs.precipitation(), models.Condition(type='none', text='')) wd.precipIntensity = 0 wd.precipProbability = 1 wd.precipType = 'none' wbs.set_weather(wd) self.assertEqual(wbs.precipitation(), models.Condition(type='none', text='')) # testing with a few possible conditions wd.precipIntensity = 0.3 wd.precipProbability = 1 wd.precipType = 'rain' wbs.set_weather(wd) precip = wbs.precipitation() self.assertEqual(precip.type, 'moderate-rain') self.assertIn(precip.text, wbs.precipitations['rain']['moderate']) wd.precipIntensity = 0.4 wd.precipProbability = 0.85 wd.precipType = 'snow' wbs.set_weather(wd) precip = wbs.precipitation() self.assertEqual(precip.type, 'heavy-snow') self.assertIn(precip.text, wbs.precipitations['snow']['heavy']) wd.precipIntensity = 0.06 wd.precipProbability = 1 wd.precipType = 'sleet' wbs.set_weather(wd) precip = wbs.precipitation() self.assertEqual(precip.type, 'light-sleet') self.assertIn(precip.text, wbs.precipitations['sleet']['light']) wd.precipIntensity = 0.005 wd.precipProbability = 1 wd.precipType = 'rain' wbs.set_weather(wd) precip = wbs.precipitation() self.assertEqual(precip.type, 'very-light-rain') self.assertIn(precip.text, wbs.precipitations['rain']['very-light'])
def test_alert(self): """Testing that alerts are formatted""" wbs = models.WeatherBotString(self.weatherbot_strings) forecast = forecastio.manual(os.path.join('fixtures', 'ca_alert.json')) location = models.WeatherLocation(50.564167, -111.898889, 'Brooks, Alberta') wd = models.WeatherData(forecast, location) wbs.set_weather(wd) alert = wbs.alert(wd.alerts[0], wd.timezone) self.assertIn('Snowfall Warning', alert) self.assertIn('https://weather.gc.ca/warnings/report_e.html?ab6', alert)
def main(path): """ Main function called when starting weatherBot. The path is to the configuration file. :type path: str :param path: path to configuration file """ # pylint: disable=broad-except,no-member global CACHE load_config(os.path.abspath(path)) initialize_logger(CONFIG['log']['enabled'], CONFIG['log']['log_path']) logging.debug(CONFIG) keys.set_twitter_env_vars() keys.set_darksky_env_vars() CACHE['throttles']['default'] = pytz.utc.localize(datetime.utcnow()).astimezone(pytz.utc) with open(CONFIG['basic']['strings'], 'r') as file_stream: try: weatherbot_strings = yaml.safe_load(file_stream) logging.debug(weatherbot_strings) wb_string = models.WeatherBotString(weatherbot_strings) except yaml.YAMLError as err: logging.error(err, exc_info=True) logging.error('Could not read YAML file, please correct, run yamllint, and try again.') exit() location = CONFIG['default_location'] updated_time = utils.datetime_to_utc('UTC', datetime.utcnow()) - timedelta(minutes=30) try: while True: # check for new location every 30 minutes now_utc = utils.datetime_to_utc('UTC', datetime.utcnow()) if CONFIG['variable_location']['enabled'] and updated_time + timedelta(minutes=30) < now_utc: location = get_location_from_user_timeline(CONFIG['variable_location']['user'], location) updated_time = now_utc forecast = get_forecast_object(location.lat, location.lng, CONFIG['basic']['units'], wb_string.language) if forecast is not None: weather_data = models.WeatherData(forecast, location) if weather_data.valid: CACHE = get_cache() tweet_logic(weather_data, wb_string) CACHE['throttles'] = cleanse_throttles(CACHE['throttles'], now_utc) set_cache(CACHE) time.sleep(CONFIG['basic']['refresh'] * 60) else: time.sleep(60) except Exception as err: logging.error(err) logging.error('We got an exception!', exc_info=True) if CONFIG['basic']['dm_errors']: api = get_tweepy_api() api.send_direct_message(screen_name=api.me().screen_name, text=str(random.randint(0, 9999)) + traceback.format_exc())
def test_dict(self): """Testing that __dict__ returns the correct data""" forecast = forecastio.manual(os.path.join('fixtures', 'us.json')) wd = models.WeatherData(forecast, self.location) wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) self.assertEqual({ 'language': wbs.language, 'weather_data': wbs.weather_data, 'forecasts': wbs.forecasts, 'forecast_endings': wbs.forecasts_endings, 'normal_conditions': wbs.normal_conditions, 'special_conditions': wbs.special_conditions, 'precipitations': wbs.precipitations }, wbs.__dict__())
def test_forecast(self): """Testing that forecasts are formatted correctly""" forecast = forecastio.manual(os.path.join('fixtures', 'us.json')) wd = models.WeatherData(forecast, self.location) self.weatherbot_strings['forecast_endings'] = [] wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) forecast_string = wbs.forecast() self.assertIn(forecast_string, wbs.forecasts) self.weatherbot_strings['forecast_endings'] = ['Test ending!'] self.weatherbot_strings['forecasts'] = ['The forecast for today is {summary_lower} {high}/{low}.'] wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) forecast_string = wbs.forecast() self.assertEqual(forecast_string, 'The forecast for today is mostly cloudy throughout the day. 66ºF/50ºF. Test ending!')
def test_init(self): """Testing that weather data is loaded correctly""" forecast = forecastio.manual(os.path.join('fixtures', 'us.json')) wd = models.WeatherData(forecast, self.location) self.assertEqual(wd.units, utils.get_units('us')) self.assertEqual(wd.windBearing, 'SW') self.assertEqual(wd.windSpeed, 10.81) self.assertEqual(wd.apparentTemperature, 50.84) self.assertEqual(wd.temp, 50.84) self.assertEqual(wd.humidity, 89) self.assertEqual(wd.precipIntensity, 0) self.assertEqual(wd.precipProbability, 0) self.assertEqual(wd.precipType, 'none') self.assertEqual(wd.summary, 'Partly Cloudy') self.assertEqual(wd.icon, 'partly-cloudy-day') self.assertEqual(wd.location, self.location) self.assertEqual(wd.timezone, 'Europe/Copenhagen') self.assertEqual(wd.alerts, []) self.assertTrue(wd.valid) self.assertEqual(str(wd), '<WeatherData: Lyngby-Taarbæk, Hovedstaden(55.76,12.49) at 2016-10-01 05:56:38+00:00>')
def test_special(self): """Testing if special events are triggered""" forecast_si = forecastio.manual(os.path.join('fixtures', 'si.json')) forecast_us = forecastio.manual(os.path.join('fixtures', 'us.json')) forecast_ca = forecastio.manual(os.path.join('fixtures', 'ca.json')) forecast_uk2 = forecastio.manual(os.path.join('fixtures', 'uk2.json')) wd = models.WeatherData(forecast_si, self.location) wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) self.assertEqual('normal', wbs.special().type) self.assertEqual('', wbs.special().text) """Testing if wind-chill type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.apparentTemperature = -34 wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) self.assertEqual('wind-chill', wbs.special().type) self.assertIn(wbs.special().text, wbs.special_conditions[wbs.special().type]) wd = models.WeatherData(forecast_us, self.location) wd.apparentTemperature = -30 wbs = models.WeatherBotString(self.weatherbot_strings) wbs.set_weather(wd) self.assertEqual('wind-chill', wbs.special().type) self.assertIn(wbs.special().text, wbs.special_conditions[wbs.special().type]) """Testing if precip type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.precipProbability = 0.9 wd.precipType = 'rain' wd.precipIntensity = 10.0 wbs.set_weather(wd) self.assertEqual('heavy-rain', wbs.special().type) self.assertIn(wbs.special().text, wbs.precipitations['rain']['heavy']) wd = models.WeatherData(forecast_us, self.location) wd.precipProbability = 0.9 wd.precipType = 'rain' wd.precipIntensity = 1.0 wbs.set_weather(wd) self.assertEqual('heavy-rain', wbs.special().type) self.assertIn(wbs.special().text, wbs.precipitations['rain']['heavy']) wd = models.WeatherData(forecast_us, self.location) wd.precipProbability = 0.9 wd.precipType = 'none' wd.precipIntensity = 1.0 wbs.set_weather(wd) self.assertEqual('normal', wbs.special().type) self.assertEqual('', wbs.special().text) """Testing if medium-wind type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.icon = 'medium-wind' wbs.set_weather(wd) self.assertEqual('medium-wind', wbs.special().type) """Testing if heavy-wind type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.icon = 'heavy-wind' wbs.set_weather(wd) self.assertEqual('heavy-wind', wbs.special().type) wd = models.WeatherData(forecast_si, self.location) wd.windSpeed = 15.0 wbs.set_weather(wd) self.assertEqual('heavy-wind', wbs.special().type) wd = models.WeatherData(forecast_ca, self.location) wd.windSpeed = 56.0 wbs.set_weather(wd) self.assertEqual('heavy-wind', wbs.special().type) wd = models.WeatherData(forecast_us, self.location) wd.windSpeed = 35.0 wbs.set_weather(wd) self.assertEqual('heavy-wind', wbs.special().type) wd = models.WeatherData(forecast_uk2, self.location) wd.windSpeed = 35.0 wbs.set_weather(wd) self.assertEqual('heavy-wind', wbs.special().type) """Testing if fog type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.icon = 'fog' wbs.set_weather(wd) self.assertEqual('fog', wbs.special().type) """Testing if cold type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.temp = -28.0 wbs.set_weather(wd) self.assertEqual('cold', wbs.special().type) wd = models.WeatherData(forecast_us, self.location) wd.temp = -20.0 wbs.set_weather(wd) self.assertEqual('cold', wbs.special().type) """Testing if super-hot type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.temp = 43.0 wbs.set_weather(wd) self.assertEqual('super-hot', wbs.special().type) wd = models.WeatherData(forecast_us, self.location) wd.temp = 110.0 wbs.set_weather(wd) self.assertEqual('super-hot', wbs.special().type) """Testing if hot type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.temp = 37.0 wbs.set_weather(wd) self.assertEqual('hot', wbs.special().type) wd = models.WeatherData(forecast_us, self.location) wd.temp = 100.0 wbs.set_weather(wd) self.assertEqual('hot', wbs.special().type) """Testing if dry type is triggered""" wd = models.WeatherData(forecast_si, self.location) wd.humidity = 25.0 wbs.set_weather(wd) self.assertEqual('dry', wbs.special().type)
def test_json(self): """Testing that json() returns a dict containing the response from the Dark Sky API""" forecast = forecastio.manual(os.path.join('fixtures', 'us.json')) wd = models.WeatherData(forecast, self.location) self.assertEqual(wd.json(), forecast.json)