mirror of https://github.com/stijndcl/didier
Add vaccine stats (fixes #26), fix a few bugs in Corona, allow negative numbers to be displayed properly in corona, clean code up a bit, add daily difference for tests
parent
2877def272
commit
5dd6b62a40
130
cogs/corona.py
130
cogs/corona.py
|
@ -31,7 +31,10 @@ class Corona(commands.Cog):
|
|||
await self.sendError(ctx)
|
||||
return
|
||||
|
||||
await self.sendEmbed(ctx, dic)
|
||||
# Vaccination stats
|
||||
vaccine = self.getVaccineData(country, dic["today"]["population"], dic["yesterday"]["population"])
|
||||
|
||||
await self.sendEmbed(ctx, dic, vaccine)
|
||||
|
||||
@corona.command(aliases=["lb", "leaderboards"], hidden=True)
|
||||
async def leaderboard(self, ctx):
|
||||
|
@ -43,7 +46,7 @@ class Corona(commands.Cog):
|
|||
"""
|
||||
await self.client.get_cog("Leaderboards").callLeaderboard("corona", ctx)
|
||||
|
||||
async def sendEmbed(self, ctx, dic):
|
||||
async def sendEmbed(self, ctx, dic, vaccines):
|
||||
"""
|
||||
Function that sends a Corona embed from a dictionary.
|
||||
:param ctx: Discord Context
|
||||
|
@ -54,7 +57,7 @@ class Corona(commands.Cog):
|
|||
|
||||
# Total
|
||||
embed.add_field(name="Totale Gevallen (Vandaag):",
|
||||
value="{:,} **(+{:,})** {}".format(
|
||||
value=self.createEmbedString(
|
||||
dic["today"]["cases"],
|
||||
dic["today"]["todayCases"],
|
||||
self.trendIndicator(dic, "todayCases")
|
||||
|
@ -63,7 +66,7 @@ class Corona(commands.Cog):
|
|||
|
||||
# Active
|
||||
embed.add_field(name="Actieve Gevallen (Vandaag):",
|
||||
value="{:,} **(+{:,})** {}".format(
|
||||
value=self.createEmbedString(
|
||||
dic["today"]["activeCases"],
|
||||
dic["today"]["activeCases"] - dic["yesterday"]["activeCases"],
|
||||
self.activeTrendIndicator(dic)
|
||||
|
@ -72,7 +75,7 @@ class Corona(commands.Cog):
|
|||
|
||||
# Deaths
|
||||
embed.add_field(name="Sterfgevallen (Vandaag):",
|
||||
value="{:,} **(+{:,})** {}".format(
|
||||
value=self.createEmbedString(
|
||||
dic["today"]["deaths"],
|
||||
dic["today"]["todayDeaths"],
|
||||
self.trendIndicator(dic, "todayDeaths")
|
||||
|
@ -81,7 +84,7 @@ class Corona(commands.Cog):
|
|||
|
||||
# Recovered
|
||||
embed.add_field(name="Hersteld (Vandaag):",
|
||||
value="{:,} **(+{:,}) {}**".format(
|
||||
value=self.createEmbedString(
|
||||
dic["today"]["recovered"],
|
||||
dic["today"]["todayRecovered"],
|
||||
self.trendIndicator(dic, "todayRecovered")
|
||||
|
@ -90,15 +93,40 @@ class Corona(commands.Cog):
|
|||
|
||||
# Test Cases
|
||||
embed.add_field(name="Aantal uitgevoerde tests:",
|
||||
value="{:,}".format(dic["today"]["tests"]),
|
||||
value=self.createEmbedString(
|
||||
dic["today"]["tests"],
|
||||
dic["today"]["todayTests"]
|
||||
),
|
||||
inline=False)
|
||||
|
||||
# Vaccines
|
||||
if vaccines is not None:
|
||||
embed.add_field(name="Aantal toegediende vaccins:",
|
||||
value=self.createEmbedString(
|
||||
vaccines["today"]["vaccines"],
|
||||
vaccines["today"]["todayVaccines"],
|
||||
self.trendIndicator(vaccines, "todayVaccines")
|
||||
))
|
||||
|
||||
# Timestamp of last update
|
||||
timeFormatted = timeFormatters.epochToDate(int(dic["today"]["updated"])/1000)
|
||||
timeFormatted = timeFormatters.epochToDate(int(dic["today"]["updated"]) / 1000)
|
||||
embed.set_footer(text="Laatst geüpdatet op {} ({} geleden)".format(
|
||||
timeFormatted["date"], timeFormatted["timeAgo"]))
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
def createEmbedString(self, total, today, indicator="", isPercentage=False):
|
||||
"""
|
||||
Function that formats a string to add covid data into the embed,
|
||||
separate function to make code more readable
|
||||
"""
|
||||
# + or - symbol | minus is included in the number so no need
|
||||
symbol = "+" if today >= 0 else ""
|
||||
perc = "%" if isPercentage else ""
|
||||
|
||||
return "{:,}{} **({}{:,}{})** {}".format(
|
||||
total, perc, symbol, today, perc, indicator
|
||||
)
|
||||
|
||||
@commands.command(name="Trends", aliases=["Ct"], usage="[Land]*")
|
||||
@commands.check(checks.allowedChannels)
|
||||
@help.Category(category=Category.Other)
|
||||
|
@ -146,7 +174,7 @@ class Corona(commands.Cog):
|
|||
distribution[0], distribution[1], distribution[2]), inline=False)
|
||||
|
||||
# Timestamp of last update
|
||||
timeFormatted = timeFormatters.epochToDate(int(dic["today"]["updated"])/1000)
|
||||
timeFormatted = timeFormatters.epochToDate(int(dic["today"]["updated"]) / 1000)
|
||||
embed.set_footer(text="Laatst geüpdatet op {} ({} geleden)".format(
|
||||
timeFormatted["date"], timeFormatted["timeAgo"]))
|
||||
await ctx.send(embed=embed)
|
||||
|
@ -184,7 +212,9 @@ class Corona(commands.Cog):
|
|||
"recovered": today["recovered"],
|
||||
"todayRecovered": today["todayRecovered"],
|
||||
"tests": today["tests"],
|
||||
"updated": today["updated"]
|
||||
"todayTests": today["tests"] - yesterday["tests"],
|
||||
"updated": today["updated"],
|
||||
"population": today["population"]
|
||||
},
|
||||
"yesterday": {
|
||||
"cases": yesterday["cases"],
|
||||
|
@ -195,11 +225,78 @@ class Corona(commands.Cog):
|
|||
"recovered": yesterday["recovered"],
|
||||
"todayRecovered": yesterday["todayRecovered"],
|
||||
"tests": yesterday["tests"],
|
||||
"updated": yesterday["updated"]
|
||||
"updated": yesterday["updated"],
|
||||
"population": yesterday["population"]
|
||||
}
|
||||
}
|
||||
|
||||
return dic
|
||||
|
||||
def getVaccineData(self, country: str, todayPopulation: int, yesterdayPopulation: int):
|
||||
"""
|
||||
Function that gets vaccination stats for a specicic country.
|
||||
This information is later added to the embed.
|
||||
"""
|
||||
if todayPopulation == 0:
|
||||
todayPopulation = 1
|
||||
|
||||
if yesterdayPopulation == 0:
|
||||
yesterdayPopulation = 1
|
||||
|
||||
# "all" has a different endpoint
|
||||
if country == "global":
|
||||
vaccine: dict = requests.get("https://disease.sh/v3/covid-19/vaccine/coverage?lastdays=3").json()
|
||||
else:
|
||||
vaccine: dict = requests.get("https://disease.sh/v3/covid-19/vaccine/coverage/countries/{}?lastdays=3"
|
||||
.format(country)).json()
|
||||
|
||||
# Country-specific is structured differently
|
||||
if "timeline" in vaccine:
|
||||
vaccine = vaccine["timeline"]
|
||||
|
||||
# Error message returned or not enough data yet
|
||||
if "message" in vaccine or len(vaccine.keys()) != 3:
|
||||
return None
|
||||
|
||||
timeFormat = "%m/%d/%y"
|
||||
|
||||
def getDt(dt):
|
||||
"""
|
||||
Function that calls fromString with an argument
|
||||
so it can be used in map
|
||||
"""
|
||||
return timeFormatters.fromString(dt, timeFormat)
|
||||
|
||||
def toString(dt):
|
||||
"""
|
||||
Function to cast datetime back to string
|
||||
"""
|
||||
st: str = dt.strftime(timeFormat)
|
||||
|
||||
# Api doesn't add leading zeroes so the keys don't match anymore ---'
|
||||
if st.startswith("0"):
|
||||
st = st[1:]
|
||||
|
||||
return st
|
||||
|
||||
# Order dates
|
||||
ordered = sorted(map(getDt, vaccine.keys()))
|
||||
# Datetime objects are only required for sorting, turn back into strings
|
||||
ordered = list(map(toString, ordered))
|
||||
|
||||
info = {"today": {}, "yesterday": {}}
|
||||
|
||||
# Total vaccines
|
||||
info["today"]["vaccines"] = vaccine[ordered[2]]
|
||||
# New vaccines today
|
||||
info["today"]["todayVaccines"] = vaccine[ordered[2]] - vaccine[ordered[1]]
|
||||
# % of total population
|
||||
info["today"]["perc"] = round(100 * vaccine[ordered[2]] / todayPopulation, 2)
|
||||
info["yesterday"]["vaccines"] = vaccine[ordered[1]]
|
||||
info["yesterday"]["todayVaccines"] = vaccine[ordered[1]] - vaccine[ordered[0]]
|
||||
|
||||
return info
|
||||
|
||||
def distribution(self, dic):
|
||||
"""
|
||||
Calculates the percentage distribution for every key & shows an indicator.
|
||||
|
@ -209,9 +306,9 @@ class Corona(commands.Cog):
|
|||
totalToday = dic["today"]["cases"] if dic["today"]["cases"] != 0 else 1
|
||||
totalYesterday = dic["yesterday"]["cases"] if dic["yesterday"]["cases"] != 0 else 1
|
||||
|
||||
tap = round(100 * dic["today"]["activeCases"]/totalToday, 2) # Today Active Percentage
|
||||
trp = round(100 * dic["today"]["recovered"]/totalToday, 2) # Today Recovered Percentage
|
||||
tdp = round(100 * dic["today"]["deaths"]/totalToday, 2) # Today Deaths Percentage
|
||||
tap = round(100 * dic["today"]["activeCases"] / totalToday, 2) # Today Active Percentage
|
||||
trp = round(100 * dic["today"]["recovered"] / totalToday, 2) # Today Recovered Percentage
|
||||
tdp = round(100 * dic["today"]["deaths"] / totalToday, 2) # Today Deaths Percentage
|
||||
yap = round(100 * dic["yesterday"]["activeCases"] / totalYesterday, 2) # Yesterday Active Percentage
|
||||
yrp = round(100 * dic["yesterday"]["recovered"] / totalYesterday, 2) # Yesterday Recovered Percentage
|
||||
ydp = round(100 * dic["yesterday"]["deaths"] / totalYesterday, 2) # Yesterday Deaths Percentage
|
||||
|
@ -245,7 +342,7 @@ class Corona(commands.Cog):
|
|||
yesterday = dic["yesterday"][key] if dic["yesterday"][key] != 0 else 1
|
||||
|
||||
# Percentage
|
||||
perc = round(100 * change/yesterday, 2)
|
||||
perc = round(100 * change / yesterday, 2)
|
||||
|
||||
# Sign to add to the number
|
||||
sign = "+" if change >= 0 else ""
|
||||
|
@ -263,7 +360,8 @@ class Corona(commands.Cog):
|
|||
:return: a triangle emoji or empty string
|
||||
"""
|
||||
todayNew = dic["today"]["todayCases"] - dic["today"]["todayDeaths"] - dic["today"]["todayRecovered"]
|
||||
yesterdayNew = dic["yesterday"]["todayCases"] - dic["yesterday"]["todayDeaths"] - dic["yesterday"]["todayRecovered"]
|
||||
yesterdayNew = dic["yesterday"]["todayCases"] - dic["yesterday"]["todayDeaths"] - dic["yesterday"][
|
||||
"todayRecovered"]
|
||||
|
||||
return ":small_red_triangle:" if todayNew > yesterdayNew else \
|
||||
(":small_red_triangle_down:" if todayNew < yesterdayNew else "")
|
||||
|
|
|
@ -142,3 +142,10 @@ def weekdayToInt(day):
|
|||
|
||||
def intToWeekday(day):
|
||||
return ["Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"][day]
|
||||
|
||||
|
||||
def fromString(timeString: str, formatString="%d/%m/%Y"):
|
||||
"""
|
||||
Constructs a datetime object from an input string
|
||||
"""
|
||||
return datetime.datetime.strptime(timeString, formatString)
|
||||
|
|
Loading…
Reference in New Issue