Skip to content

Commit

Permalink
most of the misc cog
Browse files Browse the repository at this point in the history
  • Loading branch information
SlimShadyIAm committed Mar 22, 2022
1 parent 7bf52a4 commit 3c8a6be
Show file tree
Hide file tree
Showing 12 changed files with 505 additions and 35 deletions.
366 changes: 366 additions & 0 deletions cogs/commands/misc/misc.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions emojis.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"cogs.commands.info.userinfo",
"cogs.commands.misc.admin",
"cogs.commands.misc.genius",
"cogs.commands.misc.misc",
"cogs.monitors.logging",
"cogs.monitors.xp",
]
16 changes: 8 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from discord.ext import commands
from discord.app_commands import AppCommandError, Command, ContextMenu, CommandInvokeError
from extensions import initial_extensions
from utils import cfg, db, logger, BlooContext, IssueCache
from utils.framework import PermissionsFailure
from utils import cfg, db, logger, BlooContext, IssueCache, Tasks
from utils.cache import RuleCache
from utils.framework import PermissionsFailure, gatekeeper

from typing import Union

Expand All @@ -27,20 +28,18 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.issue_cache = IssueCache(self)

# TODO: tasks
# self.tasks = Tasks(self)
self.rule_cache = RuleCache(self)

# force the config object and database connection to be loaded
# TODO: permissions
# if cfg and db and permissions:
if cfg and db:
if cfg and db and gatekeeper:
logger.info("Presetup phase completed! Connecting to Discord...")

async def setup_hook(self):
for extension in initial_extensions:
await self.load_extension(extension)

self.tasks = Tasks(self)

bot = Bot(command_prefix='!', intents=intents, allowed_mentions=mentions)


Expand Down Expand Up @@ -92,6 +91,7 @@ async def on_ready():
logger.info(f'Successfully logged in and booted...!')

await bot.issue_cache.fetch_issue_cache()
await bot.rule_cache.fetch_rule_cache()


async def main():
Expand Down
41 changes: 24 additions & 17 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
APScheduler==3.8.1
aiocache==0.11.1
aiohttp==3.8.1
aiosignal==1.2.0
APScheduler==3.9.1
async-timeout==4.0.2
attrs==21.4.0
autopep8==1.6.0
charset-normalizer==2.0.12
aiofiles==0.8.0
aiohttp==3.7.4.post0
async-timeout==3.0.1
attrs==21.2.0
chardet==4.0.0
e==1.4.5
expiringdict==1.2.1
fold-to-ascii==1.0.2.post1
git+https://github.com/Rapptz/discord.py@4dc24a0
fold_to_ascii==1.0.2.post1
frozenlist==1.3.0
humanfriendly==10.0
humanize==3.12.0
idna==3.3
mongoengine==0.24.0
multidict==6.0.2
psutil==5.9.0
pycodestyle==2.8.0
pymongo==4.0
python-dotenv==0.19.2
markovify==0.9.3
mongoengine==0.23.1
multidict==5.2.0
psutil==5.8.0
pymongo[srv]==3.12.1
pytimeparse==1.1.8
python-dotenv==0.19.1
pytz==2021.3
pytz-deprecation-shim==0.1.0.post0
radium==1.0.2
six==1.16.0
toml==0.10.2
typing-extensions==3.10.0.2
yarl==1.7.0
colorthief==0.2.1
tzdata==2021.5
tzlocal==4.1
yarl==1.7.2
bs4==0.0.1
ujson==4.2.0
msgpack==1.0.2
2 changes: 1 addition & 1 deletion utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
from .database import *
from .logging import *
from .cache import *
# from .tasks import *
from .jobs import *
23 changes: 23 additions & 0 deletions utils/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,26 @@ async def fetch_issue_cache(self):
self.cache[f"{embed.title}"] = message
else:
continue

class RuleCache():
def __init__(self, bot):
self.bot = bot
self.cache = {}

async def fetch_rule_cache(self):
guild: discord.TextChannel = self.bot.get_guild(cfg.guild_id)
if not guild:
return

