Skip to content

Commit 7a56462

Browse files
committed
My progress on the todo app PyBites challenge.
Signed-off-by: Martin Uribe <[email protected]>
1 parent 6373774 commit 7a56462

10 files changed

+320
-0
lines changed

15/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
*.db
2+
venv

15/app-clamytoe.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from flask import Flask, request
2+
from flask import render_template
3+
from flask import redirect
4+
from datetime import datetime, date
5+
from flask_sqlalchemy import SQLAlchemy
6+
7+
app = Flask(__name__)
8+
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///clamytoe.db'
9+
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
10+
db = SQLAlchemy(app)
11+
12+
13+
class Tasks(db.Model):
14+
task_id = db.Column(db.Integer, primary_key=True)
15+
task = db.Column(db.Text)
16+
status = db.Column(db.Boolean, default=False)
17+
18+
def __init__(self, task, status=True):
19+
self.task = task
20+
self.status = status
21+
22+
def __repr__(self):
23+
return '<Task %s>' % self.task
24+
25+
26+
db.create_all()
27+
28+
29+
@app.route('/')
30+
def index():
31+
tasks = Tasks.query.all()
32+
return render_template('clamytoe.html', tasks=tasks)
33+
34+
35+
@app.route('/add', methods=['POST'])
36+
def add_task():
37+
task = request.form['task']
38+
39+
if not task:
40+
return redirect('/')
41+
42+
status = int(request.form['status'])
43+
44+
new_task = Tasks(task, status)
45+
db.session.add(new_task)
46+
db.session.commit()
47+
return redirect('/')
48+
49+
50+
@app.route('/delete/<int:task_id>')
51+
def delete_task(task_id):
52+
task = Tasks.query.get(task_id)
53+
54+
if not task:
55+
return redirect('/')
56+
57+
db.session.delete(task)
58+
db.session.commit()
59+
return redirect('/')
60+
61+
62+
@app.route('/clear')
63+
def clear_all():
64+
db.drop_all()
65+
db.create_all()
66+
return redirect('/')
67+
68+
69+
@app.route('/close/<int:task_id>')
70+
def close_task(task_id):
71+
task = Tasks.query.get(task_id)
72+
73+
if not task:
74+
return redirect('/')
75+
76+
if task.status:
77+
task.status = False
78+
else:
79+
task.status = True
80+
81+
db.session.commit()
82+
return redirect('/')
83+
84+
85+
if __name__ == '__main__':
86+
app.run(debug=True)

15/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
click==6.7
22
Flask==0.12.1
3+
Flask-SQLAlchemy (2.2)
34
itsdangerous==0.24
45
Jinja2==2.9.6
56
MarkupSafe==1.0
7+
SQLAlchemy (1.1.9)
68
Werkzeug==0.12.1
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*!
2+
* IE10 viewport hack for Surface/desktop Windows 8 bug
3+
* Copyright 2014-2015 Twitter, Inc.
4+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5+
*/
6+
7+
/*
8+
* See the Getting Started docs for more information:
9+
* http://getbootstrap.com/getting-started/#support-ie10-width
10+
*/
11+
@-ms-viewport { width: device-width; }
12+
@-o-viewport { width: device-width; }
13+
@viewport { width: device-width; }
14+

15/static/css/jquery-demo-ui.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
body {
2+
font-family: Arial, Helvetica, sans-serif;
3+
}
4+
5+
table {
6+
font-size: 1em;
7+
}
8+
9+
.ui-draggable, .ui-droppable {
10+
background-position: top;
11+
}
12+

15/static/css/navbar-fixed-top.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
body {
2+
min-height: 2000px;
3+
padding-top: 70px;
4+
}
5+
.jumbotron {
6+
padding-top: 12px;
7+
padding-bottom: 72px;
8+
}

15/static/favicon.ico

1.31 KB
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*!
2+
* IE10 viewport hack for Surface/desktop Windows 8 bug
3+
* Copyright 2014-2015 Twitter, Inc.
4+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5+
*/
6+
7+
// See the Getting Started docs for more information:
8+
// http://getbootstrap.com/getting-started/#support-ie10-width
9+
10+
(function () {
11+
'use strict';
12+
13+
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
14+
var msViewportStyle = document.createElement('style')
15+
msViewportStyle.appendChild(
16+
document.createTextNode(
17+
'@-ms-viewport{width:auto!important}'
18+
)
19+
)
20+
document.querySelector('head').appendChild(msViewportStyle)
21+
}
22+
23+
})();
24+

15/static/js/jquery.min.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

15/templates/clamytoe.html

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
8+
<meta name="description"
9+
content="PyBites challenge 15, creating a Flask web app that allows you to enter data via a web form. Data is displayed and is persistent with a sqllite3 database using SQLAlchemy.">
10+
<meta name="author" content="Martin Uribe">
11+
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
12+
13+
<title>Clamytoe's Task Tracking App</title>
14+
15+
<!-- Latest compiled and minified CSS -->
16+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
17+
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
18+
19+
<!-- Optional theme -->
20+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
21+
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
22+
23+
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
24+
<link href="{{ url_for('static', filename='css/ie10-viewport-bug-workaround.css') }}" rel="stylesheet">
25+
26+
<!-- Custom styles for this template -->
27+
<link href="{{ url_for('static', filename='css/navbar-fixed-top.css') }}" rel="stylesheet">
28+
</head>
29+
30+
<body>
31+
32+
<!-- Fixed navbar -->
33+
<nav class="navbar navbar-inverse navbar-fixed-top">
34+
<div class="container">
35+
<div class="navbar-header">
36+
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
37+
aria-expanded="false" aria-controls="navbar">
38+
<span class="sr-only">Toggle navigation</span>
39+
<span class="icon-bar"></span>
40+
<span class="icon-bar"></span>
41+
<span class="icon-bar"></span>
42+
</button>
43+
<a class="navbar-brand" href="http://pybit.es/codechallenge15.html">PyBites: Challenge 15</a>
44+
</div>
45+
<div id="navbar" class="navbar-collapse collapse">
46+
<ul class="nav navbar-nav">
47+
<li class="active"><a href="#">Task Tracking App</a></li>
48+
<li class="dropdown">
49+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
50+
aria-expanded="false">Other GitHub Projects <span class="caret"></span></a>
51+
<ul class="dropdown-menu">
52+
<li><a href="https://github.com/clamytoe/comicSnagger">Comic Snagger</a></li>
53+
<li><a href="https://github.com/clamytoe/randPic">Random Picture</a></li>
54+
<li role="separator" class="divider"></li>
55+
<li class="dropdown-header">GitHub Gists</li>
56+
<li><a href="https://gist.github.com/clamytoe/36fa8a8b69966bd1f57fa272461abd45">urldecode.py</a>
57+
</li>
58+
<li><a href="https://gist.github.com/clamytoe/ed3e39e5e943d10c359c">download_images.py</a></li>
59+
<li><a href="https://gist.github.com/clamytoe">More here...</a></li>
60+
</ul>
61+
</li>
62+
</ul>
63+
</div><!--/.nav-collapse -->
64+
</div>
65+
</nav>
66+
67+
<div class="container">
68+
69+
<!-- Page contents -->
70+
<div class="jumbotron">
71+
<h2>Clamytoe's Task Tracking App</h2>
72+
73+
<!-- Task input form -->
74+
<form class="navbar-form navbar-left" role="search" action="/add" method="POST">
75+
<div class="form-group">
76+
<div class="input-group">
77+
<span class="input-group-addon">Task</span>
78+
<input type="text" name="task" class="form-control" placeholder="Add new task" required>
79+
<span class="input-group-addon">Status</span>
80+
<select id="status" name="status" class="form-control">
81+
<option value=1 selected>Open</option>
82+
<option value=0>Close</option>
83+
</select>
84+
</div>
85+
<div class="input-group">
86+
<span class="spacer">&nbsp;</span>
87+
<button type="submit" class="btn btn-default">
88+
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add
89+
</button>
90+
<button type="reset" class="btn btn-default">
91+
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span> Reset
92+
</button>
93+
</div>
94+
</div>
95+
</form>
96+
</div><!-- jumbotron -->
97+
98+
<div class="tasks">
99+
100+
{% if tasks %}
101+
<div class="panel panel-default">
102+
<div class="panel-heading">
103+
<h3 class="panel-title">Tasks
104+
<span class="navbar-right">
105+
<a href="/clear">
106+
<span class="glyphicon glyphicon-trash" aria-label="Remove All"></span>
107+
</a>
108+
<span class="spacer">&nbsp;</span>
109+
</span>
110+
</h3>
111+
</div>
112+
<div class="panel-body">
113+
114+
<!-- Task table -->
115+
<table class="table table-bordered table-hover">
116+
<thead>
117+
<tr>
118+
<td style="width:100%">DESCRIPTION</td>
119+
<td>STATUS</td>
120+
<td align="center"><span class="glyphicon glyphicon-remove" aria-label="Delete"></span></td>
121+
</tr>
122+
</thead>
123+
<tbody>
124+
{% for task in tasks %}
125+
{% if task.status %}
126+
<tr class="success">
127+
<td>{{ task.task }}</td>
128+
{% else %}
129+
<tr class="active">
130+
<td><strike>{{ task.task }}</strike></td>
131+
{% endif %}
132+
<td align="center">
133+
<a href="/close/{{ task.task_id }}">
134+
{% if task.status %}
135+
<span class="glyphicon glyphicon-ok-circle" aria-label="Open"></span>
136+
{% else %}
137+
<span class="glyphicon glyphicon-ok-sign" aria-label="Close"></span>
138+
{% endif %}
139+
</a>
140+
</td>
141+
<td>
142+
<a href="/delete/{{ task.task_id }}">
143+
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>
144+
</a>
145+
</td>
146+
</tr>
147+
{% endfor %}
148+
</tbody>
149+
</table>
150+
</div><!-- panel body -->
151+
{% endif %}
152+
</div><!-- panel -->
153+
</div><!-- tasks -->
154+
</div> <!-- /container -->
155+
156+
<!-- Bootstrap core JavaScript
157+
================================================== -->
158+
<!-- Placed at the end of the document so the pages load faster -->
159+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
160+
<!-- Latest compiled and minified JavaScript -->
161+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
162+
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
163+
crossorigin="anonymous"></script>
164+
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
165+
<script src="{{ url_for('static', filename='js/ie10-viewport-bug-workaround.js') }}"></script>
166+
</body>
167+
</html>

0 commit comments

Comments
 (0)