Skip to content

Commit

Permalink
working on dynamically adding presentations via admin interface
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmakai committed Dec 16, 2014
1 parent 81cde49 commit 415e612
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 5 deletions.
9 changes: 8 additions & 1 deletion cyoa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import redis
from flask import Flask
from flask.ext.login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.socketio import SocketIO
import redis

app = Flask(__name__, static_url_path='/static')
app.config.from_pyfile('config.py')
Expand All @@ -10,6 +12,11 @@
redis_db = redis.StrictRedis(host=REDIS_SERVER, port=REDIS_PORT, db=REDIS_DB)

socketio = SocketIO(app)
db = SQLAlchemy(app)

login_manager = LoginManager()
login_manager.login_view = 'admin_sign_in'
login_manager.init_app(app)

from . import views
from . import websockets
1 change: 1 addition & 0 deletions cyoa/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# General Flask app settings
DEBUG = os.environ.get('DEBUG', None)
SECRET_KEY = os.environ.get('SECRET_KEY', None)
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', None)

# Redis connection
REDIS_SERVER = os.environ.get('REDIS_SERVER', None)
Expand Down
73 changes: 73 additions & 0 deletions cyoa/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from flask import url_for
from flask.ext.login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

from . import db


class User(UserMixin, db.Model):
"""
Represents an admin user in cyoa.
"""
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(64), unique=True, index=True)
password_hash = db.Column(db.String(128))

def __init__(self, email, password):
self.email = email
self.password = password

@property
def password(self):
raise AttributeError('password is not readable')

@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)

def verify_password(self, password):
return check_password_hash(self.password_hash, password)

def __repr__(self):
return '<User %r>' % self.email


class Presentation(db.Model):
"""
Contains data regarding a single presentation.
"""
__tablename__ = 'presentations'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
filename = db.Column(db.String(256))
is_active = db.Column(db.Boolean, default=False)
choices_number = db.Column(db.String(32), default="")
choices_email = db.Column(db.String(40), default="")
choices = db.relationship('Choice', lazy='dynamic')

def __init__(self, name, filename):
self.name = name
self.filename = filename

def __repr__(self):
return '<Presentation %r>' % self.name


class Choice(db.Model):
"""
A branch in the storyline that an audience member can vote on.
Maps directly into what is stored in Redis.
"""
__tablename__ = 'choices'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
votes = db.Column(db.Integer, default=0)
presentation = db.Column(db.Integer, db.ForeignKey('presentations.id'))

def __init__(self, name):
self.name = name

def __repr__(self):
return '<Choice %r>' % self.name

2 changes: 2 additions & 0 deletions cyoa/templates/list_presentations.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Placeholder for listing presentations.

19 changes: 17 additions & 2 deletions cyoa/views.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import cgi
from flask import render_template, abort, request
from flask.ext.login import login_user, logout_user, login_required, \
current_user
from jinja2 import TemplateNotFound
from twilio import twiml
from twilio.rest import TwilioRestClient

from .config import TWILIO_NUMBER
from .models import User, Presentation, Choice

from . import app, redis_db, socketio
from . import app, redis_db, socketio, db, login_manager

client = TwilioRestClient()

@login_manager.user_loader
def load_user(userid):
return User.query.get(int(userid))


@app.route('/', methods=['GET'])
def list_public_presentations():
presentations = Presentation.query.filter_by(is_active=True)
return render_template('list_presentations.html',
presentations=presentations)


@app.route('/<presentation_name>/', methods=['GET'])
def landing(presentation_name):
def presentation(presentation_name):
try:
return render_template(presentation_name + '.html')
except TemplateNotFound:
abort(404)


@app.route('/cyoa/twilio/webhook/', methods=['POST'])
def twilio_callback():
to = request.form.get('To', '')
Expand Down
10 changes: 8 additions & 2 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
import os
import redis

from cyoa import app, redis_db, socketio
from cyoa import app, redis_db, socketio, db
from cyoa.models import User, Presentation, Choice
from flask.ext.script import Manager, Shell

manager = Manager(app)

def make_shell_context():
return dict(app=app, redis_db=redis_db)
return dict(app=app, redis_db=redis_db, db=db, User=User,
Presentation=Presentation, Choice=Choice)

manager.add_command("shell", Shell(make_context=make_shell_context))

@manager.command
def syncdb():
db.create_all()

@manager.command
def runserver():
socketio.run(app, "0.0.0.0", port=5001)
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Flask==0.10.1
Flask-Script==2.0.5
Flask-SocketIO==0.4.1
Flask-Login==0.2.11
Flask-SQLAlchemy==2.0

gunicorn==19.1.1

redis==2.10.3

twilio==3.6.8

psycopg2==2.5.4

0 comments on commit 415e612

Please sign in to comment.