Skip to content

Commit

Permalink
Merge pull request #18 from utsavll0/analytics
Browse files Browse the repository at this point in the history
Adding analytics for last 7 days with graph and future calorie prediction
  • Loading branch information
ojas1901 authored Oct 16, 2023
2 parents e804e85 + c741670 commit d350b3c
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 86 deletions.
30 changes: 25 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
node_modules/
package-lock.json
__pycache__
.idea
.DS_Store
.DS_Store
.env
.flaskenv
*.pyc
*.pyo
env/
venv/
.venv/
env*
dist/
build/
*.egg
*.egg-info/
.tox/
.cache/
.pytest_cache/
.idea/
docs/_build/
.vscode

# Coverage reports
htmlcov/
.coverage
.coverage.*
*,cover
42 changes: 42 additions & 0 deletions Scripts/bootstrap_database_rv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import datetime
import random

from pymongo import MongoClient


def add_fake_values_to_database(email: str, days: int):
mongo = MongoClient('mongodb://127.0.0.1:27017/test')
db = mongo['test']
calories = db.get_collection('calories')
for i in range(0, days + 1):
date = datetime.date.today() - datetime.timedelta(days=i)
calories.insert_one({'date': str(date), 'email': email, 'calories': random.randint(2100, 2300)})
print("Positive Values have been added to the database")


def add_fake_negetive_values_to_database(email: str, days: int):
mongo = MongoClient('mongodb://127.0.0.1:27017/test')
db = mongo['test']
calories = db.get_collection('calories')
for i in range(0, days + 1):
if random.randint(0, 69420) % 2 == 0:
continue
date = datetime.date.today() - datetime.timedelta(days=i)
calories.insert_one({'date': str(date), 'email': email, 'calories': random.randint(-500, 0)})
print("Negative values have been added to the database")


def clear_calories_db():
mongo = MongoClient('mongodb://127.0.0.1:27017/test')
db = mongo['test']
calories = db.get_collection('calories')
calories.delete_many({})


if __name__ == '__main__':
# Add email and database will be populated with random values for that email
add_fake_values_to_database('', 30)
add_fake_negetive_values_to_database('', 30)

# Uncomment this line to clear calories collection
# clear_calories_db()
83 changes: 54 additions & 29 deletions application.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timedelta

import bcrypt
import smtplib
Expand All @@ -12,6 +12,7 @@
from flask_pymongo import PyMongo
from tabulate import tabulate
from forms import HistoryForm, RegistrationForm, LoginForm, CalorieForm, UserProfileForm, EnrollForm,WorkoutForm
from service import history as history_service

app = Flask(__name__)
app.secret_key = 'secret'
Expand Down Expand Up @@ -198,23 +199,23 @@ def workout():
now = datetime.now()
now = now.strftime('%Y-%m-%d')
get_session = session.get('email')

if get_session is not None:
form = WorkoutForm()
if form.validate_on_submit():
if request.method == 'POST':
email = session.get('email')
burn = request.form.get('burnout')


mongo.db.calories.insert_one({'date': now, 'email': email, 'calories': -int(burn)})

flash(f'Successfully updated the data', 'success')
return redirect(url_for('workout'))
else:
return redirect(url_for('home'))
return render_template('workout.html', form=form, time=now)


@app.route("/history", methods=['GET'])
def history():
Expand All @@ -228,21 +229,45 @@ def history():
email = get_session = session.get('email')
if get_session is not None:
form = HistoryForm()

# Find out the last 7 day's calories burnt by the user
labels = []
values = []
pipeline = history_service.get_calories_per_day_pipeline(7)
filtered_calories = mongo.db.calories.aggregate(pipeline)
for calorie_each_day in filtered_calories:
if calorie_each_day['_id'] == 'Other':
continue
net_calories = int(calorie_each_day['total_calories']) - 2000
labels.append(calorie_each_day['date'])
values.append(str(net_calories))

# The first day when the user registered or started using the app
user_start_date = mongo.db.user.find({'email' : email})[0]['start_date']
user_target_date = mongo.db.user.find({'email' : email})[0]['target_date']
target_weight = mongo.db.user.find({'email' : email})[0]['target_weight']
current_weight = mongo.db.user.find({'email' : email})[0]['weight']

# Find out the actual calories which user needed to burn/gain to achieve goal from the start day
target_calories_to_burn = history_service.total_calories_to_burn(
target_weight=int(target_weight), current_weight=int(current_weight))
print(f'########## {target_calories_to_burn}')

# Find out how many calories user has gained or burnt uptill now
calories_till_today = mongo.db.calories.aggregate(
history_service.get_calories_burnt_till_now_pipeline(email, user_start_date))
current_calories = 0
for calorie in calories_till_today:
current_calories += calorie['SUM']
# current_calories = [x for x in calories_till_today][0]['SUM'] if len(list(calories_till_today)) != 0 else 0

data=[
("01-01-2020",100),
("02-01-2020",101),
("03-01-2020",102)
]

# labels=[row[0] for row in data]
# values=[row[1] for row in data]
labels=[]
values=[]
for row in data:
labels.append(row[0])
values.append(row[1])
return render_template('history.html', form=form,labels=labels,values=values)
# Find out no of calories user has to burn/gain in future per day
calories_to_burn = history_service.calories_to_burn(target_calories_to_burn, current_calories,
target_date=datetime.strptime(user_target_date, '%Y-%m-%d'),
start_date=datetime.strptime(user_start_date, '%Y-%m-%d'))

return render_template('history.html', form=form, labels=labels, values=values, burn_rate=calories_to_burn,
target_date=user_target_date)


@app.route("/ajaxhistory", methods=['POST'])
Expand Down Expand Up @@ -322,34 +347,34 @@ def send_email():
data = list(mongo.db.calories.find({'email': email}, {'date','email','calories','burnout'}))
table = [['Date','Email ID','Calories','Burnout']]
for a in data:
tmp = [a['date'],a['email'],a['calories'],a['burnout']]
table.append(tmp)
tmp = [a['date'],a['email'],a['calories'],a['burnout']]
table.append(tmp)

friend_email = str(request.form.get('share')).strip()
friend_email = str(friend_email).split(',')
server = smtplib.SMTP_SSL("smtp.gmail.com",465)
#Storing sender's email address and password
sender_email = "[email protected]"
sender_password = "Temp@1234"

#Logging in with sender details
server.login(sender_email,sender_password)
message = 'Subject: Calorie History\n\n Your Friend wants to share their calorie history with you!\n {}'.format(tabulate(table))
for e in friend_email:
print(e)
server.sendmail(sender_email,e,message)

server.quit()

myFriends = list(mongo.db.friends.find(
{'sender': email, 'accept': True}, {'sender', 'receiver', 'accept'}))
myFriendsList = list()

for f in myFriends:
myFriendsList.append(f['receiver'])

allUsers = list(mongo.db.user.find({}, {'name', 'email'}))

pendingRequests = list(mongo.db.friends.find(
{'sender': email, 'accept': False}, {'sender', 'receiver', 'accept'}))
pendingReceivers = list()
Expand All @@ -361,7 +386,7 @@ def send_email():
{'receiver': email, 'accept': False}, {'sender', 'receiver', 'accept'}))
for p in pendingApprovals:
pendingApproves.append(p['sender'])

return render_template('friends.html', allUsers=allUsers, pendingRequests=pendingRequests, active=email,
pendingReceivers=pendingReceivers, pendingApproves=pendingApproves, myFriends=myFriends, myFriendsList=myFriendsList)

Expand Down
69 changes: 69 additions & 0 deletions service/history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from datetime import datetime, timedelta


def get_calories_per_day_pipeline(days: int):
start_date = (datetime.today() - timedelta(days=days))
end_date = datetime.today()
bucket_boundaries = [(start_date + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(days + 1)]
date_range_filter = {
'$match': {
'date': {
'$gte': start_date.strftime('%Y-%m-%d'),
'$lte': end_date.strftime('%Y-%m-%d')
},
}
}
total_calories_each_day = {
'$bucket': {
'groupBy': '$date',
'boundaries': bucket_boundaries,
'default': 'Other',
'output': {
'date': {
'$max': '$date'
},
'total_calories': {
'$sum': '$calories'
}
}
}
}
return [
date_range_filter,
total_calories_each_day
]


def get_calories_burnt_till_now_pipeline(email: str, start_date: str):
end_date = datetime.today().strftime('%Y-%m-%d')
return [
{
'$match': {
'date': {
'$gte': start_date,
'$lte': end_date
},
'email': email
}
}, {
'$group': {
'_id': 'sum of calories',
'SUM': {
'$sum': '$calories'
}
}
}
]


def total_calories_to_burn(target_weight: int, current_weight: int):
return int((target_weight - current_weight) * 7700)


def calories_to_burn(target_calories: int, current_calories: int, target_date: datetime, start_date: datetime):
actual_current_calories = current_calories - ((datetime.today() - start_date).days * 2000)

new_target = target_calories - actual_current_calories

days_remaining = (target_date - datetime.today()).days
return int(new_target / days_remaining)
5 changes: 5 additions & 0 deletions static/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,8 @@
height: 35vh;
object-fit: contain;
}

.user-chart {
display: flex;
justify-content: center;
}
Loading

0 comments on commit d350b3c

Please sign in to comment.