Created
October 4, 2018 01:42
-
-
Save the-vampiire/ae0ab723cd34af8fc5bc185cec124fe2 to your computer and use it in GitHub Desktop.
studio 8 solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from flask import request, redirect, render_template, session, flash | |
| import cgi | |
| from app import app, db | |
| from models import Movie, User | |
| # a list of movie names that nobody should have to watch | |
| terrible_movies = [ | |
| "Gigli", | |
| "Star Wars Episode 1: Attack of the Clones", | |
| "Paul Blart: Mall Cop 2", | |
| "Nine Lives", | |
| "Starship Troopers" | |
| ] | |
| def get_current_watchlist(user): | |
| return Movie.query.filter_by(watched=False, user_id=user.id).all() | |
| def get_watched_movies(user): | |
| return Movie.query.filter_by(watched=True, user_id=user.id).all() | |
| @app.route("/login", methods=['GET', 'POST']) | |
| def login(): | |
| if request.method == 'GET': | |
| return render_template('login.html') | |
| elif request.method == 'POST': | |
| email = request.form['email'] | |
| password = request.form['password'] | |
| users = User.query.filter_by(email=email) | |
| if users.count() == 1: | |
| user = users.first() | |
| if password == user.password: | |
| session['user'] = user.email | |
| flash('welcome back, '+user.email) | |
| return redirect("/") | |
| flash('bad username or password') | |
| return redirect("/login") | |
| @app.route("/register", methods=['GET', 'POST']) | |
| def register(): | |
| if request.method == 'POST': | |
| email = request.form['email'] | |
| password = request.form['password'] | |
| verify = request.form['verify'] | |
| if not is_email(email): | |
| flash('zoiks! "' + email + '" does not seem like an email address') | |
| return redirect('/register') | |
| email_db_count = User.query.filter_by(email=email).count() | |
| if email_db_count > 0: | |
| flash('yikes! "' + email + '" is already taken and password reminders are not implemented') | |
| return redirect('/register') | |
| if password != verify: | |
| flash('passwords did not match') | |
| return redirect('/register') | |
| user = User(email=email, password=password) | |
| db.session.add(user) | |
| db.session.commit() | |
| session['user'] = user.email | |
| return redirect("/") | |
| else: | |
| return render_template('register.html') | |
| def is_email(string): | |
| # for our purposes, an email string has an '@' followed by a '.' | |
| # there is an embedded language called 'regular expression' that would crunch this implementation down | |
| # to a one-liner, but we'll keep it simple: | |
| atsign_index = string.find('@') | |
| atsign_present = atsign_index >= 0 | |
| if not atsign_present: | |
| return False | |
| else: | |
| domain_dot_index = string.find('.', atsign_index) | |
| domain_dot_present = domain_dot_index >= 0 | |
| return domain_dot_present | |
| @app.route("/logout", methods=['POST']) | |
| def logout(): | |
| del session['user'] | |
| return redirect("/") | |
| # Create a new route called rate_movie which handles a POST request on /rating-confirmation | |
| @app.route("/rating-confirmation", methods=['POST']) | |
| def rate_movie(): | |
| movie_id = request.form['movie_id'] | |
| rating = request.form['rating'] | |
| user_email = session["user"] | |
| user = User.query.filter_by(email=user_email).first() | |
| movie = Movie.query.get(movie_id) | |
| if movie not in get_watched_movies(user): | |
| # the user tried to rate a movie that isn't in their list, | |
| # so we redirect back to the front page and tell them what went wrong | |
| error = "'{0}' is not in your Watched Movies list, so you can't rate it!".format(movie) | |
| # redirect to homepage, and include error as a query parameter in the URL | |
| return redirect("/?error=" + error) | |
| # if we didn't redirect by now, then all is well | |
| movie.rating = rating | |
| db.session.add(movie) | |
| db.session.commit() | |
| return render_template('rating-confirmation.html', movie=movie, rating=rating) | |
| # Creates a new route called movie_ratings which handles a GET on /ratings | |
| @app.route("/ratings", methods=['GET']) | |
| def movie_ratings(): | |
| user = User.get_authed_user(session, "user") | |
| return render_template('ratings.html', movies = get_watched_movies(user)) | |
| @app.route("/crossoff", methods=['POST']) | |
| def crossoff_movie(): | |
| crossed_off_movie_id = request.form['crossed-off-movie'] | |
| crossed_off_movie = Movie.query.get(crossed_off_movie_id) | |
| if not crossed_off_movie: | |
| return redirect("/?error=Attempt to watch a movie unknown to this database") | |
| # if we didn't redirect by now, then all is well | |
| crossed_off_movie.watched = True | |
| db.session.add(crossed_off_movie) | |
| db.session.commit() | |
| return render_template('crossoff.html', crossed_off_movie=crossed_off_movie) | |
| @app.route("/add", methods=['POST']) | |
| def add_movie(): | |
| # look inside the request to figure out what the user typed | |
| new_movie_name = request.form['new-movie'] | |
| # get the logged in user | |
| user_email = session["user"] | |
| user = User.query.filter_by(email=user_email).first() | |
| if not user: | |
| error = "User not found" | |
| return redirect(f"/?error={error}") | |
| # if the user typed nothing at all, redirect and tell them the error | |
| if (not new_movie_name) or (new_movie_name.strip() == ""): | |
| error = "Please specify the movie you want to add." | |
| return redirect("/?error=" + error) | |
| # if the user wants to add a terrible movie, redirect and tell them the error | |
| if new_movie_name in terrible_movies: | |
| error = "Trust me, you don't want to add '{0}' to your Watchlist".format(new_movie_name) | |
| return redirect("/?error=" + error) | |
| movie = Movie(new_movie_name) | |
| movie.user = user | |
| db.session.add(movie) | |
| db.session.commit() | |
| return render_template('add-confirmation.html', movie=movie) | |
| @app.route("/") | |
| def index(): | |
| encoded_error = request.args.get("error") | |
| user_email = session["user"] | |
| user = User.query.filter_by(email=user_email).first() | |
| return render_template('edit.html', watchlist=get_current_watchlist(user), error=encoded_error and cgi.escape(encoded_error, quote=True)) | |
| endpoints_without_login = ['login', 'register'] | |
| @app.before_request | |
| def require_login(): | |
| if not ('user' in session or request.endpoint in endpoints_without_login): | |
| return redirect("/register") | |
| # In a real application, this should be kept secret (i.e. not on github) | |
| # As a consequence of this secret being public, I think connection snoopers or | |
| # rival movie sites' javascript could hijack our session and act as us, | |
| # perhaps giving movies bad ratings - the HORROR. | |
| app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RU' | |
| if __name__ == "__main__": | |
| app.run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from app import db | |
| class User(db.Model): | |
| id = db.Column(db.Integer, primary_key=True) | |
| email = db.Column(db.String(120), unique=True) | |
| password = db.Column(db.String(120)) | |
| movies = db.relationship("Movie", backref="user") | |
| @classmethod | |
| def get_authed_user(cls, session, identifier): | |
| user_email = session[identifier] | |
| return cls.query.filter_by(email=user_email).first() | |
| def __init__(self, email, password): | |
| self.email = email | |
| self.password = password | |
| def __repr__(self): | |
| return '<User %r>' % self.email | |
| class Movie(db.Model): | |
| id = db.Column(db.Integer, primary_key=True) | |
| name = db.Column(db.String(120)) | |
| watched = db.Column(db.Boolean) | |
| rating = db.Column(db.String(20)) | |
| user_id = db.Column(db.ForeignKey("user.id")) | |
| def __init__(self, name): | |
| self.name = name | |
| self.watched = False | |
| def __repr__(self): | |
| return '<Movie %r>' % self.name |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment