mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-05-18 19:32:29 +12:00
added jpeg compress to imagmagic, fixed some issues with rolemanagement age
This commit is contained in:
parent
b56b54578a
commit
df579194c2
|
@ -4,6 +4,7 @@ from wand.image import Image
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Optional, Tuple, Literal
|
from typing import Optional, Tuple, Literal
|
||||||
import asyncio, functools, urllib
|
import asyncio, functools, urllib
|
||||||
|
from PIL import Image as PILImage
|
||||||
|
|
||||||
MAX_SIZE = 8 * 1024 * 1024
|
MAX_SIZE = 8 * 1024 * 1024
|
||||||
|
|
||||||
|
@ -18,7 +19,9 @@ class ImageMagic(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.config = Config.get_conf(self, identifier=4928034571, force_registration=True)
|
self.config = Config.get_conf(
|
||||||
|
self, identifier=4928034571, force_registration=True
|
||||||
|
)
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
async def _get_image(self, ctx, link: str = None) -> Image:
|
async def _get_image(self, ctx, link: str = None) -> Image:
|
||||||
|
@ -33,7 +36,9 @@ class ImageMagic(commands.Cog):
|
||||||
if ctx.message.reference:
|
if ctx.message.reference:
|
||||||
msg = ctx.message.reference.resolved
|
msg = ctx.message.reference.resolved
|
||||||
if msg is None:
|
if msg is None:
|
||||||
msg = await ctx.channel.fetch_message(ctx.message.reference.message_id)
|
msg = await ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
)
|
||||||
if msg and msg.attachments:
|
if msg and msg.attachments:
|
||||||
for a in msg.attachments:
|
for a in msg.attachments:
|
||||||
path = urllib.parse.urlparse(a.url).path
|
path = urllib.parse.urlparse(a.url).path
|
||||||
|
@ -61,7 +66,9 @@ class ImageMagic(commands.Cog):
|
||||||
except:
|
except:
|
||||||
raise ImageFindError("Invalid filetype")
|
raise ImageFindError("Invalid filetype")
|
||||||
except (OSError, aiohttp.ClientError):
|
except (OSError, aiohttp.ClientError):
|
||||||
raise ImageFindError("An image could not be found. Make sure you provide a direct link.")
|
raise ImageFindError(
|
||||||
|
"An image could not be found. Make sure you provide a direct link."
|
||||||
|
)
|
||||||
else: # attached image
|
else: # attached image
|
||||||
path = urllib.parse.urlparse(ctx.message.attachments[0].url).path
|
path = urllib.parse.urlparse(ctx.message.attachments[0].url).path
|
||||||
if ctx.message.attachments[0].size > max_filesize:
|
if ctx.message.attachments[0].size > max_filesize:
|
||||||
|
@ -85,6 +92,27 @@ class ImageMagic(commands.Cog):
|
||||||
intensity /= 10
|
intensity /= 10
|
||||||
return intensity
|
return intensity
|
||||||
|
|
||||||
|
def _jpeg_compress(self, img: Image, quality: int) -> Image:
|
||||||
|
# save image to temp variable to load it as a PIL image
|
||||||
|
temp_file = BytesIO()
|
||||||
|
img.save(file=temp_file)
|
||||||
|
temp_file.seek(0)
|
||||||
|
|
||||||
|
# load as PIL image
|
||||||
|
pil_img = PILImage.open(temp_file)
|
||||||
|
img = PILImage.new("RGB", pil_img.size)
|
||||||
|
img.paste(pil_img)
|
||||||
|
|
||||||
|
# compress
|
||||||
|
temp_file = BytesIO()
|
||||||
|
img.save(temp_file, "JPEG", quality=quality)
|
||||||
|
temp_file.seek(0)
|
||||||
|
|
||||||
|
# return as wand image
|
||||||
|
img = Image(file=temp_file)
|
||||||
|
|
||||||
|
return img, "jpeg.jpeg"
|
||||||
|
|
||||||
def _distortion(self, img: Image, func: str, args: Tuple) -> Tuple[Image, str]:
|
def _distortion(self, img: Image, func: str, args: Tuple) -> Tuple[Image, str]:
|
||||||
# distort
|
# distort
|
||||||
img.iterator_reset()
|
img.iterator_reset()
|
||||||
|
@ -110,7 +138,9 @@ class ImageMagic(commands.Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await ctx.reply(file=discord.File(BytesIO(img.make_blob()), name), mention_author=False)
|
await ctx.reply(
|
||||||
|
file=discord.File(BytesIO(img.make_blob()), name), mention_author=False
|
||||||
|
)
|
||||||
except discord.errors.HTTPException:
|
except discord.errors.HTTPException:
|
||||||
await ctx.reply("That image is too large.", mention_author=False)
|
await ctx.reply("That image is too large.", mention_author=False)
|
||||||
return
|
return
|
||||||
|
@ -126,8 +156,21 @@ class ImageMagic(commands.Cog):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@distort.command()
|
@distort.command()
|
||||||
async def barrel(self, ctx, intensity: Optional[float] = 10, *, link: str = None):
|
async def jpeg(self, ctx, quality: Optional[float] = 10, *, link: str = None):
|
||||||
|
"""
|
||||||
|
Applies JPEG compression to image
|
||||||
|
"""
|
||||||
|
quality = int(self._intensity(quality) * 100)
|
||||||
|
async with ctx.typing():
|
||||||
|
try:
|
||||||
|
img = await self._get_image(ctx, link)
|
||||||
|
except ImageFindError as e:
|
||||||
|
return await ctx.reply(e, mention_author=False)
|
||||||
|
|
||||||
|
await self._command_body(ctx, args=(self._jpeg_compress, img, quality))
|
||||||
|
|
||||||
|
@distort.command()
|
||||||
|
async def barrel(self, ctx, intensity: Optional[float] = 10, *, link: str = None):
|
||||||
"""
|
"""
|
||||||
Bulges the center of the image outward
|
Bulges the center of the image outward
|
||||||
"""
|
"""
|
||||||
|
@ -145,7 +188,10 @@ class ImageMagic(commands.Cog):
|
||||||
self._distortion,
|
self._distortion,
|
||||||
img,
|
img,
|
||||||
"distort",
|
"distort",
|
||||||
("barrel", (amount * intensity, amount * intensity, amount * intensity, 0)),
|
(
|
||||||
|
"barrel",
|
||||||
|
(amount * intensity, amount * intensity, amount * intensity, 0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -162,7 +208,9 @@ class ImageMagic(commands.Cog):
|
||||||
except ImageFindError as e:
|
except ImageFindError as e:
|
||||||
return await ctx.reply(e, mention_author=False)
|
return await ctx.reply(e, mention_author=False)
|
||||||
|
|
||||||
await self._command_body(ctx, args=(self._distortion, img, "implode", (amount * intensity,)))
|
await self._command_body(
|
||||||
|
ctx, args=(self._distortion, img, "implode", (amount * intensity,))
|
||||||
|
)
|
||||||
|
|
||||||
@distort.command()
|
@distort.command()
|
||||||
async def swirl(self, ctx, intensity: Optional[float] = 10, *, link: str = None):
|
async def swirl(self, ctx, intensity: Optional[float] = 10, *, link: str = None):
|
||||||
|
@ -170,7 +218,19 @@ class ImageMagic(commands.Cog):
|
||||||
Swirls the center of the image
|
Swirls the center of the image
|
||||||
"""
|
"""
|
||||||
|
|
||||||
switch = {0: 0, 1: 18, 2: 36, 3: 54, 4: 72, 5: 90, 6: 108, 7: 126, 8: 144, 9: 162, 10: 180}
|
switch = {
|
||||||
|
0: 0,
|
||||||
|
1: 18,
|
||||||
|
2: 36,
|
||||||
|
3: 54,
|
||||||
|
4: 72,
|
||||||
|
5: 90,
|
||||||
|
6: 108,
|
||||||
|
7: 126,
|
||||||
|
8: 144,
|
||||||
|
9: 162,
|
||||||
|
10: 180,
|
||||||
|
}
|
||||||
intensity = float(switch.get(round(intensity), 180))
|
intensity = float(switch.get(round(intensity), 180))
|
||||||
|
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
|
@ -179,7 +239,9 @@ class ImageMagic(commands.Cog):
|
||||||
except ImageFindError as e:
|
except ImageFindError as e:
|
||||||
return await ctx.reply(e, mention_author=False)
|
return await ctx.reply(e, mention_author=False)
|
||||||
|
|
||||||
await self._command_body(ctx, args=(self._distortion, img, "swirl", (intensity,)))
|
await self._command_body(
|
||||||
|
ctx, args=(self._distortion, img, "swirl", (intensity,))
|
||||||
|
)
|
||||||
|
|
||||||
@distort.command()
|
@distort.command()
|
||||||
async def charcoal(self, ctx, intensity: Optional[float], *, link: str = None):
|
async def charcoal(self, ctx, intensity: Optional[float], *, link: str = None):
|
||||||
|
@ -193,7 +255,9 @@ class ImageMagic(commands.Cog):
|
||||||
except ImageFindError as e:
|
except ImageFindError as e:
|
||||||
return await ctx.reply(e, mention_author=False)
|
return await ctx.reply(e, mention_author=False)
|
||||||
|
|
||||||
await self._command_body(ctx, args=(self._distortion, img, "charcoal", (1.5, 0.5)))
|
await self._command_body(
|
||||||
|
ctx, args=(self._distortion, img, "charcoal", (1.5, 0.5))
|
||||||
|
)
|
||||||
|
|
||||||
@distort.command()
|
@distort.command()
|
||||||
async def sketch(self, ctx, intensity: Optional[float], *, link: str = None):
|
async def sketch(self, ctx, intensity: Optional[float], *, link: str = None):
|
||||||
|
@ -207,7 +271,9 @@ class ImageMagic(commands.Cog):
|
||||||
except ImageFindError as e:
|
except ImageFindError as e:
|
||||||
return await ctx.reply(e, mention_author=False)
|
return await ctx.reply(e, mention_author=False)
|
||||||
|
|
||||||
await self._command_body(ctx, args=(self._distortion, img, "sketch", (0.5, 0.0, 98.0)))
|
await self._command_body(
|
||||||
|
ctx, args=(self._distortion, img, "sketch", (0.5, 0.0, 98.0))
|
||||||
|
)
|
||||||
|
|
||||||
@distort.command()
|
@distort.command()
|
||||||
async def zoom(self, ctx, intensity: Optional[float], *, link: str = None):
|
async def zoom(self, ctx, intensity: Optional[float], *, link: str = None):
|
||||||
|
@ -225,7 +291,15 @@ class ImageMagic(commands.Cog):
|
||||||
w = img.width
|
w = img.width
|
||||||
img = self._distortion(img, "transform", (f"{w}x{h}", "150%"))[0]
|
img = self._distortion(img, "transform", (f"{w}x{h}", "150%"))[0]
|
||||||
|
|
||||||
await self._command_body(ctx, args=(self._distortion, img, "transform", (f"{w/1.5}x{h/1.5}+{w/2}+{h/2}",)))
|
await self._command_body(
|
||||||
|
ctx,
|
||||||
|
args=(
|
||||||
|
self._distortion,
|
||||||
|
img,
|
||||||
|
"transform",
|
||||||
|
(f"{w/1.5}x{h/1.5}+{w/2}+{h/2}",),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def red_delete_data_for_user(
|
async def red_delete_data_for_user(
|
||||||
|
|
|
@ -7,5 +7,8 @@
|
||||||
"description": "Manipulates images.",
|
"description": "Manipulates images.",
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"end_user_data_statement": "This cog does not store user data.",
|
"end_user_data_statement": "This cog does not store user data.",
|
||||||
"requirements": ["wand"]
|
"requirements": [
|
||||||
}
|
"wand",
|
||||||
|
"Pillow"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
from .core import RoleManagement
|
from .core import RoleManagement
|
||||||
|
|
||||||
__red_end_user_data_statement__ = "This will only store sticky and subscribed roles for users."
|
__red_end_user_data_statement__ = "This will only store birthdays, sticky, and subscribed roles for users."
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
|
|
|
@ -101,6 +101,7 @@ class RoleManagement(
|
||||||
age_verification=None,
|
age_verification=None,
|
||||||
) # subscribed_users maps str(user.id)-> end time in unix timestamp
|
) # subscribed_users maps str(user.id)-> end time in unix timestamp
|
||||||
self.config.register_member(roles=[], forbidden=[], birthday=None)
|
self.config.register_member(roles=[], forbidden=[], birthday=None)
|
||||||
|
self.config.register_user(birthday=None)
|
||||||
self.config.init_custom("REACTROLE", 2)
|
self.config.init_custom("REACTROLE", 2)
|
||||||
self.config.register_custom(
|
self.config.register_custom(
|
||||||
"REACTROLE", roleid=None, channelid=None, guildid=None
|
"REACTROLE", roleid=None, channelid=None, guildid=None
|
||||||
|
@ -176,6 +177,16 @@ class RoleManagement(
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# fix moving birthdays to user config from member config
|
||||||
|
for guild in self.bot.guilds:
|
||||||
|
for member in guild.members:
|
||||||
|
m_age = await self.config.member(member).birthday()
|
||||||
|
u_age = await self.config.user(member).birthday()
|
||||||
|
|
||||||
|
if m_age and u_age is None:
|
||||||
|
await self.config.user(member).birthday.set(m_age)
|
||||||
|
await self.config.member(member).birthday.set(None)
|
||||||
|
|
||||||
self._ready.set()
|
self._ready.set()
|
||||||
|
|
||||||
async def wait_for_ready(self):
|
async def wait_for_ready(self):
|
||||||
|
@ -295,7 +306,7 @@ class RoleManagement(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
await self.config.member(member).birthday.set(dob.strftime("%m/%d/%Y"))
|
await self.config.user(member).birthday.set(dob.strftime("%m/%d/%Y"))
|
||||||
await ctx.tick()
|
await ctx.tick()
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -1279,7 +1290,7 @@ class RoleManagement(
|
||||||
member = ctx.author
|
member = ctx.author
|
||||||
|
|
||||||
guild = member.guild
|
guild = member.guild
|
||||||
dob = await self.config.member(member).birthday()
|
dob = await self.config.user(member).birthday()
|
||||||
min_age = await self.config.role(role).age_verification()
|
min_age = await self.config.role(role).age_verification()
|
||||||
age_log = await self.config.guild(guild).age_log()
|
age_log = await self.config.guild(guild).age_log()
|
||||||
today = datetime.utcnow().date()
|
today = datetime.utcnow().date()
|
||||||
|
@ -1351,7 +1362,7 @@ class RoleManagement(
|
||||||
await member.send(
|
await member.send(
|
||||||
f"Thank you! Please check back in `{guild}` to confirm you obtained the role. If not, you may not meet the age requirement for the role."
|
f"Thank you! Please check back in `{guild}` to confirm you obtained the role. If not, you may not meet the age requirement for the role."
|
||||||
)
|
)
|
||||||
await self.config.member(member).birthday.set(dob_str)
|
await self.config.user(member).birthday.set(dob_str)
|
||||||
if age_log:
|
if age_log:
|
||||||
try:
|
try:
|
||||||
await modlog.create_case(
|
await modlog.create_case(
|
||||||
|
@ -1424,4 +1435,4 @@ class RoleManagement(
|
||||||
requester: Literal["discord_deleted_user", "owner", "user", "user_strict"],
|
requester: Literal["discord_deleted_user", "owner", "user", "user_strict"],
|
||||||
user_id: int,
|
user_id: int,
|
||||||
):
|
):
|
||||||
pass
|
await self.config.user_from_id(user_id).clear()
|
||||||
|
|
|
@ -18,5 +18,5 @@
|
||||||
],
|
],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"min_bot_version": "3.4.0",
|
"min_bot_version": "3.4.0",
|
||||||
"end_user_data_statement": "This will only store sticky and subscribed roles for users."
|
"end_user_data_statement": "This will only store birthdays, sticky, and subscribed roles for users."
|
||||||
}
|
}
|
Loading…
Reference in a new issue