### # Copyright (c) 2024, Darren VanBuren # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions, and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions, and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the author of this software nor the name of # contributors to this software may be used to endorse or promote products # derived from this software without specific prior written consent. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. ### from supybot import utils, plugins, ircutils, callbacks, conf from supybot.commands import * from supybot.i18n import PluginInternationalization from pyowm import OWM from pyowm.utils import config as pyowm_config from pyowm.utils import timestamps as pyowm_timestamps import time import regex _ = PluginInternationalization('OpenWeather') class OpenWeather(callbacks.Plugin): """This plugin fetches weather information from the OpenWeather One Call API v3.""" threaded = True def __init__(self, irc): super().__init__(irc) self.loc_regex = regex.compile("([A-Za-z]+(?: [A-Za-z]+)*),? ([A-Za-z]{2}) ?([A-Za-z]{2})?") owm = OWM(self.registryValue('apiKey')) self.weather_manager = owm.weather_manager() self.geocoding_manager = owm.geocoding_manager() conf.supybot.plugins.OpenWeather.apiKey.addCallback(self._configCallback) def _configCallback(self, name=None): owm = OWM(self.registryValue('apiKey')) self.weather_manager = owm.weather_manager() self.geocoding_manager = owm.geocoding_manager() self.log.info('Recreated managers after apiKey changed') #@wrap([('matches', regex.compile("([A-Za-z]+(?: [A-Za-z]+)*),? ([A-Za-z]{2}) ?([A-Za-z]{2})?"), 'Not a Location')]) def weather(self, irc, msg, args): """ [] Will return current conditions at . should be in the format City ST CC.""" location_string = ' '.join(args) matches = self.loc_regex.search(location_string) city = matches.group(1) state = matches.group(2) country = matches.group(3) if (country == None or country == 'US'): loc_arr = self.geocoding_manager.geocode(city, country='US', state_code = state, limit = 1) else: loc_arr = self.geocoding_manager.geocode(city, country, limit = 1) if len(loc_arr) == 0: irc.error(f'Could not find location with city {city}, state {state}, country {country}', Raise=True) loc = loc_arr[0] self.log.info(str(loc)) one_call = self.weather_manager.one_call(lat=loc.lat, lon=loc.lon, exclude='minutely,hourly,daily', units='imperial') self.log.info(str(one_call)) curr = one_call.current report_time = curr.reference_time('iso') self.log.info(str(curr)) temp = curr.temperature() measured_temp = temp['temp'] feels_like = temp['feels_like'] wind_data = curr.wind('miles_hour') wind_speed = round(wind_data.get('speed', 0), 2) wind_gust = round(wind_data.get('gust', -1), 2) wind_dir = wind_data['deg'] wind_str = str() if('gust' in wind_data): wind_str = f'Wind {wind_dir} @ {wind_speed} mph, gusts to {wind_gust} mph.' else: wind_str = f'Wind {wind_dir} @ {wind_speed} mph.' cond = curr.detailed_status irc.reply(f'Conditions at {loc.name} as of {report_time}: ' + f'{cond} and {measured_temp} F, feels like {feels_like} F. ' + wind_str) Class = OpenWeather # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: