Skip to content

Commit

Permalink
Pace and speed with UI changes (#24)
Browse files Browse the repository at this point in the history
* changes for stats page and adding pace and speed

* distance fix

* fix for formatting
  • Loading branch information
HarshiSharma committed Mar 27, 2024
1 parent 32a7291 commit 6c1d405
Show file tree
Hide file tree
Showing 10 changed files with 474 additions and 246 deletions.
3 changes: 3 additions & 0 deletions activity-tracking/models/exercise.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const exerciseSchema = new Schema(
required: false,
min: [0, 'Distance should be positive.']
},
distance: { type: Number, required: false },
speed: { type: Number, required: false },
pace: { type: Number, required: false },
date: { type: Date, required: true },
},
{ timestamps: true }
Expand Down
79 changes: 44 additions & 35 deletions activity-tracking/routes/exercises.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ const express = require('express');
const router = express.Router();
const Exercise = require('../models/exercise.model');


// GET: Retrieve all exercises
router.get('/', async (req, res) => {
try {
const exercises = await Exercise.find().sort({ date: 'desc' });
res.json(exercises);
} catch (error) {
console.error(error);
res.status(400).json({ error: 'Error: ' + error.message });
}
});
Expand All @@ -19,42 +19,81 @@ router.get('/user/:username', async (req, res) => {
const exercises = await Exercise.find({ "username": req.params.username }).sort({ date: 'desc' });
res.json(exercises);
} catch (error) {
console.error(error);
res.status(400).json({ error: 'Error: ' + error.message });
}
});

// POST: Add a new exercise
router.post('/add', async (req, res) => {
try {
const { username, exerciseType, description, duration, distance, date } = req.body;
const { username, exerciseType, description, duration, date, distance, speed, pace } = req.body;

const newExercise = new Exercise({
username,
exerciseType,
description,
duration: Number(duration),
date: new Date(date),
distance: Number(distance),
date: Date.parse(date),
speed: Number(speed),
pace: Number(pace)
});

await newExercise.save();
res.json({ message: 'Exercise added!' });
} catch (error) {
console.error(error);
res.status(400).json({ error: 'Error: ' + error.message });
}
});

// PUT: Update an exercise by ID
router.put('/update/:id', async (req, res) => {
try {
const { username, exerciseType, description, duration, date, distance, speed, pace } = req.body;

if (!username || !exerciseType || !duration || !date) {
res.status(400).json({ error: 'All fields are required' });
return;
}

const updatedFields = {
username,
exerciseType,
description,
duration: Number(duration),
date: new Date(date),
distance: Number(distance),
speed: Number(speed),
pace: Number(pace)
};

const exercise = await Exercise.findByIdAndUpdate(req.params.id, updatedFields, { new: true });

if (!exercise) {
res.status(404).json({ error: 'Exercise not found' });
return;
}

res.json({ message: 'Exercise updated!', exercise });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'An error occurred while updating the exercise' });
}
});

// GET: Retrieve an exercise by ID
router.get('/:id', async (req, res) => {
try {
const exercise = await Exercise.findById(req.params.id);
console.log(exercise)
if (!exercise) {
res.status(404).json({ error: 'Exercise not found' });
return;
}
res.json(exercise);
} catch (error) {
console.error(error);
res.status(400).json({ error: 'Error: ' + error.message });
}
});
Expand All @@ -68,39 +107,9 @@ router.delete('/:id', async (req, res) => {
return;
}
res.json({ message: 'Exercise deleted.' });
} catch (error) {
res.status(400).json({ error: 'Error: ' + error.message });
}
});

// PUT: Update an exercise by ID
router.put('/update/:id', async (req, res) => {
try {
const { username, exerciseType, description, duration, distance, date } = req.body;

if (!username || !exerciseType || !description || !duration || !date) {
res.status(400).json({ error: 'All fields are required' });
return;
}

const exercise = await Exercise.findById(req.params.id);
if (!exercise) {
res.status(404).json({ error: 'Exercise not found' });
return;
}

exercise.username = username;
exercise.exerciseType = exerciseType;
exercise.description = description;
exercise.duration = Number(duration);
exercise.distance = Number(distance);
exercise.date = new Date(date);

await exercise.save();
res.json({ message: 'Exercise updated!', exercise });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'An error occurred while updating the exercise' });
res.status(400).json({ error: 'Error: ' + error.message });
}
});

Expand Down
21 changes: 15 additions & 6 deletions analytics/core/gql_schema.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from ariadne import gql, make_executable_schema, QueryType
from core.models import mongo


