From c54cd8b81b8d86e5fcfee79c5b221aa3f5d7e641 Mon Sep 17 00:00:00 2001 From: Kamal Curi Date: Sat, 20 Aug 2022 12:47:08 -0300 Subject: [PATCH 1/5] CHANGE: It's 'quote count' not 'cuote qount' --- utils/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/commands.py b/utils/commands.py index 506cc25..823d109 100644 --- a/utils/commands.py +++ b/utils/commands.py @@ -143,7 +143,7 @@ async def queue_stack(bot: object) -> str: return await bot.send('A list of the 5 latest message IDs follows:'\ f' `{",".join(str(q) for q in quote_id_stack[-5:])}`') -@client.command(aliases=['cq', 'cquotes']) +@client.command(aliases=['qc', 'cquotes']) async def quote_count(bot: object) -> str: """ Outputs a quote count from the database From a7b1df2d467bf02d8470788c8df35fd5d7b07c37 Mon Sep 17 00:00:00 2001 From: Kamal Curi Date: Sat, 20 Aug 2022 12:48:50 -0300 Subject: [PATCH 2/5] CHANGE: We support all versions, so long as it 'supports us' --- requirements/common.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/common.txt b/requirements/common.txt index b2718ec..78a6c39 100644 --- a/requirements/common.txt +++ b/requirements/common.txt @@ -1,3 +1,3 @@ -discord.py==1.7.3 -mysqlclient==2.1.1 -SQLAlchemy==1.4.40 +discord.py +mysqlclient +SQLAlchemy From 50a1f46f73e8a20ac2ae13cdac09e4a79df67120 Mon Sep 17 00:00:00 2001 From: Kamal Curi Date: Sat, 20 Aug 2022 12:49:48 -0300 Subject: [PATCH 3/5] ADD: Added weather command --- environment/template | 1 + requirements/common.txt | 2 + settings/config.py | 6 +++ utils/commands.py | 42 +++++++++++++++++- utils/weather.py | 98 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 utils/weather.py diff --git a/environment/template b/environment/template index 7d47bcc..c70b7fd 100644 --- a/environment/template +++ b/environment/template @@ -3,6 +3,7 @@ ######################## export DISCORD_BOT_TOKEN=<> +export OPENWEATHER_API_TOKEN=<> export MYSQL_HOST=<> export MYSQL_PORT=<> export MYSQL_DATABASE=<> diff --git a/requirements/common.txt b/requirements/common.txt index 78a6c39..138a057 100644 --- a/requirements/common.txt +++ b/requirements/common.txt @@ -1,3 +1,5 @@ discord.py mysqlclient SQLAlchemy +json +pyre2 \ No newline at end of file diff --git a/settings/config.py b/settings/config.py index a6b3dc7..7435b77 100644 --- a/settings/config.py +++ b/settings/config.py @@ -80,4 +80,10 @@ PERMISSIONS = { 'v' : ['Operador', 'BotMan'] } +OW_API_CONFIG = { + 'api_id' : os.environ.get('OPENWEATHER_API_TOKEN'), + 'gc_url' : 'http://api.openweathermap.org/geo/1.0/direct?q=,,&limit=1&appid=', + 'wh_url' : 'https://api.openweathermap.org/data/2.5/weather?lat=&lon=&units=metric&appid=' +} + logger.dictConfig(LOGGING_CONFIG) diff --git a/utils/commands.py b/utils/commands.py index 823d109..e0f2c89 100644 --- a/utils/commands.py +++ b/utils/commands.py @@ -3,10 +3,12 @@ Bot commands. """ import logging from random import choice +import re2 from discord.ext import commands from utils.database import get_by_id, get_quotes, remove_quote, set_quote, count_quotes +from utils.weather import geocode, getweatherdata, displayweather from settings.config import PERMISSIONS @@ -178,4 +180,42 @@ async def info(bot: object) -> str: fullbanner = fullbanner + lines msg = f'''```\n''' + fullbanner + f'''\n```''' - return await bot.send(msg) \ No newline at end of file + return await bot.send(msg) + +@client.command(aliases=['w']) +async def weather(bot: object, *location: str) -> str: + """ + Displays the weather information for a given place + """ + if location: + location = str(location) + stripped = re2.sub(" ", "", location) # Strips all whitespace + separated = stripped.split(',') # Splits between commas + separated.pop(-1) + separated[0] = separated[0][1:len(separated[0])] # These two commands clean up input for the parser + + if len(separated) > 3: + return await bot.send("This command takes 3 parameters at most!") + if len(separated) == 1: + city = separated[0] + state = "" + country = "" + elif len(separated) == 2: + city = separated[0] + state = separated[1] + country = "" + else: + city = separated[0] + state = separated[1] + country = separated[2] + else: + city = "" + state = "" + country = "" + + lat, lon = geocode(city, state, country) + weatherdata = getweatherdata(lat, lon) + msg = displayweather(weatherdata) + + return await bot.send(msg) + \ No newline at end of file diff --git a/utils/weather.py b/utils/weather.py new file mode 100644 index 0000000..b672cb7 --- /dev/null +++ b/utils/weather.py @@ -0,0 +1,98 @@ +import logging + +from settings.config import OW_API_CONFIG + +import urllib.request +import json +import re2 + +def geocode(city = 'curitiba', state = 'parana', country = 'BR') -> str: + """ + Converts city, state and country parameters into their coordinates + """ + if city == "" and state == "" and country == "": + city = 'curitiba' + state = 'parana' + country = 'BR' + ow_gc_url = OW_API_CONFIG['gc_url'] + ow_gc_url = re2.sub('', city, ow_gc_url) + ow_gc_url = re2.sub('', state, ow_gc_url) + ow_gc_url = re2.sub('', OW_API_CONFIG['api_id'], ow_gc_url) + + placedata = urllib.request.urlopen(ow_gc_url) + placedata = placedata.read().decode() + placedata = json.loads(str(placedata)) + + return str(placedata[0]['lat']), str(placedata[0]['lon']) + +def getweatherdata(lat, lon): + """ + Gets weather data based on coordinates + """ + ow_wh_url = OW_API_CONFIG['wh_url'] + ow_wh_url = re2.sub('', lat, ow_wh_url) + ow_wh_url = re2.sub('', lon, ow_wh_url) + ow_wh_url = re2.sub('', OW_API_CONFIG['api_id'], ow_wh_url) + + weatherdata = urllib.request.urlopen(ow_wh_url) + weatherdata = weatherdata.read().decode() + weatherdata = json.loads(str(weatherdata)) + + return weatherdata + +def displayweather(wdata): + """ + "Prettifies" the output for discord + """ + try: + wdata['weather'][0]['description'] + description = wdata['weather'][0]['description'] + except: + description = "No data on description" + try: + wdata['main']['temp'] + temp = wdata['main']['temp'] + tempmsg = f"Temperature is {temp}ºC" + except: + tempmsg = "No data on temperature" + try: + wdata['main']['feels_like'] + feels_like = wdata['main']['feels_like'] + feels_likemsg = f"Feels like {feels_like}ºC" + except: + feels_likemsg = "No data on perceived temperature" + try: + wdata['main']['humidity'] + humidity = wdata['main']['humidity'] + humiditymsg = f"Humidity is {humidity}%" + except: + humiditymsg = "No data on humidity" + try: + wdata['wind']['speed'] + wind_speed = wdata['wind']['speed'] + wind_speedmsg = f"Wind speed is {wind_speed}m/s" + except: + wind_speedmsg = "No data on wind speed" + try: + wdata['wind']['gust'] + wind_gusts = wdata['wind']['gust'] + wind_gustsmsg = f"with gusts of {wind_gusts}m/s" + except: + wind_gustsmsg = "with no data on gusts" + try: + wdata['clouds']['all'] + cloud_coverage = wdata['clouds']['all'] + cloud_coveragemsg = f"Cloud coverage is {cloud_coverage}%" + except: + cloud_coveragemsg = "No data on cloud coverage" + name = wdata['name'] + + msg = f""" + ``` + Weather for {name}: + {description}, {tempmsg}. {feels_likemsg}. {humiditymsg}. + {wind_speedmsg}, {wind_gustsmsg}. {cloud_coveragemsg}. + ```""" + + return msg \ No newline at end of file From 4dcad8d24852e8e658a17cd267111eb8f6789248 Mon Sep 17 00:00:00 2001 From: Kamal Curi Date: Sat, 20 Aug 2022 12:54:18 -0300 Subject: [PATCH 4/5] CHANGE: Unset environment variables won't let the weather command be executed --- settings/config.py | 2 +- utils/commands.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/settings/config.py b/settings/config.py index 7435b77..61fa33f 100644 --- a/settings/config.py +++ b/settings/config.py @@ -81,7 +81,7 @@ PERMISSIONS = { } OW_API_CONFIG = { - 'api_id' : os.environ.get('OPENWEATHER_API_TOKEN'), + 'api_id' : os.environ.get('OPENWEATHER_API_TOKEN', 'no'), 'gc_url' : 'http://api.openweathermap.org/geo/1.0/direct?q=,,&limit=1&appid=', 'wh_url' : 'https://api.openweathermap.org/data/2.5/weather?lat=&lon=&units=metric&appid=' } diff --git a/utils/commands.py b/utils/commands.py index e0f2c89..d29cc0f 100644 --- a/utils/commands.py +++ b/utils/commands.py @@ -10,7 +10,7 @@ from discord.ext import commands from utils.database import get_by_id, get_quotes, remove_quote, set_quote, count_quotes from utils.weather import geocode, getweatherdata, displayweather -from settings.config import PERMISSIONS +from settings.config import PERMISSIONS, OW_API_CONFIG client = commands.Bot(command_prefix='--') logger = logging.getLogger(__name__) @@ -187,6 +187,9 @@ async def weather(bot: object, *location: str) -> str: """ Displays the weather information for a given place """ + if OW_API_CONFIG['api_id'] == 'no': + return await bot.send("You haven't set up an API key! Make an user and set up an API key in https://openweathermap.org/\n \ + (The weather command hansn't been set up properly, make sure you have `OPENWEATHER_API_TOKEN` set up") if location: location = str(location) stripped = re2.sub(" ", "", location) # Strips all whitespace From 16a60eebf570bb85c2751c282b18a1c59e0383b0 Mon Sep 17 00:00:00 2001 From: Kamal Curi Date: Sat, 20 Aug 2022 12:59:35 -0300 Subject: [PATCH 5/5] CHANGE: Verbose hint for weather command --- utils/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/commands.py b/utils/commands.py index d29cc0f..772ae60 100644 --- a/utils/commands.py +++ b/utils/commands.py @@ -198,7 +198,8 @@ async def weather(bot: object, *location: str) -> str: separated[0] = separated[0][1:len(separated[0])] # These two commands clean up input for the parser if len(separated) > 3: - return await bot.send("This command takes 3 parameters at most!") + return await bot.send("This command takes 3 parameters at most!\n \ + (Syntax: `--w , , `)") if len(separated) == 1: city = separated[0] state = ""