Skip to content

Commit

Permalink
finished the project, now it just needs comments
Browse files Browse the repository at this point in the history
  • Loading branch information
lucobaco committed Feb 6, 2023
1 parent 48ed474 commit 9d2dd68
Show file tree
Hide file tree
Showing 14 changed files with 699 additions and 146 deletions.
87 changes: 83 additions & 4 deletions movie_library/forms.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,92 @@
from flask_wtf import FlaskForm
from wtforms import IntegerField, StringField, SubmitField
from wtforms.validators import InputRequired, NumberRange
from wtforms import (
IntegerField,
PasswordField,
StringField,
SubmitField,
TextAreaField,
URLField,
)

from wtforms.validators import (
InputRequired,
Email,
EqualTo,
Length,
NumberRange,
)


class LoginForm(FlaskForm):
email = StringField("Email", validators=[InputRequired(), Email()])
password = PasswordField("Password", validators=[InputRequired()])
submit = SubmitField("Login")


class RegisterForm(FlaskForm):
email = StringField("Email", validators=[InputRequired(), Email()])

password = PasswordField(
"Password",
validators=[
InputRequired(),
Length(
min=4,
max=20,
message="Your password must be between 4 and 20 characters long.",
),
],
)

confirm_password = PasswordField(
"Confirm Password",
validators=[
InputRequired(),
EqualTo(
"password",
message="This password did not match the one in the password field.",
),
],
)

submit = SubmitField("Register")


class MovieForm(FlaskForm):
title = StringField("Title", validators=[InputRequired()])
director = StringField("Director", validators=[InputRequired()])

year = IntegerField("Year", validators=[InputRequired(),
NumberRange(min=1878, message="Please enter a year in YYYY format")])
year = IntegerField(
"Year",
validators=[
InputRequired(),
NumberRange(min=1878, message="Please enter a year in the format YYYY."),
],
)

submit = SubmitField("Add Movie")


class StringListField(TextAreaField):
def _value(self):
if self.data:
return "\n".join(self.data)
else:
return ""

def process_formdata(self, valuelist):
# checks valuelist contains at least 1 element, and the first element isn't falsy (i.e. empty string)
if valuelist and valuelist[0]:
self.data = [line.strip() for line in valuelist[0].split("\n")]
else:
self.data = []


class ExtendedMovieForm(MovieForm):
cast = StringListField("Cast")
series = StringListField("Series")
tags = StringListField("Tags")
description = TextAreaField("Description")
video_link = URLField("Video link")

submit = SubmitField("Submit")
10 changes: 8 additions & 2 deletions movie_library/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ class Movie:
title: str
director: str
year: int

# optional
cast: list[str] = field(default_factory=list)
series: list[str] = field(default_factory=list)
last_watched: datetime = None
rating: int = 0
tags: list[str] = field(default_factory=list)
description: str = None
video_link: str = None


@dataclass
class User:
_id: str
email: str
password: str
movies: list[str] = field(default_factory=list)
159 changes: 151 additions & 8 deletions movie_library/routes.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,109 @@
import functools
import uuid
from flask import Blueprint, render_template, session, redirect, request, current_app, url_for
from movie_library.forms import MovieForm
from movie_library.models import Movie
import datetime
from dataclasses import asdict

from flask import (
Blueprint,
current_app,
flash,
redirect,
render_template,
session,
url_for,
request,
)
from movie_library.forms import LoginForm, RegisterForm, MovieForm, ExtendedMovieForm
from movie_library.models import User, Movie
from passlib.hash import pbkdf2_sha256

pages = Blueprint(
"pages", __name__, template_folder="templates", static_folder="static"
)


def login_required(route):
@functools.wraps(route)
def route_wrapper(*args, **kwargs):
if session.get("email") is None:
return redirect(url_for(".login"))

return route(*args, **kwargs)

return route_wrapper


@pages.route("/")
@login_required
def index():
movie_data = current_app.db.movie.find({})
user_data = current_app.db.user.find_one({"email": session["email"]})
user = User(**user_data)

