mirror of https://github.com/stijndcl/didier
commit
21aa118ffa
2
.flake8
2
.flake8
|
@ -32,7 +32,7 @@ max-line-length = 120
|
||||||
# Disable some rules for entire files
|
# Disable some rules for entire files
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
# DALL000: Missing __all__, main isn't supposed to be imported
|
# DALL000: Missing __all__, main isn't supposed to be imported
|
||||||
main.py: DALL000,
|
main.py: DALL000, run_db_scripts.py: DALL000,
|
||||||
# DALL000: Missing __all__, Cogs aren't modules
|
# DALL000: Missing __all__, Cogs aren't modules
|
||||||
./didier/cogs/*: DALL000,
|
./didier/cogs/*: DALL000,
|
||||||
# DALL000: Missing __all__, tests aren't supposed to be imported
|
# DALL000: Missing __all__, tests aren't supposed to be imported
|
||||||
|
|
|
@ -9,6 +9,7 @@ from database.crud.dad_jokes import get_random_dad_joke
|
||||||
from database.crud.memes import get_all_memes, get_meme_by_name
|
from database.crud.memes import get_all_memes, get_meme_by_name
|
||||||
from didier import Didier
|
from didier import Didier
|
||||||
from didier.data.apis.imgflip import generate_meme
|
from didier.data.apis.imgflip import generate_meme
|
||||||
|
from didier.data.apis.xkcd import fetch_xkcd_post
|
||||||
from didier.exceptions.no_match import expect
|
from didier.exceptions.no_match import expect
|
||||||
from didier.menus.memes import MemeSource
|
from didier.menus.memes import MemeSource
|
||||||
from didier.utils.discord import constants
|
from didier.utils.discord import constants
|
||||||
|
@ -132,6 +133,18 @@ class Fun(commands.Cog):
|
||||||
"""Autocompletion for the 'template'-parameter"""
|
"""Autocompletion for the 'template'-parameter"""
|
||||||
return self.client.database_caches.memes.get_autocomplete_suggestions(current)
|
return self.client.database_caches.memes.get_autocomplete_suggestions(current)
|
||||||
|
|
||||||
|
@commands.hybrid_command(name="xkcd")
|
||||||
|
@app_commands.rename(comic_id="id")
|
||||||
|
async def xkcd(self, ctx: commands.Context, comic_id: Optional[int] = None):
|
||||||
|
"""Fetch comic `#id` from xkcd.
|
||||||
|
|
||||||
|
If no argument to `id` is passed, this fetches today's comic instead.
|
||||||
|
"""
|
||||||
|
async with ctx.typing():
|
||||||
|
post = await fetch_xkcd_post(self.client.http_session, num=comic_id)
|
||||||
|
|
||||||
|
await ctx.reply(embed=post.to_embed(), mention_author=False, ephemeral=False)
|
||||||
|
|
||||||
|
|
||||||
async def setup(client: Didier):
|
async def setup(client: Didier):
|
||||||
"""Load the cog"""
|
"""Load the cog"""
|
||||||
|
|
|
@ -38,7 +38,9 @@ class School(commands.Cog):
|
||||||
|
|
||||||
@commands.hybrid_command(name="les", aliases=["sched", "schedule"])
|
@commands.hybrid_command(name="les", aliases=["sched", "schedule"])
|
||||||
@app_commands.rename(day_dt="date")
|
@app_commands.rename(day_dt="date")
|
||||||
async def les(self, ctx: commands.Context, day_dt: Optional[app_commands.Transform[date, DateTransformer]] = None):
|
async def les(
|
||||||
|
self, ctx: commands.Context, *, day_dt: Optional[app_commands.Transform[date, DateTransformer]] = None
|
||||||
|
):
|
||||||
"""Show your personalized schedule for a given day.
|
"""Show your personalized schedule for a given day.
|
||||||
|
|
||||||
If no day is provided, this defaults to the schedule for the current day. When invoked during a weekend,
|
If no day is provided, this defaults to the schedule for the current day. When invoked during a weekend,
|
||||||
|
@ -71,7 +73,9 @@ class School(commands.Cog):
|
||||||
aliases=["eten", "food"],
|
aliases=["eten", "food"],
|
||||||
)
|
)
|
||||||
@app_commands.rename(day_dt="date")
|
@app_commands.rename(day_dt="date")
|
||||||
async def menu(self, ctx: commands.Context, day_dt: Optional[app_commands.Transform[date, DateTransformer]] = None):
|
async def menu(
|
||||||
|
self, ctx: commands.Context, *, day_dt: Optional[app_commands.Transform[date, DateTransformer]] = None
|
||||||
|
):
|
||||||
"""Show the menu in the Ghent University restaurants on `date`.
|
"""Show the menu in the Ghent University restaurants on `date`.
|
||||||
|
|
||||||
If no value for `date` is provided, this defaults to the schedule for the current day.
|
If no value for `date` is provided, this defaults to the schedule for the current day.
|
||||||
|
@ -116,10 +120,22 @@ class School(commands.Cog):
|
||||||
mention_author=False,
|
mention_author=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@commands.hybrid_command(name="ufora")
|
||||||
|
async def ufora(self, ctx: commands.Context, course: str):
|
||||||
|
"""Link the Ufora page for a course."""
|
||||||
|
async with self.client.postgres_session as session:
|
||||||
|
ufora_course = await ufora_courses.get_course_by_name(session, course)
|
||||||
|
|
||||||
|
if ufora_course is None:
|
||||||
|
return await ctx.reply(f"Found no course matching `{course}`", ephemeral=True)
|
||||||
|
|
||||||
|
return await ctx.reply(
|
||||||
|
f"https://ufora.ugent.be/d2l/le/content/{ufora_course.course_id}/home", mention_author=False
|
||||||
|
)
|
||||||
|
|
||||||
@study_guide.autocomplete("course")
|
@study_guide.autocomplete("course")
|
||||||
async def _study_guide_course_autocomplete(
|
@ufora.autocomplete("course")
|
||||||
self, _: discord.Interaction, current: str
|
async def _course_autocomplete(self, _: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
|
||||||
) -> list[app_commands.Choice[str]]:
|
|
||||||
"""Autocompletion for the 'course'-parameter"""
|
"""Autocompletion for the 'course'-parameter"""
|
||||||
return self.client.database_caches.ufora_courses.get_autocomplete_suggestions(current)
|
return self.client.database_caches.ufora_courses.get_autocomplete_suggestions(current)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from aiohttp import ClientSession
|
||||||
|
|
||||||
|
from didier.data.embeds.xkcd import XKCDPost
|
||||||
|
from didier.utils.http.requests import ensure_get
|
||||||
|
|
||||||
|
__all__ = ["fetch_xkcd_post"]
|
||||||
|
|
||||||
|
|
||||||
|
async def fetch_xkcd_post(http_session: ClientSession, *, num: Optional[int] = None) -> XKCDPost:
|
||||||
|
"""Fetch a post from xkcd.com"""
|
||||||
|
url = "https://xkcd.com" + (f"/{num}" if num is not None else "") + "/info.0.json"
|
||||||
|
|
||||||
|
async with ensure_get(http_session, url) as response:
|
||||||
|
return XKCDPost.parse_obj(response)
|
|
@ -0,0 +1,28 @@
|
||||||
|
import discord
|
||||||
|
from overrides import overrides
|
||||||
|
|
||||||
|
from didier.data.embeds.base import EmbedPydantic
|
||||||
|
from didier.utils.discord.colours import xkcd_blue
|
||||||
|
|
||||||
|
__all__ = ["XKCDPost"]
|
||||||
|
|
||||||
|
|
||||||
|
class XKCDPost(EmbedPydantic):
|
||||||
|
"""A post from xkcd.com"""
|
||||||
|
|
||||||
|
num: int
|
||||||
|
img: str
|
||||||
|
safe_title: str
|
||||||
|
day: int
|
||||||
|
month: int
|
||||||
|
year: int
|
||||||
|
|
||||||
|
@overrides
|
||||||
|
def to_embed(self, **kwargs) -> discord.Embed:
|
||||||
|
embed = discord.Embed(colour=xkcd_blue(), title=self.safe_title)
|
||||||
|
|
||||||
|
embed.set_author(name=f"XKCD #{self.num}")
|
||||||
|
embed.set_image(url=self.img)
|
||||||
|
embed.set_footer(text=f"Published {self.day:02d}/{self.month:02d}/{self.year}")
|
||||||
|
|
||||||
|
return embed
|
|
@ -9,6 +9,7 @@ __all__ = [
|
||||||
"google_blue",
|
"google_blue",
|
||||||
"steam_blue",
|
"steam_blue",
|
||||||
"urban_dictionary_green",
|
"urban_dictionary_green",
|
||||||
|
"xkcd_blue",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,3 +47,7 @@ def steam_blue() -> discord.Colour:
|
||||||
|
|
||||||
def urban_dictionary_green() -> discord.Colour:
|
def urban_dictionary_green() -> discord.Colour:
|
||||||
return discord.Colour.from_rgb(220, 255, 0)
|
return discord.Colour.from_rgb(220, 255, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def xkcd_blue() -> discord.Colour:
|
||||||
|
return discord.Colour.from_rgb(150, 168, 200)
|
||||||
|
|
|
@ -8,7 +8,9 @@ import importlib
|
||||||
import sys
|
import sys
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
async def main():
|
||||||
|
"""Try to parse all command-line arguments into modules and run them sequentially"""
|
||||||
scripts = sys.argv[1:]
|
scripts = sys.argv[1:]
|
||||||
if not scripts:
|
if not scripts:
|
||||||
print("No scripts provided.", file=sys.stderr)
|
print("No scripts provided.", file=sys.stderr)
|
||||||
|
@ -20,8 +22,12 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
try:
|
try:
|
||||||
script_main: Callable = module.main
|
script_main: Callable = module.main
|
||||||
asyncio.run(script_main())
|
await script_main()
|
||||||
print(f"Successfully ran {script}")
|
print(f"Successfully ran {script}")
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
print(f'Script "{script}" not found.', file=sys.stderr)
|
print(f'Script "{script}" not found.', file=sys.stderr)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
|
|
Loading…
Reference in New Issue