Skip to content

Commit 8f63566

Browse files
committed
initial commit
0 parents  commit 8f63566

File tree

8 files changed

+190
-0
lines changed

8 files changed

+190
-0
lines changed

application/__init__.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
from urlparse import urlparse
3+
from flask import Flask, render_template
4+
5+
from application.cache import recipes
6+
7+
app = Flask(__name__)
8+
9+
@app.template_filter('hostname_link')
10+
def hostname(url):
11+
if not url:
12+
return 'Unknown'
13+
14+
parsed = urlparse(url)
15+
if not parsed.hostname:
16+
return url
17+
18+
return '<a href="{}" target="_blank">{}</a>'.format(url, parsed.hostname)
19+
20+
21+
@app.template_filter('sorted')
22+
def mysorted(mylist):
23+
return sorted(mylist)
24+
25+
26+
@app.template_filter('nl2br')
27+
def nl2br(string):
28+
return string.replace('\n', '<br/>')
29+
30+
31+
@app.route("/")
32+
def index():
33+
return render_template('recipes.html', recipes=recipes.all())
34+
35+
36+
@app.route("/recipe/<string:id>")
37+
def recipe(id):
38+
single = recipes.single(id)
39+
print(single)
40+
return render_template('recipe.html', recipe=single, categories=[])
41+
42+
43+
@app.route("/cat")
44+
def categories():
45+
return render_template('categories.html', categories=[])
46+
47+
48+
@app.route("/cat/<string:id>")
49+
def category(id):
50+
return render_template('recipes.html', recipes=recipes.in_category(id))
51+
52+
53+
@app.route("/search")
54+
def search():
55+
pass

application/cache.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
import boto3
3+
import datetime
4+
import json
5+
import os
6+
7+
# In minutes, cache recipe list for this long
8+
CACHE_TTL = 30
9+
10+
class Recipes():
11+
def __init__(self, s3_bucket, s3_key):
12+
self.s3 = boto3.resource('s3')
13+
self.s3_bucket = s3_bucket
14+
self.s3_key = s3_key
15+
self.data = None
16+
17+
self._get_recipes()
18+
19+
def _get_recipes(self):
20+
if not self.data or self.refresh_time < datetime.datetime.utcnow():
21+
self.data = json.load(self.s3.Object(self.s3_bucket, self.s3_key).get().get('Body'))
22+
print('Refreshed data')
23+
self.refresh_time = datetime.datetime.utcnow() + datetime.timedelta(minutes=CACHE_TTL)
24+
25+
return self.data
26+
27+
def all(self):
28+
return self._get_recipes()
29+
30+
def single(self, title):
31+
recipes = self._get_recipes()
32+
if title in recipes:
33+
return recipes[title]
34+
35+
return False
36+
37+
recipes = Recipes(
38+
os.environ.get('S3_BUCKET', 'not-your-grandmas-recipe-box'),
39+
os.environ.get('S3_KEY', 'recipe-box-conversion.json')
40+
)

application/templates/categories.html

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<html>
2+
<body>
3+
<table>
4+
<tr>
5+
<th>Category Name</th>
6+
<th>View Recipes</th>
7+
</tr>
8+
{% for category in categories: %}
9+
<tr>
10+
<td>{{category['ZCATEGORYNAME']}}: {{category['ZCATEGORYITEM']}}</td>
11+
<td><a href="{{url_for('category', id=category['CATEGORY_ID'])}}">Show</a></td>
12+
</tr>
13+
{% endfor %}
14+
</table>
15+
</body>
16+
</html>

application/templates/recipe.html

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<html>
2+
<head>
3+
<title>{{recipe['title']}}</title>
4+
</head>
5+
<body>
6+
<h1>{{recipe['title']}}</h1>
7+
8+
<h3>Ingredients</h3>
9+
10+
{% if recipe.get('image'): %}
11+
<div style="float: right"><img src="{{recipe.get('image')}}" alt="preview image of {{recipe['title']}}"/></div>
12+
{% endif %}
13+
14+
<ul>
15+
{% for ingredient in recipe['ingredients'].split('\n'): %}
16+
<li>{{ingredient}}</li>
17+
{% endfor %}
18+
</ul>
19+
20+
<h3>Instructions</h3>
21+
<ul>
22+
{% for instruction in recipe['instructions'].split('\n'): %}
23+
<li>{{instruction}}</li>
24+
{% endfor %}
25+
</ul>
26+
27+
{% if recipe.get('creation_date'): %}
28+
<div>Added to my collection: {{recipe['creation_date']}}</div>
29+
{% endif %}
30+
<div>Source: {{recipe['source']|hostname_link|safe}}</div>
31+
</body>
32+
</html>

application/templates/recipes.html

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<html>
2+
<head>
3+
<title>My Recipes</title>
4+
<style>
5+
IMG {
6+
max-width: 300px;
7+
max-height: 300px;
8+
}
9+
</style>
10+
</head>
11+
<body>
12+
<table>
13+
<tr>
14+
<th>Title</th>
15+
<th>Source</th>
16+
<th>Image</th>
17+
</tr>
18+
{% for recipe in recipes.keys()|sorted: %}
19+
<tr>
20+
<td><a href="{{url_for('recipe', id=recipe)}}">{{recipes[recipe]['title']}}</a></td>
21+
<td>{{recipes[recipe].get('source', '')|hostname_link|safe}}</td>
22+
{% if recipes[recipe].get('image'): %}
23+
<td><img src="{{recipes[recipe].get('image')}}" alt="preview image of {{recipe}}"/></td>
24+
{% else: %}
25+
<td></td>
26+
{% endif %}
27+
</tr>
28+
{% endfor %}
29+
</table>
30+
</body>
31+
</html>

manage.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
from application import app
3+
4+
app.run(debug=True)

requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask==1.0.2
2+
Zappa==0.46.2

zappa_settings.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"dev": {
3+
"app_function": "application.app",
4+
"project_name": "recipebox",
5+
"runtime": "python2.7",
6+
"s3_bucket": "zappa-oqur98hrv",
7+
"domain": "recipebox.archertech.ca",
8+
"exclude": ["unarchiving"]
9+
}
10+
}

0 commit comments

Comments
 (0)