forgot to add some files

This commit is contained in:
Feliciaan De Palmenaer 2015-03-26 21:49:14 +01:00
parent cf9fcfbad3
commit eba3fc5f07
11 changed files with 374 additions and 0 deletions

28
app/admin.py Normal file
View file

@ -0,0 +1,28 @@
from flask import url_for, redirect
from flask.ext.admin import Admin, BaseView, expose
from flask.ext.admin.contrib.sqla import ModelView
from flask.ext import login
from app import app, db
from models import User
from utils import send_command
class ModelBaseView(ModelView):
def is_accessible(self):
if login.current_user.is_anonymous():
return False
return login.current_user.is_admin()
class UserAdminModel(ModelBaseView):
column_searchable_list = ('username',)
inline_models = None
form_columns = ('username', 'admin')
admin = Admin(app, name='FoodBot', url='/foodbot/admin', template_mode='bootstrap3')
admin.add_view(UserAdminModel(User, db.session))

13
app/app.py Normal file
View file

@ -0,0 +1,13 @@
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from werkzeug.contrib.cache import SimpleCache
from logbook import Logger
app = Flask(__name__)
app.config.from_object('config.Configuration')
db = SQLAlchemy(app)
logger = Logger('FoodBot-Web')

13
app/config.example.py Normal file
View file

@ -0,0 +1,13 @@
# config
class Configuration(object):
SQLALCHEMY_DATABASE_URI = 'sqlite:///foodbot.db'
DEBUG = True
SECRET_KEY = '<change>'
SLACK_WEBHOOK = '<add url>'
PROCESS = 'python test.py'
LOGFILE = 'slotmachien.log'
ZEUS_KEY = '<fill in>'
ZEUS_SECRET = '<fill in>'
SLACK_TOKEN = '<fill in>'

13
app/config.py Normal file
View file

@ -0,0 +1,13 @@
# config
class Configuration(object):
SQLALCHEMY_DATABASE_URI = 'sqlite:///foodbot.db'
DEBUG = True
SECRET_KEY = '<change>'
SLACK_WEBHOOK = ''
PROCESS = 'python test.py'
LOGFILE = 'slotmachien.log'
ZEUS_KEY = 'tomtest'
ZEUS_SECRET = 'blargh'
SLACK_TOKEN = 'xoxp-2484654576-2486580711-4114448516-f21087'

18
app/create_database.py Normal file
View file

@ -0,0 +1,18 @@
from models import *
from app import db
db.drop_all()
db.create_all()
feli = User()
feli.configure("feliciaan", True, True)
db.session.add(feli)
don = User()
don.configure("don", True, True)
db.session.add(don)
# To future developers, add yourself here
# commit all the things
db.session.commit()

34
app/login.py Normal file
View file

@ -0,0 +1,34 @@
from flask import redirect, request, url_for, abort, session
from flask.ext.login import LoginManager, current_user, logout_user
from flask_oauthlib.client import OAuth
import requests
from app import app, db, logger, cache
from models import User
from zeus import oauth, zeus_login
login_manager = LoginManager()
login_manager.init_app(app)
@login_manager.user_loader
def load_user(userid):
return User.query.filter_by(id=userid).first()
@app.route('/foodbot/login')
def login():
return zeus_login()
@app.route('/foodbot/logout')
def logout():
if 'zeus_token' in session:
session.pop('zeus_token', None)
logout_user()
return redirect(url_for('admin.index'))
def before_request():
if current_user.is_anonymous() or not current_user.is_allowed():
abort(401)

103
app/models.py Normal file
View file

@ -0,0 +1,103 @@
import uuid
from datetime import date, timedelta
from app import db
# Create database models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
admin = db.Column(db.Boolean)
bias = db.Column(db.Integer)
courrier = db.relationship('Courrier', backref='courrier', lazy='dynamic')
logactions = db.relationship('LogAction', backref='user', lazy='dynamic')
def configure(self, username, allowed, admin, bias):
self.username = username
self.allowed = allowed
self.admin = admin
self.bias = bias
def is_authenticated(self):
return True
def is_active(self):
return True
def is_admin(self):
return self.admin
def is_anonymous(self):
return False
def get_id(self):
try:
return unicode(self.id) # python 2
except NameError:
return str(self.id) # python 3
def __repr__(self):
return '%s' % self.username
class Location(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120))
address = db.Column(db.String(254))
website = db.Column(db.String(120))
food = db.relationship('Food', backref='location', lazy='dynamic')
def configure(self, name, address, website):
self.name = name
self.address = address
self.website = website
def __repr__(self):
return '%s: %s' % (self.name, self.address)
class Food(db.Model):
id = db.Column(db.Integer, primary_key=True)
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
name = db.Column(db.String(120))
price = db.Column(db.Integer)
def configure(self, location, name, price):
self.location = location
self.name = name
self.price = price
def __repr__(self):
return '%s' % self.name
class Order(db.Model):
id = db.Column(db.Integer, primary_key=True)
courrier_id = db.Column(db.Integer, db.ForeignKey('user.id'))
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
starttime = db.Column(db.DateTime)
stoptime = db.Column(db.DateTime)
orders = db.relationship('OrdreItem', backref='order', lazy='dynamic')
def configure(self, courrier, location, starttime, stoptime):
self.courrier = courrier
self.location = location
self.starttime = starttime
self.stoptime = stoptime
def __repr__(self):
return 'Order'
class OrderItem(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
food_id = db.Column(db.Integer, db.ForeignKey('food.id'))
def configure(self, user, order, food):
self.user = user
self.order = order
self.food = food
def __repr__(self):
return 'OrderItem'

16
app/requirements.txt Normal file
View file

@ -0,0 +1,16 @@
Flask==0.10.1
Flask-Admin==1.0.9
Flask-Login==0.2.11
Flask-SQLAlchemy==2.0
Flask-WTF==0.10.3
Jinja2==2.7.2
Logbook==0.8.1
MarkupSafe==0.23
SQLAlchemy==0.9.8
WTForms==2.0
Werkzeug==0.9.6
flup==1.0.2
itsdangerous==0.24
requests==2.4.0
Flask-OAuthlib==0.8.0
oauthlib==0.7.2

43
app/views.py Normal file
View file

@ -0,0 +1,43 @@
from flask import Blueprint, request, jsonify, redirect, url_for
from app import app
from login import before_request
@app.route('/')
def home():
return render_template('home.html')
@app.route('/about/')
def about():
return render_template('about.html')
@app.route('/stats/')
def stats():
return render_template('stats.html')
if app.debug: # add route information
@app.route('/routes')
def list_routes(self):
import urllib
output = []
for rule in app.url_map.iter_rules():
options = {}
for arg in rule.arguments:
options[arg] = "[{0}]".format(arg)
methods = ','.join(rule.methods)
url = url_for(rule.endpoint, **options)
line = urllib.unquote(
"{:50s} {:20s} {}".format(rule.endpoint, methods, url))
output.append(line)
string = ''
for line in sorted(output):
string += line + "<br/>"
return string

93
app/zeus.py Normal file
View file

@ -0,0 +1,93 @@
from flask import Flask, redirect, url_for, session, request, jsonify, flash, request
from flask.ext.login import LoginManager, login_user, current_user, logout_user
from flask.ext.admin import helpers
from flask_oauthlib.client import OAuth, OAuthException
import json
import requests
from app import app, db
from models import User, Token
oauth = OAuth(app)
zeus = oauth.remote_app(
'zeus',
consumer_key=app.config['ZEUS_KEY'],
consumer_secret=app.config['ZEUS_SECRET'],
request_token_params={},
base_url='http://kelder.zeus.ugent.be/oauth/api/',
access_token_method='POST',
access_token_url='https://kelder.zeus.ugent.be/oauth/oauth2/token/',
authorize_url='https://kelder.zeus.ugent.be/oauth/oauth2/authorize/'
)
def zeus_login():
if app.debug:
return zeus.authorize(callback=url_for('authorized', _external=True))
else: # temporary solution because it otherwise gives trouble on the pi because of proxies and such
return zeus.authorize(callback='http://zeus.ugent.be/foodbot/login/zeus/authorized')
@app.route('/slotmachien/login/zeus/authorized')
def authorized():
resp = zeus.authorized_response()
if resp is None:
return 'Access denied: reason=%s error=%s' % (
request.args['error'],
request.args['error_description']
)
if isinstance(resp, OAuthException):
return 'Access denied: %s' % resp.message + '<br>' + str(resp.data)
session['zeus_token'] = (resp['access_token'], '')
me = zeus.get('current_user/')
username = me.data.get('username', '').lower()
user = User.query.filter_by(username=username).first()
if len(username) > 0 and user:
return login_and_redirect_user(user)
elif len(username) > 0:
user = create_user(username)
return login_and_redirect_user(user)
flash("You're not allowed to enter, please contact a system administrator")
return redirect(url_for("admin.index"))
@zeus.tokengetter
def get_zeus_oauth_token():
return session.get('zeus_token')
def login_and_redirect_user(user):
login_user(user)
# add_token(resp['access_token'], user)
content_type = request.headers.get('Content-Type', None)
if content_type and content_type in 'application/json':
token = add_token(user)
return jsonify({'token': token.token})
return redirect(url_for("admin.index"))
def add_token(user):
token = Token()
token.configure(user)
db.session.add(token)
db.session.commit()
return token
def create_user(username):
user = User()
user.configure(username, False)
db.session.add(user)
db.session.commit()
# EASTER EGG
text = 'Welcome ' + username + '!'
js = json.dumps({'text': text})
url = app.config['SLACK_WEBHOOK']
if len(url) > 0:
requests.post(url, data=js)
return user