papiez_ipsum/src/papiezator/pope_utils.py

159 lines
3.8 KiB
Python
Raw Normal View History

from papiezator.models import Pope, PopeImage, PerfectPope, DECIMAL_PLACES
2013-11-26 22:32:11 +00:00
from PIL import Image
from io import BytesIO
2013-12-23 18:53:20 +00:00
from django.core.exceptions import ObjectDoesNotExist
from random import choice
2014-01-09 20:49:38 +00:00
from django.http import HttpResponse
from papiezator.papiezator_settings import (
REDIS_TTL, SAGE_REDIS, POPE_SPAN,
POPE_CHOICE_RANGE
)
try:
from redis import Redis
from redis.exceptions import ConnectionError as RedisConnectionError
redis = Redis()
except ImportError:
redis = None
2013-11-26 22:32:11 +00:00
def unpopable(width, height):
if width == 0 or height == 0:
return True
if (width+height) >= 9001:
return True
return False
2014-01-09 20:49:38 +00:00
#======== your friendly decorators :3 ======================================
2014-02-02 14:51:30 +00:00
def redis_me(func):
def inner(*args, **kwargs):
import ipdb; ipdb.set_trace()
if not redis or SAGE_REDIS:
return func(*args, **kwargs)
# FIXME: perhaps some better key value?
key = (func.__name__, args)
try:
image = redis.get(key)
if not image:
image = func(*args, **kwargs)
redis.set(key, image)
redis.expire(key, REDIS_TTL)
return image
except RedisConnectionError:
return func(*args, **kwargs)
2014-02-02 14:51:30 +00:00
return inner
def habemus_papam(func):
"""Your friendly, pointless decorator ;3
"""
def inner(aspect_ratio, pope):
pp = PerfectPope.objects.filter(aspect_ratio=aspect_ratio, pope=pope)
if pp: return pp[0].image
PopeImage = func(aspect_ratio, pope)
pp = PerfectPope(aspect_ratio=aspect_ratio, image=PopeImage, pope=pope)
pp.save()
return PopeImage
return inner
2014-01-09 20:49:38 +00:00
def http_return_image(func):
def inner(*args, **kwargs):
image = func(*args, **kwargs)
if image:
return HttpResponse(image, content_type="image/jpeg")
else:
return HttpResponse("Jan Paweł II spadał z rowerka")
return inner
# =============================================================================
2014-02-02 14:51:30 +00:00
@redis_me
2014-01-09 20:49:38 +00:00
def get_pope(width, height, pope_id):
width, height = int(width), int(height)
if not unpopable(width, height):
pope = pope_or_death(Pope, id=pope_id)
if pope:
aspect_ratio = round(width/height, DECIMAL_PLACES)
pope_image = select_best_pope(aspect_ratio, pope)
if pope_image:
return read_pope(width, height, pope_image)
return None
@habemus_papam
def select_best_pope(aspect_ratio, pope, random=True):
""" (float, Pope) -> PopeImage
2013-11-29 19:16:10 +00:00
"""
# popes below and above this ratio
2014-01-08 06:12:39 +00:00
popes = []
2014-01-08 06:12:39 +00:00
popes.extend(
PopeImage.objects.filter(
aspect_ratio__lte=aspect_ratio,
pope=pope).order_by('-aspect_ratio')[0:POPE_SPAN]
)
2014-01-08 06:12:39 +00:00
popes.extend(
PopeImage.objects.filter(
aspect_ratio__gte=aspect_ratio,
pope=pope).order_by('aspect_ratio')[0:POPE_SPAN]
2014-01-08 06:12:39 +00:00
)
2013-11-26 22:32:11 +00:00
2014-01-08 06:12:39 +00:00
if popes:
p = sorted(
2014-01-08 06:12:39 +00:00
popes,
key=lambda x: abs(aspect_ratio - x.aspect_ratio)
)
if random: return choice(p[:POPE_CHOICE_RANGE])
else: return p[0]
else: return None
2013-11-29 19:16:10 +00:00
def read_pope(width, height, pope_image):
""" (int, int, PopeImage) -> bytes
get pope for display
"""
im = Image.open(pope_image.path)
im = im.resize((width, height))
f = BytesIO() # FIXME: ceriously.
im.save(f, "jpeg")
f.seek(0)
return f.read()
2013-11-26 22:32:11 +00:00
def parse_pope(path):
im = Image.open(path)
width, height = im.size
2013-12-23 18:53:20 +00:00
aspect_ratio = round(width/height, DECIMAL_PLACES)
return PopeImage(
path=path,
width=width,
height=height,
aspect_ratio=aspect_ratio
)
2013-12-23 18:53:20 +00:00
def pope_or_death(p, **kwargs):
try:
x = p.objects.get(**kwargs)
except ObjectDoesNotExist:
x = None
return x