Become a programmer, they said. It'll be fun, they said.

master
daz 2014-01-08 05:50:03 +01:00
parent 483272ce50
commit 7c5965dcd8
7 changed files with 82 additions and 86 deletions

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
from django.contrib import admin from django.contrib import admin
from papiezator.models import Pope, PopeImage, PerfectPope from papiezator.models import Pope, PopeImage, PerfectPope
admin.site.register(PopeImage) admin.site.register(PopeImage)

View File

@ -1,5 +0,0 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
class ENOPopeException(Exception): pass

View File

@ -2,6 +2,7 @@ from django.db import models
DECIMAL_PLACES = 3 DECIMAL_PLACES = 3
class PopeImage(models.Model): class PopeImage(models.Model):
path = models.CharField(max_length=200, primary_key=True) path = models.CharField(max_length=200, primary_key=True)
width = models.IntegerField() width = models.IntegerField()
@ -12,6 +13,7 @@ class PopeImage(models.Model):
def __str__(self): def __str__(self):
return self.path.split('/')[-1] return self.path.split('/')[-1]
class Pope(models.Model): class Pope(models.Model):
id = models.IntegerField(primary_key=True) id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
@ -19,6 +21,7 @@ class Pope(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
class PerfectPope(models.Model): class PerfectPope(models.Model):
aspect_ratio = models.FloatField(primary_key=True) aspect_ratio = models.FloatField(primary_key=True)
image = models.ForeignKey('PopeImage') image = models.ForeignKey('PopeImage')

View File

@ -11,40 +11,44 @@ try:
except ImportError: except ImportError:
redis = None redis = None
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
@habemus_papam
def select_best_pope(aspect_ratio, pope): def select_best_pope(aspect_ratio, pope):
""" (float, Pope) -> PopeImage """ (float, Pope) -> PopeImage
""" """
pp = PerfectPope.objects.filter(aspect_ratio=aspect_ratio, pope=pope)
if pp:
return pp[0].image
# popes below and above this ratio # popes below and above this ratio
lte = PopeImage.objects.filter(aspect_ratio__lte=aspect_ratio, pope=pope).order_by('-aspect_ratio')[0:1] lte = PopeImage.objects.filter(aspect_ratio__lte=aspect_ratio, pope=pope).order_by('-aspect_ratio')[0:1]
gte = PopeImage.objects.filter(aspect_ratio__gte=aspect_ratio, pope=pope).order_by('aspect_ratio')[0:1] gte = PopeImage.objects.filter(aspect_ratio__gte=aspect_ratio, pope=pope).order_by('aspect_ratio')[0:1]
if gte and lte: if gte and lte:
p = min(
p = min([lte[0], gte[0]], [lte[0], gte[0]],
key= lambda x: abs(aspect_ratio - x.aspect_ratio) key=lambda x: abs(aspect_ratio - x.aspect_ratio)
) )
return_PopeImage = p return p
# if there are no popes above or below this ratio # if there are no popes above or below this ratio # do i want to get rid of this?
elif gte: elif gte: return gte[0]
return_PopeImage = gte[0] elif lte: return lte[0]
elif lte: else: return None
return_PopeImage = lte[0]
# or even if there are no popes at all :c
else:
return None
return habemus_papam(aspect_ratio, PopeImage=return_PopeImage, pope=pope)
def habemus_papam(aspect_ratio, PopeImage, pope):
pp = PerfectPope(aspect_ratio=aspect_ratio, image=PopeImage, pope=pope)
pp.save()
return PopeImage
def unpopable(width, height): def unpopable(width, height):
@ -55,48 +59,47 @@ def unpopable(width, height):
return False return False
def redis_me(func,):
def inner(*args, **kwargs):
if not redis or SAGE_REDIS:
return func(*args, **kwargs)
try:
image = redis.get(args)
if not image:
image = func(*args, **kwargs)
redis.set(args, image) # FIXME: perhaps some better key value?
redis.expire(args, REDIS_TTL)
return image
except RedisConnectionError:
return func(*args, **kwargs)
return inner
def read_pope_from_fs(width, height, pope_image): @redis_me
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()
def read_pope(width, height, pope_image): def read_pope(width, height, pope_image):
""" (int, int, PopeImage) -> bytes """ (int, int, PopeImage) -> bytes
get pope for display get pope for display
""" """
if redis and not SAGE_REDIS: im = Image.open(pope_image.path)
try: im = im.resize((width, height))
f = BytesIO() # FIXME: ceriously.
key = (width,height, pope_image) im.save(f, "jpeg")
im = redis.get(key) f.seek(0)
if not im: return f.read()
im = read_pope_from_fs(width, height, pope_image)
redis.set(key, im)
redis.expire(key, REDIS_TTL)
except RedisConnectionError:
im = read_pope_from_fs(width, height, pope_image)
else: #TODO: join those two
im = read_pope_from_fs(width, height, pope_image)
return im
def parse_pope(path): def parse_pope(path):
im = Image.open(path) im = Image.open(path)
width, height = im.size width, height = im.size
aspect_ratio = round(width/height, DECIMAL_PLACES) aspect_ratio = round(width/height, DECIMAL_PLACES)
return PopeImage(path=path, width=width, height=height, aspect_ratio=aspect_ratio) return PopeImage(
path=path,
width=width,
height=height,
aspect_ratio=aspect_ratio
)
def pope_or_death(p, **kwargs): def pope_or_death(p, **kwargs):
@ -105,4 +108,3 @@ def pope_or_death(p, **kwargs):
except ObjectDoesNotExist: except ObjectDoesNotExist:
x = None x = None
return x return x

View File

@ -5,26 +5,24 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title> </title> <title> </title>
<link rel="stylesheet" href=""> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
<style>
@media (min-width: 768px) {
.container {
max-width: 730px;
}
}
.pope {
display: inline;
}
</style>
</head> </head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
<style>
@media (min-width: 768px) {
.container {
max-width: 730px;
}
}
.pope {
display: inline;
}
</style>
<body> <body>
<a href="{{github_url}}"><img style="position: absolute; top: 0; left: 0; border: 0;" src="{% static 'img/forkme.png' %}" alt="Fork me on $%#@^%@^%"></a> <a href="{{github_url}}"><img style="position: absolute; top: 0; left: 0; border: 0;" src="{% static 'img/forkme.png' %}" alt="Fork me on $%#@^%@^%"></a>
@ -41,7 +39,7 @@
<div class="alert alert-info"> <div class="alert alert-info">
beta feature: <a href={% url 'papiezator:grand_conclave' 255 200 1 %}>BXVI!</a> beta feature: <a href="{% url 'papiezator:grand_conclave' 255 200 1 %}">BXVI!</a>
</div> </div>
<h3>How do i popes?</h3> <h3>How do i popes?</h3>

View File

@ -7,6 +7,7 @@ Replace this with more appropriate tests for your application.
from django.test import TestCase from django.test import TestCase
# TODO: kek.
class SimpleTest(TestCase): class SimpleTest(TestCase):
def test_basic_addition(self): def test_basic_addition(self):

View File

@ -15,20 +15,19 @@ def index(request):
} }
return render(request, "papiezator/index.html", c) return render(request, "papiezator/index.html", c)
def conclave(request, width, height, pope_id=0): def conclave(request, width, height, pope_id=0):
width, height = int(width), int(height) width, height = int(width), int(height)
if not unpopable(width, height): if not unpopable(width, height):
pope = pope_or_death(Pope, id=pope_id) pope = pope_or_death(Pope, id=pope_id)
if pope: if pope:
aspect_ratio = round(width/height, DECIMAL_PLACES) aspect_ratio = round(width/height, DECIMAL_PLACES)
pope_image = select_best_pope(aspect_ratio, pope) pope_image = select_best_pope(aspect_ratio, pope)
if pope_image: if pope_image:
return HttpResponse( return HttpResponse(
read_pope(width, height, pope_image), read_pope(width, height, pope_image),
mimetype="image/jpeg" content_type="image/jpeg"
) )
return HttpResponse(":c") return HttpResponse(":c")