diff options
| -rw-r--r-- | app/app.py | 9 | ||||
| -rw-r--r-- | app/forms/user.py | 4 | ||||
| -rw-r--r-- | app/forms/workout.py | 10 | ||||
| -rw-r--r-- | app/routes/api.py | 13 | ||||
| -rw-r--r-- | app/routes/user.py | 22 | ||||
| -rw-r--r-- | app/routes/workout.py | 52 | ||||
| -rw-r--r-- | app/tables/user.py | 8 | ||||
| -rw-r--r-- | app/tables/workout.py | 32 | ||||
| -rw-r--r-- | app/templates/workout/create.html | 10 |
9 files changed, 99 insertions, 61 deletions
@@ -4,10 +4,10 @@ from flask_login import LoginManager # Setup app before doing imports app = Flask(__name__) -app.config['TEMPLATES_AUTO_RELOAD'] = True -app.config['SECRET_KEY'] = "super duper secret" # FIXME: do not use in prod -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../strengthy.db' -app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +app.config["TEMPLATES_AUTO_RELOAD"] = True +app.config["SECRET_KEY"] = "super duper secret" # FIXME: do not use in prod +app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///../strengthy.db" +app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # Setup flask-login login_manager = LoginManager(app) @@ -19,6 +19,7 @@ login_manager.login_view = "/login" db = SQLAlchemy(app) # TODO: do in script import tables.user + db.create_all() # Load routes diff --git a/app/forms/user.py b/app/forms/user.py index 12e4bf8..f3f72a6 100644 --- a/app/forms/user.py +++ b/app/forms/user.py @@ -2,10 +2,12 @@ from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, BooleanField from wtforms.validators import DataRequired, Email + class LoginForm(FlaskForm): username = StringField("username", validators=[DataRequired()]) password = PasswordField("password", validators=[DataRequired()]) - #remember_me = BooleanField() + # remember_me = BooleanField() + class RegisterForm(FlaskForm): username = StringField("username", validators=[DataRequired()]) diff --git a/app/forms/workout.py b/app/forms/workout.py index b406024..a5614eb 100644 --- a/app/forms/workout.py +++ b/app/forms/workout.py @@ -5,23 +5,29 @@ from wtforms.validators import DataRequired, Email # /workout/create class ExerciseCreateForm(Form): # TODO no exercise_*, breaks workout_edit endpoint - exercise_name = StringField("name", [DataRequired()]) + name = StringField("name", [DataRequired()], name="name") sets = IntegerField("sets", [DataRequired()]) units = IntegerField("units", [DataRequired()]) - exercise_type = SelectField("type", [DataRequired()], choices=[('reps', 'Reps'), ('time', 'Time')]) + type = SelectField( + "type", [DataRequired()], choices=[("reps", "Reps"), ("time", "Time")] + ) + class WorkoutCreateForm(FlaskForm): name = StringField("name", [DataRequired()]) exercises = FieldList(FormField(ExerciseCreateForm), min_entries=1) + # /workout/record class SetForm(Form): lbs = IntegerField("lbs", [DataRequired()]) reps = IntegerField("reps", [DataRequired()]) + class ExerciseRecordForm(Form): sets = FieldList(FormField(SetForm)) + # Actual forms class WorkoutRecordForm(FlaskForm): exercises = FieldList(FormField(ExerciseRecordForm)) diff --git a/app/routes/api.py b/app/routes/api.py index 58b4732..2373fa3 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -3,15 +3,18 @@ from flask import redirect, request from flask_login import current_user, login_required from tables import Workout -@app.route("/api/workout/delete", methods=['GET']) + +@app.route("/api/workout/delete", methods=["GET"]) @login_required def api_workout_delete(): - if 'id' not in request.args: - return redirect('/home'); + if "id" not in request.args: + return redirect("/home") - workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first() + workout = Workout.query.filter_by( + id=int(request.args["id"]), user_id=current_user.id + ).first() if workout: db.session.delete(workout) db.session.commit() - return redirect('/home') + return redirect("/home") diff --git a/app/routes/user.py b/app/routes/user.py index d218738..7044366 100644 --- a/app/routes/user.py +++ b/app/routes/user.py @@ -2,9 +2,10 @@ from app import app, db from flask import render_template, redirect, request, url_for, flash from flask_login import current_user, login_user, login_required, logout_user from forms import LoginForm, RegisterForm -from tables import User +from tables import User -@app.route("/login", methods=['GET', 'POST']) + +@app.route("/login", methods=["GET", "POST"]) def login(): form = LoginForm() username = form.username.data @@ -17,19 +18,21 @@ def login(): # TODO: show user if login succeeded if user and user.verify_password(password): login_user(user) - return redirect(url_for('home')) + return redirect(url_for("home")) else: flash("Invalid username or password", "danger") - return render_template('user/login.html', form=form) + return render_template("user/login.html", form=form) + -@app.route("/logout", methods=['GET', 'POST']) +@app.route("/logout", methods=["GET", "POST"]) @login_required def logout(): logout_user() - return redirect('/') + return redirect("/") -@app.route("/register", methods=['GET', 'POST']) + +@app.route("/register", methods=["GET", "POST"]) def register(): form = RegisterForm() # Load data from form @@ -45,9 +48,8 @@ def register(): user = User(username, password, email) db.session.add(user) db.session.commit() - return redirect(url_for('login')) + return redirect(url_for("login")) else: flash("User already exists", "danger") - return render_template('user/register.html', form=form) - + return render_template("user/register.html", form=form) diff --git a/app/routes/workout.py b/app/routes/workout.py index 7144d40..a929a6c 100644 --- a/app/routes/workout.py +++ b/app/routes/workout.py @@ -4,7 +4,8 @@ from flask_login import current_user, login_required from forms import WorkoutCreateForm, WorkoutRecordForm from tables import User, Workout -@app.route("/workout/create", methods=['GET', 'POST']) + +@app.route("/workout/create", methods=["GET", "POST"]) @login_required def workout_create(): form = WorkoutCreateForm() @@ -15,27 +16,32 @@ def workout_create(): workout = Workout.query.filter_by(user_id=current_user.id, name=name).first() if not workout: # TODO: add exercises - workout = Workout(current_user, name, [e.data for e in form.exercises.entries]) + workout = Workout( + current_user, name, [e.data for e in form.exercises.entries] + ) db.session.add(workout) db.session.commit() - return redirect(url_for('home')); + return redirect(url_for("home")) else: flash("Workout with this name already exists", "danger") - return render_template('workout/create.html', form=form) + return render_template("workout/create.html", form=form) + -@app.route("/workout/edit", methods=['GET', 'POST']) +@app.route("/workout/edit", methods=["GET", "POST"]) @login_required def workout_edit(): # Id is required - if 'id' not in request.args: - return redirect(url_for('home')) + if "id" not in request.args: + return redirect(url_for("home")) # Validate Id - workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first() + workout = Workout.query.filter_by( + id=int(request.args["id"]), user_id=current_user.id + ).first() if not workout: - return redirect(url_for('home')) + return redirect(url_for("home")) form = WorkoutCreateForm() @@ -47,36 +53,42 @@ def workout_edit(): # Write changes to database db.session.commit() - return redirect(url_for('home')); + return redirect(url_for("home")) else: form.name.data = workout.name - form.exercises.pop_entry() # TODO: better way to do this? + form.exercises.pop_entry() # TODO: better way to do this? for exercise in workout.exercises: form.exercises.append_entry(exercise) - return render_template('workout/create.html', form=form, title=f'Edit Workout "{workout.name}"') + return render_template( + "workout/create.html", form=form, title=f'Edit Workout "{workout.name}"' + ) -@app.route("/workout/record", methods=['GET', 'POST']) + +@app.route("/workout/record", methods=["GET", "POST"]) @login_required def workout_record(): form = WorkoutRecordForm() # Id is required - if 'id' not in request.args: - return redirect(url_for('home')) + if "id" not in request.args: + return redirect(url_for("home")) # Matching workout required - workout = Workout.query.filter_by(id=int(request.args['id']), user_id=current_user.id).first() + workout = Workout.query.filter_by( + id=int(request.args["id"]), user_id=current_user.id + ).first() if not workout: - return redirect(url_for('home')); + return redirect(url_for("home")) if form.validate_on_submit(): print(form) - return render_template('workout/record.html', workout=workout, form=form) + return render_template("workout/record.html", workout=workout, form=form) + -@app.route("/workout/select", methods=['GET']) +@app.route("/workout/select", methods=["GET"]) @login_required def workout_select(): - return render_template('workout/select.html') + return render_template("workout/select.html") diff --git a/app/tables/user.py b/app/tables/user.py index cfffb80..ddf3702 100644 --- a/app/tables/user.py +++ b/app/tables/user.py @@ -2,18 +2,20 @@ from app import db, login_manager from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash + @login_manager.user_loader def get_user(user_id): return User.query.get(user_id) + class User(db.Model, UserMixin): - __tablename__ = 'users' + __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password = db.Column(db.String(80)) email = db.Column(db.String(120), unique=True, nullable=False) - workouts = db.relationship("Workout", backref='user', lazy='dynamic') + workouts = db.relationship("Workout", backref="user", lazy="dynamic") def __init__(self, username, password, email): self.username = username @@ -21,7 +23,7 @@ class User(db.Model, UserMixin): self.email = email def __repr__(self): - return f'<User {self.username}>' + return f"<User {self.username}>" def verify_password(self, pwd): return check_password_hash(self.password, pwd) diff --git a/app/tables/workout.py b/app/tables/workout.py index 564caf1..75faf6b 100644 --- a/app/tables/workout.py +++ b/app/tables/workout.py @@ -1,39 +1,42 @@ from app import db, login_manager import enum + class ExerciseType(enum.Enum): TIME = "Seconds" REPS = "Reps" + # Represents an individual exercise class Exercise(db.Model): - __tablename__ = 'exercises' + __tablename__ = "exercises" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) sets = db.Column(db.Integer) units = db.Column(db.Integer) type = db.Column(db.Enum(ExerciseType)) # Workout Relationship - workout_id = db.Column(db.Integer, db.ForeignKey('workouts.id')) + workout_id = db.Column(db.Integer, db.ForeignKey("workouts.id")) def __init__(self, name, sets, units, type): self.name = name self.sets = sets - self.units = units + self.units = units self.type = type def __repr__(self): - return f'<Exercise {self.name} {self.sets}x{self.units}>' + return f"<Exercise {self.name} {self.sets}x{self.units}>" + # Represents a singular workout class Workout(db.Model): - __tablename__ = 'workouts' + __tablename__ = "workouts" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) # foreign keys - user_id = db.Column(db.Integer, db.ForeignKey('users.id')) + user_id = db.Column(db.Integer, db.ForeignKey("users.id")) # relationships - exercises = db.relationship("Exercise", backref='workout', lazy='dynamic') + exercises = db.relationship("Exercise", backref="workout", lazy="dynamic") def __init__(self, user, name, exercises): self.name = name @@ -41,14 +44,21 @@ class Workout(db.Model): # Create exercises for exercise in exercises: - type = ExerciseType.TIME if exercise['exercise_type'] == 'time' else ExerciseType.REPS; - self.exercises.append(Exercise(exercise['exercise_name'], exercise['sets'], exercise['units'], type)) + type = ( + ExerciseType.TIME + if exercise["exercise_type"] == "time" + else ExerciseType.REPS + ) + self.exercises.append( + Exercise(exercise["name"], exercise["sets"], exercise["units"], type) + ) def __repr__(self): - return f'<Workout {self.name}>' + return f"<Workout {self.name}>" + # Connects workouts to it's exercises -#class WorkoutExercise(db.Model): +# class WorkoutExercise(db.Model): # __table__ = 'workout_exercises' # id = db.Column(db.Integer, primary_key=True) # workout_id = db.Column(db.Integer, db.ForeignKey('workouts.id')) diff --git a/app/templates/workout/create.html b/app/templates/workout/create.html index 0336e1c..292aaa8 100644 --- a/app/templates/workout/create.html +++ b/app/templates/workout/create.html @@ -7,7 +7,7 @@ <div class="field-body"> <div class="field"> <p class="control is-expanded has-icons-left"> - {{ form.name(class_='input', placeholder='Workout Name') }} + {{ form['name'](class_='input', placeholder='Workout Name') }} <span class="icon is-small is-left"> <i class="fa fa-tag"></i> </span> @@ -22,7 +22,7 @@ <div class="field-body"> <div class="field"> <p class="control is-expanded has-icons-left"> - {{ entry.exercise_name(class_='input', placeholder='Name') }} + {{ entry['name'](class_='input', placeholder='Exercise') }} <span class="icon is-small is-left"> <i class="fa fa-tag"></i> </span> @@ -35,7 +35,7 @@ </div> <div class="field"> <p class="control is-expanded has-icons-left"> - {{ entry.sets(class_='input', placeholder='Sets') }} + {{ entry['sets'](class_='input', placeholder='Sets') }} <span class="icon is-small is-left"> <i class="fa fa-calculator"></i> </span> @@ -44,13 +44,13 @@ <div class="field has-addons"> <div class="control has-icons-left"> <div class="select"> - {{ entry.exercise_type() }} + {{ entry['type'] }} </div> <div class="icon is-small is-left"> <i class="fa fa-calculator"></i> </div> </div> - {{ entry.units(class_='input') }} + {{ entry['units'](class_='input') }} </div> <p class="button is-danger" onclick="handleDel(this)"> <span class="icon is-small"> |
