Become a programmer, they said. It'll be fun, they said.
parent
483272ce50
commit
7c5965dcd8
|
@ -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)
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- encoding: utf-8 -*-
|
|
||||||
|
|
||||||
class ENOPopeException(Exception): pass
|
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue