From 35967cb714d4727b5140397329ec94063605c5cf Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 9 Dec 2018 01:26:56 -0300 Subject: [PATCH] attachments: add basic resizing Needs GIF support. --- litecord/blueprints/attachments.py | 55 ++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/litecord/blueprints/attachments.py b/litecord/blueprints/attachments.py index be05980..cffe495 100644 --- a/litecord/blueprints/attachments.py +++ b/litecord/blueprints/attachments.py @@ -17,15 +17,46 @@ along with this program. If not, see . """ -from quart import Blueprint, send_file, current_app as app +from pathlib import Path + +from quart import Blueprint, send_file, current_app as app, request +from PIL import Image bp = Blueprint('attachments', __name__) +ATTACHMENTS = Path.cwd() / 'attachments' + + +async def _resize(image, attach_id: str, ext: str, + width: int, height: int) -> str: + """Resize an image.""" + # TODO: gif support + + # check if we have it on the folder + resized_path = ATTACHMENTS / f'{attach_id}_{width}_{height}.{ext}' + + # keep a str-fied instance since that is what + # we'll return. + resized_path_s = str(resized_path) + + if resized_path.exists(): + return resized_path_s + + # if we dont, we need to generate it off the + # given image instance. + + # NOTE: this is the same resize mode for icons. + resized = image.resize((width, height), resample=Image.LANCZOS) + resized.save(resized_path_s, format=ext) + + return resized_path_s + @bp.route('/attachments' '///', methods=['GET']) async def _get_attachment(channel_id: int, message_id: int, filename: str): + attach_id = await app.db.fetchval(""" SELECT id FROM attachments @@ -38,5 +69,25 @@ async def _get_attachment(channel_id: int, message_id: int, return '', 404 ext = filename.split('.')[-1] + filepath = f'./attachments/{attach_id}.{ext}' - return await send_file(f'./attachments/{attach_id}.{ext}') + image = Image.open(filepath) + im_width, im_height = image.size + + try: + width = int(request.args.get('width', 0)) or im_width + except ValueError: + return '', 400 + + try: + height = int(request.args.get('height', 0)) or im_height + except ValueError: + return '', 400 + + # if width and height are the same (happens if they weren't provided) + if width == im_width and height == im_height: + return await send_file(filepath) + + # resize image + new_filepath = await _resize(image, attach_id, ext, width, height) + return await send_file(new_filepath)