Skip to content

Commit

Permalink
Merge pull request #55 from murpii/pr_update_skindb_cog
Browse files Browse the repository at this point in the history
Updates to the skindb cog
  • Loading branch information
Learath2 authored Sep 23, 2023
2 parents b85bb8d + 28c7620 commit cb57a7e
Showing 1 changed file with 98 additions and 57 deletions.
155 changes: 98 additions & 57 deletions cogs/skindb.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import discord
from discord.ext import commands
import re
import logging
import asyncio
from io import BytesIO
from PIL import Image, ImageOps

GUILD_DDNET = 930664819303002123
CHAN_SKIN_SUBMIT = 986107035747766292
ROLE_ADMIN = 930665626370985994
ROLE_DISCORD_MOD = 934131865512730656
ROLE_SKIN_DB_CREW = 930665730091929650
GUILD_DDNET = 252358080522747904
CHAN_SKIN_SUBMIT = 985717921600929872
ROLE_ADMIN = 293495272892399616
ROLE_DISCORD_MOD = 737776812234506270
ROLE_SKIN_DB_CREW = 390516461741015040


def is_staff(member: discord.Member) -> bool:
Expand All @@ -22,42 +24,63 @@ def check_if_staff(message: discord.Message):

def check_if_has_attachments(message: discord.Message):
if len(message.attachments) == 0:
return (False, 'Your submission is missing attachments. Attach all skins to one message and follow the correct message format written in <#986941590780149780>')
return (True, None)
return (False, f'- Your submission is missing attachments. Attach all skins to your submission message.',
'Missing attachments')
return (True, None, None)


def check_image_format(message: discord.Message):
for attachment_type in message.attachments:
if attachment_type.content_type != 'image/png':
return (False, 'Wrong image format. Only PNGs are allowed.')
return (True, None)
return (False, f'- Wrong image format. Only PNGs are allowed.', 'Incorrect image format')
return (True, None, None)


def check_image_resolution(message: discord.Message):
has_256x128 = False
for attachment in message.attachments:
if (attachment.height == 256 and attachment.width == 128) or (attachment.height == 128 and attachment.width == 256):
has_256x128 = True
if (attachment.height != 128 or attachment.width != 256) and (attachment.height != 256 or attachment.width != 512):
return (False, 'One of the attached skins does not have the correct image resolution. Resolution must be 256x128, and if possible provide a 512x256 along with the 256x128')
return (True, None)


def check_text_format(message: discord.Message):
# Regex to make licenses optional: "^(?P<skin_name>['\"].+['\"]) by (?P<creator_name>.+?)( (\((?P<license>CC0|CC-BY|CC-BY-SA)\)))?$"gm
regex = re.compile(r"^\"(?P<skin_name>.+)\" by (?P<user_name>.+) (\((?P<license>.{3,8})\))$", re.IGNORECASE)
return (False, (f'- One of the attached skins does not have the correct image resolution. Resolution must be '
'256x128, and if possible provide a 512x256 along with the 256x128'), 'Bad image resolution')
if not has_256x128:
return (False, f'- At least one of the attached skins must have a resolution of 256x128', 'Missing 256x128px skin')
return (True, None, None)

def check_attachment_amount(message: discord.Message):
if len(message.attachments) > 2:
return (False, f'- Only 2 attachments per submission. Don\'t attach any additional images or gifs, please.',
'Exceeded upload limit')
return (True, None, None)

def check_message_structure(message: discord.Message):
# Regex to make licenses optional:
# "^(?P<skin_name>['\"].+['\"]) by (?P<creator_name>.+?)( (\((?P<license>CC0|CC-BY|CC-BY-SA)\)))?$"gm
regex = re.compile(r"^\"(?P<skin_name>.+)\" by (?P<user_name>.+) (\((?P<license>.{3,8})\))$")
re_match = regex.match(message.content)
if not re_match:
return (False,
'Your message isn\'t properly formatted. Follow the message format written in <#986941590780149780>. Also keep in mind licenses are now required for every submission.')
(f'- Your message isn\'t properly formatted. Follow the message structure written in <#986941590780149780>. '
'Also keep in mind licenses are now required for every submission and proper uppercase and lowercase formatting is important as well.'),
'Bad message structure')

licenses = ["CC0", "CC BY", "CC BY-SA"]
if re_match.group('license'):
if not re_match.group('license') in licenses:
return (
False,
('- Bad License. Possible licenses: `(CC0)`, `(CC BY)` or `(CC BY-SA)`\n'
'```md\n'
'# Recommended License Types\n'
'CC0 - skin is common property, everyone can use/edit/share it however they like\n'
'CC BY - skin can be used/edited/shared, but must be credited\n'
'CC BY-SA - skin can be used/edited/shared, but must be credited and '
'derived works must also be shared under the same license```'),
'License Missing'
)

licenses = ["CC0", "CC-BY", "CC-BY-SA"]
if re_match.group('license') is not None:
if not any(lisense in re_match.group('license') for lisense in licenses):
return (False, 'Wrong License. Possible licenses: `(CC0)`, `(CC-BY)` or `(CC-BY-SA)`'
'\n```md'
'\n# Recommended License Types'
'\nCC0 - skin is common property, everyone can use/edit/share it however they like'
'\nCC-BY - skin can be used/edited/shared, but must be credited'
'\nCC-BY-SA - skin can be used/edited/shared, but must be credited and derived works must also be shared under the same license```')
return (True, None)
return (True, None, None)


def crop_and_generate_image(img):
Expand Down Expand Up @@ -159,36 +182,49 @@ async def check_message_format_and_render(self, message: discord.Message):
if check_if_staff(message) or message.author.bot:
return

check_result, check_message = check_if_has_attachments(message)
error_messages = []
log_errors = []

check_result, check_message, error = check_if_has_attachments(message)
if not check_result:
await message.delete()
await message.author.send(check_message)
return
error_messages.append(check_message)
log_errors.append(error)

check_result, check_message = check_image_format(message)
check_result, check_message, error = check_image_format(message)
if not check_result:
await message.delete()
await message.author.send(check_message)
return
error_messages.append(check_message)
log_errors.append(error)

check_result, check_message = check_image_resolution(message)
check_result, check_message, error = check_image_resolution(message)
if not check_result:
await message.delete()
await message.author.send(check_message)
return
error_messages.append(check_message)
log_errors.append(error)

check_result, check_message = check_text_format(message)
check_result, check_message, error = check_message_structure(message)
if not check_result:
await message.delete()
await message.author.send(check_message)
return
error_messages.append(check_message)
log_errors.append(error)

if len(message.attachments) > 2:
await message.author.send(
'Only 2 attachments per submission. '
'Don\'t attach any additional images or gifs, please.'
)
check_result, check_message, error = check_attachment_amount(message)
if not check_result:
error_messages.append(check_message)
log_errors.append(error)

if error_messages:
await message.delete()
log_errors[0] = f'Skin submit errors by {message.author}: {", ".join(log_errors)}'
logging.info(log_errors[0])

try:
error_messages.insert(0, "Submit Errors: ")
await message.author.send("\n".join(error_messages))
except discord.Forbidden:
logging.info(f'Skin submit: Unable to DM {message.author} due to their privacy settings.')
privacy_err = (f'Skin submission failed. Unable to DM {message.author.mention}. '
f'Change your privacy settings to allow direct messages from this server.')
privacy_err_msg = await message.channel.send(content=privacy_err)
await asyncio.sleep(2 * 60)
await privacy_err_msg.delete()
else:
attachments = message.attachments
images = []
Expand All @@ -203,11 +239,7 @@ async def check_message_format_and_render(self, message: discord.Message):
image_to_process = img
break

if not image_to_process:
await message.author.send("One of the attachments should be 128x256.")
return

processed_images = crop_and_generate_image(images[0])
processed_images = crop_and_generate_image(image_to_process)

final_image = Image.new('RGBA', (512, 64))

Expand All @@ -228,8 +260,8 @@ async def check_message_format_and_render(self, message: discord.Message):
image_preview_message = await message.channel.send(file=file)
self.original_message_id_and_preview_message_id[message.id] = image_preview_message.id

f3_emoji = self.bot.get_emoji(933103235651223632)
f4_emoji = self.bot.get_emoji(933102663841751061)
f3_emoji = self.bot.get_emoji(346683497701834762)
f4_emoji = self.bot.get_emoji(346683496476966913)
await message.add_reaction(f3_emoji)
await message.add_reaction(f4_emoji)

Expand All @@ -241,7 +273,16 @@ async def message_delete_handler(self, message: discord.Message):
await preview_message.delete()
del self.original_message_id_and_preview_message_id[message.id]

@commands.Cog.listener('on_message_edit')
async def message_edit_handler(self, before: discord.Message, after: discord.Message):
if before.guild is None or before.guild.id != GUILD_DDNET or before.channel.id != CHAN_SKIN_SUBMIT \
or before.author.bot or is_staff(before.author):
return

if before.content != after.content:
await after.delete()
await after.author.send('Editing submissions is not allowed. Please re-submit your submissions.')

def setup(bot: commands.Bot):
bot.add_cog(SkinDB(bot))
async def setup(bot: commands.Bot):
await bot.add_cog(SkinDB(bot))

0 comments on commit cb57a7e

Please sign in to comment.