diff --git a/didier/cogs/other.py b/didier/cogs/other.py index dff1376..fac1a04 100644 --- a/didier/cogs/other.py +++ b/didier/cogs/other.py @@ -10,6 +10,7 @@ from didier import Didier from didier.data.apis import disease_sh, inspirobot, urban_dictionary from didier.data.embeds.google import GoogleSearch from didier.data.scrapers import google +from didier.utils.discord.autocompletion.country import autocomplete_country class Other(commands.Cog): @@ -34,7 +35,12 @@ class Other(commands.Cog): else: data = await disease_sh.get_country_info(self.client.http_session, country) - await ctx.reply(str(data), mention_author=False) + await ctx.reply(embed=data.to_embed(), mention_author=False) + + @covid.autocomplete("country") + async def _covid_country_autocomplete(self, interaction: discord.Interaction, value: str): + """Autocompletion for the 'country'-parameter""" + return autocomplete_country(value)[:25] @commands.hybrid_command( name="define", aliases=["ud", "urban"], description="Look up the definition of a word on the Urban Dictionary" diff --git a/didier/data/embeds/disease_sh.py b/didier/data/embeds/disease_sh.py index 4056ec6..d619419 100644 --- a/didier/data/embeds/disease_sh.py +++ b/didier/data/embeds/disease_sh.py @@ -1,6 +1,6 @@ import discord from overrides import overrides -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, validator from didier.data.embeds.base import EmbedPydantic @@ -8,7 +8,10 @@ __all__ = ["CovidData"] class _CovidNumbers(BaseModel): - """Covid information for a country""" + """Covid numbers for a country + + For worldwide numbers, country_info will be None + """ updated: int country: str = "Worldwide" @@ -17,10 +20,15 @@ class _CovidNumbers(BaseModel): deaths: int today_deaths: int = Field(alias="todayDeaths") recovered: int - todayRecovered: int = Field(alias="todayRecovered") + today_recovered: int = Field(alias="todayRecovered") active: int tests: int + @validator("updated") + def updated_to_seconds(cls, value: int) -> int: + """Turn the updated field into seconds instead of milliseconds""" + return int(value) // 1000 + class CovidData(EmbedPydantic): """Covid information from two days combined into one model""" @@ -30,4 +38,63 @@ class CovidData(EmbedPydantic): @overrides def to_embed(self, **kwargs) -> discord.Embed: - pass + embed = discord.Embed(colour=discord.Colour.red(), title=f"Coronatracker {self.today.country}") + embed.description = f"Last update: " + embed.set_thumbnail(url="https://i.imgur.com/aWnDuBt.png") + + cases_indicator = self._trend_indicator(self.today.today_cases, self.yesterday.today_cases) + embed.add_field( + name="Cases (Today)", + value=f"{self.today.cases:,} **({self.today.today_cases:,})** {cases_indicator}".replace(",", "."), + inline=False, + ) + + active_indicator = self._trend_indicator(self.today.active, self.yesterday.active) + active_diff = self.today.active - self.yesterday.active + embed.add_field( + name="Active (Today)", + value=f"{self.today.active:,} **({self._with_sign(active_diff)})** {active_indicator}".replace(",", "."), + inline=False, + ) + + deaths_indicator = self._trend_indicator(self.today.today_deaths, self.yesterday.today_deaths) + embed.add_field( + name="Deaths (Today)", + value=f"{self.today.deaths:,} **({self.today.today_deaths:,})** {deaths_indicator}".replace(",", "."), + inline=False, + ) + + recovered_indicator = self._trend_indicator(self.today.today_recovered, self.yesterday.today_recovered) + embed.add_field( + name="Recovered (Today)", + value=f"{self.today.recovered} **({self.today.today_recovered:,})** {recovered_indicator}".replace( + ",", "." + ), + inline=False, + ) + + tests_diff = self.today.tests - self.yesterday.tests + embed.add_field( + name="Tests Administered (Today)", + value=f"{self.today.tests:,} **({tests_diff:,})**".replace(",", "."), + inline=False, + ) + + return embed + + def _with_sign(self, value: int) -> str: + """Prepend a + symbol if a number is positive""" + if value > 0: + return f"+{value:,}" + + return f"{value:,}" + + def _trend_indicator(self, today: int, yesterday: int) -> str: + """Function that returns a rise/decline indicator for the target key.""" + if today > yesterday: + return ":small_red_triangle:" + + if yesterday > today: + return ":small_red_triangle_down:" + + return "" diff --git a/didier/utils/discord/autocompletion/country.py b/didier/utils/discord/autocompletion/country.py new file mode 100644 index 0000000..f11a110 --- /dev/null +++ b/didier/utils/discord/autocompletion/country.py @@ -0,0 +1,250 @@ +from discord import app_commands + +__all__ = ["autocomplete_country"] + +# This list was parsed out of a request to https://disease.sh/v3/covid-19/countries +country_list = [ + "Afghanistan", + "Albania", + "Algeria", + "Andorra", + "Angola", + "Anguilla", + "Antigua and Barbuda", + "Argentina", + "Armenia", + "Aruba", + "Australia", + "Austria", + "Azerbaijan", + "Bahamas", + "Bahrain", + "Bangladesh", + "Barbados", + "Belarus", + "Belgium", + "Belize", + "Benin", + "Bermuda", + "Bhutan", + "Bolivia", + "Bosnia", + "Botswana", + "Brazil", + "British Virgin Islands", + "Brunei", + "Bulgaria", + "Burkina Faso", + "Burundi", + "Cabo Verde", + "Cambodia", + "Cameroon", + "Canada", + "Caribbean Netherlands", + "Cayman Islands", + "Central African Republic", + "Chad", + "Channel Islands", + "Chile", + "China", + "Colombia", + "Comoros", + "Congo", + "Cook Islands", + "Costa Rica", + "Croatia", + "Cuba", + "Curaçao", + "Cyprus", + "Czechia", + "Côte d'Ivoire", + "DRC", + "Denmark", + "Diamond Princess", + "Djibouti", + "Dominica", + "Dominican Republic", + "Ecuador", + "Egypt", + "El Salvador", + "Equatorial Guinea", + "Eritrea", + "Estonia", + "Ethiopia", + "Falkland Islands (Malvinas)", + "Faroe Islands", + "Fiji", + "Finland", + "France", + "French Guiana", + "French Polynesia", + "Gabon", + "Gambia", + "Georgia", + "Germany", + "Ghana", + "Gibraltar", + "Greece", + "Greenland", + "Grenada", + "Guadeloupe", + "Guatemala", + "Guinea", + "Guinea-Bissau", + "Guyana", + "Haiti", + "Holy See (Vatican City State)", + "Honduras", + "Hong Kong", + "Hungary", + "Iceland", + "India", + "Indonesia", + "Iran", + "Iraq", + "Ireland", + "Isle of Man", + "Israel", + "Italy", + "Jamaica", + "Japan", + "Jordan", + "Kazakhstan", + "Kenya", + "Kiribati", + "Kuwait", + "Kyrgyzstan", + "Lao People's Democratic Republic", + "Latvia", + "Lebanon", + "Lesotho", + "Liberia", + "Libyan Arab Jamahiriya", + "Liechtenstein", + "Lithuania", + "Luxembourg", + "MS Zaandam", + "Macao", + "Macedonia", + "Madagascar", + "Malawi", + "Malaysia", + "Maldives", + "Mali", + "Malta", + "Marshall Islands", + "Martinique", + "Mauritania", + "Mauritius", + "Mayotte", + "Mexico", + "Micronesia", + "Moldova", + "Monaco", + "Mongolia", + "Montenegro", + "Montserrat", + "Morocco", + "Mozambique", + "Myanmar", + "N. Korea", + "Namibia", + "Nauru", + "Nepal", + "Netherlands", + "New Caledonia", + "New Zealand", + "Nicaragua", + "Niger", + "Nigeria", + "Niue", + "Norway", + "Oman", + "Pakistan", + "Palau", + "Palestine", + "Panama", + "Papua New Guinea", + "Paraguay", + "Peru", + "Philippines", + "Poland", + "Portugal", + "Qatar", + "Romania", + "Russia", + "Rwanda", + "Réunion", + "S. Korea", + "Saint Helena", + "Saint Kitts and Nevis", + "Saint Lucia", + "Saint Martin", + "Saint Pierre Miquelon", + "Saint Vincent and the Grenadines", + "Samoa", + "San Marino", + "Sao Tome and Principe", + "Saudi Arabia", + "Senegal", + "Serbia", + "Seychelles", + "Sierra Leone", + "Singapore", + "Sint Maarten", + "Slovakia", + "Slovenia", + "Solomon Islands", + "Somalia", + "South Africa", + "South Sudan", + "Spain", + "Sri Lanka", + "St. Barth", + "Sudan", + "Suriname", + "Swaziland", + "Sweden", + "Switzerland", + "Syrian Arab Republic", + "Taiwan", + "Tajikistan", + "Tanzania", + "Thailand", + "Timor-Leste", + "Togo", + "Tonga", + "Trinidad and Tobago", + "Tunisia", + "Turkey", + "Turks and Caicos Islands", + "Tuvalu", + "UAE", + "UK", + "USA", + "Uganda", + "Ukraine", + "Uruguay", + "Uzbekistan", + "Vanuatu", + "Venezuela", + "Vietnam", + "Wallis and Futuna", + "Western Sahara", + "Yemen", + "Zambia", + "Zimbabwe", +] + + +def autocomplete_country(argument: str) -> list[app_commands.Choice]: + """Autocompletion for country names""" + argument = argument.lower() + + global_autocomplete = ["Global"] + + return [ + app_commands.Choice(name=country, value=country) + for country in global_autocomplete + country_list + if argument in country.lower() + ]