2014-01-09 05:41:41 +00:00
|
|
|
from papiezator.models import Pope, PopeImage, PerfectPope, DECIMAL_PLACES
|
2013-11-26 22:32:11 +00:00
|
|
|
from PIL import Image
|
2014-01-07 00:05:20 +00:00
|
|
|
from io import BytesIO
|
2013-12-23 18:53:20 +00:00
|
|
|
from django.core.exceptions import ObjectDoesNotExist
|
2014-01-09 05:41:41 +00:00
|
|
|
from random import choice
|
2014-01-09 20:49:38 +00:00
|
|
|
from django.http import HttpResponse
|
2014-01-09 05:41:41 +00:00
|
|
|
from papiezator.papiezator_settings import (
|
|
|
|
REDIS_TTL, SAGE_REDIS, POPE_SPAN,
|
|
|
|
POPE_CHOICE_RANGE
|
|
|
|
)
|
2014-01-08 03:53:36 +00:00
|
|
|
|
2014-01-07 00:05:20 +00:00
|
|
|
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
|
|
|
|
2014-01-08 04:50:03 +00:00
|
|
|
|
2014-01-09 05:41:41 +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-01-09 05:41:41 +00:00
|
|
|
|
2014-02-02 14:51:30 +00:00
|
|
|
return inner
|
2014-01-09 05:41:41 +00:00
|
|
|
|
|
|
|
|
2014-01-08 04:50:03 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2014-01-08 04:50:03 +00:00
|
|
|
@habemus_papam
|
2014-01-09 05:41:41 +00:00
|
|
|
def select_best_pope(aspect_ratio, pope, random=True):
|
2014-01-08 03:53:36 +00:00
|
|
|
""" (float, Pope) -> PopeImage
|
2013-11-29 19:16:10 +00:00
|
|
|
|
|
|
|
"""
|
2014-01-07 00:05:20 +00:00
|
|
|
# popes below and above this ratio
|
2014-01-08 06:12:39 +00:00
|
|
|
popes = []
|
2014-01-09 05:41:41 +00:00
|
|
|
|
2014-01-08 06:12:39 +00:00
|
|
|
popes.extend(
|
|
|
|
PopeImage.objects.filter(
|
|
|
|
aspect_ratio__lte=aspect_ratio,
|
2014-01-09 05:41:41 +00:00
|
|
|
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,
|
2014-01-09 05:41:41 +00:00
|
|
|
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:
|
2014-01-09 05:41:41 +00:00
|
|
|
p = sorted(
|
2014-01-08 06:12:39 +00:00
|
|
|
popes,
|
2014-01-08 04:50:03 +00:00
|
|
|
key=lambda x: abs(aspect_ratio - x.aspect_ratio)
|
2014-01-08 03:53:36 +00:00
|
|
|
)
|
2013-12-22 13:31:17 +00:00
|
|
|
|
2014-01-09 05:41:41 +00:00
|
|
|
if random: return choice(p[:POPE_CHOICE_RANGE])
|
|
|
|
else: return p[0]
|
2013-11-27 05:25:45 +00:00
|
|
|
|
2014-01-09 05:41:41 +00:00
|
|
|
else: return None
|
2013-11-29 19:16:10 +00:00
|
|
|
|
2013-11-27 05:25:45 +00:00
|
|
|
|
2014-01-07 00:05:20 +00:00
|
|
|
def read_pope(width, height, pope_image):
|
2014-01-08 03:53:36 +00:00
|
|
|
""" (int, int, PopeImage) -> bytes
|
|
|
|
get pope for display
|
2014-01-07 00:05:20 +00:00
|
|
|
"""
|
2014-01-08 04:50:03 +00:00
|
|
|
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-27 05:25:45 +00:00
|
|
|
|
2013-11-26 22:32:11 +00:00
|
|
|
|
2013-12-22 13:31:17 +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)
|
2014-01-08 04:50:03 +00:00
|
|
|
return PopeImage(
|
|
|
|
path=path,
|
|
|
|
width=width,
|
|
|
|
height=height,
|
|
|
|
aspect_ratio=aspect_ratio
|
|
|
|
)
|
2013-12-22 13:31:17 +00:00
|
|
|
|
|
|
|
|
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
|