diff --git a/app/app.py b/app/app.py index 11bac36..c4e09cd 100644 --- a/app/app.py +++ b/app/app.py @@ -1,8 +1,10 @@ from flask import Flask +from flask.ext.bootstrap import Bootstrap from flask.ext.sqlalchemy import SQLAlchemy app = Flask(__name__) app.config.from_object('config.Configuration') +Bootstrap(app) db = SQLAlchemy(app) diff --git a/app/create_database.py b/app/create_database.py index 82caa5b..44c7b21 100644 --- a/app/create_database.py +++ b/app/create_database.py @@ -9,7 +9,8 @@ feli.configure("feliciaan", True, 0) db.session.add(feli) destro = User() -destro.configure('destro', True, 0) +destro.configure('wout', True, 0) +db.session.add(destro) # To future developers, add yourself here diff --git a/app/foodbot.py b/app/foodbot.py index 0165261..92df91e 100644 --- a/app/foodbot.py +++ b/app/foodbot.py @@ -10,7 +10,9 @@ from app import app, db from admin import admin from login import login_manager from models import * +from forms import * +from utils import * from views import * if __name__ == '__main__': - app.run(debug=True) + app.run() diff --git a/app/forms.py b/app/forms.py new file mode 100644 index 0000000..8aa1a20 --- /dev/null +++ b/app/forms.py @@ -0,0 +1,31 @@ +from datetime import datetime, timedelta +from flask_wtf import Form +from wtforms import SelectField, DateTimeField, validators, SubmitField, HiddenField +from models import User, Location +from utils import euro + +__author__ = 'feliciaan' + + +class OrderForm(Form): + courrier_id = SelectField('Courrier', coerce=int) + location_id = SelectField('Location', coerce=int, validators=[validators.required()]) + starttime = DateTimeField('Starttime', default=datetime.now) + stoptime = DateTimeField('Stoptime') + submit_button = SubmitField('Submit') + + def populate(self): + self.courrier_id.choices = [(0, None)] + \ + [(u.id, u.username) for u in User.query.order_by('username')] + self.location_id.choices = [(l.id, l.name) + for l in Location.query.order_by('name')] + if self.stoptime.data is None: + self.stoptime.data = datetime.now() + timedelta(hours=1) + + +class OrderItemForm(Form): + food_id = SelectField('Item', coerce=int) + submit_button = SubmitField('Submit') + + def populate(self, location): + self.food_id.choices = [(i.id, (i.name + ": " + euro(i.price))) for i in location.food] \ No newline at end of file diff --git a/app/models.py b/app/models.py index 2fc7274..86ca9e5 100644 --- a/app/models.py +++ b/app/models.py @@ -43,6 +43,8 @@ class Location(db.Model): address = db.Column(db.String(254)) website = db.Column(db.String(120)) food = db.relationship('Food', backref='location', lazy='dynamic') + orders = db.relationship('Order', backref='location', lazy='dynamic') + def configure(self, name, address, website): self.name = name @@ -85,7 +87,7 @@ class Order(db.Model): self.stoptime = stoptime def __repr__(self): - return 'Order' + return 'Order %s' % (self.location.name) class OrderItem(db.Model): diff --git a/app/requirements.txt b/app/requirements.txt index 44bb7c4..b101d8f 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -3,6 +3,7 @@ Flask-Admin==1.0.9 Flask-Login==0.2.11 Flask-SQLAlchemy==2.0 Flask-WTF==0.10.3 +Flask-Bootstrap==3.3.2.1 Jinja2==2.7.2 MarkupSafe==0.23 SQLAlchemy==0.9.8 diff --git a/app/templates/about.html b/app/templates/about.html index a36d7c4..b2732d5 100644 --- a/app/templates/about.html +++ b/app/templates/about.html @@ -1,6 +1,7 @@ -{% extends "layout.html" %} - -{% block content %} +{% extends "layout.html" -%} +{% set active_page = "about" -%} + +{% block container %}

About

This is an About page for FoodBot. Don't I look good? Oh stop, you're making me blush.

{% endblock %} \ No newline at end of file diff --git a/app/templates/errors/401.html b/app/templates/errors/401.html new file mode 100644 index 0000000..59d7815 --- /dev/null +++ b/app/templates/errors/401.html @@ -0,0 +1,9 @@ +{% extends "layout.html" -%} + +{% block container %} +
+

