aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/utilities')
-rw-r--r--bot/exts/utilities/bookmark.py7
-rw-r--r--bot/exts/utilities/challenges.py10
-rw-r--r--bot/exts/utilities/cheatsheet.py3
-rw-r--r--bot/exts/utilities/colour.py13
-rw-r--r--bot/exts/utilities/conversationstarters.py9
-rw-r--r--bot/exts/utilities/emoji.py7
-rw-r--r--bot/exts/utilities/epoch.py13
-rw-r--r--bot/exts/utilities/githubinfo.py25
-rw-r--r--bot/exts/utilities/realpython.py10
-rw-r--r--bot/exts/utilities/reddit.py33
-rw-r--r--bot/exts/utilities/stackoverflow.py6
-rw-r--r--bot/exts/utilities/twemoji.py10
-rw-r--r--bot/exts/utilities/wikipedia.py4
-rw-r--r--bot/exts/utilities/wolfram.py13
-rw-r--r--bot/exts/utilities/wtf_python.py5
15 files changed, 81 insertions, 87 deletions
diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py
index 65a32203..150dfc48 100644
--- a/bot/exts/utilities/bookmark.py
+++ b/bot/exts/utilities/bookmark.py
@@ -1,6 +1,5 @@
import logging
import random
-from typing import Optional
import discord
from discord.ext import commands
@@ -145,15 +144,15 @@ class Bookmark(commands.Cog):
This command allows deleting any message sent by Sir-Lancebot in the user's DM channel with the bot.
The command invocation must be a reply to the message that is to be deleted.
"""
- target_message: Optional[discord.Message] = getattr(ctx.message.reference, "resolved", None)
+ target_message: discord.Message | None = getattr(ctx.message.reference, "resolved", None)
if target_message is None:
raise commands.UserInputError("You must reply to the message from Sir-Lancebot you wish to delete.")
if not isinstance(ctx.channel, discord.DMChannel):
raise commands.UserInputError("You can only run this command your own DMs!")
- elif target_message.channel != ctx.channel:
+ if target_message.channel != ctx.channel:
raise commands.UserInputError("You can only delete messages in your own DMs!")
- elif target_message.author != self.bot.user:
+ if target_message.author != self.bot.user:
raise commands.UserInputError("You can only delete messages sent by Sir Lancebot!")
await target_message.delete()
diff --git a/bot/exts/utilities/challenges.py b/bot/exts/utilities/challenges.py
index 46bc0fae..2f9ac73e 100644
--- a/bot/exts/utilities/challenges.py
+++ b/bot/exts/utilities/challenges.py
@@ -1,7 +1,6 @@
import logging
from asyncio import to_thread
from random import choice
-from typing import Union
from bs4 import BeautifulSoup
from discord import Embed, Interaction, SelectOption, ui
@@ -58,7 +57,7 @@ class InformationDropdown(ui.Select):
SelectOption(
label="Other Information",
description="See how other people performed on this kata and more!",
- emoji="ℹ"
+ emoji="🇮"
)
]
@@ -101,7 +100,7 @@ class Challenges(commands.Cog):
def __init__(self, bot: Bot):
self.bot = bot
- async def kata_id(self, search_link: str, params: dict) -> Union[str, Embed]:
+ async def kata_id(self, search_link: str, params: dict) -> str | Embed:
"""
Uses bs4 to get the HTML code for the page of katas, where the page is the link of the formatted `search_link`.
@@ -123,14 +122,13 @@ class Challenges(commands.Cog):
if not first_kata_div:
raise commands.BadArgument("No katas could be found with the filters provided.")
- else:
- first_kata_div = choice(first_kata_div)
# There are numerous divs before arriving at the id of the kata, which can be used for the link.
+ first_kata_div = choice(first_kata_div)
first_kata_id = first_kata_div.a["href"].split("/")[-1]
return first_kata_id
- async def kata_information(self, kata_id: str) -> Union[dict, Embed]:
+ async def kata_information(self, kata_id: str) -> dict | Embed:
"""
Returns the information about the Kata.
diff --git a/bot/exts/utilities/cheatsheet.py b/bot/exts/utilities/cheatsheet.py
index d7eb4917..98ce3f57 100644
--- a/bot/exts/utilities/cheatsheet.py
+++ b/bot/exts/utilities/cheatsheet.py
@@ -1,6 +1,5 @@
import random
import re
-from typing import Union
from urllib.parse import quote_plus
from discord import Embed
@@ -52,7 +51,7 @@ class CheatSheet(commands.Cog):
)
return embed
- def result_fmt(self, url: str, body_text: str) -> tuple[bool, Union[str, Embed]]:
+ def result_fmt(self, url: str, body_text: str) -> tuple[bool, str | Embed]:
"""Format Result."""
if body_text.startswith("# 404 NOT FOUND"):
embed = self.fmt_error_embed()
diff --git a/bot/exts/utilities/colour.py b/bot/exts/utilities/colour.py
index 20f97e4b..b8f1d62d 100644
--- a/bot/exts/utilities/colour.py
+++ b/bot/exts/utilities/colour.py
@@ -4,7 +4,6 @@ import pathlib
import random
import string
from io import BytesIO
-from typing import Optional
import discord
import rapidfuzz
@@ -25,7 +24,7 @@ class Colour(commands.Cog):
self.bot = bot
with open(pathlib.Path("bot/resources/utilities/ryanzec_colours.json")) as f:
self.colour_mapping = json.load(f)
- del self.colour_mapping['_'] # Delete source credit entry
+ del self.colour_mapping["_"] # Delete source credit entry
async def send_colour_response(self, ctx: commands.Context, rgb: tuple[int, int, int]) -> None:
"""Create and send embed from user given colour information."""
@@ -84,7 +83,7 @@ class Colour(commands.Cog):
roles=constants.STAFF_ROLES,
categories=[constants.Categories.development, constants.Categories.media]
)
- async def colour(self, ctx: commands.Context, *, colour_input: Optional[str] = None) -> None:
+ async def colour(self, ctx: commands.Context, *, colour_input: str | None = None) -> None:
"""
Create an embed that displays colour information.
@@ -209,7 +208,7 @@ class Colour(commands.Cog):
def _rgb_to_hsl(rgb: tuple[int, int, int]) -> tuple[int, int, int]:
"""Convert RGB values to HSL values."""
rgb_list = [val / 255.0 for val in rgb]
- h, l, s = colorsys.rgb_to_hls(*rgb_list)
+ h, l, s = colorsys.rgb_to_hls(*rgb_list) # noqa: E741
hsl = (round(h * 360), round(s * 100), round(l * 100))
return hsl
@@ -233,7 +232,7 @@ class Colour(commands.Cog):
hex_code = f"#{hex_}".upper()
return hex_code
- def _rgb_to_name(self, rgb: tuple[int, int, int]) -> Optional[str]:
+ def _rgb_to_name(self, rgb: tuple[int, int, int]) -> str | None:
"""Convert RGB values to a fuzzy matched name."""
input_hex_colour = self._rgb_to_hex(rgb)
try:
@@ -247,7 +246,7 @@ class Colour(commands.Cog):
colour_name = None
return colour_name
- def match_colour_name(self, ctx: commands.Context, input_colour_name: str) -> Optional[str]:
+ def match_colour_name(self, ctx: commands.Context, input_colour_name: str) -> str | None:
"""Convert a colour name to HEX code."""
try:
match, certainty, _ = rapidfuzz.process.extractOne(
@@ -256,7 +255,7 @@ class Colour(commands.Cog):
score_cutoff=80
)
except (ValueError, TypeError):
- return
+ return None
return f"#{self.colour_mapping[match]}"
diff --git a/bot/exts/utilities/conversationstarters.py b/bot/exts/utilities/conversationstarters.py
index 410ea884..a019c789 100644
--- a/bot/exts/utilities/conversationstarters.py
+++ b/bot/exts/utilities/conversationstarters.py
@@ -2,7 +2,6 @@ import asyncio
from contextlib import suppress
from functools import partial
from pathlib import Path
-from typing import Union
import discord
import yaml
@@ -16,11 +15,11 @@ from bot.utils.randomization import RandomCycle
SUGGESTION_FORM = "https://forms.gle/zw6kkJqv8U43Nfjg9"
with Path("bot/resources/utilities/starter.yaml").open("r", encoding="utf8") as f:
- STARTERS = yaml.load(f, Loader=yaml.FullLoader)
+ STARTERS = yaml.safe_load(f)
with Path("bot/resources/utilities/py_topics.yaml").open("r", encoding="utf8") as f:
# First ID is #python-general and the rest are top to bottom categories of Topical Chat/Help.
- PY_TOPICS = yaml.load(f, Loader=yaml.FullLoader)
+ PY_TOPICS = yaml.safe_load(f)
# Removing `None` from lists of topics, if not a list, it is changed to an empty one.
PY_TOPICS = {k: [i for i in v if i] if isinstance(v, list) else [] for k, v in PY_TOPICS.items()}
@@ -67,7 +66,7 @@ class ConvoStarters(commands.Cog):
@staticmethod
def _predicate(
- command_invoker: Union[discord.User, discord.Member],
+ command_invoker: discord.User | discord.Member,
message: discord.Message,
reaction: discord.Reaction,
user: discord.User
@@ -84,7 +83,7 @@ class ConvoStarters(commands.Cog):
async def _listen_for_refresh(
self,
- command_invoker: Union[discord.User, discord.Member],
+ command_invoker: discord.User | discord.Member,
message: discord.Message
) -> None:
await message.add_reaction("🔄")
diff --git a/bot/exts/utilities/emoji.py b/bot/exts/utilities/emoji.py
index ec40be01..ce352fe2 100644
--- a/bot/exts/utilities/emoji.py
+++ b/bot/exts/utilities/emoji.py
@@ -2,8 +2,7 @@ import logging
import random
import textwrap
from collections import defaultdict
-from datetime import datetime
-from typing import Optional
+from datetime import UTC, datetime
from discord import Color, Embed, Emoji
from discord.ext import commands
@@ -28,7 +27,7 @@ class Emojis(commands.Cog):
embed = Embed(
color=Colours.orange,
title="Emoji Count",
- timestamp=datetime.utcnow()
+ timestamp=datetime.now(tz=UTC)
)
msg = []
@@ -71,7 +70,7 @@ class Emojis(commands.Cog):
return embed, msg
@commands.group(name="emoji", invoke_without_command=True)
- async def emoji_group(self, ctx: commands.Context, emoji: Optional[Emoji]) -> None:
+ async def emoji_group(self, ctx: commands.Context, emoji: Emoji | None) -> None:
"""A group of commands related to emojis."""
if emoji is not None:
await ctx.invoke(self.info_command, emoji)
diff --git a/bot/exts/utilities/epoch.py b/bot/exts/utilities/epoch.py
index 6f572640..d1ba98bb 100644
--- a/bot/exts/utilities/epoch.py
+++ b/bot/exts/utilities/epoch.py
@@ -1,4 +1,5 @@
-from typing import Optional, Union
+
+import contextlib
import arrow
import discord
@@ -24,7 +25,7 @@ DROPDOWN_TIMEOUT = 60
class DateString(commands.Converter):
"""Convert a relative or absolute date/time string to an arrow.Arrow object."""
- async def convert(self, ctx: commands.Context, argument: str) -> Union[arrow.Arrow, Optional[tuple]]:
+ async def convert(self, ctx: commands.Context, argument: str) -> arrow.Arrow | tuple | None:
"""
Convert a relative or absolute date/time string to an arrow.Arrow object.
@@ -88,10 +89,8 @@ class Epoch(commands.Cog):
view = TimestampMenuView(ctx, self._format_dates(date_time), epoch)
original = await ctx.send(f"`{epoch}`", view=view)
await view.wait() # wait until expiration before removing the dropdown
- try:
+ with contextlib.suppress(discord.NotFound):
await original.edit(view=None)
- except discord.NotFound: # disregard the error message if the message is deleled
- pass
@staticmethod
def _format_dates(date: arrow.Arrow) -> list[str]:
@@ -100,7 +99,7 @@ class Epoch(commands.Cog):
These are used in the description of each style in the dropdown
"""
- date = date.to('utc')
+ date = date.to("utc")
formatted = [str(int(date.timestamp()))]
formatted += [date.format(format[1]) for format in list(STYLES.values())[1:7]]
formatted.append(date.humanize())
@@ -115,7 +114,7 @@ class TimestampMenuView(discord.ui.View):
self.ctx = ctx
self.epoch = epoch
self.dropdown: discord.ui.Select = self.children[0]
- for label, date_time in zip(STYLES.keys(), formatted_times):
+ for label, date_time in zip(STYLES.keys(), formatted_times, strict=True):
self.dropdown.add_option(label=label, description=date_time)
@discord.ui.select(placeholder="Select the format of your timestamp")
diff --git a/bot/exts/utilities/githubinfo.py b/bot/exts/utilities/githubinfo.py
index 4e008e9f..74120f2d 100644
--- a/bot/exts/utilities/githubinfo.py
+++ b/bot/exts/utilities/githubinfo.py
@@ -1,9 +1,8 @@
import logging
import random
import re
-import typing as t
from dataclasses import dataclass
-from datetime import datetime
+from datetime import UTC, datetime
from urllib.parse import quote
import discord
@@ -48,7 +47,7 @@ AUTOMATIC_REGEX = re.compile(
class FoundIssue:
"""Dataclass representing an issue found by the regex."""
- organisation: t.Optional[str]
+ organisation: str | None
repository: str
number: str
@@ -89,7 +88,7 @@ class GithubInfo(commands.Cog):
number: int,
repository: str,
user: str
- ) -> t.Union[IssueState, FetchError]:
+ ) -> IssueState | FetchError:
"""
Retrieve an issue from a GitHub repository.
@@ -105,9 +104,9 @@ class GithubInfo(commands.Cog):
log.info(f"Ratelimit reached while fetching {url}")
return FetchError(403, "Ratelimit reached, please retry in a few minutes.")
return FetchError(403, "Cannot access issue.")
- elif r.status in (404, 410):
+ if r.status in (404, 410):
return FetchError(r.status, "Issue not found.")
- elif r.status != 200:
+ if r.status != 200:
return FetchError(r.status, "Error while fetching issue.")
# The initial API request is made to the issues API endpoint, which will return information
@@ -141,7 +140,7 @@ class GithubInfo(commands.Cog):
@staticmethod
def format_embed(
- results: t.List[t.Union[IssueState, FetchError]]
+ results: list[IssueState | FetchError]
) -> discord.Embed:
"""Take a list of IssueState or FetchError and format a Discord embed for them."""
description_list = []
@@ -261,7 +260,7 @@ class GithubInfo(commands.Cog):
description=f"```\n{user_data['bio']}\n```\n" if user_data["bio"] else "",
colour=discord.Colour.og_blurple(),
url=user_data["html_url"],
- timestamp=datetime.strptime(user_data["created_at"], "%Y-%m-%dT%H:%M:%SZ")
+ timestamp=datetime.strptime(user_data["created_at"], "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=UTC)
)
embed.set_thumbnail(url=user_data["avatar_url"])
embed.set_footer(text="Account created at")
@@ -293,7 +292,7 @@ class GithubInfo(commands.Cog):
await ctx.send(embed=embed)
- @github_group.command(name='repository', aliases=('repo',))
+ @github_group.command(name="repository", aliases=("repo",))
async def github_repo_info(self, ctx: commands.Context, *repo: str) -> None:
"""
Fetches a repositories' GitHub information.
@@ -347,8 +346,12 @@ class GithubInfo(commands.Cog):
icon_url=repo_owner["avatar_url"]
)
- repo_created_at = datetime.strptime(repo_data["created_at"], "%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y")
- last_pushed = datetime.strptime(repo_data["pushed_at"], "%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y at %H:%M")
+ repo_created_at = datetime.strptime(
+ repo_data["created_at"], "%Y-%m-%dT%H:%M:%SZ"
+ ).replace(tzinfo=UTC).strftime("%d/%m/%Y")
+ last_pushed = datetime.strptime(
+ repo_data["pushed_at"], "%Y-%m-%dT%H:%M:%SZ"
+ ).replace(tzinfo=UTC).strftime("%d/%m/%Y at %H:%M")
embed.set_footer(
text=(
diff --git a/bot/exts/utilities/realpython.py b/bot/exts/utilities/realpython.py
index 46b02866..c63fca85 100644
--- a/bot/exts/utilities/realpython.py
+++ b/bot/exts/utilities/realpython.py
@@ -1,6 +1,5 @@
import logging
from html import unescape
-from typing import Optional
from urllib.parse import quote_plus
from discord import Embed
@@ -31,8 +30,13 @@ class RealPython(commands.Cog):
@commands.command(aliases=["rp"])
@commands.cooldown(1, 10, commands.cooldowns.BucketType.user)
- async def realpython(self, ctx: commands.Context, amount: Optional[int] = 5, *,
- user_search: Optional[str] = None) -> None:
+ async def realpython(
+ self,
+ ctx: commands.Context,
+ amount: int | None = 5,
+ *,
+ user_search: str | None = None
+ ) -> None:
"""
Send some articles from RealPython that match the search terms.
diff --git a/bot/exts/utilities/reddit.py b/bot/exts/utilities/reddit.py
index f7c196ae..f8e358de 100644
--- a/bot/exts/utilities/reddit.py
+++ b/bot/exts/utilities/reddit.py
@@ -3,8 +3,7 @@ import logging
import random
import textwrap
from collections import namedtuple
-from datetime import datetime, timedelta
-from typing import Union
+from datetime import UTC, datetime, timedelta
from aiohttp import BasicAuth, ClientError
from discord import Colour, Embed, TextChannel
@@ -43,8 +42,8 @@ class Reddit(Cog):
async def cog_unload(self) -> None:
"""Stop the loop task and revoke the access token when the cog is unloaded."""
self.auto_poster_loop.cancel()
- if self.access_token and self.access_token.expires_at > datetime.utcnow():
- asyncio.create_task(self.revoke_access_token())
+ if self.access_token and self.access_token.expires_at > datetime.now(tz=UTC):
+ await self.revoke_access_token()
async def cog_load(self) -> None:
"""Sets the reddit webhook when the cog is loaded."""
@@ -55,7 +54,7 @@ class Reddit(Cog):
"""Get the #reddit channel object from the bot's cache."""
return self.bot.get_channel(Channels.reddit)
- def build_pagination_pages(self, posts: list[dict], paginate: bool) -> Union[list[tuple], str]:
+ def build_pagination_pages(self, posts: list[dict], paginate: bool) -> list[tuple] | str:
"""Build embed pages required for Paginator."""
pages = []
first_page = ""
@@ -138,17 +137,15 @@ class Reddit(Cog):
expiration = int(content["expires_in"]) - 60 # Subtract 1 minute for leeway.
self.access_token = AccessToken(
token=content["access_token"],
- expires_at=datetime.utcnow() + timedelta(seconds=expiration)
+ expires_at=datetime.now(tz=UTC) + timedelta(seconds=expiration)
)
log.debug(f"New token acquired; expires on UTC {self.access_token.expires_at}")
return
- else:
- log.debug(
- f"Failed to get an access token: "
- f"status {response.status} & content type {response.content_type}; "
- f"retrying ({i}/{self.MAX_RETRIES})"
- )
+ log.debug(
+ f"Failed to get an access token: status {response.status} & content type {response.content_type}; "
+ f"retrying ({i}/{self.MAX_RETRIES})"
+ )
await asyncio.sleep(3)
@@ -183,7 +180,7 @@ class Reddit(Cog):
raise ValueError("Invalid amount of subreddit posts requested.")
# Renew the token if necessary.
- if not self.access_token or self.access_token.expires_at < datetime.utcnow():
+ if not self.access_token or self.access_token.expires_at < datetime.now(tz=UTC):
await self.get_access_token()
url = f"{self.OAUTH_URL}/{route}"
@@ -193,7 +190,7 @@ class Reddit(Cog):
headers={**self.HEADERS, "Authorization": f"bearer {self.access_token.token}"},
params=params
)
- if response.status == 200 and response.content_type == 'application/json':
+ if response.status == 200 and response.content_type == "application/json":
# Got appropriate response - process and return.
content = await response.json()
posts = content["data"]["children"]
@@ -205,11 +202,11 @@ class Reddit(Cog):
await asyncio.sleep(3)
log.debug(f"Invalid response from: {url} - status code {response.status}, mimetype {response.content_type}")
- return list() # Failed to get appropriate response within allowed number of retries.
+ return [] # Failed to get appropriate response within allowed number of retries.
async def get_top_posts(
self, subreddit: Subreddit, time: str = "all", amount: int = 5, paginate: bool = False
- ) -> Union[Embed, list[tuple]]:
+ ) -> Embed | list[tuple]:
"""
Get the top amount of posts for a given subreddit within a specified timeframe.
@@ -248,7 +245,7 @@ class Reddit(Cog):
"""Post the top 5 posts daily, and the top 5 posts weekly."""
# once d.py get support for `time` parameter in loop decorator,
# this can be removed and the loop can use the `time=datetime.time.min` parameter
- now = datetime.utcnow()
+ now = datetime.now(tz=UTC)
tomorrow = now + timedelta(days=1)
midnight_tomorrow = tomorrow.replace(hour=0, minute=0, second=0)
@@ -257,7 +254,7 @@ class Reddit(Cog):
if not self.webhook:
await self.bot.fetch_webhook(RedditConfig.webhook)
- if datetime.utcnow().weekday() == 0:
+ if datetime.now(tz=UTC).weekday() == 0:
await self.top_weekly_posts()
# if it's a monday send the top weekly posts
diff --git a/bot/exts/utilities/stackoverflow.py b/bot/exts/utilities/stackoverflow.py
index b248e83f..1eeff45b 100644
--- a/bot/exts/utilities/stackoverflow.py
+++ b/bot/exts/utilities/stackoverflow.py
@@ -42,10 +42,10 @@ class Stackoverflow(commands.Cog):
if response.status == 200:
data = await response.json()
else:
- logger.error(f'Status code is not 200, it is {response.status}')
+ logger.error(f"Status code is not 200, it is {response.status}")
await ctx.send(embed=ERR_EMBED)
return
- if not data['items']:
+ if not data["items"]:
no_search_result = Embed(
title=f"No search results found for {search_query}",
color=Colours.soft_red
@@ -63,7 +63,7 @@ class Stackoverflow(commands.Cog):
)
for item in top5:
embed.add_field(
- name=unescape(item['title']),
+ name=unescape(item["title"]),
value=(
f"[{Emojis.reddit_upvote} {item['score']} "
f"{Emojis.stackoverflow_views} {item['view_count']} "
diff --git a/bot/exts/utilities/twemoji.py b/bot/exts/utilities/twemoji.py
index 25a03d25..a936f733 100644
--- a/bot/exts/utilities/twemoji.py
+++ b/bot/exts/utilities/twemoji.py
@@ -1,6 +1,6 @@
import logging
import re
-from typing import Literal, Optional
+from typing import Literal
import discord
from discord.ext import commands
@@ -57,7 +57,7 @@ class Twemoji(commands.Cog):
return embed
@staticmethod
- def emoji(codepoint: Optional[str]) -> Optional[str]:
+ def emoji(codepoint: str | None) -> str | None:
"""
Returns the emoji corresponding to a given `codepoint`, or `None` if no emoji was found.
@@ -66,9 +66,10 @@ class Twemoji(commands.Cog):
"""
if code := Twemoji.trim_code(codepoint):
return chr(int(code, 16))
+ return None
@staticmethod
- def codepoint(emoji: Optional[str]) -> Optional[str]:
+ def codepoint(emoji: str | None) -> str | None:
"""
Returns the codepoint, in a trimmed format, of a single emoji.
@@ -82,7 +83,7 @@ class Twemoji(commands.Cog):
return hex(ord(emoji)).removeprefix("0x")
@staticmethod
- def trim_code(codepoint: Optional[str]) -> Optional[str]:
+ def trim_code(codepoint: str | None) -> str | None:
"""
Returns the meaningful information from the given `codepoint`.
@@ -98,6 +99,7 @@ class Twemoji(commands.Cog):
"""
if code := CODEPOINT_REGEX.search(codepoint or ""):
return code.group()
+ return None
@staticmethod
def codepoint_from_input(raw_emoji: tuple[str, ...]) -> str:
diff --git a/bot/exts/utilities/wikipedia.py b/bot/exts/utilities/wikipedia.py
index d87982c9..d12cb19d 100644
--- a/bot/exts/utilities/wikipedia.py
+++ b/bot/exts/utilities/wikipedia.py
@@ -1,6 +1,6 @@
import logging
import re
-from datetime import datetime
+from datetime import UTC, datetime
from html import unescape
from discord import Color, Embed, TextChannel
@@ -85,7 +85,7 @@ class WikipediaSearch(commands.Cog):
colour=Color.og_blurple()
)
embed.set_thumbnail(url=WIKI_THUMBNAIL)
- embed.timestamp = datetime.utcnow()
+ embed.timestamp = datetime.now(tz=UTC)
await LinePaginator.paginate(contents, ctx, embed, restrict_to_user=ctx.author)
else:
await ctx.send(
diff --git a/bot/exts/utilities/wolfram.py b/bot/exts/utilities/wolfram.py
index 21029d47..d5669c6b 100644
--- a/bot/exts/utilities/wolfram.py
+++ b/bot/exts/utilities/wolfram.py
@@ -1,6 +1,6 @@
import logging
+from collections.abc import Callable
from io import BytesIO
-from typing import Callable, Optional
from urllib.parse import urlencode
import arrow
@@ -64,10 +64,10 @@ def custom_cooldown(*ignore: int) -> Callable:
if ctx.invoked_with == "help":
# if the invoked command is help we don't want to increase the ratelimits since it's not actually
# invoking the command/making a request, so instead just check if the user/guild are on cooldown.
- guild_cooldown = not guildcd.get_bucket(ctx.message).get_tokens() == 0 # if guild is on cooldown
+ guild_cooldown = guildcd.get_bucket(ctx.message).get_tokens() != 0 # if guild is on cooldown
# check the message is in a guild, and check user bucket if user is not ignored
if ctx.guild and not any(r.id in ignore for r in ctx.author.roles):
- return guild_cooldown and not usercd.get_bucket(ctx.message).get_tokens() == 0
+ return guild_cooldown and usercd.get_bucket(ctx.message).get_tokens() != 0
return guild_cooldown
user_bucket = usercd.get_bucket(ctx.message)
@@ -105,7 +105,7 @@ def custom_cooldown(*ignore: int) -> Callable:
return check(predicate)
-async def get_pod_pages(ctx: Context, bot: Bot, query: str) -> Optional[list[tuple[str, str]]]:
+async def get_pod_pages(ctx: Context, bot: Bot, query: str) -> list[tuple[str, str]] | None:
"""Get the Wolfram API pod pages for the provided query."""
async with ctx.typing():
params = {
@@ -253,10 +253,7 @@ class Wolfram(Cog):
if not pages:
return
- if len(pages) >= 2:
- page = pages[1]
- else:
- page = pages[0]
+ page = pages[1] if len(pages) >= 2 else pages[0]
await send_embed(ctx, page[0], colour=Colours.soft_orange, img_url=page[1])
diff --git a/bot/exts/utilities/wtf_python.py b/bot/exts/utilities/wtf_python.py
index 0c0375cb..29a9611c 100644
--- a/bot/exts/utilities/wtf_python.py
+++ b/bot/exts/utilities/wtf_python.py
@@ -1,7 +1,6 @@
import logging
import random
import re
-from typing import Optional
import rapidfuzz
from discord import Embed, File
@@ -67,7 +66,7 @@ class WTFPython(commands.Cog):
hyper_link = match[0].split("(")[1].replace(")", "")
self.headers[match[0]] = f"{BASE_URL}/{hyper_link}"
- def fuzzy_match_header(self, query: str) -> Optional[str]:
+ def fuzzy_match_header(self, query: str) -> str | None:
"""
Returns the fuzzy match of a query if its ratio is above "MINIMUM_CERTAINTY" else returns None.
@@ -79,7 +78,7 @@ class WTFPython(commands.Cog):
return match if certainty > MINIMUM_CERTAINTY else None
@commands.command(aliases=("wtf",))
- async def wtf_python(self, ctx: commands.Context, *, query: Optional[str] = None) -> None:
+ async def wtf_python(self, ctx: commands.Context, *, query: str | None = None) -> None:
"""
Search WTF Python repository.