attachments: add basic resizing

Needs GIF support.
This commit is contained in:
Luna 2018-12-09 01:26:56 -03:00
parent d093e9c1ce
commit 35967cb714
1 changed files with 53 additions and 2 deletions

View File

@ -17,15 +17,46 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
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__) 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' @bp.route('/attachments'
'/<int:channel_id>/<int:message_id>/<filename>', '/<int:channel_id>/<int:message_id>/<filename>',
methods=['GET']) methods=['GET'])
async def _get_attachment(channel_id: int, message_id: int, async def _get_attachment(channel_id: int, message_id: int,
filename: str): filename: str):
attach_id = await app.db.fetchval(""" attach_id = await app.db.fetchval("""
SELECT id SELECT id
FROM attachments FROM attachments
@ -38,5 +69,25 @@ async def _get_attachment(channel_id: int, message_id: int,
return '', 404 return '', 404
ext = filename.split('.')[-1] 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)