Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a8c73cc
Update README.md
SAlcibar Jan 26, 2025
217ff27
Update README.md
SAlcibar Jan 26, 2025
3a1e4d2
Update README.md
SAlcibar Jan 26, 2025
f1db75c
Update README.md
JGMink Jan 28, 2025
d81a1d1
Sprint 1 Commit
tlm273623 Mar 23, 2025
aeba003
dev-container setup
JGMink Mar 23, 2025
5b4919c
Merge branch 'main' of https://github.com/SAlcibar/CMSC-Mental-Health
JGMink Mar 23, 2025
716c068
Update Dockerfile
JGMink Mar 23, 2025
4c63a81
Adapted Files for Mac Implementation
JGMink Mar 25, 2025
6d5dd21
Update README.md
JGMink Mar 25, 2025
5ece06a
Sprint 1 Update
tlm273623 Mar 25, 2025
e204ea9
Sprint 1 Update
thomasm4657 Mar 25, 2025
6fe1bf3
Sprint-1 Test Case
tlm273623 Mar 27, 2025
9c624c1
Sprint-1 Test Case
thomasm4657 Mar 27, 2025
29945c4
Sprint-2
tlm273623 Mar 28, 2025
d7de670
Copying project to Sprint-2
thomasm4657 Mar 28, 2025
7976bdb
Test Commit
tlm273623 Mar 28, 2025
72ba0fa
Testing Commits to Sprint 2
thomasm4657 Mar 28, 2025
0b1c4c0
Adding fitness log script and style
rayanm231 Apr 3, 2025
f400cb5
Fitness Calendar
rayanm231 Apr 3, 2025
34bf176
Added calendar
rayanm231 Apr 7, 2025
a0c05a9
Sprint-2 Update
tlm273623 Apr 7, 2025
b066e8b
Merge branch 'main' into Sprint-2-Commit
thomasm4657 Apr 7, 2025
f7f1d60
Sprint-2 Update
thomasm4657 Apr 7, 2025
41b8c95
Sprint 2 Final Commit
tlm273623 Apr 9, 2025
c207b52
Merge branch 'Sprint-2-Commit' of https://github.com/SAlcibar/CMSC-Me…
tlm273623 Apr 9, 2025
9b65fdb
Sprint 2 Final
tlm273623 Apr 9, 2025
317c6cf
Sprint 2 Final Commit
thomasm4657 Apr 9, 2025
cc0db9a
Updated port for clean local running
JGMink Apr 13, 2025
81add0e
Began Sprint 3 and updated main-chat
JGMink Apr 13, 2025
6c94e38
sprint3 calendar script update
rayanm231 Apr 14, 2025
ce80693
sprint3 calendar update final
rayanm231 Apr 14, 2025
5d320b7
commit 1
rayanm231 Apr 14, 2025
ea68a16
commit 2
rayanm231 Apr 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Binary file modified .DS_Store
Binary file not shown.
36 changes: 36 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Use the official Python 3.10 slim image
FROM python:3.10-slim

# Set the working directory inside the container
WORKDIR /app