movie_data = current_app.db.movie.find({"_id": {"$in": user.movies}})
movies = [Movie(**movie) for movie in movie_data]

return render_template(
"index.html",
title="Movies Watchlist",
movies_data = movies
movies_data=movies,
)


@pages.route("/register", methods=["POST", "GET"])
def register():
if session.get("email"):
return redirect(url_for(".index"))

form = RegisterForm()

if form.validate_on_submit():
user = User(
_id=uuid.uuid4().hex,
email=form.email.data,
password=pbkdf2_sha256.hash(form.password.data),
)

current_app.db.user.insert_one(asdict(user))

flash("User registered successfully", "success")

return redirect(url_for(".login"))

return render_template(
"register.html", title="Movies Watchlist - Register", form=form
)


@pages.route("/login", methods=["GET", "POST"])
def login():
if session.get("email"):
return redirect(url_for(".index"))

form = LoginForm()

if form.validate_on_submit():
user_data = current_app.db.user.find_one({"email": form.email.data})
if not user_data:
flash("Login credentials not correct", category="danger")
return redirect(url_for(".login"))

user = User(**user_data)

if user and pbkdf2_sha256.verify(form.password.data, user.password):
session["user_id"] = user._id
session["email"] = user.email

return redirect(url_for(".index"))

flash("Login credentials not correct", category="danger")

return render_template("login.html", title="Movies Watchlist - Login", form=form)




@pages.route("/add", methods=["GET", "POST"])
@login_required
def add_movie():
form = MovieForm()

Expand All @@ -29,14 +112,74 @@ def add_movie():
_id=uuid.uuid4().hex,
title=form.title.data,
director=form.director.data,
year=form.year.data
year=form.year.data,
)

current_app.db.movie.insert_one(asdict(movie))

return redirect(url_for(".index"))
current_app.db.user.update_one(
{"_id": session["user_id"]}, {"$push": {"movies": movie._id}}
)

return redirect(url_for(".movie", _id=movie._id))

return render_template(
"new_movie.html", title="Movies Watchlist - Add Movie", form=form
)


@pages.route("/logout/")
def logout():
current_theme = session.get("theme")
session.clear()
session["theme"] = current_theme

return redirect(url_for(".login"))


@pages.get("/movie/<string:_id>")
def movie(_id: str):
movie = Movie(**current_app.db.movie.find_one({"_id": _id}))
return render_template("movie_details.html", movie=movie)


@pages.route("/edit/<string:_id>", methods=["GET", "POST"])
@login_required
def edit_movie(_id: str):
movie = Movie(**current_app.db.movie.find_one({"_id": _id}))
form = ExtendedMovieForm(obj=movie)
if form.validate_on_submit():
movie.title = form.title.data
movie.director = form.director.data
movie.year = form.year.data
movie.cast = form.cast.data
movie.series = form.series.data
movie.tags = form.tags.data
movie.description = form.description.data
movie.video_link = form.video_link.data

current_app.db.movie.update_one({"_id": movie._id}, {"$set": asdict(movie)})
return redirect(url_for(".movie", _id=movie._id))
return render_template("movie_form.html", movie=movie, form=form)


@pages.get("/movie/<string:_id>/watch")
@login_required
def watch_today(_id):
current_app.db.movie.update_one(
{"_id": _id}, {"$set": {"last_watched": datetime.datetime.today()}}
)

return redirect(url_for(".movie", _id=_id))


@pages.get("/movie/<string:_id>/rate")
@login_required
def rate_movie(_id):
rating = int(request.args.get("rating"))
current_app.db.movie.update_one({"_id": _id}, {"$set": {"rating": rating}})

return render_template("new_movie.html", title="Movies Watchlist - Add Movie", form=form)
return redirect(url_for(".movie", _id=_id))


@pages.get("/toggle-theme")
Expand Down
Loading

0 comments on commit 9d2dd68

Please sign in to comment.