type_defs = gql("""
type Query {
stats: [Stats]
}
type Stats {
username: String!
exercises: [Exercise!]
Expand All @@ -15,6 +14,10 @@
type Exercise {
exerciseType: ExerciseType!
totalDuration: Int!
totalDistance: Int
averagePace: Float
averageSpeed: Float
topSpeed: Float
}
enum ExerciseType {
Expand All @@ -28,7 +31,6 @@

query = QueryType()


@query.field("stats")
def stats_resolver(*_):
pipeline = [
Expand All @@ -38,7 +40,11 @@ def stats_resolver(*_):
"username": "$username",
"exerciseType": "$exerciseType"
},
"totalDuration": {"$sum": "$duration"}
"totalDuration": {"$sum": "$duration"},
"totalDistance": {"$sum": "$distance"},
"averagePace": {"$avg": "$pace"},
"averageSpeed": {"$avg": "$speed"},
"topSpeed": {"$max": "$speed"}
}
},
{
Expand All @@ -47,7 +53,11 @@ def stats_resolver(*_):
"exercises": {
"$push": {
"exerciseType": "$_id.exerciseType",
"totalDuration": "$totalDuration"
"totalDuration": "$totalDuration",
"totalDistance": "$totalDistance",
"averagePace": "$averagePace",
"averageSpeed": "$averageSpeed",
"topSpeed": "$topSpeed"
}
}
}
Expand All @@ -64,5 +74,4 @@ def stats_resolver(*_):
stats = list(mongo.db.exercises.aggregate(pipeline))
return stats


schema = make_executable_schema(type_defs, query)
46 changes: 31 additions & 15 deletions analytics/core/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from flask import current_app as app
from core.gql_schema import schema
from core.models import mongo
from flask import Blueprint
from flask import jsonify, request
from flask import Blueprint, jsonify, request
from bson import json_util
import traceback
import logging
Expand All @@ -13,14 +12,12 @@

stats_page = Blueprint('stats_page', __name__)


@stats_page.route('/')
def index():
exercises = mongo.db.exercises.find()
exercises_list = list(exercises)
return json_util.dumps(exercises_list)


@stats_page.route('/stats')
def stats():
pipeline = [
Expand All @@ -30,7 +27,11 @@ def stats():
"username": "$username",
"exerciseType": "$exerciseType"
},
"totalDuration": {"$sum": "$duration"}
"totalDuration": {"$sum": "$duration"},
"totalDistance": {"$sum": "$distance"},
"averagePace": {"$avg": "$pace"},
"averageSpeed": {"$avg": "$speed"},
"topSpeed": {"$max": "$speed"}
}
},
{
Expand All @@ -39,7 +40,11 @@ def stats():
"exercises": {
"$push": {
"exerciseType": "$_id.exerciseType",
"totalDuration": "$totalDuration"
"totalDuration": "$totalDuration",
"totalDistance": "$totalDistance",
"averagePace": "$averagePace",
"averageSpeed": "$averageSpeed",
"topSpeed": "$topSpeed"
}
}
}
Expand All @@ -56,7 +61,6 @@ def stats():
stats = list(mongo.db.exercises.aggregate(pipeline))
return jsonify(stats=stats)


@stats_page.route('/stats/<username>', methods=['GET'])
def user_stats(username):
pipeline = [
Expand All @@ -69,7 +73,11 @@ def user_stats(username):
"username": "$username",
"exerciseType": "$exerciseType"
},
"totalDuration": {"$sum": "$duration"}
"totalDuration": {"$sum": "$duration"},
"totalDistance": {"$sum": "$distance"},
"averagePace": {"$avg": "$pace"},
"averageSpeed": {"$avg": "$speed"},
"topSpeed": {"$max": "$speed"}
}
},
{
Expand All @@ -78,7 +86,11 @@ def user_stats(username):
"exercises": {
"$push": {
"exerciseType": "$_id.exerciseType",
"totalDuration": "$totalDuration"
"totalDuration": "$totalDuration",
"totalDistance": "$totalDistance",
"averagePace": "$averagePace",
"averageSpeed": "$averageSpeed",
"topSpeed": "$topSpeed"
}
}
}
Expand All @@ -95,7 +107,6 @@ def user_stats(username):
stats = list(mongo.db.exercises.aggregate(pipeline))
return jsonify(stats=stats)


@stats_page.route('/stats/weekly/', methods=['GET'])
def weekly_user_stats():
username = request.args.get('user')
Expand Down Expand Up @@ -130,13 +141,21 @@ def weekly_user_stats():
"_id": {
"exerciseType": "$exerciseType"
},
"totalDuration": {"$sum": "$duration"}
"totalDuration": {"$sum": "$duration"},
"totalDistance": {"$sum": "$distance"},
"averagePace": {"$avg": "$pace"},
"averageSpeed": {"$avg": "$speed"},
"topSpeed": {"$max": "$speed"}
}
},
{
"$project": {
"exerciseType": "$_id.exerciseType",
"totalDuration": 1,
"totalDistance": 1,
"averagePace": 1,
"averageSpeed": 1,
"topSpeed": 1,
"_id": 0
}
}
Expand All @@ -151,20 +170,17 @@ def weekly_user_stats():
traceback.print_exc()
return jsonify(error="An internal error occurred"), 500


explorer_html = ExplorerGraphiQL().html(None)


@stats_page.route('/stats/graphql', methods=["GET"])
def graphql_explorer():
return explorer_html, 200


@stats_page.route("/stats/graphql", methods=["POST"])
def graphql_server():
data = request.get_json()
success, result = graphql_sync(
schema, data, context_value={"request": request}, debug=app.debug
)
status_code = 200 if success else 400
return jsonify(result), status_code
return jsonify(result), status_code
Loading

0 comments on commit 6c1d405

Please sign in to comment.