Unauthorized

+

You're not authorized to look to this page!

+

Go somewhere nice

+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/errors/404.html b/app/templates/errors/404.html new file mode 100644 index 0000000..534a1e1 --- /dev/null +++ b/app/templates/errors/404.html @@ -0,0 +1,9 @@ +{% extends "layout.html" -%} + +{% block container %} +
+

Page Not Found

+

What you were looking for is just not there.

+

Go somewhere nice

+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/home.html b/app/templates/home.html index 91b872c..f2bd54d 100644 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -1,5 +1,6 @@ -{% extends "layout.html" %} -{% block content %} +{% extends "layout.html" -%} +{% set active_page = "home" -%} +{% block container %}

Welcome to FoodBot

This is the home page for FoodBot

diff --git a/app/templates/home_loggedin.html b/app/templates/home_loggedin.html new file mode 100644 index 0000000..8207d05 --- /dev/null +++ b/app/templates/home_loggedin.html @@ -0,0 +1,14 @@ +{% extends "home.html" %} +{% block container %} +{{ super() }} +
+
+

Open orders:

+ +
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/layout.html b/app/templates/layout.html index 772121c..fd0ca1d 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -1,16 +1,24 @@ - - - - - - - FoodBot +{% extends "bootstrap/base.html" %} - +{% set navbar = [ + ('home', 'Home'), + ('orders', 'Orders'), + ('about', 'About'), + ('stats', 'Stats'), +] -%} +{% if not current_user.is_anonymous() and current_user.is_admin() -%} + {% set navbar = navbar + [('admin.index', 'Admin')] -%} +{% endif -%} +{% set active_page = active_page|default('index') -%} + +{% block title %} + FoodBot +{% endblock %} +{% block styles %} + {{ super() }} - - - +{% endblock %} +{% block navbar %} +{% endblock %} + +{% block content -%}
- {% block content %} - {% endblock %} + {% block container -%} + {%- endblock %}
- - - - - - \ No newline at end of file +{%- endblock %} diff --git a/app/templates/login.html b/app/templates/login.html deleted file mode 100644 index a70fb3d..0000000 --- a/app/templates/login.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "layout.html" %} - -{% block content %} -
- - - -
-{% endblock %} \ No newline at end of file diff --git a/app/templates/order.html b/app/templates/order.html new file mode 100644 index 0000000..7485461 --- /dev/null +++ b/app/templates/order.html @@ -0,0 +1,18 @@ +{% extends "layout.html" %} +{% set active_page = "orders" -%} + +{% block container %} +
+
+

Order {{ order.id }}

+ Courrier: {{ order.courrier.username }}
+ Location: {{ order.location.name }}
+ Starttime: {{ order.starttime }}
+ Stoptime: {{ order.stoptime }}
+

Orders

+ {% for item in order.orders %} + {{ item.user.username }} - {{ item.food.name }} - {{ item.food.price|euro }}
+ {% endfor %} +
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/order_form.html b/app/templates/order_form.html new file mode 100644 index 0000000..a5b5068 --- /dev/null +++ b/app/templates/order_form.html @@ -0,0 +1,9 @@ +{% extends "layout.html" %} +{% set active_page = "orders" -%} + +{% import "bootstrap/wtf.html" as wtf %} +{% block container %} +
+ {{ wtf.quick_form(form, action=url, button_map={'submit_button': 'primary'}) }} +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/orders.html b/app/templates/orders.html new file mode 100644 index 0000000..4673a78 --- /dev/null +++ b/app/templates/orders.html @@ -0,0 +1,20 @@ +{% extends 'layout.html' %} +{% set active_page = "orders" -%} + +{% import "bootstrap/wtf.html" as wtf %} +{% block container %} +
+
+

Open orders:

+ +
+
+ {{ wtf.quick_form(form, action=url_for('order_create'), button_map={'submit_button': 'primary'}, form_type='horizontal') }} +
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/stats.html b/app/templates/stats.html index 553a0d1..5518a47 100644 --- a/app/templates/stats.html +++ b/app/templates/stats.html @@ -1,6 +1,6 @@ -{% extends "layout.html" %} - -{% block content %} +{% extends "layout.html" -%} +{% set active_page = "stats" -%} +{% block container %}

