Skip to content

Commit d30b970

Browse files
committed
basic flask app for pcc50
1 parent f311ea8 commit d30b970

File tree

6 files changed

+226
-0
lines changed

6 files changed

+226
-0
lines changed

50/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Code Challenge 50 - Use Celery to offload a task
2+
3+
* Take the challenge [on our platform](https://codechalleng.es/challenges/50)

50/app.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import time
2+
3+
from flask import render_template, request, Flask
4+
5+
DEFAULT_BANNER = 'https://pbs.twimg.com/media/DZsKAs9W4AAEdpO.jpg:large'
6+
DEFAULT_GREETING = 'I wish your a Happy Easter'
7+
MSG = '''<p>Hey {name}, {greeting}!</p>
8+
<p>Enjoy and keep calm and code in Python!</p>
9+
<img width="400px;" src="{banner}" alt="nice Easter banner">
10+
'''
11+
TIMEOUT = 1
12+
13+
app = Flask(__name__)
14+
15+
16+
def _emails_users(emails, banner, message):
17+
emails_done = {}
18+
for email in emails:
19+
# just printing message, bonus challenge: make it work with Sendgrid
20+
name = email.split('@')[0] # for demo purposes
21+
mail_body = MSG.format(name=name,
22+
greeting=message or DEFAULT_GREETING,
23+
banner=banner,
24+
message=message)
25+
26+
emails_done[email] = mail_body
27+
28+
# simulate some heavy processing
29+
time.sleep(TIMEOUT)
30+
31+
return emails_done
32+
33+
34+
@app.route('/', methods=['GET', 'POST'])
35+
def login():
36+
banner = emails = message = emails_done = None
37+
38+
if request.method == 'POST':
39+
banner = request.form.get('url') or DEFAULT_BANNER
40+
emails = [email.strip() for email in
41+
request.form.get('emails').split(',')]
42+
message = request.form.get('message')
43+
44+
emails_done = _emails_users(emails, banner, message).items()
45+
46+
return render_template("index.html",
47+
default_banner=DEFAULT_BANNER,
48+
banner=banner or '',
49+
emails=emails and ', '.join(emails) or '',
50+
message=message or '',
51+
emails_done=emails_done)
52+
53+
54+
if __name__ == "__main__":
55+
app.run(debug=True)

50/requirements.txt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
amqp==2.2.2
2+
billiard==3.5.0.3
3+
celery==4.1.0
4+
click==6.7
5+
Flask==0.12.2
6+
itsdangerous==0.24
7+
Jinja2==2.10
8+
kombu==4.1.0
9+
MarkupSafe==1.0
10+
pytz==2018.3
11+
vine==1.1.4
12+
Werkzeug==0.14.1

50/static/style.css

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
body {
2+
font : 85% "Lucida Grande", Helvetica, "Lucida Sans Unicode", Arial, Verdana, sans-serif;
3+
color:#000;
4+
margin: 0 auto;
5+
width: 800px;
6+
}
7+
8+
form {
9+
margin: 20px 0;
10+
}
11+
12+
table {
13+
margin: 20px 0;
14+
width: 800px;
15+
}
16+
17+
th {
18+
text-align: left;
19+
}
20+
21+
a {
22+
text-decoration: underline !important;
23+
}
24+
a.pure-button {
25+
text-decoration: underline !important;
26+
}
27+
28+
td, th {
29+
border: 1px solid #ddd !important;
30+
}
31+
textarea {
32+
height: 50px;
33+
}
34+
.pure-form-stacked input,
35+
.pure-form-stacked textarea {
36+
width: 600px;
37+
margin: 10px 0;
38+
}
39+
.alert {
40+
font-weight: bold;
41+
color: #900;
42+
}
43+
.ok {
44+
font-weight: bold;
45+
color: green;
46+
}
47+
.done {
48+
text-decoration: line-through;
49+
}
50+
51+
.active {
52+
background-color: #000 !important;
53+
}
54+
.active a {
55+
color: #fff;
56+
}
57+
58+
.button-success,
59+
.button-error,
60+
.button-warning,
61+
.button-secondary {
62+
color: white;
63+
border-radius: 4px;
64+
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
65+
}
66+
67+
.button-success {
68+
background: rgb(28, 184, 65); /* this is a green */
69+
}
70+
71+
.button-error {
72+
background: rgb(202, 60, 60); /* this is a maroon */
73+
}
74+
75+
.button-warning {
76+
background: rgb(223, 117, 20); /* this is an orange */
77+
}
78+
79+
.button-secondary {
80+
background: rgb(66, 184, 221); /* this is a light blue */
81+
}
82+
83+
.button-inactive {
84+
opacity: 0.3;
85+
}
86+
87+
.currentDate {
88+
border: 2px solid green;
89+
}
90+
.loginSection {
91+
padding: 15px 0 0 10px;
92+
}

50/templates/base.html

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
{% block head %}
5+
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
6+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
7+
<link rel="shortcut icon" href="{{ url_for('static', filename='images/send_sms.png') }}">
8+
9+
<title>PyBites Easter Challenge</title>
10+
{% endblock %}
11+
</head>
12+
<body>
13+
<div class="pure-g">
14+
<div class="pure-u-5-5">
15+
<h1>PyBites Easter Challenge</h1>
16+
<p>Don't forget to <a href="https://codechalleng.es/challenges/50/" target="_blank">PR when done</a> to obtain our special
17+
<a href="https://codechalleng.es/badge/easter" target="_blank">PyBites Easter Badge</a>!</p>
18+
</div>
19+
20+
</div>
21+
22+
<div id="content">{% block content %}{% endblock %}</div>
23+
</body>
24+
</html>

50/templates/index.html

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{% extends "base.html" %}
2+
{% block content %}
3+
4+
{% if emails_done %}
5+
6+
<h2 class='ok'>Messages sent! <small>(<a href="/">go back</a>)</small></h2>
7+
<table class="pure-table">
8+
<thead>
9+
<tr>
10+
<th>Email</th>
11+
<th>Message</th>
12+
</tr>
13+
</thead>
14+
15+
<tbody>
16+
{% for email, message in emails_done %}
17+
<tr>
18+
<td>{{ email }}</td>
19+
<td>{{ message|safe }}</td>
20+
</tr>
21+
{% endfor %}
22+
</tbody>
23+
</table>
24+
25+
{% else %}
26+
27+
<img src="{{ default_banner }}" alt="PyBites Easter banner">
28+
<br>
29+
30+
<h2>Send your friends a Easter card:</h2>
31+
<form id="search" class="pure-form pure-form-stacked" action="/" method="post">
32+
<input name="banner" value="{{ banner }}" placeholder="Choose a banner URL (leave empty to use PyBites banner above)">
33+
<textarea name="emails" placeholder="Comma separated emails">{{ emails }}</textarea>
34+
<textarea name="message" placeholder="Optional message">{{ message }}</textarea>
35+
<button type="submit" class="pure-button pure-button-primary">Send</button>
36+
</form>
37+
38+
{% endif%}
39+
40+
{% endblock %}

0 commit comments

Comments
 (0)