-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Restructure `Triggered` according to SFUAnime/Ren#608. No functional changes. - Remove redundant imports. - Remove redundant constant `AVATAR_URL`. - Sort imports in this order: standard library imports, third-party imports, upstream (`redbot`) imports, and lastly, our code. - Rework enum `Modes` by making it an `Enum`-derived class.
- Loading branch information
1 parent
917fb70
commit d7cbb4b
Showing
4 changed files
with
147 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import discord | ||
|
||
from redbot.core import commands | ||
from redbot.core.commands import Context | ||
|
||
from .commandsCore import CommandsCore | ||
|
||
|
||
class CommandHandlers(CommandsCore): | ||
@commands.hybrid_command(name="triggered") | ||
async def _cmdTriggered(self, ctx: Context, user: discord.Member = None): | ||
await self.cmdTriggered(ctx=ctx, user=user) | ||
|
||
@commands.hybrid_command(name="reallytriggered") | ||
async def _cmdHypertriggered(self, ctx: Context, user: discord.Member = None): | ||
await self.cmdHypertriggered(ctx=ctx, user=user) | ||
|
||
@commands.hybrid_command(name="hypertriggered") | ||
async def _cmdDeepfry(self, ctx: Context, user: discord.Member = None): | ||
await self.cmdDeepfry(ctx=ctx, user=user) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import discord | ||
|
||
from redbot.core.commands import Context | ||
|
||
from .core import AVATAR_FILE_NAME, Core, Modes | ||
|
||
|
||
class CommandsCore(Core): | ||
async def cmdTriggered(self, ctx: Context, user: discord.Member = None): | ||
"""Are you triggered? Say no more.""" | ||
await ctx.defer() | ||
if not user: | ||
user = ctx.message.author | ||
data = await self._createTrigger(user, mode=Modes.TRIGGERED) | ||
if not data: | ||
await ctx.send("Something went wrong, try again.") | ||
return | ||
await ctx.send(file=discord.File(data, filename=AVATAR_FILE_NAME.format(user))) | ||
|
||
async def cmdHypertriggered(self, ctx: Context, user: discord.Member = None): | ||
"""Are you in an elevated state of triggered? Say no more.""" | ||
await ctx.defer() | ||
if not user: | ||
user = ctx.message.author | ||
data = await self._createTrigger(user, mode=Modes.REALLY_TRIGGERED) | ||
if not data: | ||
await ctx.send("Something went wrong, try again.") | ||
return | ||
await ctx.send(file=discord.File(data, filename=AVATAR_FILE_NAME.format(user))) | ||
|
||
async def cmdDeepfry(self, ctx: Context, user: discord.Member = None): | ||
"""Are you incredibly triggered? Say no more.""" | ||
await ctx.defer() | ||
if not user: | ||
user = ctx.message.author | ||
data = await self._createTrigger(user, mode=Modes.HYPER_TRIGGERED) | ||
if not data: | ||
await ctx.send("Something went wrong, try again.") | ||
return | ||
await ctx.send(file=discord.File(data, filename=AVATAR_FILE_NAME.format(user))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import enum | ||
from enum import Enum | ||
import io | ||
import logging | ||
|
||
import discord | ||
from PIL import Image, ImageChops, ImageOps, ImageEnhance | ||
|
||
from redbot.core import data_manager | ||
from redbot.core.bot import Red | ||
|
||
AVATAR_FILE_NAME = "{0.id}-triggered.gif" | ||
|
||
|
||
class Modes(Enum): | ||
TRIGGERED = enum.auto() | ||
REALLY_TRIGGERED = enum.auto() | ||
HYPER_TRIGGERED = enum.auto() | ||
|
||
|
||
class Core: | ||
# Class constructor | ||
def __init__(self, bot: Red): | ||
self.bot = bot | ||
self.logger = logging.getLogger("red.luicogs.Triggered") | ||
self.saveFolder = data_manager.cog_data_path(cog_instance=self) | ||
# We need a custom header or else we get a HTTP 403 Unauthorized | ||
self.headers = {"User-agent": "Mozilla/5.0"} | ||
|
||
async def _createTrigger(self, user: discord.User, mode=Modes.TRIGGERED): | ||
"""Fetches the user's avatar, and creates a triggered GIF, applies additional PIL image transformations based on specified mode | ||
Parameters: | ||
----------- | ||
user: discord.User | ||
mode: Modes | ||
Returns: | ||
-------- | ||
An io.BytesIO object containing the data for the generated trigger image | ||
""" | ||
avatarData: bytes | ||
|
||
avatar = user.display_avatar.with_size(512) | ||
avatarData = await avatar.read() | ||
|
||
if not avatarData: | ||
self.logger.error("No avatar data received!") | ||
return | ||
|
||
with Image.open(io.BytesIO(avatarData)) as avatar: | ||
|
||
if not avatar: | ||
return | ||
|
||
offsets = [(15, 15), (5, 10), (-15, -15), (10, -10), (10, 0), (-15, 10), (10, -5)] | ||
images = [] | ||
|
||
# if hyper mode is set | ||
if mode == Modes.REALLY_TRIGGERED: | ||
red_overlay = Image.new(mode="RGBA", size=avatar.size, color=(255, 0, 0, 255)) | ||
mask = Image.new(mode="RGBA", size=avatar.size, color=(255, 255, 255, 127)) | ||
avatar = Image.composite(avatar, red_overlay, mask) | ||
|
||
elif mode == Modes.HYPER_TRIGGERED: | ||
avatar = ImageEnhance.Color(avatar).enhance(5) | ||
avatar = ImageEnhance.Sharpness(avatar).enhance(24) | ||
avatar = ImageEnhance.Contrast(avatar).enhance(4) | ||
|
||
for xcoord, ycoord in offsets: | ||
image = ImageChops.offset(avatar, xcoord, ycoord) | ||
image = ImageOps.crop(image, 15) | ||
images.append(image) | ||
avatar = ImageOps.crop(avatar, 15) | ||
|
||
result = io.BytesIO() | ||
avatar.save( | ||
result, format="GIF", append_images=images, save_all=True, duration=25, loop=0 | ||
) | ||
|
||
# IMPORTANT: rewind to beginning of the stream before returning | ||
result.seek(0) | ||
|
||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters