aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Amrou Bellalouna <[email protected]>2024-07-13 07:46:36 +0100
committerGravatar GitHub <[email protected]>2024-07-13 07:46:36 +0100
commit535c54b1b90f756c103e32590524df6d66e2647c (patch)
treeed670d7313bed75044d18d6e7ed572645bee3f19
parentMerge pull request #236 from python-discord/set-user-agent-explicitly (diff)
parentadd programming quotes command (diff)
Merge pull request #235 from python-discord/quotes
Add a quotes command
-rw-r--r--arthur/exts/fun/quotes.py67
-rw-r--r--poetry.lock41
-rw-r--r--pyproject.toml1
3 files changed, 104 insertions, 5 deletions
diff --git a/arthur/exts/fun/quotes.py b/arthur/exts/fun/quotes.py
new file mode 100644
index 0000000..1673117
--- /dev/null
+++ b/arthur/exts/fun/quotes.py
@@ -0,0 +1,67 @@
+import random
+from typing import NamedTuple
+
+import aiohttp
+from bs4 import BeautifulSoup
+from discord.ext import commands
+
+from arthur import KingArthur
+from arthur.log import logger
+
+
+class Quote(NamedTuple):
+ """A data structure to hold quotes and their source."""
+
+ text: str
+ source: str | None
+
+ def __str__(self):
+ return f"{self.text}\n-- {self.source}"
+
+
+class QuotesCog(commands.Cog):
+ """A cog that sends programming quotes."""
+
+ def __init__(self, bot: KingArthur) -> None:
+ self.bot = bot
+ self.quotes = []
+
+ async def cog_load(self) -> None:
+ """Fetch the quotes to be used."""
+ try:
+ async with self.bot.http_session.get(
+ "http://quotes.cat-v.org/programming/"
+ ) as response:
+ content = await response.content.read()
+ except aiohttp.ClientResponseError:
+ logger.exception("Couldn't fetch programming quotes.")
+ return
+
+ soup = BeautifulSoup(content, "html.parser")
+ prev_text = None
+
+ for item in soup.article.find_all("p"):
+ text = item.get_text().replace("\xa0", "")
+
+ if prev_text is not None:
+ if text.startswith("—"):
+ self.quotes.append(Quote(text=prev_text, source=text.removeprefix("— ")))
+ elif not prev_text.startswith("—"):
+ self.quotes.append(Quote(text=prev_text, source=None))
+
+ prev_text = text
+
+ @commands.command(name="quote")
+ async def quote(self, ctx: commands.Context) -> None:
+ """Send a random programming quote."""
+ if not self.quotes:
+ await ctx.reply(":x: Couldn't fetch quotes, try reloading the cog.")
+ return
+
+ quote = random.choice(self.quotes)
+ await ctx.reply(str(quote))
+
+
+async def setup(bot: KingArthur) -> None:
+ """Load the QuotesCog."""
+ await bot.add_cog(QuotesCog(bot))
diff --git a/poetry.lock b/poetry.lock
index 6c8b0af..0a97609 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -169,6 +169,27 @@ tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
[[package]]
+name = "beautifulsoup4"
+version = "4.12.3"
+description = "Screen-scraping library"
+optional = false
+python-versions = ">=3.6.0"
+files = [
+ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"},
+ {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"},
+]
+
+[package.dependencies]
+soupsieve = ">1.2"
+
+[package.extras]
+cchardet = ["cchardet"]
+chardet = ["chardet"]
+charset-normalizer = ["charset-normalizer"]
+html5lib = ["html5lib"]
+lxml = ["lxml"]
+
+[[package]]
name = "braceexpand"
version = "0.1.7"
description = "Bash-style brace expansion for Python"
@@ -439,13 +460,13 @@ tests = ["freezegun", "pytest", "pytest-cov"]
[[package]]
name = "identify"
-version = "2.5.36"
+version = "2.6.0"
description = "File identification library for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"},
- {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"},
+ {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"},
+ {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"},
]
[package.extras]
@@ -1015,7 +1036,6 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
@@ -1139,6 +1159,17 @@ files = [
]
[[package]]
+name = "soupsieve"
+version = "2.5"
+description = "A modern CSS selector implementation for Beautiful Soup."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"},
+ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"},
+]
+
+[[package]]
name = "statsd"
version = "4.0.1"
description = "A simple statsd client."
@@ -1402,4 +1433,4 @@ multidict = ">=4.0"
[metadata]
lock-version = "2.0"
python-versions = "3.12.*"
-content-hash = "db9d27092767c531fb846b64b810c7358d13e19e9c458ef13d0528bb96616c66"
+content-hash = "c71dc35a49ca14e28875227d2b86c1f25b5ed96290a6ca1a3c40a4d8695b5d90"
diff --git a/pyproject.toml b/pyproject.toml
index 36d9a31..9b9d7b7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -12,6 +12,7 @@ python = "3.12.*"
# See https://bot-core.pythondiscord.com/ for docs.
pydis-core = "11.2.0"
+beautifulsoup4 = "4.12.3"
pydantic = "2.8.2"
pydantic-settings = "2.3.4"
loguru = "0.7.2"