From: CMDR furrycat Date: Mon, 26 Sep 2016 13:11:58 +0000 (+0100) Subject: Let anyone Deltaify an image. X-Git-Url: http://git.furryclan.net/?a=commitdiff_plain;h=bdbe0fde78917195deadb2a67f614b84cd5b6931;p=furrycat%2Fcatbot.git Let anyone Deltaify an image. --- diff --git a/bot.py b/bot.py index d71cefd..603b6bf 100755 --- a/bot.py +++ b/bot.py @@ -5,12 +5,15 @@ import bs4 import discord import feedparser import hashlib +import io import logging +import math import os import pexpect import random import re import sys +from PIL import Image dryrun = os.getenv('DRYRUN') is not None @@ -110,14 +113,71 @@ def is_admin(server, member): return True return False +def delta_avatar(url): + # Get Delta images. + bg = Image.open('DELTA-BG.png') + fg = Image.open('DELTA-FURRYTEMPLATE.png') + if not bg or not fg: + log.warning("Can't open Delta foreground and/or background image!") + return None + cutoff = bg.width / 2 + + # Get provided image. + fd = open_url(url) + if fd is None: + log.debug('Failed to open URL {} for avatar creation'.format(url)) + return None + try: + image = Image.open(fd) + except: + log.warning('Failed to get image from {}'.format(url)) + return None + fd.close() + if image is None: + return None + + # Crop square. + box = None + if image.height > image.width: + top = math.floor((image.height - image.width) / 2) + box = 0, top, image.width - 1, top + image.width - 1 + elif image.height < image.width: + left = math.floor((image.width - image.height) / 2) + box = left, 0, left + image.height - 1, image.height - 1 + if box is not None: + cropped = image.crop(box) + image = cropped.copy() + + # Scale leaving space for background. + if image.height > cutoff: + image.thumbnail((cutoff, cutoff)) + elif image.height < cutoff: + width = image.width * 2 + height = image.height * 2 + bg.thumbnail((width, height)) + fg.thumbnail((width, height)) + + # Pad with blank pixels. + padded = Image.new(image.mode, fg.size) + left = math.floor((padded.width - image.width) / 2) + top = math.floor((padded.height - image.height) / 2) + padded.paste(image, (left, top, left + image.width, top + image.height)) + + # Merge them. + result = Image.alpha_composite(Image.alpha_composite(bg, padded), fg) + b = io.BytesIO() + result.save(b, 'PNG') + return b.getvalue() + @asyncio.coroutine -def do_admin(message, command, raw): - result = yield from is_admin(message.server, message.author) - if not result: - yield from not_admin(message) - return +def do_commands(message, command, raw, non_admin): + if not non_admin: + result = yield from is_admin(message.server, message.author) + if not result: + yield from not_admin(message) + return - log.debug('Admin command: {}'.format(raw)) + log.debug('Command: {}'.format(raw)) if command == 'avatar': # avatar @@ -139,6 +199,25 @@ def do_admin(message, command, raw): yield from client.edit_profile(avatar = fd.read()) fd.close() + elif command == 'bling': + # bling + url = None + m = re.match(r'\bbling\s+(\S+)', raw.lower()) + if m is not None: + url = m.group(1) + elif len(message.attachments): + url = message.attachments[0]['url'] + if url is None: + log.debug('No URL for avatar to Deltaify') + yield from say(message.channel, 'zzz') + return + yield from client.send_typing(message.channel) + data = delta_avatar(url) + if data is None: + yield from say(message.channel, 'yelp!') + return + yield from client.send_file(message.channel, data, filename = message.author.name + '.png', content = message.author.mention if not message.channel.is_private else 'purr') + elif command == 'debug': # debug m = re.match(r'\bdebug\s+(o(?:ff|n))\b', raw.lower()) @@ -326,10 +405,15 @@ wait_for_prompt(p) modules = { 'admin': { - 'fn': do_admin, + 'fn': do_commands, 'args': [], 'commands': ['avatar', 'debug', 'delete', 'rss'] }, + 'any': { + 'fn': do_commands, + 'args': [True], + 'commands': ['bling'] + }, 'edi': { 'fn': do_edi, 'args': [p],