Stats bruh

TOP 4

{% endblock %} \ No newline at end of file diff --git a/app/utils.py b/app/utils.py new file mode 100644 index 0000000..60150bf --- /dev/null +++ b/app/utils.py @@ -0,0 +1,17 @@ +from flask import render_template + +from app import app +__author__ = 'feliciaan' + +@app.template_filter('euro') +def euro(value): + result = '€' + str(value/100) + return result + +@app.errorhandler(404) +def handle404(e): + return render_template('errors/404.html'), 404 + +@app.errorhandler(401) +def handle401(e): + return render_template('errors/401.html'), 401 \ No newline at end of file diff --git a/app/views.py b/app/views/__init__.py similarity index 56% rename from app/views.py rename to app/views/__init__.py index d9401f0..f68989f 100644 --- a/app/views.py +++ b/app/views/__init__.py @@ -1,11 +1,20 @@ -from flask import url_for, render_template +__author__ = 'feliciaan' -from app import app +from flask import url_for, render_template, abort, redirect, request +from flask.ext.login import current_user, login_required +from datetime import datetime +from app import app, db +from models import Order, OrderItem +# import views +import views.order @app.route('/') def home(): + if not current_user.is_anonymous(): + orders = Order.query.filter((Order.stoptime > datetime.now()) | (Order.stoptime == None)).all() + return render_template('home_loggedin.html', orders=orders) return render_template('home.html') @@ -15,23 +24,25 @@ def about(): @app.route('/stats/') +@login_required def stats(): return render_template('stats.html') if app.debug: # add route information @app.route('/routes') - def list_routes(self): + @login_required + def list_routes(): import urllib output = [] for rule in app.url_map.iter_rules(): options = {} for arg in rule.arguments: options[arg] = "[{0}]".format(arg) - + print(rule.endpoint) methods = ','.join(rule.methods) url = url_for(rule.endpoint, **options) - line = urllib.unquote( + line = urllib.parse.unquote( "{:50s} {:20s} {}".format(rule.endpoint, methods, url)) output.append(line) diff --git a/app/views/order.py b/app/views/order.py new file mode 100644 index 0000000..e3f094c --- /dev/null +++ b/app/views/order.py @@ -0,0 +1,61 @@ +__author__ = 'feliciaan' +from flask import url_for, render_template, abort, redirect +from flask.ext.login import current_user, login_required +from datetime import datetime + +from app import app, db +from models import Order, OrderItem +from forms import OrderItemForm, OrderForm + + +@app.route('/order/') +@login_required +def order(id): + order = Order.query.filter(Order.id == id).first() + if order is not None: + return render_template('order.html', order=order) + return abort(404) + + +@app.route('/order//create', methods=['GET', 'POST']) +@login_required +def order_item_create(id): + order = Order.query.filter(Order.id == id).first() + if order is not None: + form = OrderItemForm() + form.populate(order.location) + if form.validate_on_submit(): + item = OrderItem() + form.populate_obj(item) + item.order_id = id + item.user_id = current_user.id + db.session.add(item) + db.session.commit() + return redirect(url_for('order', id=id)) + return render_template('order_form.html', form=form, url=url_for("order_item_create", id=id)) + return abort(404) + + +@app.route('/order/create', methods=['GET', 'POST']) +@login_required +def order_create(): + orderForm = OrderForm() + orderForm.populate() + if orderForm.validate_on_submit(): + order = Order() + orderForm.populate_obj(order) + db.session.add(order) + db.session.commit() + return redirect(url_for('order', id=order.id)) + + return render_template('order_form.html', form=orderForm, url=url_for("order_create")) + + +@app.route('/order') +@login_required +def orders(): + orders = Order.query.filter((Order.stoptime > datetime.now()) | (Order.stoptime == None)).all() + orderForm = OrderForm() + orderForm.populate() + return render_template('orders.html', orders=orders, form=orderForm) + diff --git a/app/zeus.py b/app/zeus.py index 553509d..5fecf91 100644 --- a/app/zeus.py +++ b/app/zeus.py @@ -60,7 +60,7 @@ def get_zeus_oauth_token(): def login_and_redirect_user(user): login_user(user) - return redirect(url_for("admin.index")) + return redirect(url_for("home")) def create_user(username):