channel = guild.get_channel(
guild_service.get_guild().channel_rules)
if channel is None:
logger.warn("#rules-and-info channel not found! The /rule command will not work! Make sure to set `channel_rules` in the database if you want it.")
return

async for message in channel.history(limit=None, oldest_first=True):
if not message.embeds:
continue

for embed in message.embeds:
self.cache[f"{embed.title}"] = embed
28 changes: 20 additions & 8 deletions utils/context.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import asyncio
import functools
from typing import Optional

import discord

from .jobs import Tasks


def transform_context(func: discord.app_commands.Command):
@functools.wraps(func)
Expand Down Expand Up @@ -61,6 +64,10 @@ def me(self):
def send(self):
return self.interaction.channel.send

@property
def tasks(self) -> Tasks:
return self.bot.tasks

async def respond_or_edit(self, *args, **kwargs):
"""Respond to an interaction if not already responded, otherwise edit the original response.
Takes in the same args and kwargs as `respond`.
Expand All @@ -70,7 +77,9 @@ async def respond_or_edit(self, *args, **kwargs):
if kwargs.get("followup") or self.interaction.message is None:
if kwargs.get("view") is None:
kwargs["view"] = discord.utils.MISSING
del kwargs["followup"]

if "followup" in kwargs:
del kwargs["followup"]

delete_after = kwargs.get("delete_after")
if "delete_after" in kwargs:
Expand All @@ -92,7 +101,7 @@ async def respond_or_edit(self, *args, **kwargs):
else:
if "followup" in kwargs:
del kwargs["followup"]

delete_after = kwargs.get("delete_after")
if "delete_after" in kwargs:
del kwargs["delete_after"]
Expand All @@ -111,7 +120,7 @@ async def send_followup(self, *args, **kwargs):
if not kwargs.get("ephemeral") and delete_after is not None:
await response.delete(delay=delete_after)

async def send_success(self, description: str, title:Optional[str] = None, delete_after: Optional[float] = None, followup: Optional[bool] = None):
async def send_success(self, description: str, title: Optional[str] = None, delete_after: Optional[float] = None, followup: Optional[bool] = None):
"""Send an embed response with green color to an interaction.
Parameters
Expand All @@ -126,10 +135,11 @@ async def send_success(self, description: str, title:Optional[str] = None, delet
Whether to send this as a followup to the original response, by default None
"""

embed = discord.Embed(title=title, description=description, color=discord.Color.dark_green())
embed = discord.Embed(
title=title, description=description, color=discord.Color.dark_green())
return await self.respond_or_edit(content="", embed=embed, ephemeral=self.whisper, view=discord.utils.MISSING, delete_after=delete_after, followup=followup)

async def send_warning(self, description: str, title:Optional[str] = None, delete_after: Optional[float] = None, followup: Optional[bool] = None):
async def send_warning(self, description: str, title: Optional[str] = None, delete_after: Optional[float] = None, followup: Optional[bool] = None):
"""Send an embed response with orange color to an interaction.
Parameters
Expand All @@ -144,10 +154,11 @@ async def send_warning(self, description: str, title:Optional[str] = None, delet
Whether to send this as a followup to the original response, by default None
"""

embed = discord.Embed(title=title, description=description, color=discord.Color.orange())
embed = discord.Embed(
title=title, description=description, color=discord.Color.orange())
return await self.respond_or_edit(content="", embed=embed, ephemeral=self.whisper, view=discord.utils.MISSING, delete_after=delete_after, followup=followup)

async def send_error(self, description: str, title:Optional[str] = ":(\nYour command ran into a problem", delete_after: Optional[float] = None, followup: Optional[bool] = None, whisper: Optional[bool] = False):
async def send_error(self, description: str, title: Optional[str] = ":(\nYour command ran into a problem", delete_after: Optional[float] = None, followup: Optional[bool] = None, whisper: Optional[bool] = False):
"""Send an embed response with red color to an interaction.
Parameters
Expand All @@ -162,5 +173,6 @@ async def send_error(self, description: str, title:Optional[str] = ":(\nYour com
Whether to send this as a followup to the original response, by default None
"""

embed = discord.Embed(title=title, description=description, color=discord.Color.red())
embed = discord.Embed(
title=title, description=description, color=discord.Color.red())
return await self.respond_or_edit(content="", embed=embed, ephemeral=self.whisper or whisper, view=discord.utils.MISSING, delete_after=delete_after, followup=followup)
2 changes: 1 addition & 1 deletion utils/tasks.py → utils/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,4 +377,4 @@ async def end_giveaway(channel_id: int, message_id: int, winners: int) -> None:
if winners == 1:
await channel.send(f"Congratulations {mentions[0]}! You won the giveaway of **{g.name}**! Please DM or contact <@{g.sponsor}> to collect.")
else:
await channel.send(f"Congratulations {', '.join(mentions)}! You won the giveaway of **{g.name}**! Please DM or contact <@{g.sponsor}> to collect.")
await channel.send(f"Congratulations {', '.join(mentions)}! You won the giveaway of **{g.name}**! Please DM or contact <@{g.sponsor}> to collect.")
1 change: 1 addition & 0 deletions utils/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .autocompleters import *
from .confirm import *
from .menu import *
from .misc import *
from .modals.commonissue import *
from .modals.prompt import *
from .modals.tag import *
10 changes: 10 additions & 0 deletions utils/views/autocompleters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from itertools import groupby
import re
from typing import List

import aiohttp
Expand Down Expand Up @@ -111,7 +112,16 @@ async def device_autocomplete(_: discord.Interaction, current: str) -> List[app_

return [app_commands.Choice(name=device.get('name'), value=device.get("devices")[0] if device.get("devices") else device.get("name")) for device in devices][:25]


async def issue_autocomplete(interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
issue_titles = [issue for issue in interaction.client.issue_cache.cache]
issue_titles.sort(key=lambda issue: issue.lower())
return [app_commands.Choice(name=issue_title, value=issue_title) for issue_title in issue_titles if current.lower() in issue_title.lower()][:25]


async def rule_autocomplete(interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
rule_titles = [(issue_title, issue.description) for issue_title, issue in interaction.client.rule_cache.cache.items()]
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key[0])]
rule_titles.sort(key=alphanum_key)
return [app_commands.Choice(name=f"{title} - {description}"[:100], value=title) for title, description in rule_titles if current.lower() in title.lower() or current.lower() in description.lower()][:25]
49 changes: 49 additions & 0 deletions utils/views/misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import discord

from utils import BlooContext


class PFPView(discord.ui.View):
def __init__(self, ctx: BlooContext, embed=discord.Embed):
super().__init__(timeout=3)
self.embed = embed
self.ctx = ctx

async def on_timeout(self):
for child in self.children:
child.disabled = True
await self.ctx.respond_or_edit(embed=self.embed, view=self)


class PFPButton(discord.ui.Button):
def __init__(self, ctx: BlooContext, member: discord.Member):
super().__init__(label="Show other avatar", style=discord.ButtonStyle.primary)
self.ctx = ctx
self.member = member
self.other = False

async def callback(self, interaction: discord.Interaction):
if interaction.user != self.ctx.author:
return
if not self.other:
avatar = self.member.guild_avatar
self.other = not self.other
else:
avatar = self.member.avatar or self.member.default_avatar
self.other = not self.other

embed = interaction.message.embeds[0]
embed.set_image(url=avatar.replace(size=4096))

animated = ["gif", "png", "jpeg", "webp"]
not_animated = ["png", "jpeg", "webp"]

def fmt(format_):
return f"[{format_}]({avatar.replace(format=format_, size=4096)})"

if avatar.is_animated():
embed.description = f"View As\n {' '.join([fmt(format_) for format_ in animated])}"
else:
embed.description = f"View As\n {' '.join([fmt(format_) for format_ in not_animated])}"

await interaction.response.edit_message(embed=embed)

0 comments on commit 3c8a6be

Please sign in to comment.