# Install system dependencies including build tools and MariaDB development files
RUN apt-get update && \
apt-get install -y \
build-essential \
pkg-config \
python3-dev \
libmariadb-dev-compat \
libmariadb-dev \
&& rm -rf /var/lib/apt/lists/*

# Upgrade pip (optional but recommended)
RUN pip install --upgrade pip

# Copy the requirements.txt file from the correct relative path into the container
COPY Sprint_1/AI_Fitness_Project/requirements.txt /app/requirements.txt

# Install Python dependencies from requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt

# Copy the rest of your application code into the container
COPY Sprint_1/AI_Fitness_Project /app

# Set environment variables (using the recommended syntax)
ENV PYTHONUNBUFFERED=1

# Expose the port your app uses (adjust if needed)
EXPOSE 5000

# Run the application
CMD ["python", "/app/app.py"]
10 changes: 10 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "AI Fitness Dev Container",
"build": {
"dockerfile": "Dockerfile"
},
"workspaceFolder": "/workspace",
"mounts": ["source=${localWorkspaceFolder},target=/workspace,type=bind"],
"remoteUser": "vscode"
}

12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
My groupmembers are:
- XXXX
- XXXX
- XXXX
- XXXX
The groupmembers are:
- Sebastian Alcibar
- Ryan Maazous
- Thomas Marshall
- Jonah Minkoff
- Brady Miller


------------------ Fill in some information about your project under this ------------------
## Our group has decided to work on the Mental Health Support App.
Binary file added Sprint 1/.DS_Store
Binary file not shown.
Binary file added Sprint 1/AI Fitness Project/.DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions Sprint 1/AI Fitness Project/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.env
database.db
__pycache__/
venv/
112 changes: 112 additions & 0 deletions Sprint 1/AI Fitness Project/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from flask import Flask, render_template, session
import os
from backend.db import db
from backend.tables import User
from flask_login import LoginManager, login_required, login_user, logout_user, current_user
from flask import Flask, render_template, redirect, url_for, flash
from flask_bcrypt import Bcrypt
from backend.forms import RegisterForm, LoginForm, SurveyForm, FitnessLogWorkoutForm, FitnessLogCardioForm
from backend.tables import User
import secrets


app = Flask(__name__)
bcrypt = Bcrypt(app)

# Handles our SQLite database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SECRET_KEY'] = secrets.token_hex(16)
db.init_app(app)

# Handles login verification
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))


# Renders home page
@app.route('/', methods=['GET', 'POST'])
@login_required
def home():
fitness_goals= current_user.fitness_goals

if fitness_goals:
fitness_goals_list = fitness_goals.split(",")
else:
fitness_goals_list = None
return render_template('index.html', first_name=current_user.first_name, fitness_goals=fitness_goals_list)


# Renders fitness log page
@app.route('/fitness-log', methods=['GET', 'POST'])
def fitness_log():
workout_form = FitnessLogWorkoutForm()
cardio_form = FitnessLogCardioForm()
return render_template('fitness-log.html', workout_form=workout_form, cardio_form=cardio_form)

# Renders about page
@app.route('/about')
def about():
return render_template('about.html')

# Renders main AI chat page
@app.route('/main-chat')
def main_chat():
return render_template('main-chat.html')

# Renders login page
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user:
if bcrypt.check_password_hash(user.password, form.password.data):
login_user(user)
return redirect(url_for('home'))
return render_template('login.html', form=form)

# Handles logout functionality
@app.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
logout_user()
return redirect(url_for('login'))

# Renders register page
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm()


if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data)
new_user = User(username=form.username.data, password=hashed_password, first_name=form.first_name.data, last_name=form.last_name.data)
db.session.add(new_user)
db.session.commit()
login_user(new_user)
return redirect(url_for('survey'))

return render_template('register.html', form=form)

@app.route('/survey', methods=['GET', 'POST'])
def survey():
form = SurveyForm()

if form.validate_on_submit():
selected_goals = ",".join(form.fitness_goals.data)
current_user.fitness_goals = selected_goals
db.session.commit()
return redirect(url_for('home'))

return render_template('survey.html', form=form)

with app.app_context():
db.create_all()

if __name__ == "__main__":

app.run(debug=True, host="0.0.0.0", port=5000)
3 changes: 3 additions & 0 deletions Sprint 1/AI Fitness Project/backend/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
70 changes: 70 additions & 0 deletions Sprint 1/AI Fitness Project/backend/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, SelectMultipleField, widgets, IntegerField, FieldList, FormField, DecimalField
from wtforms.validators import InputRequired, Length, ValidationError, DataRequired, NumberRange
from backend.tables import User

# Sets up the form on the register page
class RegisterForm(FlaskForm):
username = StringField(validators=[InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Username"})
password = PasswordField(validators=[InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Password"})
first_name = StringField(validators=[InputRequired(), Length(min=1)], render_kw={"placeholder": "First Name"})
last_name = StringField(validators=[InputRequired(), Length(min=1)], render_kw={"placeholder": "Last Name"})

submit = SubmitField("Register")

def validate_username(self, username):
existing_user = User.query.filter_by(
username=username.data).first()
if existing_user:
raise ValidationError(
"That username already exists."
)


# Sets up form on login page
class LoginForm(FlaskForm):
username = StringField(validators=[InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Username"})

password = PasswordField(validators=[InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Password"})

submit = SubmitField("Login")


class SurveyForm(FlaskForm):
fitness_goals = SelectMultipleField(
"What are your fitness goals?",
choices=[
("Build Muscle", "Build Muscle"),
("Lose Weight", "Lose Weight"),
("Increase Strength", "Increase Strength"),
("Improve Cardio", "Improve Cardio")
],
option_widget=widgets.CheckboxInput(),
widget=widgets.ListWidget(prefix_label=False)
)

submit = SubmitField("Submit")


class FitnessLogWorkoutForm(FlaskForm):
legs_reps = IntegerField('Total Reps', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])
legs_sets = IntegerField('Total Sets', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])

chest_reps = IntegerField('Total Reps', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])
chest_sets = IntegerField('Total Sets', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])

back_reps = IntegerField('Total Reps', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])
back_sets = IntegerField('Total Sets', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])

bicep_reps = IntegerField('Total Reps', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])
bicep_sets = IntegerField('Total Sets', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])

tricep_reps = IntegerField('Total Reps', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])
tricep_sets = IntegerField('Total Sets', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])

submit = SubmitField("Submit")

class FitnessLogCardioForm(FlaskForm):
miles = DecimalField('Total Miles', default=0, validators=[NumberRange(min=0, message="Value must be 0 or greater")])

submit = SubmitField("Submit")
15 changes: 15 additions & 0 deletions Sprint 1/AI Fitness Project/backend/tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from backend.db import db
from flask_login import UserMixin

# Creates our Sqlite table that holds user login/register info.
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False, unique=True)
password = db.Column(db.String(80), nullable=False)
first_name = db.Column(db.String(20), nullable=False)
last_name = db.Column(db.String(20), nullable=False)
fitness_goals = db.Column(db.String(255), nullable=True)




41 changes: 41 additions & 0 deletions Sprint 1/AI Fitness Project/login_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import requests
from bs4 import BeautifulSoup


base_url = "http://localhost:5000"
login_url = f"{base_url}/login"
home_url = f"{base_url}/home"

test_username = 'test'
test_password = 'test'

session = requests.Session()

login_page = session.get(login_url)

soup = BeautifulSoup(login_page.text, 'html.parser')

csrf_token = soup.find('input', {'name': 'csrf_token'})['value']

login_data = {
'csrf_token': csrf_token,
'username': test_username,
'password': test_password,
'submit': 'Login'
}

login_response = session.post(login_url, data=login_data)

print("\nLogin Response Status Code:", login_response.status_code)

if login_response.status_code == 200:
if "Welcome" in login_response.text:
print("Login test passed.")
elif "Invalid username or password" in login_response.text:
print("Login failed. Invalid username or password.")
else:
print("Login failed with status code 200 but no error message found.")
else:
print("Login failed. Status code:", login_response.status_code)
print("Response Content:")
print(login_response.text)
51 changes: 51 additions & 0 deletions Sprint 1/AI Fitness Project/requirements_mac.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
asttokens==3.0.0
bcrypt==4.3.0
blinker==1.9.0
click==8.1.8
colorama==0.4.6
comm==0.2.2
debugpy==1.8.13
decorator==5.2.1
dnspython==2.7.0
email_validator==2.2.0
executing==2.2.0
Flask==3.1.0
Flask-Bcrypt==1.0.1
Flask-Login==0.6.3
Flask-MySQLdb==2.0.0
Flask-SQLAlchemy==3.1.1
Flask-WTF==1.2.2
greenlet==3.1.1
idna==3.10
ipykernel==6.29.5
ipython==8.10.0
ipython_pygments_lexers==1.1.1
itsdangerous==2.2.0
jedi==0.19.2
Jinja2==3.1.6
jupyter_client==8.6.3
jupyter_core==5.7.2
MarkupSafe==3.0.2
matplotlib-inline==0.1.7
PyMySQL==1.0.2 #mysqlclient==2.2.7
nest-asyncio==1.6.0
packaging==24.2
parso==0.8.4
platformdirs==4.3.7
prompt_toolkit==3.0.50
psutil==7.0.0
pure_eval==0.2.3
Pygments==2.19.1
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
pywin32==310; sys_platform == "win32"
pyzmq==26.3.0
six==1.17.0
SQLAlchemy==2.0.39
stack-data==0.6.3
tornado==6.4.2
traitlets==5.14.3
typing_extensions==4.12.2
wcwidth==0.2.13
Werkzeug==3.1.3
WTForms==3.2.1
Loading