diff options
author | 2024-07-13 07:46:36 +0100 | |
---|---|---|
committer | 2024-07-13 07:46:36 +0100 | |
commit | 535c54b1b90f756c103e32590524df6d66e2647c (patch) | |
tree | ed670d7313bed75044d18d6e7ed572645bee3f19 | |
parent | Merge pull request #236 from python-discord/set-user-agent-explicitly (diff) | |
parent | add programming quotes command (diff) |
Merge pull request #235 from python-discord/quotes
Add a quotes command
-rw-r--r-- | arthur/exts/fun/quotes.py | 67 | ||||
-rw-r--r-- | poetry.lock | 41 | ||||
-rw-r--r-- | pyproject.toml | 1 |
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" |